mirror of
https://github.com/zeldaret/ss
synced 2026-08-11 03:26:06 -04:00
Move missing Ghidra symbols from REL data to decomp symbols (#116)
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user