integrate properly debug info serialization
This commit is contained in:
parent
652bab50f7
commit
5899c8d160
1 changed files with 116 additions and 31 deletions
|
|
@ -436,6 +436,25 @@ impl DexWriter {
|
||||||
let mut max_addr = 0;
|
let mut max_addr = 0;
|
||||||
let mut label_min_max_addrs: HashMap<String, (usize, usize)> = HashMap::new();
|
let mut label_min_max_addrs: HashMap<String, (usize, usize)> = HashMap::new();
|
||||||
|
|
||||||
|
let parameter_names = if let Some(parameter_names) = code.parameter_names {
|
||||||
|
let mut parameter_names_idxs = vec![];
|
||||||
|
for name in ¶meter_names {
|
||||||
|
if let Some(name) = name {
|
||||||
|
parameter_names_idxs.push(Uleb128p1(*self.strings.get(name).ok_or(anyhow!(
|
||||||
|
"String {} (name of param of {}) not found",
|
||||||
|
name.__str__(),
|
||||||
|
method_id.__repr__()
|
||||||
|
))? as u32));
|
||||||
|
} else {
|
||||||
|
parameter_names_idxs.push(NO_INDEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameter_names_idxs
|
||||||
|
} else {
|
||||||
|
vec![NO_INDEX; method_id.proto.parameters.len()]
|
||||||
|
};
|
||||||
|
let mut debug_builder = DebugInfoBuilder::new(parameter_names);
|
||||||
|
|
||||||
for ins in &code.insns {
|
for ins in &code.insns {
|
||||||
match ins {
|
match ins {
|
||||||
Instruction::Label { name } => {
|
Instruction::Label { name } => {
|
||||||
|
|
@ -701,6 +720,91 @@ impl DexWriter {
|
||||||
encoded_handlers.list.push(catches);
|
encoded_handlers.list.push(catches);
|
||||||
}
|
}
|
||||||
Instruction::Label { .. } => (),
|
Instruction::Label { .. } => (),
|
||||||
|
Instruction::DebugLocal {
|
||||||
|
reg,
|
||||||
|
name,
|
||||||
|
type_,
|
||||||
|
signature,
|
||||||
|
} => {
|
||||||
|
debug_builder
|
||||||
|
.add_info(&DebugInfo::DefLocal {
|
||||||
|
addr: addr as u32,
|
||||||
|
reg: *reg,
|
||||||
|
val: DebugRegState {
|
||||||
|
type_idx: type_
|
||||||
|
.map(|ty| {
|
||||||
|
self.type_ids.get(&ty).ok_or(anyhow!(
|
||||||
|
"Could not found type {} of local variable {} in debug info of {} \
|
||||||
|
in the dex builder",
|
||||||
|
ty.__repr__(),
|
||||||
|
name.unwrap_or(String::new()),
|
||||||
|
method_id.__repr__()
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.map(|idx| *idx as u32),
|
||||||
|
name_idx: name
|
||||||
|
.map(|name| {
|
||||||
|
self.strings.get(&name.into()).ok_or(anyhow!(
|
||||||
|
"Could not found string '{}' (name of local variable in debug info of {}) \
|
||||||
|
in the dex builder",
|
||||||
|
name,
|
||||||
|
method_id.__repr__()
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.map(|idx| *idx as u32),
|
||||||
|
sig_idx: signature
|
||||||
|
.map(|sig| {
|
||||||
|
self.strings.get(&sig.into()).ok_or(anyhow!(
|
||||||
|
"Could not found string '{}' (signature of local variable {} in debug info of {}) \
|
||||||
|
in the dex builder",
|
||||||
|
sig,
|
||||||
|
name.unwrap_or(String::new()),
|
||||||
|
method_id.__repr__()
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.map(|idx| *idx as u32),
|
||||||
|
in_scope: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.context("Failled to serialize DebugLocal information")?;
|
||||||
|
}
|
||||||
|
Instruction::DebugEndLocal { reg } => debug_builder
|
||||||
|
.add_info(&DebugInfo::EndLocal {
|
||||||
|
addr: addr as u32,
|
||||||
|
reg: *reg,
|
||||||
|
})
|
||||||
|
.context("Failled to serialize DebugEndLocal information")?,
|
||||||
|
Instruction::DebugEndPrologue {} => debug_builder
|
||||||
|
.add_info(&DebugInfo::PrologueEnd { addr: addr as u32 })
|
||||||
|
.context("Failled to serialize DebugEndPrologue information")?,
|
||||||
|
Instruction::DebugBeginEpilogue {} => debug_builder
|
||||||
|
.add_info(&DebugInfo::EpilogueBegin { addr: addr as u32 })
|
||||||
|
.context("Failled to serialize DebugBeginEpilogue information")?,
|
||||||
|
Instruction::DebugSourceFile { file } => debug_builder
|
||||||
|
.add_info(&DebugInfo::SetSourceFile {
|
||||||
|
addr: addr as u32,
|
||||||
|
source_file_idx: file
|
||||||
|
.map(|file| {
|
||||||
|
self.strings.get(&file.into()).ok_or(anyhow!(
|
||||||
|
"Could not found string '{}' (name of the source file of part of {}) \
|
||||||
|
in the dex builder",
|
||||||
|
file,
|
||||||
|
method_id.__repr__()
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.transpose()?
|
||||||
|
.map(|idx| *idx as u32),
|
||||||
|
})
|
||||||
|
.context("Failled to serialize DebugSourceFile information")?,
|
||||||
|
Instruction::DebugLine { number } => debug_builder
|
||||||
|
.add_info(&DebugInfo::SetLineNumber {
|
||||||
|
addr: addr as u32,
|
||||||
|
line_num: *number as u32,
|
||||||
|
})
|
||||||
|
.context("Failled to serialize DebugLine information")?,
|
||||||
_ => {
|
_ => {
|
||||||
let ins = ins
|
let ins = ins
|
||||||
.get_raw_ins(GetRawInsParam {
|
.get_raw_ins(GetRawInsParam {
|
||||||
|
|
@ -724,6 +828,18 @@ impl DexWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let debug_info_off = if let Some(debug_info) = debug_builder.build() {
|
||||||
|
let debug_info_off = self
|
||||||
|
.section_manager
|
||||||
|
.get_aligned_size(Section::DebugInfoItem);
|
||||||
|
self.section_manager
|
||||||
|
.add_elt(Section::DebugInfoItem, Some(debug_info.size()));
|
||||||
|
self.debug_info_items.push(debug_info);
|
||||||
|
debug_info_off + 1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
if addr % 2 != 0 {
|
if addr % 2 != 0 {
|
||||||
// make sure the payload section is 4 bytes aligned
|
// make sure the payload section is 4 bytes aligned
|
||||||
let nop = (Instruction::Nop {}).get_raw_ins(GetRawInsParam::default())?;
|
let nop = (Instruction::Nop {}).get_raw_ins(GetRawInsParam::default())?;
|
||||||
|
|
@ -736,37 +852,6 @@ impl DexWriter {
|
||||||
try_.handler_off += encoded_handlers.size_field().size() as u16;
|
try_.handler_off += encoded_handlers.size_field().size() as u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
let debug_info_off = if code.debug_info.1.is_empty() && code.parameter_names.is_none() {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
let debug_info_off = self
|
|
||||||
.section_manager
|
|
||||||
.get_aligned_size(Section::DebugInfoItem);
|
|
||||||
let mut cursor = Cursor::new(code.debug_info.1);
|
|
||||||
let mut item = DebugInfoItem {
|
|
||||||
line_start: Uleb128(code.debug_info.0),
|
|
||||||
parameter_names: vec![],
|
|
||||||
bytecode: Vec::<DbgBytecode>::deserialize(&mut cursor, DbgBytecode::EndSequence)?,
|
|
||||||
};
|
|
||||||
if let Some(parameter_names) = code.parameter_names {
|
|
||||||
for name in ¶meter_names {
|
|
||||||
if let Some(name) = name {
|
|
||||||
item.parameter_names
|
|
||||||
.push(Uleb128p1(*self.strings.get(name).ok_or(anyhow!(
|
|
||||||
"String {} (name of param of {}) not found",
|
|
||||||
name.__str__(),
|
|
||||||
method_id.__repr__()
|
|
||||||
))? as u32));
|
|
||||||
} else {
|
|
||||||
item.parameter_names.push(NO_INDEX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.section_manager
|
|
||||||
.add_elt(Section::DebugInfoItem, Some(item.size()));
|
|
||||||
self.debug_info_items.push(item);
|
|
||||||
debug_info_off + 1
|
|
||||||
};
|
|
||||||
let handlers = if encoded_handlers.list.is_empty() {
|
let handlers = if encoded_handlers.list.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue