(
&self,
_file: &object::File<'_>,
section: &object::Section,
address: u64,
relocation: &object::Relocation,
)
| 333 | } |
| 334 | |
| 335 | fn relocation_override( |
| 336 | &self, |
| 337 | _file: &object::File<'_>, |
| 338 | section: &object::Section, |
| 339 | address: u64, |
| 340 | relocation: &object::Relocation, |
| 341 | ) -> Result<Option<RelocationOverride>> { |
| 342 | match relocation.flags() { |
| 343 | // Handle ELF implicit relocations |
| 344 | object::RelocationFlags::Elf { r_type } => { |
| 345 | if relocation.has_implicit_addend() { |
| 346 | let section_data = section.data()?; |
| 347 | let address = address as usize; |
| 348 | let addend = match r_type { |
| 349 | // ARM calls |
| 350 | elf::R_ARM_PC24 |
| 351 | | elf::R_ARM_XPC25 |
| 352 | | elf::R_ARM_CALL |
| 353 | | elf::R_ARM_JUMP24 => { |
| 354 | let data = section_data[address..address + 4].try_into()?; |
| 355 | let addend = self.endianness.read_i32_bytes(data); |
| 356 | let imm24 = addend & 0xffffff; |
| 357 | (imm24 << 2) << 8 >> 8 |
| 358 | } |
| 359 | |
| 360 | // Thumb calls |
| 361 | elf::R_ARM_THM_PC22 | elf::R_ARM_THM_XPC22 => { |
| 362 | let data = section_data[address..address + 2].try_into()?; |
| 363 | let high = self.endianness.read_i16_bytes(data) as i32; |
| 364 | let data = section_data[address + 2..address + 4].try_into()?; |
| 365 | let low = self.endianness.read_i16_bytes(data) as i32; |
| 366 | |
| 367 | let imm22 = ((high & 0x7ff) << 11) | (low & 0x7ff); |
| 368 | (imm22 << 1) << 9 >> 9 |
| 369 | } |
| 370 | |
| 371 | // Thumb unconditional branch (B, 11-bit offset) |
| 372 | elf::R_ARM_THM_PC11 => { |
| 373 | let data = section_data[address..address + 2].try_into()?; |
| 374 | let insn = self.endianness.read_u16_bytes(data) as i32; |
| 375 | let imm11 = insn & 0x7ff; |
| 376 | (imm11 << 1) << 20 >> 20 |
| 377 | } |
| 378 | |
| 379 | // Thumb conditional branch (B<cond>, 8-bit offset) |
| 380 | elf::R_ARM_THM_PC9 => { |
| 381 | let data = section_data[address..address + 2].try_into()?; |
| 382 | let insn = self.endianness.read_u16_bytes(data) as i32; |
| 383 | let imm8 = insn & 0xff; |
| 384 | (imm8 << 1) << 23 >> 23 |
| 385 | } |
| 386 | |
| 387 | // Data |
| 388 | elf::R_ARM_ABS32 => { |
| 389 | let data = section_data[address..address + 4].try_into()?; |
| 390 | self.endianness.read_i32_bytes(data) |
| 391 | } |
| 392 |
no outgoing calls
no test coverage detected