mirror of https://github.com/Nonannet/copapy.git
Compare commits
3 Commits
58120f292c
...
83ce6ce0e7
| Author | SHA1 | Date |
|---|---|---|
|
|
83ce6ce0e7 | |
|
|
a81236a3fc | |
|
|
bc0ccd90b7 |
|
|
@ -80,11 +80,20 @@ def get_return_function_type(symbol: pelfy.elf_symbol) -> str:
|
||||||
|
|
||||||
def get_stencil_position(func: pelfy.elf_symbol) -> tuple[int, int]:
|
def get_stencil_position(func: pelfy.elf_symbol) -> tuple[int, int]:
|
||||||
start_index = 0 # There must be no prolog
|
start_index = 0 # There must be no prolog
|
||||||
|
|
||||||
# Find last relocation in function
|
# Find last relocation in function
|
||||||
last_instr = get_last_call_in_function(func)
|
last_instr = get_last_call_in_function(func)
|
||||||
function_size = func.fields['st_size']
|
|
||||||
if last_instr + 5 >= function_size: # Check if jump is last instruction
|
assert func.section, f"No code section specified for symbol {func.name}"
|
||||||
end_index = last_instr # Jump can be striped
|
|
||||||
|
# func.section.fields['sh_size'] is equivalent to func.fields['st_size']
|
||||||
|
# expect for ARM thumb, here nop padding at the end for 4-byte alignment
|
||||||
|
# is not included in st_size
|
||||||
|
function_size = func.section.fields['sh_size']
|
||||||
|
|
||||||
|
# Check if jump is the last instruction and can be striped
|
||||||
|
if last_instr + 5 >= function_size:
|
||||||
|
end_index = last_instr
|
||||||
else:
|
else:
|
||||||
end_index = function_size
|
end_index = function_size
|
||||||
|
|
||||||
|
|
@ -98,11 +107,12 @@ def get_last_call_in_function(func: pelfy.elf_symbol) -> int:
|
||||||
if reloc.symbol.name.startswith('dummy_'):
|
if reloc.symbol.name.startswith('dummy_'):
|
||||||
return -0xFFFF # Last relocation is not a jump
|
return -0xFFFF # Last relocation is not a jump
|
||||||
else:
|
else:
|
||||||
# Assume the call instruction is 4 bytes long for relocations with less than 32 bit and 5 bytes otherwise
|
# Assume the jump/call instruction is 4 bytes long for relocations
|
||||||
|
# with less than 32 bit and 5 bytes otherwise
|
||||||
instruction_lengths = 4 if reloc.bits < 32 else 5
|
instruction_lengths = 4 if reloc.bits < 32 else 5
|
||||||
address_field_length = 4
|
address_field_length = 4
|
||||||
#print(f"-> {[r.fields['r_offset'] - func.fields['st_value'] for r in func.relocations]}")
|
#print(f"-> {[r.fields['r_offset'] - func.fields['st_value'] for r in func.relocations]}")
|
||||||
return reloc.fields['r_offset'] - func.fields['st_value'] + address_field_length - instruction_lengths
|
return reloc.fields['r_offset'] - func.offset_in_section + address_field_length - instruction_lengths
|
||||||
|
|
||||||
|
|
||||||
def get_op_after_last_call_in_function(func: pelfy.elf_symbol) -> int:
|
def get_op_after_last_call_in_function(func: pelfy.elf_symbol) -> int:
|
||||||
|
|
@ -110,7 +120,7 @@ def get_op_after_last_call_in_function(func: pelfy.elf_symbol) -> int:
|
||||||
assert func.relocations, f'No call function in stencil function {func.name}.'
|
assert func.relocations, f'No call function in stencil function {func.name}.'
|
||||||
reloc = func.relocations[-1]
|
reloc = func.relocations[-1]
|
||||||
assert reloc.bits <= 32, "Relocation segment might be larger then 32 bit"
|
assert reloc.bits <= 32, "Relocation segment might be larger then 32 bit"
|
||||||
return reloc.fields['r_offset'] - func.fields['st_value'] + 4
|
return reloc.fields['r_offset'] - func.offset_in_section + 4
|
||||||
|
|
||||||
|
|
||||||
class stencil_database():
|
class stencil_database():
|
||||||
|
|
@ -121,7 +131,7 @@ class stencil_database():
|
||||||
var_size (dict[str, int]): dictionary of object names and their sizes
|
var_size (dict[str, int]): dictionary of object names and their sizes
|
||||||
byteorder (ByteOrder): byte order of the ELF file
|
byteorder (ByteOrder): byte order of the ELF file
|
||||||
elf (elf_file): the loaded ELF file
|
elf (elf_file): the loaded ELF file
|
||||||
thumb_mode (int): 1 if ARM in thumb mode, 0 otherwise
|
thumb_mode (bool): entry_function_shell in ARM thumb mode
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, obj_file: str | bytes):
|
def __init__(self, obj_file: str | bytes):
|
||||||
|
|
@ -148,10 +158,7 @@ class stencil_database():
|
||||||
# if s.info == 'STT_OBJECT'}
|
# if s.info == 'STT_OBJECT'}
|
||||||
self.byteorder: ByteOrder = self.elf.byteorder
|
self.byteorder: ByteOrder = self.elf.byteorder
|
||||||
|
|
||||||
self.arm = '.ARM.attributes' in self.elf.sections
|
self.thumb_mode = self.elf.symbols['entry_function_shell'].thumb_mode
|
||||||
|
|
||||||
# Returns 1 for ARM in thumb mode, 0 otherwise
|
|
||||||
self.thumb_mode = self.elf.symbols['entry_function_shell'].fields['st_value'] & 1
|
|
||||||
|
|
||||||
#for name in self.function_definitions.keys():
|
#for name in self.function_definitions.keys():
|
||||||
# sym = self.elf.symbols[name]
|
# sym = self.elf.symbols[name]
|
||||||
|
|
@ -194,14 +201,14 @@ class stencil_database():
|
||||||
for reloc in symbol.relocations:
|
for reloc in symbol.relocations:
|
||||||
|
|
||||||
# address to fist byte to patch relative to the start of the symbol
|
# address to fist byte to patch relative to the start of the symbol
|
||||||
patch_offset = reloc.fields['r_offset'] - symbol.fields['st_value'] - start_index
|
patch_offset = reloc.fields['r_offset'] - symbol.offset_in_section - start_index
|
||||||
|
|
||||||
if patch_offset < end_index - start_index: # Exclude the call to the result_* function
|
if patch_offset < end_index - start_index: # Exclude the call to the result_* function
|
||||||
reloc_entry = relocation_entry(reloc.symbol.name,
|
reloc_entry = relocation_entry(reloc.symbol.name,
|
||||||
reloc.symbol.info,
|
reloc.symbol.info,
|
||||||
reloc.symbol.fields['st_value'],
|
reloc.symbol.fields['st_value'], # LSB on ARM indicates thumb mode
|
||||||
reloc.symbol.fields['st_shndx'],
|
reloc.symbol.fields['st_shndx'],
|
||||||
symbol.fields['st_value'],
|
symbol.offset_in_section,
|
||||||
start_index,
|
start_index,
|
||||||
reloc)
|
reloc)
|
||||||
cache.append(reloc_entry)
|
cache.append(reloc_entry)
|
||||||
|
|
@ -348,10 +355,7 @@ class stencil_database():
|
||||||
start_stencil, end_stencil = get_stencil_position(func)
|
start_stencil, end_stencil = get_stencil_position(func)
|
||||||
assert func.section
|
assert func.section
|
||||||
|
|
||||||
# For arm functions, mask out the thumb mode bit
|
start_index = func.offset_in_file + start_stencil
|
||||||
function_offset = func.fields['st_value'] & ~int(self.arm)
|
|
||||||
|
|
||||||
start_index = func.section['sh_offset'] + function_offset + start_stencil
|
|
||||||
lengths = end_stencil - start_stencil
|
lengths = end_stencil - start_stencil
|
||||||
self._stencil_cache[name] = (start_index, lengths)
|
self._stencil_cache[name] = (start_index, lengths)
|
||||||
|
|
||||||
|
|
@ -389,7 +393,7 @@ class stencil_database():
|
||||||
|
|
||||||
def get_symbol_offset(self, name: str) -> int:
|
def get_symbol_offset(self, name: str) -> int:
|
||||||
"""Returns the offset of a specified symbol in the section."""
|
"""Returns the offset of a specified symbol in the section."""
|
||||||
return self.elf.symbols[name].fields['st_value']
|
return self.elf.symbols[name].offset_in_section
|
||||||
|
|
||||||
def get_symbol_section_index(self, name: str) -> int:
|
def get_symbol_section_index(self, name: str) -> int:
|
||||||
"""Returns the section index for a specified symbol name."""
|
"""Returns the section index for a specified symbol name."""
|
||||||
|
|
@ -420,13 +424,6 @@ class stencil_database():
|
||||||
func = self.elf.symbols[name]
|
func = self.elf.symbols[name]
|
||||||
assert func.info == 'STT_FUNC', f"{name} is not a function"
|
assert func.info == 'STT_FUNC', f"{name} is not a function"
|
||||||
|
|
||||||
# For arm functions, mask out the thumb mode bit
|
|
||||||
function_offset = func.fields['st_value'] & ~int(self.arm)
|
|
||||||
|
|
||||||
start_index = func.section['sh_offset'] + function_offset
|
|
||||||
lengths = end_stencil - start_stencil
|
|
||||||
|
|
||||||
#return self.elf.read_bytes(start_index, func.fields['st_size'])
|
|
||||||
if part == 'start':
|
if part == 'start':
|
||||||
index = get_last_call_in_function(func)
|
index = get_last_call_in_function(func)
|
||||||
return func.data[:index]
|
return func.data[:index]
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,16 @@ ar x ../../musl/lib/libc.a sinf.o cosf.o tanf.o asinf.o acosf.o atanf.o atan2f.o
|
||||||
ar x ../../musl/lib/libc.a sqrtf.o logf.o expf.o sqrt.o
|
ar x ../../musl/lib/libc.a sqrtf.o logf.o expf.o sqrt.o
|
||||||
ar x ../../musl/lib/libc.a logf_data.o __tandf.o __cosdf.o __sindf.o
|
ar x ../../musl/lib/libc.a logf_data.o __tandf.o __cosdf.o __sindf.o
|
||||||
ar x ../../musl/lib/libc.a fabsf.o scalbn.o floor.o floorf.o exp2f_data.o powf.o powf_data.o
|
ar x ../../musl/lib/libc.a fabsf.o scalbn.o floor.o floorf.o exp2f_data.o powf.o powf_data.o
|
||||||
ar x ../../musl/lib/libc.a __rem_pio2f.o __math_invalidf.o __stack_chk_fail.o __math_divzerof.o __math_oflowf.o __rem_pio2_large.o __math_uflowf.o __math_xflowf.o
|
ar x ../../musl/lib/libc.a __rem_pio2f.o __math_invalid.o __math_invalidf.o __stack_chk_fail.o
|
||||||
|
ar x ../../musl/lib/libc.a __math_divzerof.o __math_oflowf.o __rem_pio2_large.o __math_uflowf.o __math_xflowf.o __rsqrt_tab.o
|
||||||
|
|
||||||
# Check out .lo (PIC)
|
# Check out .lo (PIC)
|
||||||
ar x ../../musl/lib/libc.a sinf.lo cosf.lo tanf.lo asinf.lo acosf.lo atanf.lo atan2f.lo
|
ar x ../../musl/lib/libc.a sinf.lo cosf.lo tanf.lo asinf.lo acosf.lo atanf.lo atan2f.lo
|
||||||
ar x ../../musl/lib/libc.a sqrtf.lo logf.lo expf.lo sqrt.lo
|
ar x ../../musl/lib/libc.a sqrtf.lo logf.lo expf.lo sqrt.lo
|
||||||
ar x ../../musl/lib/libc.a logf_data.lo __tandf.lo __cosdf.lo __sindf.lo
|
ar x ../../musl/lib/libc.a logf_data.lo __tandf.lo __cosdf.lo __sindf.lo
|
||||||
ar x ../../musl/lib/libc.a fabsf.lo scalbn.lo floor.lo floorf.o exp2f_data.lo powf.lo powf_data.lo
|
ar x ../../musl/lib/libc.a fabsf.lo scalbn.lo floor.lo floorf.o exp2f_data.lo powf.lo powf_data.lo
|
||||||
ar x ../../musl/lib/libc.a __rem_pio2f.lo __math_invalidf.lo __stack_chk_fail.lo __math_divzerof.lo __math_oflowf.lo __rem_pio2_large.lo __math_uflowf.lo __math_xflowf.lo
|
ar x ../../musl/lib/libc.a __rem_pio2f.lo __math_invalid.lo __math_invalidf.lo __stack_chk_fail.lo
|
||||||
|
ar x ../../musl/lib/libc.a __math_divzerof.lo __math_oflowf.lo __rem_pio2_large.lo __math_uflowf.lo __math_xflowf.lo __rsqrt_tab.lo
|
||||||
|
|
||||||
cd ../../musl
|
cd ../../musl
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue