WIP link offset

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2024-03-29 11:21:31 +01:00
parent 01c496aaac
commit 82c1140eae
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
2 changed files with 62 additions and 11 deletions

View file

@ -1991,7 +1991,7 @@ impl DexFragment {
} else {
bail!("Fragment cannot be linked without the frag index (see DexFragment::frag_index doc)")
};
self.link_state.start_linking_idx()?;
self.link_state = self.link_state.start_linking_idx()?;
let string_reindex = Vec::with_capacity(self.strings.len());
// TODO: considering we have the map, this can be simplified a lot
let mut global_idx = 0;
@ -2419,6 +2419,11 @@ impl DexFragment {
pub fn get_interfaces(&self) -> &Vec<IdType> {
&self.interfaces
}
pub fn link_offsets_but_class_data(&mut self, offsets: &SectionOffsets) -> Result<()> {
self.link_state = self.link_state.start_linking_offset()?;
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -2627,25 +2632,51 @@ enum FragLinkState {
//code_item_relocation: HashMap<u32, u32>,
//debug_info_item_relocation: HashMap<u32, u32>,
annotation_item_relocation: HashMap<u32, u32>,
encoded_array_relocation: HashMap<u32, u32>, // TODO only one?
encoded_array_relocation: HashMap<u32, u32>,
},
/// The index used in the fragment are linked and offset are in the process of beeing linked.
LinkingOffset {
// Not relocation: the code are entirely generated at link id time
//code_item_relocation: HashMap<u32, u32>,
//debug_info_item_relocation: HashMap<u32, u32>,
annotation_item_relocation: HashMap<u32, u32>,
encoded_array_relocation: HashMap<u32, u32>,
},
}
impl FragLinkState {
fn start_linking_idx(&mut self) -> Result<()> {
fn start_linking_idx(self) -> Result<Self> {
match self {
Self::Unlinked => {
*self = Self::LinkedIdx {
Ok(Self::LinkedIdx {
// code_item_relocation: HashMap::<u32, u32>::new(),
// debug_info_item_relocation: HashMap::<u32, u32>::new(),
annotation_item_relocation: HashMap::<u32, u32>::new(),
encoded_array_relocation: HashMap::<u32, u32>::new(),
};
Ok(())
})
}
_ => {
bail!("Cannot link the idx in a fragment that is already linked");
}
}
}
fn start_linking_offset(self) -> Result<Self> {
match self {
Self::LinkedIdx {
annotation_item_relocation,
encoded_array_relocation,
} => {
Ok(Self::LinkingOffset {
// code_item_relocation: HashMap::<u32, u32>::new(),
// debug_info_item_relocation: HashMap::<u32, u32>::new(),
annotation_item_relocation,
encoded_array_relocation,
})
}
_ => {
bail!("Cannot link the offsets in a fragment that have already linked offset of not linked ids");
}
}
}
}

View file

@ -167,6 +167,8 @@ impl<'a> DexWriter<'a> {
// collect section offsets
// The type are quite uggly but I'm behind on time
let mut fragment_section_manager = FragSectionManager::default();
// DexFragment and the merged fragment section managers of the previous fragments
// (excluding the current fragment)
let fragments_in_file: Vec<(FragSectionManager, DexFragment)> = fragments_in_file
.into_iter()
.map(|fragment| {
@ -228,8 +230,8 @@ impl<'a> DexWriter<'a> {
Ok(ty_list)
})
.collect::<Result<_>>()?;
section_manager.add_elt(Section::MapList, Some(4));
let offsets = section_manager.get_offsets();
let map_item_size = 12; /* = MapItem {
type_: MapItemType::HeaderItem,
unused: 0,
@ -237,6 +239,15 @@ impl<'a> DexWriter<'a> {
offset: 0,
}
.size(); */
for section in Section::VARIANT_LIST {
if !section.is_data() && section_manager.get_nb_elt(*section) != 0 {
section_manager.incr_section_size(Section::MapList, map_item_size);
}
}
let offsets = section_manager.get_offsets();
// Sections are computed (except for class_data_item sizes, but those are at the end of the
// file so it does not affect the map_list)
let mut map_list = MapList::default();
for section in Section::VARIANT_LIST {
if !section.is_data() && section_manager.get_nb_elt(*section) != 0 {
@ -250,9 +261,18 @@ impl<'a> DexWriter<'a> {
}
}
// TODO: link en correct data section
// link everything but class_def_item.class_data_off and collect the offsets of the
// sections of the fragments
let fragments_in_file: Vec<(SectionOffsets, DexFragment)> = fragments_in_file
.into_iter()
.map(|(frag_section_manager, fragment)| {
let fragment_offsets = offsets.get_fragment_offset(&frag_section_manager);
fragment.link_offsets_but_class_data(&fragment_offsets);
todo!()
})
.collect();
// TODO: link everything else
// TODO: class_def_item.class_data_off
// TODO: serialize
@ -324,7 +344,7 @@ impl<'a> DexIndex<'a> {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Section {
pub(crate) enum Section {
HeaderItem,
StringIdItem,
TypeIdItem,
@ -662,7 +682,7 @@ impl SectionManager {
}
#[derive(Debug, Default, Clone)]
struct SectionOffsets {
pub(crate) struct SectionOffsets {
offsets: [u32; SectionManager::NB_SECTION],
}