Move missing Ghidra symbols from REL data to decomp symbols (#116)

This commit is contained in:
robojumper
2025-02-17 13:19:48 +01:00
committed by GitHub
parent cec09ad023
commit 6269e82659
308 changed files with 1196 additions and 1164 deletions
+65 -33
View File
@@ -8,57 +8,82 @@
import os
import re
from ghidra.program.model.symbol.SourceType import *
from ghidra.program.model.symbol.Namespace import *
from ghidra.program.model.listing.CodeUnit import *
AF = currentProgram.getAddressFactory()
mem = currentProgram.getMemory()
listing = currentProgram.getListing()
sym_re = re.compile("(?:lbl|fn|FUN|DAT)_[0-9A-Fa-f_]+ = \\.([a-z0-9]+):0x([0-9A-Fa-f]{8})(.*)\n")
default_sym_re = re.compile(".*_[0-9A-Za-z]+$")
sym_re = re.compile("(?:lbl|fn|FUN|DAT)(?:_[0-9]+_[a-z]+)_[0-9A-Fa-f_]+ = \\.([a-z0-9]+):0x([0-9A-Fa-f]{8})(.*)\n")
default_sym_re = re.compile("^(lbl|fn|FUN|DAT)_[0-9A-Za-z]+$")
rel_default_sym_re = re.compile("lbl_[0-9]+_[a-z]+_[0-9A-Za-z]+$")
used_symbols = set()
def transformer_for_file(file_name):
def get_section_names(file_name, config_dir):
splits_path = os.path.join(config_dir, "rels", file_name, "splits.txt")
section_names = []
with open(splits_path, "rt") as file:
for line in file:
line = line.strip()
if line == "":
break
elif line == "Sections:":
continue
else:
section_names.append(line.split()[0])
return section_names
def transformer_for_file(file_name, config_dir, fix_mistakes_mode):
if file_name != "MAIN":
section_names = get_section_names(file_name, config_dir)
blocks = mem.getBlocks()
blocks = [b for b in blocks if b.getName().startswith(file_name)]
def transformer(section, address):
if file_name == "MAIN":
# in the main dol, each symbol is loaded at a fixed address
addr_obj = AF.getAddress("0x%08X" % address)
else:
# REL sections can't be reliably identified
if section != "text":
return None
# in rels, every section is relocated indivdually, so treat
# this as an offset
block_name = file_name + "_." + section + "0"
print(block_name)
block = mem.getBlock(block_name)
index = section_names.index("." + section)
block = blocks[index]
addr_obj = block.getStart().add(address)
symbol = getSymbolAt(addr_obj)
if symbol: #and symbol.getAddress().equals(addr_obj):
name = symbol.getName(True)
if default_sym_re.match(name):
if fix_mistakes_mode and rel_default_sym_re.match(name):
unit = listing.getCodeUnitAt(addr_obj)
if unit:
comment_str = unit.getComment(PLATE_COMMENT)
if comment_str and comment_str.startswith("original-name"):
name = comment_str.split('\n')[0][len("original-name "):]
if default_sym_re.match(name) or name.startswith("@"):
return None
# in our Ghidra the RVL symbols are helpfully namespaced...
bad_prefixes = [
"ai::",
"arc::",
"axfx::",
"dvd::",
"exi::",
"gx::",
"kpad::",
"mem::",
"mtx::",
"nand::",
"os::",
"sc::",
"si::",
"tpl::",
"vi::",
"wenc::",
"wpad::",
"wud::",
"ai::",
"arc::",
"axfx::"
"dvd::",
"exi::",
"gx::",
"kpad::",
"mem::",
"mtx::",
"nand::",
"os::",
"sc::",
"si::",
"tpl::",
"vi::",
"wenc::",
"wpad::",
"wud::",
]
lowercase_name = name.lower()
for prefix in bad_prefixes:
@@ -99,17 +124,24 @@ def transform_symbols_file(file, transformer):
continue
used_symbols.add(line.split("=")[0][:-1])
new_file += line
return new_file
path = str(askDirectory("Program config directory (e.g. config/SOUE01)", "Export"))
# we accidentally "lost" some symbols during our symbols migration
fix_mistakes_mode = askChoice(
"Fix accidental symbol loss mistake",
"Select no if you don't know what this is",
["Yes", "No"],
"No"
) == "Yes"
new_contents = None
main_symbols = os.path.join(path, "symbols.txt")
with open(main_symbols, "rt") as file:
new_contents = transform_symbols_file(file, transformer_for_file("MAIN"))
new_contents = transform_symbols_file(file, transformer_for_file("MAIN", path, fix_mistakes_mode))
with open(main_symbols, 'w') as f:
f.write(new_contents)
@@ -120,7 +152,7 @@ for rel_name in os.listdir(rels_dir):
if rel_name.endswith("NP"):
rel_symbols = os.path.join(rels_dir, rel_name, "symbols.txt")
with open(rel_symbols, "rt") as file:
new_contents = transform_symbols_file(file, transformer_for_file(rel_name))
new_contents = transform_symbols_file(file, transformer_for_file(rel_name, path, fix_mistakes_mode))
with open(rel_symbols, 'w') as f:
f.write(new_contents)