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 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 {
|
||||
match ins {
|
||||
Instruction::Label { name } => {
|
||||
|
|
@ -701,6 +720,91 @@ impl DexWriter {
|
|||
encoded_handlers.list.push(catches);
|
||||
}
|
||||
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
|
||||
.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 {
|
||||
// make sure the payload section is 4 bytes aligned
|
||||
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;
|
||||
}
|
||||
|
||||
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() {
|
||||
None
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue