// ExportSymbols.java — headless, read-only: export all USER_DEFINED symbols (our manual RE work) to // a committable text file, so the annotations are version-controlled / re-importable independent of the // gitignored Ghidra .rep. This is the durable, diffable record of the symbols (sotn model; Phase-5 splat // will consume/refine config/symbols.us.txt). // // analyzeHeadless ~/bfm-decomp/ghidra bfm -process SLUS_007.26 -noanalysis -readOnly \ // -scriptPath ~/bfm-decomp/tools/ghidra_scripts -postScript ExportSymbols.java import ghidra.app.script.GhidraScript; import ghidra.program.model.symbol.Symbol; import ghidra.program.model.symbol.SymbolTable; import ghidra.program.model.symbol.SourceType; import ghidra.program.model.symbol.SymbolType; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; public class ExportSymbols extends GhidraScript { public void run() throws Exception { SymbolTable st = currentProgram.getSymbolTable(); ArrayList keys = new ArrayList<>(); // [addr] ArrayList lines = new ArrayList<>(); java.util.TreeMap rows = new java.util.TreeMap<>(); int n = 0; for (Symbol s : st.getAllSymbols(true)) { if (s.getSource() != SourceType.USER_DEFINED) continue; if (s.isExternal()) continue; long a = s.getAddress().getOffset(); // only KSEG0 program space (skip GTE/register-space user labels if any) String kind = (s.getSymbolType() == SymbolType.FUNCTION) ? "func" : "data"; rows.put((a << 4) | (kind.equals("func") ? 0 : 1), String.format("%-32s = 0x%08X; // %s", s.getName(), a, kind)); n++; } StringBuilder sb = new StringBuilder(); sb.append("// config/symbols.us.txt — USER_DEFINED symbols exported from the Ghidra project.\n"); sb.append("// Auto-generated by tools/ghidra_scripts/ExportSymbols.java; re-run to refresh.\n"); sb.append("// Durable text record of manual RE work (the .rep is gitignored). Phase-5 splat refines this.\n"); sb.append("// count=").append(n).append("\n\n"); for (String v : rows.values()) sb.append(v).append("\n"); java.nio.file.Path out = Paths.get(System.getProperty("user.home"), "bfm-decomp", "config", "symbols.us.txt"); Files.write(out, sb.toString().getBytes()); println("BFMSYM exported " + n + " USER_DEFINED symbols -> " + out); } }