mirror of https://github.com/zeldaret/mm.git
67 lines
2.9 KiB
Python
Executable File
67 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys, argparse
|
|
|
|
from elftools.elf.elffile import ELFFile
|
|
from elftools.elf.relocation import RelocationSection
|
|
|
|
def get_section_type_from_name(name):
|
|
if name == '.text':
|
|
return 1
|
|
elif name == '.data':
|
|
return 2
|
|
elif name == '.rodata':
|
|
return 3
|
|
elif name == '.bss': # TODO is this actually a thing? It doesn't fit in 2 bits and why would there be a relocation in .bss?
|
|
return 4
|
|
else:
|
|
assert False, 'Unrecognized section for relocation: ' + name
|
|
|
|
if __name__ == '__main__':
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('input', help='Input object file to create overlay info', metavar='input')
|
|
parser.add_argument('output', help='Overlay info output', metavar='output')
|
|
args = parser.parse_args()
|
|
|
|
with open(args.input, 'rb') as f, open(args.output, 'w') as out:
|
|
elffile = ELFFile(f)
|
|
|
|
out.write('.section .ovl\n');
|
|
|
|
relocs = []
|
|
for section_name in ['.rel.text', '.rel.data', '.rel.rodata']:
|
|
section = elffile.get_section_by_name(section_name)
|
|
if section is not None:
|
|
symtab = elffile.get_section(section['sh_link'])
|
|
for reloc in section.iter_relocations():
|
|
symbol = symtab.get_symbol(reloc['r_info_sym'])
|
|
if symbol.entry['st_shndx'] != 'SHN_UNDEF':
|
|
section_id = get_section_type_from_name(section.name[4:])
|
|
relocation_type = reloc['r_info_type']
|
|
offset = reloc['r_offset']
|
|
assert offset <= 0xFFFFFF, 'Object too big to convert into overlay'
|
|
word = (section_id << 30) | (relocation_type << 24) | (offset)
|
|
relocs.append(word)
|
|
|
|
text_section = elffile.get_section_by_name('.text')
|
|
data_section = elffile.get_section_by_name('.data')
|
|
rodata_section = elffile.get_section_by_name('.rodata')
|
|
bss_section = elffile.get_section_by_name('.bss')
|
|
|
|
text_size = text_section.data_size if text_section is not None else 0
|
|
data_size = data_section.data_size if data_section is not None else 0
|
|
rodata_size = rodata_section.data_size if rodata_section is not None else 0
|
|
bss_size = bss_section.data_size if bss_section is not None else 0
|
|
|
|
out.write('.word 0x{:08X}\n'.format(text_size));
|
|
out.write('.word 0x{:08X}\n'.format(data_size));
|
|
out.write('.word 0x{:08X}\n'.format(rodata_size));
|
|
out.write('.word 0x{:08X}\n'.format(bss_size));
|
|
out.write('.word 0x{:08X}\n'.format(len(relocs)));
|
|
for reloc in relocs:
|
|
out.write('.word 0x{:08X}\n'.format(reloc));
|
|
offset = len(relocs) + 5
|
|
while (offset % 4) != 3:
|
|
out.write('.word 0\n');
|
|
offset += 1
|
|
out.write('.word 0x{:08X}\n'.format(offset*4 + 4));
|