Add dmadata vrom symbols. Link rom in two passes: first to generate dmadata, second to apply dmadata symbols. Clean up symbols at low addresses.

This commit is contained in:
rozlette
2019-11-16 03:28:05 -06:00
parent 6905647e4f
commit 08d128bdaa
12 changed files with 9435 additions and 1054 deletions
+11 -2
View File
@@ -468,7 +468,7 @@ class Disassembler:
# TODO workaround to avoid classifying loading constants as loading pointers
# This unfortunately causes it to not detect object addresses
if addr >= 0x2000000 and addr < 0x80000000:
if addr < 0x80000000:
return
if self.is_in_data_or_undef(addr):
@@ -481,6 +481,12 @@ class Disassembler:
elif is_load(next_inst) and (get_rt(cur_inst) == get_rs(next_inst)): # lui + load (load pointer)
addr = (get_imm(cur_inst) << 16) + get_signed_imm(next_inst)
# TODO workaround to avoid classifying loading constants as loading pointers
# This unfortunately causes it to not detect object addresses
if addr < 0x80000000:
return
if self.is_in_data_or_undef(addr):
self.add_variable(addr)
else:
@@ -687,9 +693,12 @@ class Disassembler:
with open(path + "/variables.h", 'w', newline='\n') as f:
f.write("#ifndef _VARIABLES_H_\n#define _VARIABLES_H_\n\n")
f.write('#include <PR/ultratypes.h>\n#include <osint.h>\n#include <viint.h>\n#include <guint.h>\n#include <unk.h>\n#include <structs.h>\n#include <stdlib.h>\n#include <xstdio.h>\n\n')
f.write('#include <PR/ultratypes.h>\n#include <osint.h>\n#include <viint.h>\n#include <guint.h>\n#include <unk.h>\n#include <structs.h>\n#include <stdlib.h>\n#include <xstdio.h>\n#include <dmadata.h>\n\n')
for addr in sorted(self.vars):
if addr < 0x02000000:
continue # Don't print out symbols of dmadata files' vrom addresses. These will be defined in another file.
if addr in known_vars:
f.write("extern %s %s%s; // D_%08X\n" % (known_vars[addr][1], self.make_load(addr), "[]" if known_vars[addr][2] else "", addr))
else:
+15 -1
View File
@@ -7,12 +7,15 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('files', help='file list')
parser.add_argument('out', help='output file')
parser.add_argument('-l', '--linkscript', help='output linker script for file VROM addresses', metavar='filename')
parser.add_argument('-u', '--uncompressed', help='build dmadata from only uncompressed files', action='store_true', default=False)
args = parser.parse_args()
with open(args.out, 'wb') as dmadata, open(args.files, 'r') as files:
curr_vrom = 0
curr_phys = 0
dmadata_table = ast.literal_eval(files.read())
linker_info = list()
for base_file, comp_file, alignment, size_if_missing in dmadata_table:
try:
uncompressed = comp_file == ''
@@ -30,7 +33,7 @@ if __name__ == "__main__":
phys_size = vrom_size
else:
vrom_size = os.path.getsize(base_file)
if uncompressed:
if uncompressed or args.uncompressed:
phys_size = vrom_size
else:
phys_size = os.path.getsize(comp_file)
@@ -59,6 +62,17 @@ if __name__ == "__main__":
dmadata.write(vrom_end.to_bytes(4, 'big'))
dmadata.write(phys_start.to_bytes(4, 'big'))
dmadata.write(phys_end.to_bytes(4, 'big'))
if base_file != '':
linker_info.append((os.path.basename(base_file), vrom_start, vrom_end))
except:
print('Error when processing entry ' + base_file)
sys.exit(1)
if args.linkscript:
with open(args.linkscript, 'w') as file:
for name, vrom_start, vrom_end in linker_info:
formatted_name = '_' + name if name[0].isdigit() else name
file.write('{}_vrom_start = 0x{:08X};\n'.format(formatted_name, vrom_start))
file.write('{}_vrom_end = 0x{:08X};\n'.format(formatted_name, vrom_end))
file.write('\n')