fix link an alignment issues
This commit is contained in:
parent
40f1955dcd
commit
a3e9364aa0
1 changed files with 59 additions and 20 deletions
|
|
@ -1306,7 +1306,9 @@ impl DexWriter {
|
||||||
let debug_info_off = if code.debug_info.is_empty() {
|
let debug_info_off = if code.debug_info.is_empty() {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
let debug_info_off = self.section_manager.get_size(Section::DebugInfoItem);
|
let debug_info_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::DebugInfoItem);
|
||||||
let item = DebugInfoItem::deserialize_from_slice(&code.debug_info)?;
|
let item = DebugInfoItem::deserialize_from_slice(&code.debug_info)?;
|
||||||
self.section_manager
|
self.section_manager
|
||||||
.add_elt(Section::DebugInfoItem, Some(item.size()));
|
.add_elt(Section::DebugInfoItem, Some(item.size()));
|
||||||
|
|
@ -1409,7 +1411,7 @@ impl DexWriter {
|
||||||
Uleb128(class.direct_methods.get(id).unwrap().get_raw_access_flags());
|
Uleb128(class.direct_methods.get(id).unwrap().get_raw_access_flags());
|
||||||
// No if let because ownership gunfooterie
|
// No if let because ownership gunfooterie
|
||||||
let code_off = if class.direct_methods.get(id).unwrap().code.is_some() {
|
let code_off = if class.direct_methods.get(id).unwrap().code.is_some() {
|
||||||
let code_off = self.section_manager.get_size(Section::CodeItem);
|
let code_off = self.section_manager.get_aligned_size(Section::CodeItem);
|
||||||
self.insert_code_item(id.clone(), true)?;
|
self.insert_code_item(id.clone(), true)?;
|
||||||
Uleb128(code_off + 1)
|
Uleb128(code_off + 1)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1444,7 +1446,7 @@ impl DexWriter {
|
||||||
);
|
);
|
||||||
// No if let because ownership gunfooterie
|
// No if let because ownership gunfooterie
|
||||||
let code_off = if class.virtual_methods.get(id).unwrap().code.is_some() {
|
let code_off = if class.virtual_methods.get(id).unwrap().code.is_some() {
|
||||||
let code_off = self.section_manager.get_size(Section::CodeItem);
|
let code_off = self.section_manager.get_aligned_size(Section::CodeItem);
|
||||||
self.insert_code_item(id.clone(), false)?;
|
self.insert_code_item(id.clone(), false)?;
|
||||||
Uleb128(code_off + 1)
|
Uleb128(code_off + 1)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1645,7 +1647,9 @@ impl DexWriter {
|
||||||
values.push(DexValue::MethodType(call_site.type_.clone()));
|
values.push(DexValue::MethodType(call_site.type_.clone()));
|
||||||
values.extend(call_site.args.iter().cloned());
|
values.extend(call_site.args.iter().cloned());
|
||||||
self.call_site_ids.push(CallSiteIdItem {
|
self.call_site_ids.push(CallSiteIdItem {
|
||||||
call_site_off: self.section_manager.get_size(Section::EncodedArrayItem),
|
call_site_off: self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::EncodedArrayItem),
|
||||||
}); // linked in link_call_site_ids()
|
}); // linked in link_call_site_ids()
|
||||||
self.section_manager.add_elt(Section::CallSiteIdItem, None);
|
self.section_manager.add_elt(Section::CallSiteIdItem, None);
|
||||||
self.insert_encoded_array_item(DexArray(values))
|
self.insert_encoded_array_item(DexArray(values))
|
||||||
|
|
@ -1722,7 +1726,9 @@ impl DexWriter {
|
||||||
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
||||||
for annot in annotations {
|
for annot in annotations {
|
||||||
annotation_set.entries.push(AnnotationOffItem {
|
annotation_set.entries.push(AnnotationOffItem {
|
||||||
annotation_off: self.section_manager.get_size(Section::AnnotationItem),
|
annotation_off: self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationItem),
|
||||||
}); // linked in link_annotations()
|
}); // linked in link_annotations()
|
||||||
|
|
||||||
let item = AnnotationItem {
|
let item = AnnotationItem {
|
||||||
|
|
@ -1769,7 +1775,9 @@ impl DexWriter {
|
||||||
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
||||||
for annot in annotations {
|
for annot in annotations {
|
||||||
annotation_set.entries.push(AnnotationOffItem {
|
annotation_set.entries.push(AnnotationOffItem {
|
||||||
annotation_off: self.section_manager.get_size(Section::AnnotationItem),
|
annotation_off: self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationItem),
|
||||||
}); // linked in link_annotations()
|
}); // linked in link_annotations()
|
||||||
|
|
||||||
let item = AnnotationItem {
|
let item = AnnotationItem {
|
||||||
|
|
@ -1816,7 +1824,9 @@ impl DexWriter {
|
||||||
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
||||||
for annot in annotations {
|
for annot in annotations {
|
||||||
annotation_set.entries.push(AnnotationOffItem {
|
annotation_set.entries.push(AnnotationOffItem {
|
||||||
annotation_off: self.section_manager.get_size(Section::AnnotationItem),
|
annotation_off: self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationItem),
|
||||||
}); // linked in link_annotations()
|
}); // linked in link_annotations()
|
||||||
|
|
||||||
let item = AnnotationItem {
|
let item = AnnotationItem {
|
||||||
|
|
@ -1864,7 +1874,9 @@ impl DexWriter {
|
||||||
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
annotations.sort_by_key(|annot| annot.annotation.type_.clone());
|
||||||
for annot in annotations {
|
for annot in annotations {
|
||||||
annotation_set.entries.push(AnnotationOffItem {
|
annotation_set.entries.push(AnnotationOffItem {
|
||||||
annotation_off: self.section_manager.get_size(Section::AnnotationItem),
|
annotation_off: self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationItem),
|
||||||
}); // linked in link_annotations()
|
}); // linked in link_annotations()
|
||||||
|
|
||||||
let item = AnnotationItem {
|
let item = AnnotationItem {
|
||||||
|
|
@ -1914,7 +1926,9 @@ impl DexWriter {
|
||||||
for (param_idx, has_annotation) in param_has_annotation.into_iter().enumerate() {
|
for (param_idx, has_annotation) in param_has_annotation.into_iter().enumerate() {
|
||||||
list.list.push(AnnotationSetRefItem {
|
list.list.push(AnnotationSetRefItem {
|
||||||
annotations_off: if has_annotation {
|
annotations_off: if has_annotation {
|
||||||
let annotation_off = self.section_manager.get_size(Section::AnnotationSetItem);
|
let annotation_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationSetItem);
|
||||||
self.insert_parameters_annotation_set(method_id, is_direct_method, param_idx)?;
|
self.insert_parameters_annotation_set(method_id, is_direct_method, param_idx)?;
|
||||||
annotation_off + 1
|
annotation_off + 1
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1942,7 +1956,9 @@ impl DexWriter {
|
||||||
fn insert_annotations(&mut self, class_id: &IdType) -> Result<()> {
|
fn insert_annotations(&mut self, class_id: &IdType) -> Result<()> {
|
||||||
let (class, _) = self.class_defs.get(class_id).unwrap();
|
let (class, _) = self.class_defs.get(class_id).unwrap();
|
||||||
let class_annotations_off = if !class.annotations.is_empty() {
|
let class_annotations_off = if !class.annotations.is_empty() {
|
||||||
let class_annotations_off = self.section_manager.get_size(Section::AnnotationSetItem);
|
let class_annotations_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationSetItem);
|
||||||
self.insert_class_annotation_set(class_id)
|
self.insert_class_annotation_set(class_id)
|
||||||
.with_context(|| {
|
.with_context(|| {
|
||||||
format!(
|
format!(
|
||||||
|
|
@ -1973,7 +1989,10 @@ impl DexWriter {
|
||||||
field_id.__repr__(), class_id.__repr__()),
|
field_id.__repr__(), class_id.__repr__()),
|
||||||
};
|
};
|
||||||
if !field.annotations.is_empty() {
|
if !field.annotations.is_empty() {
|
||||||
let annotations_off = self.section_manager.get_size(Section::AnnotationSetItem) + 1;
|
let annotations_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationSetItem)
|
||||||
|
+ 1;
|
||||||
self.insert_field_annotation_set(&field_id, is_static)?;
|
self.insert_field_annotation_set(&field_id, is_static)?;
|
||||||
field_annotations.push(FieldAnnotation {
|
field_annotations.push(FieldAnnotation {
|
||||||
field_idx: *self.field_ids.get(&field_id).ok_or(anyhow!(
|
field_idx: *self.field_ids.get(&field_id).ok_or(anyhow!(
|
||||||
|
|
@ -2004,7 +2023,10 @@ impl DexWriter {
|
||||||
method_id.__repr__(), class_id.__repr__()),
|
method_id.__repr__(), class_id.__repr__()),
|
||||||
};
|
};
|
||||||
if !method.annotations.is_empty() {
|
if !method.annotations.is_empty() {
|
||||||
let annotations_off = self.section_manager.get_size(Section::AnnotationSetItem) + 1;
|
let annotations_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationSetItem)
|
||||||
|
+ 1;
|
||||||
self.insert_method_annotation_set(method_id, is_direct)?;
|
self.insert_method_annotation_set(method_id, is_direct)?;
|
||||||
method_annotations.push(MethodAnnotation {
|
method_annotations.push(MethodAnnotation {
|
||||||
method_idx: *self.method_ids.get(method_id).ok_or(anyhow!(
|
method_idx: *self.method_ids.get(method_id).ok_or(anyhow!(
|
||||||
|
|
@ -2030,8 +2052,10 @@ impl DexWriter {
|
||||||
method_id.__repr__(), class_id.__repr__()),
|
method_id.__repr__(), class_id.__repr__()),
|
||||||
};
|
};
|
||||||
if !method.parameters_annotations.is_empty() {
|
if !method.parameters_annotations.is_empty() {
|
||||||
let annotations_off =
|
let annotations_off = self
|
||||||
self.section_manager.get_size(Section::AnnotationSetRefList) + 1;
|
.section_manager
|
||||||
|
.get_aligned_size(Section::AnnotationSetRefList)
|
||||||
|
+ 1;
|
||||||
self.insert_parameters_annotation_set_list(&method_id, is_direct)?;
|
self.insert_parameters_annotation_set_list(&method_id, is_direct)?;
|
||||||
parameter_annotations.push(ParameterAnnotation {
|
parameter_annotations.push(ParameterAnnotation {
|
||||||
method_idx: *self.method_ids.get(&method_id).ok_or(anyhow!(
|
method_idx: *self.method_ids.get(&method_id).ok_or(anyhow!(
|
||||||
|
|
@ -2081,7 +2105,9 @@ impl DexWriter {
|
||||||
.and_modify(|(_, i)| *i = idx);
|
.and_modify(|(_, i)| *i = idx);
|
||||||
let (class, _) = self.class_defs.get(class_id).unwrap();
|
let (class, _) = self.class_defs.get(class_id).unwrap();
|
||||||
let class_data_off = if class.has_data_item() {
|
let class_data_off = if class.has_data_item() {
|
||||||
let class_data_off = self.section_manager.get_size(Section::ClassDataItem);
|
let class_data_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::ClassDataItem);
|
||||||
self.insert_class_data_item(class_id)?;
|
self.insert_class_data_item(class_id)?;
|
||||||
class_data_off + 1
|
class_data_off + 1
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2091,7 +2117,9 @@ impl DexWriter {
|
||||||
// mutating self with `insert_class_data_item`, and get a new ref afterward
|
// mutating self with `insert_class_data_item`, and get a new ref afterward
|
||||||
let (class, _) = self.class_defs.get(class_id).unwrap();
|
let (class, _) = self.class_defs.get(class_id).unwrap();
|
||||||
let static_values_off = if class.has_static_values_array() {
|
let static_values_off = if class.has_static_values_array() {
|
||||||
let static_values_off = self.section_manager.get_size(Section::EncodedArrayItem);
|
let static_values_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::EncodedArrayItem);
|
||||||
self.insert_class_static_values(class_id)?;
|
self.insert_class_static_values(class_id)?;
|
||||||
static_values_off + 1
|
static_values_off + 1
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2101,7 +2129,7 @@ impl DexWriter {
|
||||||
let annotations_off = if class.has_annotations() {
|
let annotations_off = if class.has_annotations() {
|
||||||
let annotations_off = self
|
let annotations_off = self
|
||||||
.section_manager
|
.section_manager
|
||||||
.get_size(Section::AnnotationsDirectoryItem);
|
.get_aligned_size(Section::AnnotationsDirectoryItem);
|
||||||
self.insert_annotations(class_id)?;
|
self.insert_annotations(class_id)?;
|
||||||
annotations_off + 1
|
annotations_off + 1
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2255,7 +2283,7 @@ impl DexWriter {
|
||||||
self.header.method_ids_off = self.section_manager.get_offset(Section::MethodIdItem);
|
self.header.method_ids_off = self.section_manager.get_offset(Section::MethodIdItem);
|
||||||
self.header.class_defs_size = self.section_manager.get_nb_elt(Section::ClassDefItem) as u32;
|
self.header.class_defs_size = self.section_manager.get_nb_elt(Section::ClassDefItem) as u32;
|
||||||
self.header.class_defs_off = self.section_manager.get_offset(Section::ClassDefItem);
|
self.header.class_defs_off = self.section_manager.get_offset(Section::ClassDefItem);
|
||||||
self.header.data_size = self.section_manager.get_size(Section::Data);
|
self.header.data_size = self.section_manager.get_unaligned_size(Section::Data);
|
||||||
self.header.data_off = self.section_manager.get_offset(Section::Data);
|
self.header.data_off = self.section_manager.get_offset(Section::Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2622,6 +2650,8 @@ impl DexWriter {
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
io::copy(&mut buffer, &mut hasher)?;
|
io::copy(&mut buffer, &mut hasher)?;
|
||||||
self.header.signature = hasher.finalize().into();
|
self.header.signature = hasher.finalize().into();
|
||||||
|
let size = buffer.seek(SeekFrom::End(0))? as u32;
|
||||||
|
self.header.file_size = size;
|
||||||
buffer.rewind()?;
|
buffer.rewind()?;
|
||||||
self.header.serialize(&mut buffer)?;
|
self.header.serialize(&mut buffer)?;
|
||||||
|
|
||||||
|
|
@ -3009,7 +3039,7 @@ impl SectionManager {
|
||||||
size
|
size
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(&self, section: Section) -> u32 {
|
fn get_unaligned_size(&self, section: Section) -> u32 {
|
||||||
if section.is_data() {
|
if section.is_data() {
|
||||||
self.sizes[section.get_index()..].iter().sum()
|
self.sizes[section.get_index()..].iter().sum()
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3017,6 +3047,15 @@ impl SectionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The position of a potential new item in the section considering alignment.
|
||||||
|
fn get_aligned_size(&self, section: Section) -> u32 {
|
||||||
|
let mut size = self.get_unaligned_size(section);
|
||||||
|
while size % section.get_item_alignment() != 0 {
|
||||||
|
size += 1;
|
||||||
|
}
|
||||||
|
size
|
||||||
|
}
|
||||||
|
|
||||||
fn get_nb_elt(&self, section: Section) -> usize {
|
fn get_nb_elt(&self, section: Section) -> usize {
|
||||||
self.nb_elt[section.get_index()]
|
self.nb_elt[section.get_index()]
|
||||||
}
|
}
|
||||||
|
|
@ -3045,7 +3084,7 @@ impl SectionManager {
|
||||||
fn show(&self) {
|
fn show(&self) {
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
for section in Section::VARIANT_LIST {
|
for section in Section::VARIANT_LIST {
|
||||||
let size = self.get_size(*section);
|
let size = self.get_unaligned_size(*section);
|
||||||
let new_offset = offset + size;
|
let new_offset = offset + size;
|
||||||
let nb_elt = self.get_nb_elt(*section);
|
let nb_elt = self.get_nb_elt(*section);
|
||||||
println!(
|
println!(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue