Skip to content

Commit 1856730

Browse files
committed
Add support for ghidra's Relocation Table
1 parent 608c8d6 commit 1856730

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

src/main/java/zelda64/Zelda64Loader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> optio
212212
long codeDst = Zelda64CodeInfo.TABLE.get(mGame.mVersion).mCodeDst;
213213
byte[] code = mGame.GetFile(codeVrom).mData;
214214

215-
CreateEmptySegment("boot.bss", entrypoint + boot.length, codeDst - 1, new MemPerm("RWX"), false);
215+
CreateEmptySegment("boot.bss", entrypoint + boot.length, codeDst - 1, new MemPerm("RW-"), false);
216216
CreateSegment("code", codeDst, code, new MemPerm("RWX"), false);
217217
CreateEmptySegment("code.bss", codeDst + code.length, 0x807FFFFF, new MemPerm("RW-"), false);
218218

@@ -303,12 +303,12 @@ private void LoadOvl(String name, long dst, long virtStart, Zelda64Overlay ovl)
303303
Log.info(String.format("creating %s", name));
304304

305305
// isn't really required since in our case dst == virtStart but whatever
306-
ovl.PerformRelocation(dst, virtStart);
306+
ovl.PerformRelocation(mApi, dst, virtStart);
307307

308308
CreateSegment(name, dst, ovl.mRawData, new MemPerm("RWX"), false);
309309
if (ovl.mBssSize != 0)
310310
CreateEmptySegment(name + ".bss", dst + ovl.mRawData.length, dst + ovl.mRawData.length + ovl.mBssSize - 1,
311-
new MemPerm("RWX"), false);
311+
new MemPerm("RW-"), false);
312312
var addr = mApi.toAddr(dst);
313313
try {
314314

src/main/java/zelda64/Zelda64Overlay.java

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package zelda64;
22

33
import java.nio.ByteBuffer;
4-
54
import org.python.jline.internal.Log;
5+
import ghidra.program.flatapi.FlatProgramAPI;
66

77
public class Zelda64Overlay {
88
byte[] mRawData;
@@ -35,7 +35,19 @@ public Zelda64Overlay(byte[] data) {
3535
mEntries[i] = buff.getInt() & 0xFFFFFFFFl;
3636
}
3737

38-
public void PerformRelocation(long ram, long vram) {
38+
private void AddRelocEntry(FlatProgramAPI api, ByteBuffer buff, int type, long relocAddr, long ram, long fixed) {
39+
int off = (int) (relocAddr - ram);
40+
buff.position(off);
41+
byte origBytes[] = new byte[4];
42+
buff.get(origBytes);
43+
api.getCurrentProgram().getRelocationTable().add(api.toAddr(relocAddr), type, new long[] { fixed }, origBytes,
44+
null);
45+
46+
buff.position(off);
47+
buff.putInt((int) (fixed));
48+
}
49+
50+
public void PerformRelocation(FlatProgramAPI api, long ram, long vram) {
3951
if (mRelocated)
4052
return;
4153

@@ -46,47 +58,47 @@ public void PerformRelocation(long ram, long vram) {
4658
Log.info(String.format(".data=0x%X", baseOffs[2]));
4759
Log.info(String.format(".rodata=0x%X", baseOffs[3]));
4860

49-
long[] offArray = new long[0x20];
61+
long[] addrArray = new long[0x20];
5062
long[] insArray = new long[0x20];
5163

5264
var buff = ByteBuffer.wrap(mRawData);
5365

5466
for (int i = 0; i < mEntries.length; i++) {
5567
int type = (int) (mEntries[i] >> 24) & 0x3F;
56-
long off = baseOffs[(int) (mEntries[i] >> 30)] + (mEntries[i] & 0xFFFFFF);
57-
buff.position((int) (off - ram));
68+
long relocAddr = baseOffs[(int) (mEntries[i] >> 30)] + (mEntries[i] & 0xFFFFFF);
69+
buff.position((int) (relocAddr - ram));
5870
long ins = buff.getInt() & 0xFFFFFFFFl;
5971

60-
Log.info(String.format("entry=0x%X; type=%d; off=0x%X; data=0x%X", mEntries[i], type, off, ins));
72+
Log.info(String.format("entry=0x%X; type=%d; off=0x%X; data=0x%X", mEntries[i], type, relocAddr, ins));
6173

6274
if (type == 2) // raw pointers
6375
{
6476
if ((ins & 0xf000000) == 0) {
65-
buff.position((int) (off - ram));
66-
buff.putInt((int) ((ins - vram) + ram));
77+
AddRelocEntry(api, buff, type, relocAddr, ram, (ins - vram) + ram);
6778
}
6879
} else if (type == 4) // e.g. jal
6980
{
7081
var reloc = ins & 0xfc000000 | (ram + (((ins & 0x3ffffff) << 2 | 0x80000000) - vram) & 0xfffffff) >> 2;
71-
buff.position((int) (off - ram));
72-
buff.putInt((int) (reloc));
82+
AddRelocEntry(api, buff, type, relocAddr, ram, reloc);
83+
7384
} else if (type == 5) // e.g. lui at, 0x8080 | (0x3C01 8080)
7485
{
75-
offArray[(int) ((ins >> 0x10) & 0x1F)] = off;
76-
insArray[(int) ((ins >> 0x10) & 0x1F)] = ins;
86+
int register = (int) ((ins >> 0x10) & 0x1F);
87+
addrArray[register] = relocAddr;
88+
insArray[register] = ins;
7789
} else if (type == 6) // e.g. lwc1 ft0, 0x08A0(a) | (0xC424 08A0)
7890
{
79-
var prevOff = offArray[(int) ((ins >> 0x15) & 0x1F)];
80-
var prevIns = insArray[(int) ((ins >> 0x15) & 0x1F)];
91+
int register = (int) ((ins >> 0x15) & 0x1F);
92+
var prevAddr = addrArray[register];
93+
var prevIns = insArray[register];
8194

8295
long ptr = ((prevIns & 0xFFFF) << 16) + (short) (ins & 0xFFFF);
83-
if ((ptr & 0xf000000) == 0) {
96+
if ((ptr & 0xF000000) == 0) {
8497
var reloc = (ptr - vram) + ram;
8598

86-
buff.position((int) (prevOff - ram));
87-
buff.putInt((int) (((prevIns & 0xFFFF0000) | (reloc >> 0x10)) + (((reloc & 0x8000) != 0) ? 1 : 0)));
88-
buff.position((int) (off - ram));
89-
buff.putInt((int) (ins & 0xFFFF0000 | reloc & 0xFFFF));
99+
AddRelocEntry(api, buff, 5, prevAddr, ram,
100+
((prevIns & 0xFFFF0000) | (reloc >> 0x10)) + (((reloc & 0x8000) != 0) ? 1 : 0));
101+
AddRelocEntry(api, buff, 6, relocAddr, ram, ins & 0xFFFF0000 | reloc & 0xFFFF);
90102
}
91103
}
92104
}

0 commit comments

Comments
 (0)