mirror of https://github.com/Nonannet/copapy.git
Added _ADD_ABS_LO12_NC relocation for ARM; fixed addend for R_386_PC32 and R_386_32; fixed get_return_function_type and strip_function to work with stencils that do the passing on call not at the end
This commit is contained in:
parent
0f464d74a5
commit
ab589449a3
|
|
@ -63,15 +63,16 @@ def detect_process_arch() -> str:
|
||||||
|
|
||||||
def get_return_function_type(symbol: elf_symbol) -> str:
|
def get_return_function_type(symbol: elf_symbol) -> str:
|
||||||
if symbol.relocations:
|
if symbol.relocations:
|
||||||
result_func = symbol.relocations[-1].symbol
|
for reloc in reversed(symbol.relocations):
|
||||||
if result_func.name.startswith('result_'):
|
func_name = reloc.symbol.name
|
||||||
return result_func.name[7:]
|
if func_name.startswith('result_'):
|
||||||
|
return func_name[7:]
|
||||||
return 'void'
|
return 'void'
|
||||||
|
|
||||||
|
|
||||||
def strip_function(func: elf_symbol) -> bytes:
|
def strip_function(func: elf_symbol) -> bytes:
|
||||||
"""Return stencil code by striped stancil function"""
|
"""Return stencil code by striped stancil function"""
|
||||||
assert func.relocations and func.relocations[-1].symbol.info == 'STT_NOTYPE', f"{func.name} is not a stencil function"
|
assert func.relocations and any(reloc.symbol.name.startswith('result_') for reloc in func.relocations), f"{func.name} is not a stencil function"
|
||||||
start_index, end_index = get_stencil_position(func)
|
start_index, end_index = get_stencil_position(func)
|
||||||
return func.data[start_index:end_index]
|
return func.data[start_index:end_index]
|
||||||
|
|
||||||
|
|
@ -206,6 +207,8 @@ class stencil_database():
|
||||||
scale = 1
|
scale = 1
|
||||||
mask = 0xFFFFFFFF # 32 bit
|
mask = 0xFFFFFFFF # 32 bit
|
||||||
|
|
||||||
|
#print("------- reloc ", pr.type, pr.target_section.name, pr.symbol.name)
|
||||||
|
|
||||||
if pr.type.endswith('64_PC32') or pr.type.endswith('64_PLT32'):
|
if pr.type.endswith('64_PC32') or pr.type.endswith('64_PLT32'):
|
||||||
# S + A - P
|
# S + A - P
|
||||||
patch_value = symbol_address + pr.fields['r_addend'] - patch_offset
|
patch_value = symbol_address + pr.fields['r_addend'] - patch_offset
|
||||||
|
|
@ -213,12 +216,12 @@ class stencil_database():
|
||||||
|
|
||||||
elif pr.type == 'R_386_PC32':
|
elif pr.type == 'R_386_PC32':
|
||||||
# S + A - P
|
# S + A - P
|
||||||
patch_value = symbol_address + pr.fields['r_addend'] - patch_offset - 4
|
patch_value = symbol_address + pr.fields['r_addend'] - patch_offset
|
||||||
#print(f" *> {pr.type} {patch_value=} {symbol_address=} {pr.fields['r_addend']=} {pr.bits=}, {function_offset=} {patch_offset=}")
|
#print(f" *> {pr.type} {pr.symbol.name} {patch_value=} {symbol_address=} {pr.fields['r_addend']=} {bin(pr.fields['r_addend'])} {pr.bits=}, {function_offset=} {patch_offset=}")
|
||||||
|
|
||||||
elif pr.type == 'R_386_32':
|
elif pr.type == 'R_386_32':
|
||||||
# R_386_32
|
# R_386_32
|
||||||
# (S + A)
|
# S + A
|
||||||
patch_value = symbol_address + pr.fields['r_addend']
|
patch_value = symbol_address + pr.fields['r_addend']
|
||||||
symbol_type = symbol_type + 0x03 # Relative to data section
|
symbol_type = symbol_type + 0x03 # Relative to data section
|
||||||
#print(f" *> {pr.type} {patch_value=} {symbol_address=} {pr.fields['r_addend']=} {pr.bits=}, {function_offset=} {patch_offset=}")
|
#print(f" *> {pr.type} {patch_value=} {symbol_address=} {pr.fields['r_addend']=} {pr.bits=}, {function_offset=} {patch_offset=}")
|
||||||
|
|
@ -232,7 +235,6 @@ class stencil_database():
|
||||||
scale = 4
|
scale = 4
|
||||||
|
|
||||||
elif pr.type.endswith('_ADR_PREL_PG_HI21'):
|
elif pr.type.endswith('_ADR_PREL_PG_HI21'):
|
||||||
# R_AARCH64_LDST32_ABS_LO12_NC
|
|
||||||
# R_AARCH64_ADR_PREL_PG_HI21
|
# R_AARCH64_ADR_PREL_PG_HI21
|
||||||
assert pr.file.byteorder == 'little', "Big endian not supported for ARM64"
|
assert pr.file.byteorder == 'little', "Big endian not supported for ARM64"
|
||||||
mask = 0 # Handled by runner
|
mask = 0 # Handled by runner
|
||||||
|
|
@ -250,6 +252,15 @@ class stencil_database():
|
||||||
scale = 4
|
scale = 4
|
||||||
#print(f" *> {patch_value=} {symbol_address=} {pr.fields['r_addend']=}, {function_offset=}")
|
#print(f" *> {patch_value=} {symbol_address=} {pr.fields['r_addend']=}, {function_offset=}")
|
||||||
|
|
||||||
|
elif pr.type.endswith('_ADD_ABS_LO12_NC'):
|
||||||
|
# R_AARCH64_ADD_ABS_LO12_NC
|
||||||
|
# (S + A) & 0xFFF
|
||||||
|
mask = 0b11_1111_1111_1100_0000_0000
|
||||||
|
patch_value = symbol_address + pr.fields['r_addend']
|
||||||
|
symbol_type = symbol_type + 0x02 # Absolut value
|
||||||
|
scale = 1
|
||||||
|
#print(f" *> {patch_value=} {symbol_address=} {pr.fields['r_addend']=}, {function_offset=}")
|
||||||
|
|
||||||
elif pr.type.endswith('_LDST64_ABS_LO12_NC'):
|
elif pr.type.endswith('_LDST64_ABS_LO12_NC'):
|
||||||
# R_AARCH64_LDST64_ABS_LO12_NC
|
# R_AARCH64_LDST64_ABS_LO12_NC
|
||||||
# (S + A) & 0xFFF
|
# (S + A) & 0xFFF
|
||||||
|
|
@ -288,10 +299,12 @@ class stencil_database():
|
||||||
for name in names:
|
for name in names:
|
||||||
#print('- get_sub_functions: ', name)
|
#print('- get_sub_functions: ', name)
|
||||||
if name not in name_set:
|
if name not in name_set:
|
||||||
|
#print('||||', name)
|
||||||
# assert name in self.elf.symbols, f"Stencil {name} not found" <-- see: https://github.com/Nonannet/pelfy/issues/1
|
# assert name in self.elf.symbols, f"Stencil {name} not found" <-- see: https://github.com/Nonannet/pelfy/issues/1
|
||||||
func = self.elf.symbols[name]
|
func = self.elf.symbols[name]
|
||||||
for r in func.relocations:
|
for r in func.relocations:
|
||||||
if r.symbol.info == 'STT_FUNC':
|
if r.symbol.info == 'STT_FUNC':
|
||||||
|
#print(' ', r.symbol.name, r.symbol.section.type)
|
||||||
name_set.add(r.symbol.name)
|
name_set.add(r.symbol.name)
|
||||||
name_set |= self.get_sub_functions([r.symbol.name])
|
name_set |= self.get_sub_functions([r.symbol.name])
|
||||||
return name_set
|
return name_set
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue