MCPcopy Index your code
hub / github.com/encounter/objdiff / scan_instructions_internal

Method scan_instructions_internal

objdiff-core/src/arch/arm.rs:169–313  ·  view source on GitHub ↗
(
        &self,
        address: u64,
        code: &[u8],
        section_index: usize,
        _relocations: &[Relocation],
        diff_config: &DiffObjConfig,
    )

Source from the content-addressed store, hash-verified

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(&section_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

Callers

nothing calls this directly

Calls 4

getMethod · 0.80
nextMethod · 0.80
unarm_optionsMethod · 0.80
pushMethod · 0.80

Tested by

no test coverage detected