(
&self,
address: u64,
code: &[u8],
section_index: usize,
_relocations: &[Relocation],
diff_config: &DiffObjConfig,
)
| 167 | } |
| 168 | |
| 169 | fn scan_instructions_internal( |
| 170 | &self, |
| 171 | address: u64, |
| 172 | code: &[u8], |
| 173 | section_index: usize, |
| 174 | _relocations: &[Relocation], |
| 175 | diff_config: &DiffObjConfig, |
| 176 | ) -> Result<Vec<InstructionRef>> { |
| 177 | let start_addr = address as u32; |
| 178 | let end_addr = start_addr + code.len() as u32; |
| 179 | |
| 180 | // Mapping symbols decide what kind of data comes after it. $a for ARM code, $t for Thumb code and $d for data. |
| 181 | let fallback_mappings = |
| 182 | [DisasmMode { address: start_addr, mapping: unarm::ParseMode::Arm }]; |
| 183 | let mapping_symbols = self |
| 184 | .disasm_modes |
| 185 | .get(§ion_index) |
| 186 | .map(|x| x.as_slice()) |
| 187 | .unwrap_or(&fallback_mappings); |
| 188 | let first_mapping_idx = mapping_symbols |
| 189 | .binary_search_by_key(&start_addr, |x| x.address) |
| 190 | .unwrap_or_else(|idx| idx.saturating_sub(1)); |
| 191 | let mut mode = mapping_symbols[first_mapping_idx].mapping; |
| 192 | |
| 193 | let mut mappings_iter = mapping_symbols |
| 194 | .iter() |
| 195 | .copied() |
| 196 | .skip(first_mapping_idx + 1) |
| 197 | .take_while(|x| x.address < end_addr); |
| 198 | let mut next_mapping = mappings_iter.next(); |
| 199 | |
| 200 | let min_ins_size = if mode == unarm::ParseMode::Thumb { 2 } else { 4 }; |
| 201 | let ins_count = code.len() / min_ins_size; |
| 202 | let mut ops = Vec::<InstructionRef>::with_capacity(ins_count); |
| 203 | |
| 204 | let options = self.unarm_options(diff_config); |
| 205 | |
| 206 | let mut address = start_addr; |
| 207 | while address < end_addr { |
| 208 | while let Some(next) = next_mapping.filter(|x| address >= x.address) { |
| 209 | // Change mapping |
| 210 | mode = next.mapping; |
| 211 | next_mapping = mappings_iter.next(); |
| 212 | } |
| 213 | |
| 214 | let data = &code[(address - start_addr) as usize..]; |
| 215 | if data.len() < min_ins_size { |
| 216 | // Push the remainder as data |
| 217 | ops.push(InstructionRef { |
| 218 | address: address as u64, |
| 219 | size: data.len() as u8, |
| 220 | opcode: OPCODE_DATA, |
| 221 | branch_dest: None, |
| 222 | }); |
| 223 | break; |
| 224 | } |
| 225 | |
| 226 | // Check how many bytes we can/should read |
nothing calls this directly
no test coverage detected