Skip to content

Commit 92dafa5

Browse files
committed
Add rellink
1 parent 90fe81e commit 92dafa5

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

ttyd-tools/rellink/rellink.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Copyright PistonMiner, all rights reserved
2+
# Revision 0.1
3+
4+
import sys
5+
import os
6+
import struct
7+
import ctypes
8+
9+
# read the data in.
10+
filename_in = sys.argv[1]
11+
input = open(filename_in, "rb")
12+
file_data = ctypes.create_string_buffer(input.read())
13+
input.close()
14+
15+
baseAddress = int(sys.argv[2], 16) #0x805ba9a0 #0x804FFF3C #
16+
17+
curOffset = 0x0
18+
relID = struct.unpack(">L", file_data[curOffset:curOffset+0x4])[0]
19+
curOffset = 0xC
20+
section_count = struct.unpack(">L", file_data[curOffset:curOffset+0x4])[0]
21+
curOffset = 0x10
22+
section_info_offset = struct.unpack(">L", file_data[curOffset:curOffset+0x4])[0]
23+
curOffset = 0x28
24+
import_offset = struct.unpack(">L", file_data[curOffset:curOffset+0x4])[0]
25+
curOffset = 0x2C
26+
import_size = struct.unpack(">L", file_data[curOffset:curOffset+0x4])[0]
27+
28+
# set imports and relocations to invalid since we are doing them
29+
struct.pack_into(">L", file_data, 0x24, 0) # reloc offset
30+
struct.pack_into(">L", file_data, 0x28, 0) # import offset
31+
struct.pack_into(">L", file_data, 0x2C, 0) # import count
32+
33+
sections = [] # [list of [offset, size]]
34+
imports = [] # [list of [id, offset]]
35+
36+
for i in xrange(section_count):
37+
curOffset = section_info_offset + 8 * i
38+
39+
offset = (struct.unpack(">L", file_data[curOffset:curOffset+0x4])[0]) & ~1 # remove bit 0 (exec bit)
40+
size = struct.unpack(">L", file_data[curOffset+0x4:curOffset+0x8])[0]
41+
42+
sections.append([offset, size])
43+
44+
print str(section_count) + " sections"
45+
46+
print sections
47+
48+
for i in xrange(import_size / 8):
49+
curOffset = import_offset + 8 * i
50+
51+
id = struct.unpack(">L", file_data[curOffset:curOffset+0x4])[0]
52+
offset = struct.unpack(">L", file_data[curOffset+0x4:curOffset+0x8])[0]
53+
54+
imports.append([id, offset])
55+
56+
print str(import_size / 8) + " import lists"
57+
58+
print imports
59+
60+
61+
for import_entry in imports:
62+
curOffset = import_entry[1] # offset
63+
if 1: #relID == import_entry[0] # self-relocations / or others apparently cause they only do it for fancy import entries.
64+
curRelOffset = 0
65+
curRelSection = 0
66+
while 1:
67+
curRelOffset += struct.unpack(">H", file_data[curOffset:curOffset+0x2])[0] # add offset
68+
operation = struct.unpack(">B", file_data[curOffset+0x2:curOffset+0x3])[0]
69+
targetSection = struct.unpack(">B", file_data[curOffset+0x3:curOffset+0x4])[0]
70+
addend = struct.unpack(">L", file_data[curOffset+0x4:curOffset+0x8])[0]
71+
curOffset += 8
72+
73+
print "Processing import entry: " + format(curRelOffset, "x") + " / " + format(operation, "x") + " / " + format(targetSection, "x") + " / " + format(addend, "x")
74+
75+
effectiveOffset = sections[curRelSection][0] + curRelOffset
76+
if relID == import_entry[0]:
77+
targetAddress = sections[targetSection][0] + addend + baseAddress
78+
else:
79+
targetAddress = addend
80+
81+
print format(effectiveOffset, "x") + " / " + format(targetAddress, "x")
82+
83+
#if operation == 0 or operation == 201: # R_PPC_NONE || R_DOLPHIN_NOP
84+
# dummy = 0
85+
if operation == 202: # R_DOLPHIN_SECTION
86+
curRelSection = targetSection
87+
curRelOffset = 0
88+
elif operation == 1: # R_PPC_ADDR32
89+
struct.pack_into(">L", file_data, effectiveOffset, targetAddress)
90+
elif operation == 4: # R_PPC_ADDR16_LO
91+
struct.pack_into(">H", file_data, effectiveOffset, targetAddress & 0xFFFF)
92+
elif operation == 6: # R_PPC_ADDR16_HA
93+
if (targetAddress & 0x8000) == 0x8000:
94+
targetAddress += 0x00010000
95+
96+
struct.pack_into(">H", file_data, effectiveOffset, (targetAddress >> 16) & 0xFFFF)
97+
elif operation == 10: # R_PPC_REL24
98+
value = addend
99+
value -= (effectiveOffset + baseAddress)
100+
orig = struct.unpack(">L", file_data[effectiveOffset:effectiveOffset+0x4])[0]
101+
orig &= 0xFC000003
102+
orig |= value & 0x03FFFFFC
103+
struct.pack_into(">L", file_data, effectiveOffset, orig)
104+
elif operation == 203: # R_DOLPHIN_END
105+
break
106+
else:
107+
print "Unknown relocation operation " + format(opcode, "x")
108+
109+
output_data = str(bytearray(file_data))
110+
111+
filename_out = filename_in + ".linked"
112+
output = open(filename_out , "wb")
113+
output.write(output_data)
114+
output.close()

0 commit comments

Comments
 (0)