From c39323a3368d54fd00479fd51eefcf0ac82606e1 Mon Sep 17 00:00:00 2001 From: cadmic Date: Sun, 8 Sep 2024 08:13:24 -0700 Subject: [PATCH] fix_bss.py: Subtract addend for relocations against global symbols (#2169) --- tools/fix_bss.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tools/fix_bss.py b/tools/fix_bss.py index 6217e822fc..d5907cbc2a 100755 --- a/tools/fix_bss.py +++ b/tools/fix_bss.py @@ -152,7 +152,19 @@ def get_file_pointers( else: assert False, "Invalid relocation" - pointers.append(Pointer(reloc.name, reloc.addend, base_value, build_value)) + # For relocations against a global symbol, subtract the addend so that the pointer + # is for the start of the symbol. This can help deal with things like STACK_TOP + # (where the pointer is past the end of the symbol) or negative addends. If the + # relocation is against a section however, it's not useful to subtract the addend, + # so we keep it as-is and hope for the best. + if reloc.name.startswith("."): # section + addend = reloc.addend + else: # symbol + addend = 0 + base_value -= reloc.addend + build_value -= reloc.addend + + pointers.append(Pointer(reloc.name, addend, base_value, build_value)) return pointers @@ -774,14 +786,8 @@ def main(): for file, bss_section in bss_sections.items(): if not bss_section.pointers: continue - # The following heuristic doesn't work for z_locale, since the first pointer into BSS is not - # at the start of the section. Fortunately z_locale either has one BSS variable (in GC versions) - # or none (in N64 versions), so we can just skip it. - if str(file) == "src/boot/z_locale.c": - continue # For the baserom, assume that the lowest address is the start of the BSS section. This might - # not be true if the first BSS variable is not referenced, but in practice this doesn't happen - # (except for z_locale above). + # not be true if the first BSS variable is not referenced, but in practice this doesn't happen. base_min_address = min(p.base_value for p in bss_section.pointers) build_min_address = bss_section.start_address if not all( @@ -798,7 +804,8 @@ def main(): print("No BSS reordering found.") if args.files: - files_to_fix = args.files + # Ignore files that don't have a BSS section in the ROM + files_to_fix = [file for file in args.files if file in bss_sections] else: files_to_fix = files_with_reordering if not files_to_fix: