WIP link offset
This commit is contained in:
parent
01c496aaac
commit
82c1140eae
2 changed files with 62 additions and 11 deletions
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue