Compare commits

..

5 Commits

8 changed files with 8466 additions and 4 deletions

View File

@ -434,7 +434,7 @@ relocation_table_types = {
44: ("R_ARM_MOVT_ABS", 16, "S + A"),
47: ("R_ARM_THM_MOVW_ABS_NC", 16, "S + A"),
48: ("R_ARM_THM_MOVT_ABS_NC", 16, "S + A"),
48: ("R_ARM_THM_MOVT_ABS", 16, "S + A"),
},
"EM_AARCH64": {
0: ("R_AARCH64_NONE", 0, ""),

View File

@ -9,6 +9,7 @@ Typical usage example:
from . import _fields_data as fdat
from . import _output_formatter
from typing import TypeVar, Literal, Iterable, Generic, Iterator, Generator, Optional, Union
import warnings
_T = TypeVar('_T')
@ -574,7 +575,7 @@ class elf_file:
if reloc_types and 'A' in reloc_types[relocation_type][2]:
name = reloc_types[relocation_type][0]
sh = self.sections[reloc_section['sh_info']]
field = self.read_int(r_offset + sh['sh_offset'], 4, True)
field = self.read_int(r_offset + sh['sh_offset'], 4, False)
if name in ('R_386_PC32', 'R_386_32', 'R_X86_64_PC32', 'R_X86_64_PLT32', 'R_ARM_REL32', 'R_ARM_ABS32'):
return field
if name == 'R_ARM_MOVW_ABS_NC':
@ -594,11 +595,20 @@ class elf_file:
return _decode_thumb_branch_imm(field, 22)
if name in ('R_ARM_THM_JUMP24', 'R_ARM_THM_CALL'):
return _decode_thumb_branch_imm(field, 24)
if name == 'R_ARM_THM_MOVW_ABS_NC' or name == 'R_ARM_THM_MOVT_ABS':
i = (field >> 10) & 1
imm4 = field & 0xF
imm3 = (field >> 28) & 0x7
imm8 = (field >> 16) & 0xFF
imm16 = imm8 | (imm3 << 8) | (i << 11) | (imm4 << 12)
if name == 'R_ARM_THM_MOVT_ABS':
return imm16 << 16
return imm16
if '_THM_' in name:
print(f'Warning: Thumb relocation addend extraction is for {name} not implemented')
warnings.warn(f'Thumb relocation addend extraction is for {name} not implemented', stacklevel=2)
return 0
if '_MIPS_' in name:
print('Warning: MIPS relocations addend extraction is not implemented')
warnings.warn('Warning: MIPS relocations addend extraction is not implemented', stacklevel=2)
return 0
raise NotImplementedError(f"Relocation addend extraction for {name} is not implemented")

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

65
tests/test_arm_addend.py Normal file
View File

@ -0,0 +1,65 @@
import pelfy._main as _main
import os
def test_arm_addend_extraction():
# Path to the test object file
obj_path = os.path.join('tests', 'obj', 'stencils_armv7_O3.o')
elf = _main.open_elf_file(obj_path)
# Collect all ARM relocations
reloc_addends: list[tuple[str, int, int, str]] = []
for reloc in elf.get_relocations():
if reloc.type.startswith('R_ARM'):
reloc_addends.append((reloc.type, reloc['r_offset'], reloc['r_addend'], reloc.symbol.name))
# Reference values from stencils_armv7_O3.asm (addend = 0 for V4BX, -8 for JUMP24/CALL)
reference = [
('R_ARM_V4BX', 0xB4, 0, ''),
('R_ARM_V4BX', 0xC0, 0, ''),
('R_ARM_V4BX', 0xD0, 0, ''),
('R_ARM_V4BX', 0x114, 0, ''),
('R_ARM_V4BX', 0x144, 0, ''),
('R_ARM_V4BX', 0x148, 0, ''),
('R_ARM_JUMP24', 0x124, -8, '__aeabi_idiv0'),
('R_ARM_JUMP24', 0x14, -8, 'auxsub_get_42'),
('R_ARM_CALL', 0x10, -8, 'result_int'),
('R_ARM_JUMP24', 0xC, -8, 'result_float_int'),
('R_ARM_JUMP24', 0xC, -8, 'result_float_float'),
('R_ARM_JUMP24', 0xC, -8, 'result_int_int'),
('R_ARM_JUMP24', 0xC, -8, 'result_int_float'),
('R_ARM_CALL', 0xC, -8, 'aux_get_42'),
('R_ARM_JUMP24', 0x14, -8, 'result_float'),
('R_ARM_CALL', 0x4, -8, 'aux_get_42'),
('R_ARM_JUMP24', 0xC, -8, 'result_float'),
('R_ARM_JUMP24', 0x4, -8, 'result_int'),
('R_ARM_JUMP24', 0x4, -8, 'result_float'),
('R_ARM_JUMP24', 0x2C, -8, 'result_float'),
('R_ARM_CALL', 0x30, -8, 'sqrtf'),
('R_ARM_JUMP24', 0x24, -8, 'result_float'),
('R_ARM_CALL', 0x28, -8, 'sqrtf'),
('R_ARM_CALL', 0xC, -8, 'expf'),
('R_ARM_JUMP24', 0x14, -8, 'result_float'),
('R_ARM_CALL', 0x4, -8, 'expf'),
('R_ARM_JUMP24', 0xC, -8, 'result_float'),
('R_ARM_CALL', 0xC, -8, 'logf'),
('R_ARM_JUMP24', 0x14, -8, 'result_float'),
('R_ARM_CALL', 0x4, -8, 'logf'),
('R_ARM_JUMP24', 0xC, -8, 'result_float'),
('R_ARM_CALL', 0xC, -8, 'sinf'),
('R_ARM_JUMP24', 0x14, -8, 'result_float'),
('R_ARM_CALL', 0x4, -8, 'sinf'),
('R_ARM_JUMP24', 0xC, -8, 'result_float'),
]
# For each reference, check that at least one matching relocation has the expected addend
for ref_type, ref_offset, ref_addend, ref_symbol in reference:
found = False
addend = None
for typ, offset, addend, symbol in reloc_addends:
if typ == ref_type and offset == ref_offset and symbol == ref_symbol and addend == ref_addend:
found = True
break
assert found, f"Missing or incorrect addend for {ref_type} offset=0x{ref_offset:X} symbol={ref_symbol} (value={addend}, expected {ref_addend})"
print(found, f"Missing or incorrect addend for {ref_type} offset=0x{ref_offset:X} symbol={ref_symbol} (value={addend}, expected {ref_addend})")
assert False

View File

@ -0,0 +1,65 @@
import pelfy._main as _main
import os
def test_thumb_addend_extraction():
# Path to the test object file
obj_path = os.path.join('tests', 'obj', 'stencils_armv7thumb_O3_THM_MOVW.o')
elf = _main.open_elf_file(obj_path)
# Collect all relocations of interest
reloc_addends: list[tuple[str, int, int, str]] = []
for reloc in elf.get_relocations():
if reloc.type.startswith('R_ARM_THM'):
reloc_addends.append((reloc.type, reloc['r_offset'], reloc['r_addend'], reloc.symbol.name))
# Reference values from the .asm file (addend = 0 for all Thumb relocations)
reference = [
('R_ARM_THM_MOVW_ABS_NC', None, 0, 'dummy_int'),
('R_ARM_THM_MOVT_ABS', None, 0, 'dummy_int'),
('R_ARM_THM_MOVW_ABS_NC', None, 0, 'dummy_float'),
('R_ARM_THM_MOVT_ABS', None, 0, 'dummy_float'),
('R_ARM_THM_JUMP24', 0x14, 0, 'auxsub_get_42'),
('R_ARM_THM_CALL', 0xA, 0, 'result_int'),
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float_int'),
('R_ARM_THM_JUMP24', 0xC, 0, 'result_float_float'),
('R_ARM_THM_JUMP24', 0xA, 0, 'result_int_int'),
('R_ARM_THM_JUMP24', 0xC, 0, 'result_int_float'),
('R_ARM_THM_CALL', 0xA, 0, 'aux_get_42'),
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
('R_ARM_THM_CALL', 0x2, 0, 'aux_get_42'),
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
('R_ARM_THM_JUMP24', 0x2, 0, 'result_int'),
('R_ARM_THM_JUMP24', 0x4, 0, 'result_float'),
('R_ARM_THM_JUMP24', 0x28, 0, 'result_float'),
('R_ARM_THM_CALL', 0x2C, 0, 'sqrtf'),
('R_ARM_THM_JUMP24', 0x20, 0, 'result_float'),
('R_ARM_THM_CALL', 0x24, 0, 'sqrtf'),
('R_ARM_THM_CALL', 0xA, 0, 'expf'),
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
('R_ARM_THM_CALL', 0x2, 0, 'expf'),
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
('R_ARM_THM_CALL', 0xA, 0, 'logf'),
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
('R_ARM_THM_CALL', 0x2, 0, 'logf'),
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
('R_ARM_THM_CALL', 0xA, 0, 'sinf'),
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
('R_ARM_THM_CALL', 0x2, 0, 'sinf'),
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
('R_ARM_THM_CALL', 0xA, 0, 'cosf'),
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
('R_ARM_THM_CALL', 0x2, 0, 'cosf'),
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
('R_ARM_THM_CALL', 0xA, 0, 'tanf'),
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
('R_ARM_THM_CALL', 0x2, 0, 'tanf'),
]
# For each reference, check that at least one matching relocation has the expected addend
for ref_type, _, ref_addend, ref_symbol in reference:
found = False
addend = 0
for typ, offset, addend, symbol in reloc_addends:
if typ == ref_type and symbol == ref_symbol and addend == ref_addend:
found = True
break
assert found, f"Missing or incorrect addend for {ref_type} {ref_symbol} (value={addend:X}, expected {ref_addend})"