mirror of https://github.com/Nonannet/pelfy.git
Compare commits
1 Commits
fc12bc769b
...
bf1559609a
| Author | SHA1 | Date |
|---|---|---|
|
|
bf1559609a |
|
|
@ -390,41 +390,50 @@ relocation_table_types = {
|
||||||
},
|
},
|
||||||
"EM_ARM": {
|
"EM_ARM": {
|
||||||
0: ("R_ARM_NONE", 0, ""),
|
0: ("R_ARM_NONE", 0, ""),
|
||||||
1: ("R_ARM_PC24", 24, "((S + A) | T) - P"),
|
|
||||||
2: ("R_ARM_ABS32", 32, "(S + A) | T"),
|
1: ("R_ARM_PC24", 24, "S - P + A"),
|
||||||
3: ("R_ARM_REL32", 32, "((S + A) | T) - P"),
|
2: ("R_ARM_ABS32", 32, "S + A"),
|
||||||
4: ("R_ARM_LDR_PC_G0", 12, "S + A - P"),
|
3: ("R_ARM_REL32", 32, "S - P + A"),
|
||||||
|
4: ("R_ARM_LDR_PC_G0", 12, "S - P + A"),
|
||||||
|
|
||||||
5: ("R_ARM_ABS16", 16, "S + A"),
|
5: ("R_ARM_ABS16", 16, "S + A"),
|
||||||
6: ("R_ARM_ABS12", 12, "S + A"),
|
6: ("R_ARM_ABS12", 12, "S + A"),
|
||||||
7: ("R_ARM_THM_ABS5", 5, "S + A"),
|
7: ("R_ARM_THM_ABS5", 5, "S + A"),
|
||||||
8: ("R_ARM_ABS8", 8, "S + A"),
|
8: ("R_ARM_ABS8", 8, "S + A"),
|
||||||
9: ("R_ARM_SBREL32", 32, "((S + A) | T) - B(S)"),
|
9: ("R_ARM_SBREL32", 32, "S - B + A"),
|
||||||
10: ("R_ARM_THM_CALL", 22, "((S + A) | T) - P"),
|
|
||||||
11: ("R_ARM_THM_PC8", 8, "S + A - Pa"),
|
10: ("R_ARM_THM_CALL", 22, "S - P + A"),
|
||||||
12: ("R_ARM_BREL_ADJ", 0, "ChangeIn[B(S)] + A"),
|
11: ("R_ARM_THM_PC8", 8, "S - P + A"),
|
||||||
|
12: ("R_ARM_BREL_ADJ", 0, ""),
|
||||||
13: ("R_ARM_TLS_DESC", 0, ""),
|
13: ("R_ARM_TLS_DESC", 0, ""),
|
||||||
14: ("R_ARM_THM_SWI8", 8, "S + A"),
|
14: ("R_ARM_THM_SWI8", 8, "S + A"),
|
||||||
|
|
||||||
15: ("R_ARM_XPC25", 25, ""),
|
15: ("R_ARM_XPC25", 25, ""),
|
||||||
16: ("R_ARM_THM_XPC22", 22, ""),
|
16: ("R_ARM_THM_XPC22", 22, ""),
|
||||||
17: ("R_ARM_TLS_DTPMOD32", 0, "Module[S]"),
|
|
||||||
18: ("R_ARM_TLS_DTPOFF32", 0, "S + A - TLS"),
|
28: ("R_ARM_CALL", 24, "((S + A) - P) >> 2"),
|
||||||
19: ("R_ARM_TLS_TPOFF32", 0, "S + A - tp"),
|
29: ("R_ARM_JUMP24", 24, "((S + A) - P) >> 2"),
|
||||||
20: ("R_ARM_COPY", 0, ""),
|
30: ("R_ARM_THM_JUMP24", 24, "((S + A) - P) >> 1"),
|
||||||
21: ("R_ARM_GLOB_DAT", 0, "(S + A) | T"),
|
|
||||||
22: ("R_ARM_JUMP_SLOT", 0, "(S + A) | T"),
|
32: ("R_ARM_ALU_PCREL_7_0", 8, "(S - P + A) & 0x000000FF"),
|
||||||
23: ("R_ARM_RELATIVE", 0, "B(S) + A"),
|
33: ("R_ARM_ALU_PCREL_15_8", 8, "(S - P + A) & 0x0000FF00"),
|
||||||
24: ("R_ARM_GOTOFF32", 0, "((S + A) | T) - GOT_ORG"),
|
34: ("R_ARM_ALU_PCREL_23_15", 9, "(S - P + A) & 0x00FF8000"),
|
||||||
25: ("R_ARM_BASE_PREL", 0, "B(S) + A - P"),
|
|
||||||
26: ("R_ARM_GOT_BREL", 0, "GOT(S) + A - GOT_ORG"),
|
35: ("R_ARM_LDR_SBREL_11_0", 12, "(S - B + A) & 0x00000FFF"),
|
||||||
27: ("R_ARM_PLT32", 0, "((S + A) | T) - P"),
|
36: ("R_ARM_ALU_SBREL_19_12", 8, "(S - B + A) & 0x000FF000"),
|
||||||
28: ("R_ARM_CALL", 24, "((S + A) | T) - P"),
|
37: ("R_ARM_ALU_SBREL_27_20", 8, "(S - B + A) & 0x0FF00000"),
|
||||||
29: ("R_ARM_JUMP24", 24, "((S + A) | T) - P"),
|
|
||||||
30: ("R_ARM_THM_JUMP24", 24, "((S + A) | T) - P"),
|
38: ("R_ARM_TARGET1", 32, "implementation defined"),
|
||||||
|
39: ("R_ARM_SBREL31", 31, "S - B + A"),
|
||||||
|
|
||||||
40: ("R_ARM_V4BX", 0, ""),
|
40: ("R_ARM_V4BX", 0, ""),
|
||||||
42: ("R_ARM_PREL31", 31, "((S + A) | T) - P"),
|
41: ("R_ARM_TARGET2", 32, "implementation defined"),
|
||||||
43: ("R_ARM_MOVW_ABS_NC", 16, "(S + A) | T"),
|
42: ("R_ARM_PREL31", 31, "S - P + A"),
|
||||||
|
|
||||||
|
43: ("R_ARM_MOVW_ABS_NC", 16, "S + A"),
|
||||||
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) | T"),
|
|
||||||
|
47: ("R_ARM_THM_MOVW_ABS_NC", 16, "S + A"),
|
||||||
48: ("R_ARM_THM_MOVT_ABS", 16, "S + A"),
|
48: ("R_ARM_THM_MOVT_ABS", 16, "S + A"),
|
||||||
},
|
},
|
||||||
"EM_AARCH64": {
|
"EM_AARCH64": {
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,51 @@ def open_elf_file(file_path: str) -> 'elf_file':
|
||||||
return elf_file(f.read())
|
return elf_file(f.read())
|
||||||
|
|
||||||
|
|
||||||
def _sign_extend(value: int, bits: int) -> int:
|
def _decode_thumb_branch_imm(field: int, bits: int) -> int:
|
||||||
"""Sign-extend a value with given bit width to 32 bits."""
|
"""
|
||||||
sign_bit = 1 << (bits - 1)
|
Decode Thumb-2 wide branch immediate.
|
||||||
if value & sign_bit:
|
bits: 22 (R_ARM_THM_PC22) or 24 (R_ARM_THM_JUMP24)
|
||||||
return value - (1 << bits)
|
"""
|
||||||
return value
|
|
||||||
|
h1 = (field >> 16) & 0xFFFF
|
||||||
|
h2 = field & 0xFFFF
|
||||||
|
|
||||||
|
S = (h1 >> 10) & 1
|
||||||
|
imm10 = h1 & 0x03FF
|
||||||
|
J1 = (h2 >> 13) & 1
|
||||||
|
J2 = (h2 >> 11) & 1
|
||||||
|
imm11 = h2 & 0x07FF
|
||||||
|
|
||||||
|
# Decode J1/J2 → I1/I2
|
||||||
|
I1 = (~(J1 ^ S)) & 1
|
||||||
|
I2 = (~(J2 ^ S)) & 1
|
||||||
|
|
||||||
|
if bits == 24:
|
||||||
|
imm = (
|
||||||
|
(S << 23) |
|
||||||
|
(I1 << 22) |
|
||||||
|
(I2 << 21) |
|
||||||
|
(imm10 << 11) |
|
||||||
|
(imm11 << 0)
|
||||||
|
)
|
||||||
|
sign_bit = 23
|
||||||
|
else:
|
||||||
|
assert bits == 22
|
||||||
|
imm = (
|
||||||
|
(S << 21) |
|
||||||
|
(I1 << 20) |
|
||||||
|
(I2 << 19) |
|
||||||
|
(imm10 << 9) |
|
||||||
|
(imm11 << 0)
|
||||||
|
)
|
||||||
|
sign_bit = 21
|
||||||
|
|
||||||
|
# Sign extend
|
||||||
|
if imm & (1 << sign_bit):
|
||||||
|
imm |= ~((1 << (sign_bit + 1)) - 1)
|
||||||
|
|
||||||
|
# Thumb branch offsets are halfword aligned
|
||||||
|
return imm << 1
|
||||||
|
|
||||||
|
|
||||||
class elf_symbol():
|
class elf_symbol():
|
||||||
|
|
@ -553,33 +592,9 @@ class elf_file:
|
||||||
imm24 |= ~0xFFFFFF
|
imm24 |= ~0xFFFFFF
|
||||||
return imm24 << 2
|
return imm24 << 2
|
||||||
if name == 'R_ARM_THM_PC22':
|
if name == 'R_ARM_THM_PC22':
|
||||||
# BL Encoding T2
|
return _decode_thumb_branch_imm(field, 22)
|
||||||
h1 = field & 0xFFFF
|
|
||||||
h2 = (field >> 16) & 0xFFFF
|
|
||||||
s = (h1 >> 10) & 0x1 # Bit 10 of h1
|
|
||||||
imm10H = h1 & 0x3FF # Bits 9..0 of h1
|
|
||||||
j1 = (h2 >> 13) & 0x1 # Bit 13 of h2
|
|
||||||
j2 = (h2 >> 11) & 0x1 # Bit 11 of h2
|
|
||||||
imm10L = (h2 >> 1) & 0x3FF # Bits 10..1 of h2
|
|
||||||
i1 = ~(j1 ^ s) & 0x1
|
|
||||||
i2 = ~(j2 ^ s) & 0x1
|
|
||||||
imm22 = (s << 21) | (i1 << 20) | (i2 << 19) | (imm10H << 9) | imm10L
|
|
||||||
imm32 = _sign_extend(imm22 << 1, 23) # Shift left by 1, then sign-extend 23 bits
|
|
||||||
return imm32
|
|
||||||
if name in ('R_ARM_THM_JUMP24', 'R_ARM_THM_CALL'):
|
if name in ('R_ARM_THM_JUMP24', 'R_ARM_THM_CALL'):
|
||||||
# B.W Encoding T4
|
return _decode_thumb_branch_imm(field, 24)
|
||||||
h1 = field & 0xFFFF
|
|
||||||
h2 = (field >> 16) & 0xFFFF
|
|
||||||
s = (h1 >> 10) & 0x1 # Bit 10 of h1
|
|
||||||
imm10 = h1 & 0x3FF # Bits 9..0 of h1
|
|
||||||
j1 = (h2 >> 13) & 0x1 # Bit 13 of h2
|
|
||||||
j2 = (h2 >> 11) & 0x1 # Bit 11 of h2
|
|
||||||
imm11 = h2 & 0x7FF # Bits 10..0 of h2
|
|
||||||
i1 = ~(j1 ^ s) & 0x1
|
|
||||||
i2 = ~(j2 ^ s) & 0x1
|
|
||||||
imm24 = (s << 23) | (i1 << 22) | (i2 << 21) | (imm10 << 11) | imm11
|
|
||||||
imm32 = _sign_extend(imm24 << 1, 25) # Shift left by 1, then sign-extend 25 bits
|
|
||||||
return imm32
|
|
||||||
if name == 'R_ARM_THM_MOVW_ABS_NC' or name == 'R_ARM_THM_MOVT_ABS':
|
if name == 'R_ARM_THM_MOVW_ABS_NC' or name == 'R_ARM_THM_MOVT_ABS':
|
||||||
i = (field >> 10) & 1
|
i = (field >> 10) & 1
|
||||||
imm4 = field & 0xF
|
imm4 = field & 0xF
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import pelfy._main as _main
|
import pelfy._main as _main
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
def test_arm_addend_extraction():
|
||||||
def test_arm_addend_extraction() -> None:
|
|
||||||
# Path to the test object file
|
# Path to the test object file
|
||||||
obj_path = os.path.join('tests', 'obj', 'stencils_armv7_O3.o')
|
obj_path = os.path.join('tests', 'obj', 'stencils_armv7_O3.o')
|
||||||
elf = _main.open_elf_file(obj_path)
|
elf = _main.open_elf_file(obj_path)
|
||||||
|
|
@ -60,3 +59,7 @@ def test_arm_addend_extraction() -> None:
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
assert found, f"Missing or incorrect addend for {ref_type} offset=0x{ref_offset:X} symbol={ref_symbol} (value={addend}, expected {ref_addend})"
|
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
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
import pelfy._main as _main
|
import pelfy._main as _main
|
||||||
import os
|
import os
|
||||||
from typing import Union
|
|
||||||
|
|
||||||
|
def test_thumb_addend_extraction():
|
||||||
def test_thumb_addend_extraction() -> None:
|
|
||||||
# Path to the test object file
|
# Path to the test object file
|
||||||
obj_path = os.path.join('tests', 'obj', 'stencils_armv7thumb_O3_THM_MOVW.o')
|
obj_path = os.path.join('tests', 'obj', 'stencils_armv7thumb_O3_THM_MOVW.o')
|
||||||
elf = _main.open_elf_file(obj_path)
|
elf = _main.open_elf_file(obj_path)
|
||||||
|
|
@ -15,46 +13,46 @@ def test_thumb_addend_extraction() -> None:
|
||||||
reloc_addends.append((reloc.type, reloc['r_offset'], reloc['r_addend'], reloc.symbol.name))
|
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 values from the .asm file (addend = 0 for all Thumb relocations)
|
||||||
reference: list[tuple[str, Union[int, None], int, str]] = [
|
reference = [
|
||||||
('R_ARM_THM_MOVW_ABS_NC', None, 0, 'dummy_int'),
|
('R_ARM_THM_MOVW_ABS_NC', None, 0, 'dummy_int'),
|
||||||
('R_ARM_THM_MOVT_ABS', 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_MOVW_ABS_NC', None, 0, 'dummy_float'),
|
||||||
('R_ARM_THM_MOVT_ABS', None, 0, 'dummy_float'),
|
('R_ARM_THM_MOVT_ABS', None, 0, 'dummy_float'),
|
||||||
('R_ARM_THM_JUMP24', 0x14, -4, 'auxsub_get_42'),
|
('R_ARM_THM_JUMP24', 0x14, 0, 'auxsub_get_42'),
|
||||||
('R_ARM_THM_CALL', 0xA, -4, 'result_int'),
|
('R_ARM_THM_CALL', 0xA, 0, 'result_int'),
|
||||||
('R_ARM_THM_JUMP24', 0xA, -4, 'result_float_int'),
|
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float_int'),
|
||||||
('R_ARM_THM_JUMP24', 0xC, -4, 'result_float_float'),
|
('R_ARM_THM_JUMP24', 0xC, 0, 'result_float_float'),
|
||||||
('R_ARM_THM_JUMP24', 0xA, -4, 'result_int_int'),
|
('R_ARM_THM_JUMP24', 0xA, 0, 'result_int_int'),
|
||||||
('R_ARM_THM_JUMP24', 0xC, -4, 'result_int_float'),
|
('R_ARM_THM_JUMP24', 0xC, 0, 'result_int_float'),
|
||||||
('R_ARM_THM_CALL', 0xA, -4, 'aux_get_42'),
|
('R_ARM_THM_CALL', 0xA, 0, 'aux_get_42'),
|
||||||
('R_ARM_THM_JUMP24', 0x12, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x2, -4, 'aux_get_42'),
|
('R_ARM_THM_CALL', 0x2, 0, 'aux_get_42'),
|
||||||
('R_ARM_THM_JUMP24', 0xA, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
|
||||||
('R_ARM_THM_JUMP24', 0x2, -4, 'result_int'),
|
('R_ARM_THM_JUMP24', 0x2, 0, 'result_int'),
|
||||||
('R_ARM_THM_JUMP24', 0x4, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x4, 0, 'result_float'),
|
||||||
('R_ARM_THM_JUMP24', 0x28, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x28, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x2C, -4, 'sqrtf'),
|
('R_ARM_THM_CALL', 0x2C, 0, 'sqrtf'),
|
||||||
('R_ARM_THM_JUMP24', 0x20, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x20, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x24, -4, 'sqrtf'),
|
('R_ARM_THM_CALL', 0x24, 0, 'sqrtf'),
|
||||||
('R_ARM_THM_CALL', 0xA, -4, 'expf'),
|
('R_ARM_THM_CALL', 0xA, 0, 'expf'),
|
||||||
('R_ARM_THM_JUMP24', 0x12, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x2, -4, 'expf'),
|
('R_ARM_THM_CALL', 0x2, 0, 'expf'),
|
||||||
('R_ARM_THM_JUMP24', 0xA, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0xA, -4, 'logf'),
|
('R_ARM_THM_CALL', 0xA, 0, 'logf'),
|
||||||
('R_ARM_THM_JUMP24', 0x12, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x2, -4, 'logf'),
|
('R_ARM_THM_CALL', 0x2, 0, 'logf'),
|
||||||
('R_ARM_THM_JUMP24', 0xA, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0xA, -4, 'sinf'),
|
('R_ARM_THM_CALL', 0xA, 0, 'sinf'),
|
||||||
('R_ARM_THM_JUMP24', 0x12, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x2, -4, 'sinf'),
|
('R_ARM_THM_CALL', 0x2, 0, 'sinf'),
|
||||||
('R_ARM_THM_JUMP24', 0xA, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0xA, -4, 'cosf'),
|
('R_ARM_THM_CALL', 0xA, 0, 'cosf'),
|
||||||
('R_ARM_THM_JUMP24', 0x12, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x2, -4, 'cosf'),
|
('R_ARM_THM_CALL', 0x2, 0, 'cosf'),
|
||||||
('R_ARM_THM_JUMP24', 0xA, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0xA, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0xA, -4, 'tanf'),
|
('R_ARM_THM_CALL', 0xA, 0, 'tanf'),
|
||||||
('R_ARM_THM_JUMP24', 0x12, -4, 'result_float'),
|
('R_ARM_THM_JUMP24', 0x12, 0, 'result_float'),
|
||||||
('R_ARM_THM_CALL', 0x2, -4, 'tanf'),
|
('R_ARM_THM_CALL', 0x2, 0, 'tanf'),
|
||||||
]
|
]
|
||||||
# For each reference, check that at least one matching relocation has the expected addend
|
# For each reference, check that at least one matching relocation has the expected addend
|
||||||
for ref_type, _, ref_addend, ref_symbol in reference:
|
for ref_type, _, ref_addend, ref_symbol in reference:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue