Skip to content

Commit

Permalink
Merge pull request #93 from Daft-Freak/reloc-itcm
Browse files Browse the repository at this point in the history
Fixes to reloc tool for ITCM
  • Loading branch information
Gadgetoid authored Dec 2, 2021
2 parents 32b8529 + 625beab commit 6036361
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 1 deletion.
Binary file added src/tests/resources/itcm-test.bin
Binary file not shown.
Binary file added src/tests/resources/itcm-test.elf
Binary file not shown.
27 changes: 27 additions & 0 deletions src/tests/test_relocs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ def test_input_elf(test_resources):
return temp_bin


@pytest.fixture
def test_input_bin_itcm(test_resources):
temp_bin = tempfile.NamedTemporaryFile('r+b', suffix='.bin')
temp_bin.write(open(test_resources / "itcm-test.bin", "rb").read())
temp_bin.flush()
return temp_bin


@pytest.fixture
def test_input_elf_itcm(test_resources):
temp_bin = tempfile.NamedTemporaryFile('r+b', suffix='.bin')
temp_bin.write(open(test_resources / "itcm-test.elf", "rb").read())
temp_bin.flush()
return temp_bin


@pytest.fixture
def test_output_file():
temp_bin = tempfile.NamedTemporaryFile('r+b', suffix='.blit')
Expand All @@ -35,3 +51,14 @@ def test_relocs(test_input_bin, test_input_elf, test_output_file):
'--elf-file', test_input_elf.name,
'--output', test_output_file.name
])

def test_relocs_itcm(test_input_bin_itcm, test_input_elf_itcm, test_output_file):
from ttblit import main

with pytest.raises(SystemExit):
main([
'relocs',
'--bin-file', test_input_bin_itcm.name,
'--elf-file', test_input_elf_itcm.name,
'--output', test_output_file.name
])
56 changes: 55 additions & 1 deletion src/ttblit/tool/relocs.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ def relocs_cli(bin_file, elf_file, output):
# find sidata/sdata
sidata = 0
sdata = 0

itcm_data = 0
itcm_text_start = 0

relocs = elffile.get_section_by_name('.rel.text')
symtable = elffile.get_section(relocs['sh_link'])
for reloc in relocs.iter_relocations():
Expand All @@ -34,8 +38,12 @@ def relocs_cli(bin_file, elf_file, output):
sidata = symbol['st_value']
elif symbol.name == '_sdata':
sdata = symbol['st_value']
elif symbol.name == 'itcm_data':
itcm_data = symbol['st_value']
elif symbol.name == 'itcm_text_start':
itcm_text_start = symbol['st_value']

if sidata and sdata:
if sidata and sdata and itcm_data and itcm_text_start:
break

assert(sidata != 0 and sdata != 0)
Expand All @@ -61,6 +69,52 @@ def relocs_cli(bin_file, elf_file, output):

reloc_offsets.append(flash_offset)

# references to the GOT from ITCM code
relocs = elffile.get_section_by_name('.rel.itcm')
if relocs:
symtable = elffile.get_section(relocs['sh_link'])

for reloc in relocs.iter_relocations():
symbol = symtable.get_symbol(reloc['r_info_sym'])

# doesn't point to flash
if symbol['st_value'] < 0x90000000:
continue

if symbol.name == '_GLOBAL_OFFSET_TABLE_':
flash_offset = (reloc['r_offset'] - itcm_text_start) + itcm_data

reloc_offsets.append(flash_offset)

# fixup ITCM veneers for long calls back to flash
itcm_section = elffile.get_section_by_name('.itcm')
if itcm_section:
itcm_section_data = itcm_section.data()

for i in range(symtable.num_symbols()):
sym = symtable.get_symbol(i)

if sym.name.endswith('_veneer') and sym['st_value'] < 0xF800:
# find where the target function is (strip leading __ and trailing _veneer from name)
orig_sym = symtable.get_symbol_by_name(sym.name[2:-7])[0]
target_addr = orig_sym['st_value']

# make sure it's in flash
if target_addr < 0x90000000:
continue

# find the function in flash
itcm_offset = (sym['st_value'] - itcm_text_start) & ~1 # clear thumb bit
flash_offset = itcm_offset + itcm_data

# check for the address where we expect it
# (ldr.w pc, [pc] followed by the address)
ex_addr, = struct.unpack('<I', itcm_section_data[itcm_offset + 4:itcm_offset + 8])

assert ex_addr == target_addr

reloc_offsets.append(flash_offset + 4)

with open(output, 'wb') as out_f:
all_offsets = got_offsets + init_offsets + fini_offsets + reloc_offsets
all_offsets.sort()
Expand Down

0 comments on commit 6036361

Please sign in to comment.