mirror of
https://github.com/zeldaret/oot.git
synced 2025-02-11 16:09:09 +00:00
68 lines
1.6 KiB
Python
68 lines
1.6 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
# SPDX-FileCopyrightText: © 2025 ZeldaRET
|
||
|
# SPDX-License-Identifier: CC0-1.0
|
||
|
|
||
|
import argparse
|
||
|
import struct
|
||
|
|
||
|
import elftools.elf.elffile
|
||
|
|
||
|
# Patches mdebug for files linked with data_with_rodata.ld by replacing storage
|
||
|
# class stData with stRData, since .data symbols are now in the .rodata section
|
||
|
|
||
|
SC_MASK = 0x03E00000
|
||
|
SC_SHIFT = 21
|
||
|
|
||
|
|
||
|
def read_u32(f, offset):
|
||
|
f.seek(offset)
|
||
|
return struct.unpack(">I", f.read(4))[0]
|
||
|
|
||
|
|
||
|
def write_u32(f, offset, value):
|
||
|
f.seek(offset)
|
||
|
f.write(struct.pack(">I", value))
|
||
|
|
||
|
|
||
|
def patch_sc(f, offset):
|
||
|
value = read_u32(f, offset)
|
||
|
sc = (value & SC_MASK) >> SC_SHIFT
|
||
|
if sc == 2: # scData
|
||
|
value = (value & ~SC_MASK) | (15 << SC_SHIFT) # scRData
|
||
|
write_u32(f, offset, value)
|
||
|
|
||
|
|
||
|
def main():
|
||
|
parser = argparse.ArgumentParser()
|
||
|
|
||
|
parser.add_argument("file", help="input file")
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
with open(args.file, "r+b") as f:
|
||
|
elf = elftools.elf.elffile.ELFFile(f)
|
||
|
|
||
|
mdebug_offset = 0
|
||
|
for section in elf.iter_sections():
|
||
|
if section.name == ".mdebug":
|
||
|
mdebug_offset = section["sh_offset"]
|
||
|
break
|
||
|
|
||
|
if mdebug_offset == 0:
|
||
|
return
|
||
|
|
||
|
isymMax = read_u32(f, mdebug_offset + 0x20)
|
||
|
cbSymOffset = read_u32(f, mdebug_offset + 0x24)
|
||
|
iextMax = read_u32(f, mdebug_offset + 0x58)
|
||
|
cbExtOffset = read_u32(f, mdebug_offset + 0x5C)
|
||
|
|
||
|
for i in range(isymMax):
|
||
|
patch_sc(f, cbSymOffset + i * 0xC + 0x8)
|
||
|
|
||
|
for i in range(iextMax):
|
||
|
patch_sc(f, cbExtOffset + i * 0x10 + 0xC)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|