// Convert TMS34010 bit-address pointer constants into Ghidra references. // // The firmware stores absolute *bit* addresses: a 32-bit constant P refers to // physical byte P >> 3. A byte-addressed Ghidra program cannot resolve those, // so this script scans the loaded ROM for such constants and adds a reference // from each constant to the byte it points at. Byte data is left untouched. // // Companion: tools/ptr_constants.py does the same off-line (shared logic). //@category VT1200 import ghidra.app.script.GhidraScript; import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressSpace; import ghidra.program.model.mem.MemoryBlock; import ghidra.program.model.symbol.RefType; import ghidra.program.model.symbol.Reference; import ghidra.program.model.symbol.SourceType; public class FixPtrConstants extends GhidraScript { private MemoryBlock loadRom() { MemoryBlock rom = null; long best = -1; for (MemoryBlock b : currentProgram.getMemory().getBlocks()) { if (b.isInitialized()) { long len = b.getEnd().getOffset() - b.getStart().getOffset(); if (len > best) { best = len; rom = b; } } } return rom; } @Override public void run() throws Exception { MemoryBlock rom = loadRom(); if (rom == null) { throw new IllegalStateException("no initialized ROM block"); } AddressSpace space = currentProgram.getAddressFactory().getDefaultAddressSpace(); long base = rom.getStart().getOffset(); long size = rom.getEnd().getOffset() - base + 1; println(String.format("ROM block 0x%08X-0x%08X (%d bytes)", base, base + size - 1, size)); int created = 0; int already = 0; int failed = 0; int skipped = 0; byte[] raw = new byte[4]; for (long off = 0; off + 4 <= size; off += 2) { Address from = space.getAddress(base + off); if (currentProgram.getListing().getInstructionContaining(from) != null) { skipped++; // don't add refs from inside code continue; } rom.getBytes(from, raw); long value = (raw[0] & 0xFFL) | ((raw[1] & 0xFFL) << 8) | ((raw[2] & 0xFFL) << 16) | ((raw[3] & 0xFFL) << 24); long target = value >>> 3; if (target < base || target >= base + size) { skipped++; continue; } Address to = space.getAddress(target); boolean exists = false; for (Reference r : currentProgram.getReferenceManager().getReferencesFrom(from)) { if (r.getToAddress().equals(to)) { exists = true; break; } } if (exists) { already++; continue; } try { currentProgram.getReferenceManager().addMemoryReference( from, to, RefType.DATA, SourceType.USER_DEFINED, 0); created++; } catch (Exception e) { failed++; } } println(String.format("references created=%d already=%d failed=%d skipped=%d", created, already, failed, skipped)); } }