mirror of https://github.com/zeldaret/mm.git
Update tools (#16)
* Clean up .gitignore * Set exec bit on all python and shell scripts * Delete unused files * Add decomp-permuter repo * Update submodules
This commit is contained in:
parent
189d0d6c30
commit
ec912054da
|
@ -1,22 +1,42 @@
|
||||||
|
# Cache files
|
||||||
|
__pycache__/
|
||||||
|
.pyc
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Text editor remnants
|
||||||
|
.vscode/
|
||||||
|
.vs/
|
||||||
|
.idea/
|
||||||
|
CMakeLists.txt
|
||||||
|
cmake-build-debug
|
||||||
|
venv/
|
||||||
|
|
||||||
|
# Project-specific ignores
|
||||||
*.z64
|
*.z64
|
||||||
*.bin
|
*.bin
|
||||||
*.elf
|
*.elf
|
||||||
doc/*
|
archive/
|
||||||
archive/*
|
build/
|
||||||
build/*
|
baserom/
|
||||||
baserom/*
|
decomp/
|
||||||
decomp/*
|
asm/
|
||||||
S/*
|
expected/
|
||||||
asm/*
|
nonmatchings/
|
||||||
font_test/*
|
|
||||||
ido/*
|
# Tool artifacts
|
||||||
__pychahe__/*
|
tools/ido5.3_compiler/
|
||||||
*.pyc
|
tools/ido7.1_compiler/
|
||||||
test.txt
|
|
||||||
*.xlsx
|
|
||||||
src/test.c
|
|
||||||
*.dump
|
|
||||||
tools/ido5.3_compiler/*
|
|
||||||
tools/ido7.1_compiler/*
|
|
||||||
expected/*
|
|
||||||
tools/qemu-mips
|
tools/qemu-mips
|
||||||
|
|
||||||
|
# Assets
|
||||||
|
*.rgba32.png
|
||||||
|
*.rgb5a1.png
|
||||||
|
*.i4.png
|
||||||
|
*.i8.png
|
||||||
|
*.ia4.png
|
||||||
|
*.ia8.png
|
||||||
|
*.ci4.png
|
||||||
|
*.ci8.png
|
||||||
|
|
||||||
|
# Per-user configuration
|
||||||
|
.python-version
|
||||||
|
|
|
@ -7,3 +7,6 @@
|
||||||
[submodule "tools/ZAP2"]
|
[submodule "tools/ZAP2"]
|
||||||
path = tools/ZAP2
|
path = tools/ZAP2
|
||||||
url = https://github.com/NEstelami/ZAP2.git
|
url = https://github.com/NEstelami/ZAP2.git
|
||||||
|
[submodule "tools/decomp-permuter"]
|
||||||
|
path = tools/decomp-permuter
|
||||||
|
url = https://github.com/simonlindholm/decomp-permuter
|
||||||
|
|
10
asmdiff.sh
10
asmdiff.sh
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
OBJDUMP="${MIPS_BINUTILS_PREFIX}objdump -D -z -mmips -EB -j .text -j .data -j .rodata"
|
|
||||||
|
|
||||||
FORMATTER="sed '/^0/!s/.*://'"
|
|
||||||
|
|
||||||
$OBJDUMP build/src/test.o | sed '1,6d; /^0/!s/.*://' > test.dump
|
|
||||||
$OBJDUMP $1 | sed '1,6d; /^0/!s/.*://' > comp.dump
|
|
||||||
diff -y test.dump comp.dump > diff.dump
|
|
||||||
rm test.dump comp.dump
|
|
3975
textures.csv
3975
textures.csv
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
||||||
Subproject commit ba00137cf7ef67477ccae2211bf541013b197367
|
Subproject commit 15fcb21d2c4e2ef2f720d28a0f7dec259ddd06f5
|
|
@ -1 +1 @@
|
||||||
Subproject commit d71fbe15c40e74c8f2226c0af596b80c9e92c97c
|
Subproject commit 9d79eb9f539e5fa58fe63c62862661c5d9ce0d27
|
|
@ -1 +1 @@
|
||||||
Subproject commit cbc5b1af79d236f914509bd037213861d65001b0
|
Subproject commit bc7db5a0e489b73595d5e97004f11d5fdea026e4
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit cbb41c125464c3cbe799d77fe2d661615f934720
|
|
@ -1,178 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
import struct;
|
|
||||||
from tkinter import *;
|
|
||||||
from tkinter.ttk import *
|
|
||||||
from PIL import Image, ImageTk, ImageDraw
|
|
||||||
|
|
||||||
import png;
|
|
||||||
|
|
||||||
#FILE_NAME = 'baserom/jpn_font_static'
|
|
||||||
FILE_NAME = 'decomp/object_boss03'
|
|
||||||
|
|
||||||
data = []
|
|
||||||
image_data = [];
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(FILE_NAME, 'rb') as f:
|
|
||||||
data = f.read()
|
|
||||||
except IOError:
|
|
||||||
print('failed to read file ' + FILE_NAME)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
#size = 0x80
|
|
||||||
height = 32
|
|
||||||
width = 32
|
|
||||||
pixel_width = 2
|
|
||||||
size = height*width*pixel_width
|
|
||||||
scale = 4
|
|
||||||
|
|
||||||
window = Tk()
|
|
||||||
|
|
||||||
window.title("MM Texture viewer")
|
|
||||||
window.geometry('500x500')
|
|
||||||
|
|
||||||
def load_file():
|
|
||||||
print('load')
|
|
||||||
update_image()
|
|
||||||
|
|
||||||
def read_i4_image(data, image_data):
|
|
||||||
for i in range(0, len(data)):
|
|
||||||
byte = data[i]
|
|
||||||
color1 = ((byte >> 4) & 0xF) * 17
|
|
||||||
color2 = (byte & 0xF) * 17
|
|
||||||
image_data.append(color1)
|
|
||||||
image_data.append(color1)
|
|
||||||
image_data.append(color1)
|
|
||||||
image_data.append(255)
|
|
||||||
image_data.append(color2)
|
|
||||||
image_data.append(color2)
|
|
||||||
image_data.append(color2)
|
|
||||||
image_data.append(255)
|
|
||||||
|
|
||||||
def read_i8_image(data, image_data):
|
|
||||||
for i in range(0, len(data)):
|
|
||||||
byte = data[i]
|
|
||||||
image_data.append(byte)
|
|
||||||
image_data.append(byte)
|
|
||||||
image_data.append(byte)
|
|
||||||
image_data.append(255)
|
|
||||||
|
|
||||||
def read_ia4_image(data, image_data):
|
|
||||||
None
|
|
||||||
|
|
||||||
def read_ia8_image(data, image_data):
|
|
||||||
None
|
|
||||||
|
|
||||||
def read_ia16_image(data, image_data):
|
|
||||||
None
|
|
||||||
|
|
||||||
def read_rbg5a1_image(data, image_data):
|
|
||||||
for i in range(0, len(data) // 2):
|
|
||||||
byte1 = data[i*2]
|
|
||||||
byte2 = data[i*2 + 1]
|
|
||||||
red = (byte1 >> 3)*8
|
|
||||||
green = (((byte1&0x7)<<2) | ((byte2>>6)&0x3))*8
|
|
||||||
blue = ((byte2 >> 1) & 0x1F)*8
|
|
||||||
alpha = (byte2&0x1)*0xFF
|
|
||||||
image_data.append(red)
|
|
||||||
image_data.append(green)
|
|
||||||
image_data.append(blue)
|
|
||||||
image_data.append(alpha)
|
|
||||||
|
|
||||||
def read_rbga32_image(data, image_data):
|
|
||||||
for i in range(0, len(data)):
|
|
||||||
byte = data[i]
|
|
||||||
image_data.append(byte)
|
|
||||||
|
|
||||||
def read_ci4_image(data, image_data):
|
|
||||||
None
|
|
||||||
|
|
||||||
def read_ci8_image(data, image_data):
|
|
||||||
None
|
|
||||||
|
|
||||||
def update_image(*args):
|
|
||||||
global image_label
|
|
||||||
global image_data
|
|
||||||
global data
|
|
||||||
|
|
||||||
image_data = []
|
|
||||||
|
|
||||||
texture_type = texture_type_combo.get()
|
|
||||||
if texture_type == 'i4':
|
|
||||||
read_i4_image(data, image_data)
|
|
||||||
elif texture_type == 'i8':
|
|
||||||
read_i8_image(data, image_data)
|
|
||||||
elif texture_type == 'ia4':
|
|
||||||
read_ia4_image(data, image_data)
|
|
||||||
elif texture_type == 'ia8':
|
|
||||||
read_ia8_image(data, image_data)
|
|
||||||
elif texture_type == 'ia16':
|
|
||||||
read_ia16_image(data, image_data)
|
|
||||||
elif texture_type == 'rbg5a1':
|
|
||||||
read_rbg5a1_image(data, image_data)
|
|
||||||
elif texture_type == 'rbga32':
|
|
||||||
read_rbga32_image(data, image_data)
|
|
||||||
elif texture_type == 'ci4':
|
|
||||||
read_ci4_image(data, image_data)
|
|
||||||
elif texture_type == 'ci8':
|
|
||||||
read_ci8_image(data, image_data)
|
|
||||||
else:
|
|
||||||
print('other type')
|
|
||||||
|
|
||||||
offset = int(offset_spinbox.get())
|
|
||||||
|
|
||||||
image = Image.frombytes("RGBA", (width, height), bytes(image_data[offset*4:])).resize((width*scale, height*scale))
|
|
||||||
image_tk = ImageTk.PhotoImage(image=image)
|
|
||||||
image_label.configure(image=image_tk)
|
|
||||||
image_label.image = image_tk # prevent GC?
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
load_button = Button(window, text='Load File', command=load_file)
|
|
||||||
load_button.pack()
|
|
||||||
|
|
||||||
texture_type_combo = Combobox(window)
|
|
||||||
texture_type_combo['values'] = ('i4', 'i8', 'ia4', 'ia8', 'ia16', 'rbg5a1', 'rbga32', 'ci4', 'ci8')
|
|
||||||
texture_type_combo.current(5)
|
|
||||||
texture_type_combo.bind("<<ComboboxSelected>>", update_image)
|
|
||||||
texture_type_combo.pack()
|
|
||||||
|
|
||||||
# TODO textures should be able to only take a few discret values, find them
|
|
||||||
width_default = StringVar(window)
|
|
||||||
width_default.set("32")
|
|
||||||
width_spinbox = Spinbox(window, from_=1, to=48, textvariable=width_default, command=update_image)
|
|
||||||
width_spinbox.pack();
|
|
||||||
|
|
||||||
offset_default = StringVar(window)
|
|
||||||
offset_default.set("0")
|
|
||||||
offset_spinbox = Spinbox(window, from_=0, to=len(data), textvariable=offset_default, command=update_image)
|
|
||||||
offset_spinbox.pack();
|
|
||||||
|
|
||||||
image_label = Label(window)
|
|
||||||
image_label.pack()
|
|
||||||
|
|
||||||
update_image()
|
|
||||||
|
|
||||||
window.mainloop()
|
|
||||||
|
|
||||||
#for i in range(0, len(data) // size):
|
|
||||||
# texture_data = data[(i * size):((i + 1) * size)]
|
|
||||||
#
|
|
||||||
# with open('font_test2/' + str(i) + '.png', 'wb') as f:
|
|
||||||
# w = png.Writer(width, height, alpha=True)#, greyscale=True)#
|
|
||||||
# png_data = [];
|
|
||||||
# for y in range(0, height):
|
|
||||||
# row = []
|
|
||||||
# '''
|
|
||||||
# for x in range(0, 16//2):
|
|
||||||
# byte = texture_data[8*y + x]
|
|
||||||
# row.append(((byte >> 4) & 0xF) * 17)
|
|
||||||
# row.append((byte & 0xF) * 17)
|
|
||||||
# '''
|
|
||||||
# '''
|
|
||||||
# for x in range(0, width*pixel_width):
|
|
||||||
# byte = texture_data[width*pixel_width*y + x]
|
|
||||||
# row.append(byte)
|
|
||||||
# '''
|
|
||||||
# png_data.append(row)
|
|
||||||
# w.write(f, png_data)
|
|
|
@ -1,57 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
# TODO generalize
|
|
||||||
|
|
||||||
data = [
|
|
||||||
0xC8580005,
|
|
||||||
0xB874FE0C,
|
|
||||||
0x801F0002,
|
|
||||||
0x30540FA0
|
|
||||||
]
|
|
||||||
|
|
||||||
last_continue = True
|
|
||||||
for entry in data:
|
|
||||||
if not last_continue:
|
|
||||||
print('Error: entries after entry without continue bit')
|
|
||||||
|
|
||||||
value = entry & 0xFFFF
|
|
||||||
offset = (entry >> 16) & 0x7FF
|
|
||||||
type = (entry >> 27) & 0xF
|
|
||||||
_continue = (entry >> 31) & 0x1
|
|
||||||
|
|
||||||
# convert to signed short
|
|
||||||
if value >= 0x8000:
|
|
||||||
value -= 0x10000
|
|
||||||
|
|
||||||
# TODO which ones are signed?
|
|
||||||
print('0x{:X}: '.format(offset), end='')
|
|
||||||
if type == 0:
|
|
||||||
print('char {}'.format(value))
|
|
||||||
elif type == 1:
|
|
||||||
print('char {}'.format(value))
|
|
||||||
elif type == 2:
|
|
||||||
print('short {}'.format(value))
|
|
||||||
elif type == 3:
|
|
||||||
print('short {}'.format(value))
|
|
||||||
elif type == 4:
|
|
||||||
print('int {}'.format(value))
|
|
||||||
elif type == 5:
|
|
||||||
print('int {}'.format(value))
|
|
||||||
elif type == 6:
|
|
||||||
print('float {:f}'.format(value))
|
|
||||||
elif type == 7:
|
|
||||||
print('float {:f}'.format(value / 1000))
|
|
||||||
elif type == 8:
|
|
||||||
print('Vector3f ({0:f}, {0:f}, {0:f})'.format(value))
|
|
||||||
elif type == 9:
|
|
||||||
value /= 1000
|
|
||||||
print('Vector3f ({0:f}, {0:f}, {0:f})'.format(value))
|
|
||||||
elif type == 10:
|
|
||||||
print('Vector3f ({0}, {0}, {0})'.format(value))
|
|
||||||
else:
|
|
||||||
print('Error: invalid type ' + str(value))
|
|
||||||
|
|
||||||
if not _continue:
|
|
||||||
print('END')
|
|
||||||
|
|
||||||
last_continue = _continue
|
|
||||||
|
|
1391
tools/parse_dl.py
1391
tools/parse_dl.py
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@ import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||||
asm_processor = ['python3', os.path.join(dir_path, "asm-processor/asm-processor.py")]
|
asm_processor = ['python3', os.path.join(dir_path, "asm-processor/asm_processor.py")]
|
||||||
prelude = os.path.join(dir_path, "prelude.inc")
|
prelude = os.path.join(dir_path, "prelude.inc")
|
||||||
|
|
||||||
all_args = sys.argv[1:]
|
all_args = sys.argv[1:]
|
||||||
|
|
|
@ -1,488 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
'''
|
|
||||||
Resources:
|
|
||||||
http://www.cs.unibo.it/~solmi/teaching/arch_2002-2003/AssemblyLanguageProgDoc.pdf
|
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/include/coff/sym.h
|
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/include/coff/symconst.h
|
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/gas/ecoff.c
|
|
||||||
https://github.com/pathscale/binutils/blob/5c2c133020e41fc4aadd80a99156d2cea4754b96/bfd/ecoff.c
|
|
||||||
https://github.com/pathscale/absoft/blob/master/svn/trunk/ekopath-gcc/ekopath-gcc-4.2.0/gcc/mips-tdump.c
|
|
||||||
'''
|
|
||||||
|
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
import collections
|
|
||||||
import sys
|
|
||||||
|
|
||||||
OFFSET = 0 # TODO why are the offsets in the symbolic header off by some amount?
|
|
||||||
|
|
||||||
indent_level = 0
|
|
||||||
is_comment = False
|
|
||||||
|
|
||||||
symbol_type_list = [
|
|
||||||
'stNil', 'stGlobal', 'stStatic', 'stParam', 'stLocal', 'stLabel', 'stProc', 'stBlock',
|
|
||||||
'stEnd', 'stMember', 'stTypedef', 'stFile', 'INVALID', 'INVALID', 'stStaticProc', 'stConstant',
|
|
||||||
'stStaParam', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID', 'INVALID',
|
|
||||||
'INVALID', 'INVALID', 'stStruct', 'stUnion', 'stEnum', 'INVALID', 'INVALID', 'INVALID',
|
|
||||||
'INVALID', 'INVALID', 'stIndirect']
|
|
||||||
storage_class_list = ['scNil', 'scText', 'scData', 'scBss', 'scRegister', 'scAbs', 'scUndefined', 'reserved',
|
|
||||||
'scBits', 'scDbx', 'scRegImage', 'scInfo', 'scUserStruct', 'scSData', 'scSBss', 'scRData',
|
|
||||||
'scVar', 'scCommon', 'scSCommon', 'scVarRegister', 'scVariant', 'scUndefined', 'scInit']
|
|
||||||
basic_type_c_list = ['nil', 'addr', 'signed char', 'unsigned char', 'short', 'unsigned short', 'int', 'unsigned int',
|
|
||||||
'long', 'unsigned long', 'float', 'double', 'struct', 'union', 'enum', 'typedef',
|
|
||||||
'range', 'set', 'complex', 'double complex', 'indirect', 'fixed decimal', 'float decimal', 'string',
|
|
||||||
'bit', 'picture', 'void', 'long long', 'unsigned long long', 'INVALID', 'long', 'unsigned long',
|
|
||||||
'long long', 'unsigned long long', 'addr', 'int64', 'unsigned int64']
|
|
||||||
|
|
||||||
def increase_indent():
|
|
||||||
global indent_level
|
|
||||||
indent_level += 1
|
|
||||||
|
|
||||||
def decrease_indent():
|
|
||||||
global indent_level
|
|
||||||
indent_level -= 1
|
|
||||||
|
|
||||||
def set_is_comment(set_to):
|
|
||||||
global is_comment
|
|
||||||
old = is_comment
|
|
||||||
is_comment = set_to
|
|
||||||
return old
|
|
||||||
|
|
||||||
def get_indent():
|
|
||||||
global indent_level
|
|
||||||
global is_comment
|
|
||||||
ret = '//' if is_comment else ''
|
|
||||||
for i in range(indent_level):
|
|
||||||
ret += ' '
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def read_uint32_be(file_data, offset):
|
|
||||||
return struct.unpack('>I', file_data[offset:offset+4])[0]
|
|
||||||
|
|
||||||
def read_uint16_be(file_data, offset):
|
|
||||||
return struct.unpack('>H', file_data[offset:offset+2])[0]
|
|
||||||
|
|
||||||
def read_uint8_be(file_data, offset):
|
|
||||||
return struct.unpack('>B', file_data[offset:offset+1])[0]
|
|
||||||
|
|
||||||
def read_elf_header(file_data, offset):
|
|
||||||
Header = collections.namedtuple('ElfHeader',
|
|
||||||
'''e_magic e_class e_data e_version e_osabi e_abiversion e_pad
|
|
||||||
e_type e_machine e_version2 e_entry e_phoff e_shoff e_flags
|
|
||||||
e_ehsize e_phentsize e_phnum e_shentsize e_shnum e_shstrndx''')
|
|
||||||
return Header._make(struct.unpack('>I5B7s2H5I6H', file_data[offset:offset+52]))
|
|
||||||
|
|
||||||
def read_elf_section_header(file_data, offset):
|
|
||||||
Header = collections.namedtuple('SectionHeader',
|
|
||||||
'''sh_name sh_type sh_flags sh_addr sh_offset sh_size sh_link
|
|
||||||
sh_info sh_addralign sh_entsize''')
|
|
||||||
return Header._make(struct.unpack('>10I', file_data[offset:offset+40]))
|
|
||||||
|
|
||||||
def read_symbolic_header(file_data, offset):
|
|
||||||
Header = collections.namedtuple('SymbolicHeader',
|
|
||||||
'''magic vstamp ilineMax cbLine cbLineOffset idnMax cbDnOffset
|
|
||||||
ipdMax cbPdOffset isymMax cbSymOffset ioptMax cbOptOffset
|
|
||||||
iauxMax cbAuxOffset issMax cbSsOffset issExtMax cbSsExtOffset
|
|
||||||
ifdMax cbFdOffset crfd cbRfdOffset iextMax cbExtOffset''')
|
|
||||||
return Header._make(struct.unpack('>2H23I', file_data[offset:offset+96]))
|
|
||||||
|
|
||||||
# TODO find a better solution for the bitfield
|
|
||||||
def read_file_descriptor(file_data, offset):
|
|
||||||
if 'init' not in read_file_descriptor.__dict__:
|
|
||||||
read_file_descriptor.cache = {}
|
|
||||||
read_file_descriptor.header = collections.namedtuple('FileDescriptor',
|
|
||||||
'''adr rss issBase cbSs isymBase csym ilineBase cline ioptBase
|
|
||||||
copt ipdFirst cpd iauxBase caux rfdBase crfd XXX_bitfield
|
|
||||||
cbLineOffset cbLine''')
|
|
||||||
read_file_descriptor.init = True
|
|
||||||
if offset in read_file_descriptor.cache:
|
|
||||||
return read_file_descriptor.cache[offset]
|
|
||||||
read_file_descriptor.cache[offset] = read_file_descriptor.header._make(
|
|
||||||
struct.unpack('>I2iI6iHh4iI2I', file_data[offset:offset+72]))
|
|
||||||
return read_file_descriptor.cache[offset]
|
|
||||||
|
|
||||||
def read_procedure_descriptor(file_data, offset):
|
|
||||||
Header = collections.namedtuple('ProcedureDescriptor',
|
|
||||||
'''adr isym iline regmask regoffset iopt fregmask fregoffset
|
|
||||||
frameoffset framereg pcreg lnLow lnHigh cbLineOffset''')
|
|
||||||
return Header._make(struct.unpack('>I8i2h2iI', file_data[offset:offset+52]))
|
|
||||||
|
|
||||||
def read_symbol(file_data, offset):
|
|
||||||
if 'init' not in read_symbol.__dict__:
|
|
||||||
read_symbol.cache = {}
|
|
||||||
read_symbol.header = collections.namedtuple('Symbol', '''iss value st sc index''')
|
|
||||||
read_symbol.init = True
|
|
||||||
if offset in read_symbol.cache:
|
|
||||||
return read_symbol.cache[offset]
|
|
||||||
(word0, word1, word2) = struct.unpack('>iII', file_data[offset:offset+12])
|
|
||||||
read_symbol.cache[offset] = read_symbol.header._make((
|
|
||||||
word0, word1, (word2 >> 26) & 0x3F, (word2 >> 21) & 0x1F, word2 & 0xFFFFF))
|
|
||||||
return read_symbol.cache[offset]
|
|
||||||
|
|
||||||
def read_auxiliary_symbol(file_data, offset):
|
|
||||||
if 'init' not in read_auxiliary_symbol.__dict__:
|
|
||||||
read_auxiliary_symbol.cache = {}
|
|
||||||
read_auxiliary_symbol.header = collections.namedtuple('AuxSymbol',
|
|
||||||
'''ti rndx dnLow dnHigh isym iss width count''')
|
|
||||||
read_auxiliary_symbol.type_info = collections.namedtuple('TypeInfo',
|
|
||||||
'''fBitfield continued bt tq4 tq5 tq0 tq1 tq2 tq3''')
|
|
||||||
read_auxiliary_symbol.rel_sym = collections.namedtuple('RelativeSymbol', '''rfd index''')
|
|
||||||
read_auxiliary_symbol.init = True
|
|
||||||
if offset in read_auxiliary_symbol.cache:
|
|
||||||
return read_auxiliary_symbol.cache[offset]
|
|
||||||
word0 = struct.unpack('>I', file_data[offset:offset+4])[0]
|
|
||||||
read_auxiliary_symbol.cache[offset] = read_auxiliary_symbol.header._make((
|
|
||||||
read_auxiliary_symbol.type_info._make(((word0 >> 31) & 1, (word0 >> 30) & 1, (word0 >> 24) & 0x3F, (word0 >> 20) & 0xF, (word0 >> 16) & 0xF, (word0 >> 12) & 0xF, (word0 >> 8) & 0xF, (word0 >> 4) & 0xF, word0 & 0xF)),
|
|
||||||
read_auxiliary_symbol.rel_sym._make(((word0 >> 20) & 0xFFF, word0 & 0xFFFFF)),
|
|
||||||
word0, word0, word0, word0, word0, word0))
|
|
||||||
return read_auxiliary_symbol.cache[offset]
|
|
||||||
|
|
||||||
def read_string(file_data, offset):
|
|
||||||
current_offset = 0
|
|
||||||
current_string = b''
|
|
||||||
while True:
|
|
||||||
char = struct.unpack('c', file_data[offset+current_offset:offset+current_offset+1])[0]
|
|
||||||
if char == b'\0':
|
|
||||||
return current_string.decode('ascii')
|
|
||||||
else:
|
|
||||||
current_string += char
|
|
||||||
current_offset += 1
|
|
||||||
|
|
||||||
def get_symbol_name_from_aux(file_data, fd, symbolic_header, aux_num, search_for_typedef):
|
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + aux_num)*4)
|
|
||||||
fd_num = aux.rndx.rfd
|
|
||||||
next_aux = aux_num+1
|
|
||||||
if fd_num == 4095:
|
|
||||||
aux2 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
|
||||||
fd_num = aux2.isym
|
|
||||||
next_aux = next_aux+1;
|
|
||||||
fd2 = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + fd_num*72)
|
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (fd2.isymBase + aux.rndx.index)*12)
|
|
||||||
ret = ''
|
|
||||||
#print('%r' % (aux,));
|
|
||||||
#print('%r' % (aux2,));
|
|
||||||
#print('%r' % (sym,));
|
|
||||||
if sym.st == 26 or sym.st == 27: #stStruct, stunion
|
|
||||||
ret = get_struct_or_union_string(file_data, fd2, symbolic_header, fd2.isymBase + aux.rndx.index, search_for_typedef)
|
|
||||||
elif sym.st == 28: #stEnum:
|
|
||||||
ret = get_enum_string(file_data, fd2, symbolic_header, fd2.isymBase + aux.rndx.index)
|
|
||||||
else:
|
|
||||||
ret = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd2.issBase + sym.iss)
|
|
||||||
return (ret, next_aux)
|
|
||||||
|
|
||||||
def get_type_string(file_data, fd, symbolic_header, aux_num, name, search_for_typedef):
|
|
||||||
ret = ''
|
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + aux_num)*4)
|
|
||||||
#print('');
|
|
||||||
#print('%r' % (aux,));
|
|
||||||
next_aux = aux_num+1
|
|
||||||
has_bitfield = aux.ti.fBitfield == 1
|
|
||||||
bitwidth = 0
|
|
||||||
if has_bitfield:
|
|
||||||
bit_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
|
||||||
bitwidth = bit_aux.isym
|
|
||||||
next_aux = next_aux+1
|
|
||||||
if aux.ti.bt == 12: # btStruct
|
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
|
||||||
elif aux.ti.bt == 13: # btUnion
|
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
|
||||||
elif aux.ti.bt == 15: # btTypedef
|
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
|
||||||
elif aux.ti.bt == 14: # btEnum
|
|
||||||
(ret, next_aux) = get_symbol_name_from_aux(file_data, fd, symbolic_header, next_aux, search_for_typedef)
|
|
||||||
else:
|
|
||||||
ret = basic_type_c_list[aux.ti.bt]
|
|
||||||
|
|
||||||
tq_list = (aux.ti.tq0, aux.ti.tq1, aux.ti.tq2, aux.ti.tq3, aux.ti.tq4, aux.ti.tq5)
|
|
||||||
|
|
||||||
# TODO this is very naive and probably does not work in a large amount of cases
|
|
||||||
last_was_proc = False # if we see a tqProc, assume the next will be a tqPtr
|
|
||||||
for tq in tq_list:
|
|
||||||
if tq == 0: # tqNil
|
|
||||||
break;
|
|
||||||
elif tq == 1: # tqPtr
|
|
||||||
if last_was_proc:
|
|
||||||
last_was_proc = False
|
|
||||||
continue
|
|
||||||
ret += '*'
|
|
||||||
elif tq == 2: # tqProc
|
|
||||||
last_was_proc = True
|
|
||||||
name = '(*%s)(/* ECOFF does not store param types */)' % name
|
|
||||||
elif tq == 3: # tqArray
|
|
||||||
next_aux += 2 # todo what does this skip over? (Apparantly the type of the index, so always int for C)
|
|
||||||
array_low_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux)*4)
|
|
||||||
array_high_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux+1)*4)
|
|
||||||
stride_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + next_aux+2)*4)
|
|
||||||
next_aux += 3
|
|
||||||
if array_high_aux.dnHigh == 0xFFFFFFFF:
|
|
||||||
name += '[]'
|
|
||||||
else:
|
|
||||||
name += '[%d]' % (array_high_aux.dnHigh + 1)
|
|
||||||
elif tq == 4: # tqFar
|
|
||||||
print('ERROR tqFar in get_type_name')
|
|
||||||
elif tq == 5: # tqVol
|
|
||||||
ret = 'volatile ' + ret
|
|
||||||
elif tq == 6: # tqConst
|
|
||||||
ret = 'const ' + ret
|
|
||||||
if has_bitfield:
|
|
||||||
name += ' : %d' % bitwidth
|
|
||||||
return ret + ' ' + name
|
|
||||||
|
|
||||||
def get_enum_string(file_data, fd, symbolic_header, enum_sym_num):
|
|
||||||
ret = ''
|
|
||||||
start_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + enum_sym_num*12)
|
|
||||||
if start_sym.st != 28:
|
|
||||||
print('ERROR unkown type in get_enum_string start:%d' % start_sym.st)
|
|
||||||
return ret
|
|
||||||
ret += 'enum {\n'
|
|
||||||
increase_indent()
|
|
||||||
sym_num = enum_sym_num + 1
|
|
||||||
while sym_num < fd.isymBase + start_sym.index:
|
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
if sym.st == 8: # stEnd
|
|
||||||
decrease_indent()
|
|
||||||
ret += get_indent()
|
|
||||||
ret += '}'
|
|
||||||
elif sym.st == 9: # stMember
|
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
|
||||||
ret += get_indent()
|
|
||||||
ret += '%s = %d,\n' % (name, sym.value)
|
|
||||||
else:
|
|
||||||
print('ERROR unkown type in get_enum_string:%d' % sym.st)
|
|
||||||
break
|
|
||||||
sym_num += 1
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def get_struct_or_union_string(file_data, fd, symbolic_header, union_sym_num, search_for_typedef):
|
|
||||||
ret = ''
|
|
||||||
start_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + union_sym_num*12)
|
|
||||||
if search_for_typedef:
|
|
||||||
typedef_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (fd.isymBase + start_sym.index)*12)
|
|
||||||
if typedef_sym.st == 10: # stTypedef
|
|
||||||
return read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + typedef_sym.iss)
|
|
||||||
else:
|
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + start_sym.iss)
|
|
||||||
if name != '':
|
|
||||||
return name
|
|
||||||
if start_sym.st == 26: # stStruct
|
|
||||||
ret += 'struct {\n'
|
|
||||||
increase_indent()
|
|
||||||
elif start_sym.st == 27: # stUnion
|
|
||||||
ret += 'union {\n'
|
|
||||||
increase_indent()
|
|
||||||
else:
|
|
||||||
print('ERROR unkown type in get_struct_or_union_string start:%d' % start_sym.st)
|
|
||||||
return ret
|
|
||||||
sym_num = union_sym_num + 1
|
|
||||||
while sym_num < fd.isymBase + start_sym.index:
|
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
if sym.st == 8: # stEnd
|
|
||||||
decrease_indent()
|
|
||||||
ret += get_indent()
|
|
||||||
ret += '}'
|
|
||||||
elif sym.st == 9: # stMember
|
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
|
||||||
ret += get_indent()
|
|
||||||
ret += '/* 0x%X */ %s;\n' % (sym.value // 8, get_type_string(file_data, fd, symbolic_header, sym.index, name, True))
|
|
||||||
elif sym.st == 26 or sym.st == 27: #stStruct, stUnion
|
|
||||||
sym_num = fd.isymBase + sym.index
|
|
||||||
continue
|
|
||||||
elif sym.st == 34: # stIndirect
|
|
||||||
# TODO what even is a stIndirect?
|
|
||||||
sym_num += 1
|
|
||||||
else:
|
|
||||||
print('ERROR unkown type in get_struct_or_union_string:%d' % sym.st)
|
|
||||||
break
|
|
||||||
sym_num += 1
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def print_typedef_symbols(file_data, fd, symbolic_header, typedef_sym_num):
|
|
||||||
typedef_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + typedef_sym_num*12)
|
|
||||||
if typedef_sym.st != 10: # stTypedef
|
|
||||||
print('ERROR expected stTypedef symbol in print_typedef_symbols, found:%d' % typedef_sym.st)
|
|
||||||
return
|
|
||||||
name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + typedef_sym.iss)
|
|
||||||
print('typedef %s;' % get_type_string(file_data, fd, symbolic_header, typedef_sym.index, name, False))
|
|
||||||
|
|
||||||
def print_procedure(file_data, fd, symbolic_header, proc_sym_num):
|
|
||||||
proc_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + proc_sym_num*12)
|
|
||||||
proc_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + proc_sym.iss)
|
|
||||||
print('%s(' % get_type_string(file_data, fd, symbolic_header, proc_sym.index+1, proc_name, True), end='')
|
|
||||||
sym_num = proc_sym_num+1
|
|
||||||
param_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
first = True
|
|
||||||
while param_sym.st == 3: # stParam
|
|
||||||
param_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + param_sym.iss)
|
|
||||||
print('%s%s' % ('' if first else ', ',
|
|
||||||
get_type_string(file_data, fd, symbolic_header, param_sym.index, param_name, True)),
|
|
||||||
end='')
|
|
||||||
sym_num += 1
|
|
||||||
param_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
first = False
|
|
||||||
|
|
||||||
print(');')
|
|
||||||
comment_old = set_is_comment(True)
|
|
||||||
while sym_num < fd.isymBase + fd.csym:
|
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
sym_num += 1
|
|
||||||
if sym.st == 7: # stBlock
|
|
||||||
print('%s{' % get_indent())
|
|
||||||
increase_indent()
|
|
||||||
elif sym.st == 8: # stEnd
|
|
||||||
if proc_name == read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss):
|
|
||||||
set_is_comment(comment_old)
|
|
||||||
return sym_num
|
|
||||||
decrease_indent()
|
|
||||||
print('%s}' % get_indent())
|
|
||||||
elif sym.st == 4: # stLocal
|
|
||||||
local_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
|
||||||
is_reg = sym.sc == 4 # scRegister
|
|
||||||
print('%s%s%s;' % (get_indent(),
|
|
||||||
'register ' if is_reg else '',
|
|
||||||
get_type_string(file_data, fd, symbolic_header, sym.index, local_name, True)))
|
|
||||||
elif sym.st == 2: # stStatic
|
|
||||||
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
|
||||||
print('%sstatic %s;' % (get_indent(),get_type_string(file_data, fd, symbolic_header, sym.index, static_name, True)))
|
|
||||||
elif sym.st == 5: # stLabel
|
|
||||||
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss)
|
|
||||||
print('%sLabel: %s @ %d;' % (get_indent(), static_name, sym.value))
|
|
||||||
elif sym.st == 6: # stProc
|
|
||||||
# multiple name for function?
|
|
||||||
sym_num = print_procedure(file_data, fd, symbolic_header, sym_num-1)
|
|
||||||
elif sym.st == 26 or sym.st == 27: #stStruct, stUnion
|
|
||||||
sym_num = fd.isymBase + sym.index
|
|
||||||
elif sym.st == 34: # stIndirect
|
|
||||||
# TODO what even is a stIndirect?
|
|
||||||
sym_num += 1
|
|
||||||
else:
|
|
||||||
print('ERROR unkown st in print_procedure: %d' % sym.st)
|
|
||||||
set_is_comment(comment_old)
|
|
||||||
return sym_num
|
|
||||||
|
|
||||||
def print_symbols(file_data, fd, symbolic_header):
|
|
||||||
sym_num = fd.isymBase
|
|
||||||
while sym_num < fd.isymBase + fd.csym:
|
|
||||||
root_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
if root_sym.st == 11: # stFile
|
|
||||||
file_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + root_sym.iss)
|
|
||||||
print('// begin file %s\n' % file_name)
|
|
||||||
sym_num += 1
|
|
||||||
leaf_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
while leaf_sym.st != 8: # stEnd
|
|
||||||
if leaf_sym.st == 26 or leaf_sym.st == 27 or leaf_sym.st == 28: # stStruct, stUnion, stEnum
|
|
||||||
sym_num = fd.isymBase + leaf_sym.index
|
|
||||||
print('')
|
|
||||||
elif leaf_sym.st == 10: # stTypedef
|
|
||||||
print_typedef_symbols(file_data, fd, symbolic_header, sym_num)
|
|
||||||
sym_num += 1
|
|
||||||
print('')
|
|
||||||
elif leaf_sym.st == 6 or leaf_sym.st == 14: # stProc, stStaticProc
|
|
||||||
# TODO how do stProc and stStaticProc differ? stStaticProc isn't exported?
|
|
||||||
sym_num = print_procedure(file_data, fd, symbolic_header, sym_num)
|
|
||||||
print('')
|
|
||||||
elif leaf_sym.st == 2: # stStatic
|
|
||||||
static_name = read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + leaf_sym.iss)
|
|
||||||
if leaf_sym.sc == 2 or leaf_sym.sc == 3 or leaf_sym.sc == 15: # scData, scBss, scRData
|
|
||||||
if leaf_sym.index != 0xFFFFF: # looks like it's an invalid value for .s files
|
|
||||||
print('static %s;\n' % get_type_string(file_data, fd, symbolic_header, leaf_sym.index, static_name, True))
|
|
||||||
else:
|
|
||||||
print('static %s;\n' % static_name)
|
|
||||||
else:
|
|
||||||
print('ERROR unkown sc for stStatic in print_symbols: %d' % leaf_sym.sc)
|
|
||||||
sym_num += 1
|
|
||||||
else:
|
|
||||||
print('ERROR unkown st in leaf_sym in print_symbols: %d' % leaf_sym.st)
|
|
||||||
sym_num += 1
|
|
||||||
leaf_sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
sym_num = fd.isymBase + root_sym.index
|
|
||||||
print('// end file %s' % file_name)
|
|
||||||
else:
|
|
||||||
print('ERROR expected st of stFile as only root type in print_symbols:%d' % root_sym.st)
|
|
||||||
return
|
|
||||||
|
|
||||||
def main():
|
|
||||||
global OFFSET
|
|
||||||
if len(sys.argv) < 2:
|
|
||||||
return # TODO print usage
|
|
||||||
|
|
||||||
filename = sys.argv[1]
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(filename, 'rb') as f:
|
|
||||||
file_data = f.read()
|
|
||||||
except IOError:
|
|
||||||
print('failed to read file ' + filename)
|
|
||||||
return
|
|
||||||
|
|
||||||
elf_header = read_elf_header(file_data, 0)
|
|
||||||
section_headers = []
|
|
||||||
debug_index = 0xFFFFFFFF
|
|
||||||
#print('%r' % (elf_header,))
|
|
||||||
for i in range(elf_header.e_shnum):
|
|
||||||
section_headers.append(read_elf_section_header(file_data, elf_header.e_shoff + i*40))
|
|
||||||
#print('%r' % (section_headers[i],))
|
|
||||||
if section_headers[i].sh_type == 0x70000005:
|
|
||||||
debug_index = i
|
|
||||||
|
|
||||||
if debug_index != 0xFFFFFFFF:
|
|
||||||
symbolic_header = read_symbolic_header(file_data, section_headers[debug_index].sh_offset)
|
|
||||||
file_descriptors = []
|
|
||||||
print('%r' % (symbolic_header,))
|
|
||||||
# Set offset by assuming that there are no optimization symbols so cbOptOffset points to the start of the symbolic header
|
|
||||||
OFFSET = symbolic_header.cbOptOffset - section_headers[debug_index].sh_offset
|
|
||||||
print('Using OFFSET of %d' % OFFSET)
|
|
||||||
#for sym_num in range(symbolic_header.isymMax):
|
|
||||||
#sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
#print('%d:%r' % (sym_num, (sym,)));
|
|
||||||
#for aux_num in range(symbolic_header.iauxMax):
|
|
||||||
#aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + aux_num*4)
|
|
||||||
#print('%d:%r' % (aux_num, (aux,)));
|
|
||||||
for file_num in range(symbolic_header.ifdMax):
|
|
||||||
fd = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + file_num*72)
|
|
||||||
file_descriptors.append(fd)
|
|
||||||
for file_num in range(symbolic_header.ifdMax):
|
|
||||||
fd = read_file_descriptor(file_data, symbolic_header.cbFdOffset - OFFSET + file_num*72)
|
|
||||||
print('%r' % (fd,))
|
|
||||||
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + fd.rss))
|
|
||||||
|
|
||||||
print(' procedures:')
|
|
||||||
for proc_num in range(fd.ipdFirst, fd.ipdFirst + fd.cpd):
|
|
||||||
pd = read_procedure_descriptor(file_data, symbolic_header.cbPdOffset - OFFSET + proc_num*52)
|
|
||||||
print(' %r' % ((pd,)))
|
|
||||||
|
|
||||||
print(' symbols:')
|
|
||||||
for sym_num in range(fd.isymBase, fd.isymBase + fd.csym):
|
|
||||||
sym = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + sym_num*12)
|
|
||||||
print(' %r' % ((sym,)))
|
|
||||||
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + fd.issBase + sym.iss))
|
|
||||||
print(' type:%s(%d)' % (symbol_type_list[sym.st], sym.st))
|
|
||||||
print(' storage class:%s(%d)' % (storage_class_list[sym.sc], sym.sc))
|
|
||||||
if sym.st == 3 or sym.st == 4 or sym.st == 9 or sym.st == 10 or sym.st == 28: # stParam, stLocal, stMember, stTypedef, stEnum
|
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index)*4)
|
|
||||||
print(' %r' % ((aux,)))
|
|
||||||
offset = 0
|
|
||||||
if aux.ti.fBitfield == 1:
|
|
||||||
bitfield_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 1)*4)
|
|
||||||
print(' %r' % ((bitfield_aux,)))
|
|
||||||
offset = 1
|
|
||||||
if aux.ti.bt == 12 or aux.ti.bt == 13 or aux.ti.bt == 14 or aux.ti.bt == 15: # btStruct, btUnion, btEnum, btTypedef
|
|
||||||
aux2 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 1 + offset)*4)
|
|
||||||
print(' %r' % ((aux2,)))
|
|
||||||
if aux2.rndx.rfd == 4095:
|
|
||||||
aux3 = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index + 2 + offset)*4)
|
|
||||||
print(' %r' % ((aux3,)))
|
|
||||||
sym2 = read_symbol(file_data, symbolic_header.cbSymOffset - OFFSET + (file_descriptors[aux3.isym].isymBase + aux2.rndx.index)*12)
|
|
||||||
print(' %r' % (sym2,))
|
|
||||||
print(' name:%s' % read_string(file_data, symbolic_header.cbSsOffset - OFFSET + file_descriptors[aux3.isym].issBase + sym2.iss))
|
|
||||||
if sym.st == 6: # stProc
|
|
||||||
# TODO what is the first aux symbol for?
|
|
||||||
aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index)*4)
|
|
||||||
type_aux = read_auxiliary_symbol(file_data, symbolic_header.cbAuxOffset - OFFSET + (fd.iauxBase + sym.index+1)*4)
|
|
||||||
print(' %r' % ((aux,)))
|
|
||||||
print(' %r' % ((type_aux,)))
|
|
||||||
|
|
||||||
print(' pretty print:')
|
|
||||||
print_symbols(file_data, fd, symbolic_header)
|
|
||||||
|
|
||||||
|
|
||||||
main()
|
|
|
@ -98,5 +98,5 @@ if __name__ == "__main__":
|
||||||
if (rupees > 0):
|
if (rupees > 0):
|
||||||
print('You have {}/{} masks and {}/{} rupee(s).\n'.format(masks, num_masks, rupees, max_rupees));
|
print('You have {}/{} masks and {}/{} rupee(s).\n'.format(masks, num_masks, rupees, max_rupees));
|
||||||
else:
|
else:
|
||||||
print('You have {}/{} masks .\n'.format(masks, num_masks));
|
print('You have {}/{} masks.\n'.format(masks, num_masks));
|
||||||
|
|
||||||
|
|
|
@ -42,8 +42,8 @@ if __name__ == '__main__':
|
||||||
if args.c_base != None:
|
if args.c_base != None:
|
||||||
os.makedirs(os.path.dirname(args.c_base), exist_ok=True)
|
os.makedirs(os.path.dirname(args.c_base), exist_ok=True)
|
||||||
with open(args.c_base, 'w') as f:
|
with open(args.c_base, 'w') as f:
|
||||||
f.write('#include <ultra64.h>\n#include <global.h>\n\n')
|
f.write('#include <ultra64.h>\n#include <global.h>\n')
|
||||||
|
|
||||||
for name in file_names:
|
for name in file_names:
|
||||||
f.write('GLOBAL_ASM("{}")\n\n'.format(name))
|
f.write('\nGLOBAL_ASM("{}")\n'.format(name))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue