mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
93 lines
3.4 KiB
Java
93 lines
3.4 KiB
Java
// 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));
|
|
}
|
|
}
|