mirror of https://github.com/Nonannet/pelfy.git
Compare commits
5 Commits
86de67a7f8
...
940488b660
| Author | SHA1 | Date |
|---|---|---|
|
|
940488b660 | |
|
|
9a4cbe92af | |
|
|
20b00109e9 | |
|
|
5663e7f5b0 | |
|
|
39bb639c1f |
|
|
@ -434,7 +434,7 @@ relocation_table_types = {
|
||||||
44: ("R_ARM_MOVT_ABS", 16, "S + A"),
|
44: ("R_ARM_MOVT_ABS", 16, "S + A"),
|
||||||
|
|
||||||
47: ("R_ARM_THM_MOVW_ABS_NC", 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": {
|
"EM_AARCH64": {
|
||||||
0: ("R_AARCH64_NONE", 0, ""),
|
0: ("R_AARCH64_NONE", 0, ""),
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ Typical usage example:
|
||||||
from . import _fields_data as fdat
|
from . import _fields_data as fdat
|
||||||
from . import _output_formatter
|
from . import _output_formatter
|
||||||
from typing import TypeVar, Literal, Iterable, Generic, Iterator, Generator, Optional, Union
|
from typing import TypeVar, Literal, Iterable, Generic, Iterator, Generator, Optional, Union
|
||||||
|
import warnings
|
||||||
|
|
||||||
_T = TypeVar('_T')
|
_T = TypeVar('_T')
|
||||||
|
|
||||||
|
|
@ -574,7 +575,7 @@ class elf_file:
|
||||||
if reloc_types and 'A' in reloc_types[relocation_type][2]:
|
if reloc_types and 'A' in reloc_types[relocation_type][2]:
|
||||||
name = reloc_types[relocation_type][0]
|
name = reloc_types[relocation_type][0]
|
||||||
sh = self.sections[reloc_section['sh_info']]
|
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'):
|
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
|
return field
|
||||||
if name == 'R_ARM_MOVW_ABS_NC':
|
if name == 'R_ARM_MOVW_ABS_NC':
|
||||||
|
|
@ -594,11 +595,20 @@ class elf_file:
|
||||||
return _decode_thumb_branch_imm(field, 22)
|
return _decode_thumb_branch_imm(field, 22)
|
||||||
if name in ('R_ARM_THM_JUMP24', 'R_ARM_THM_CALL'):
|
if name in ('R_ARM_THM_JUMP24', 'R_ARM_THM_CALL'):
|
||||||
return _decode_thumb_branch_imm(field, 24)
|
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:
|
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
|
return 0
|
||||||
if '_MIPS_' in name:
|
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
|
return 0
|
||||||
raise NotImplementedError(f"Relocation addend extraction for {name} is not implemented")
|
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.
|
|
@ -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
|
||||||
|
|
@ -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})"
|
||||||
Loading…
Reference in New Issue