From 2661db6aaa98a5bbd17691cb438ef64752dbcdf4 Mon Sep 17 00:00:00 2001 From: Julgodis <> Date: Thu, 8 Apr 2021 21:05:48 +0200 Subject: auto decompile more functions --- tools/libdol2asm/data/base.py | 14 ++++++++++++++ tools/libdol2asm/data/function/ret.py | 33 +++++++++++++++++++++++++++----- tools/libdol2asm/data/reference_array.py | 1 + tools/libdol2asm/data/symbol.py | 9 +++++++++ 4 files changed, 52 insertions(+), 5 deletions(-) (limited to 'tools/libdol2asm/data') diff --git a/tools/libdol2asm/data/base.py b/tools/libdol2asm/data/base.py index 6ceada5eb9..6878ca1341 100644 --- a/tools/libdol2asm/data/base.py +++ b/tools/libdol2asm/data/base.py @@ -84,6 +84,12 @@ class ArbitraryData(Symbol): self.size // self.element_size, self.padding // self.element_size) + def return_type(self): + array_type = self.array_type() + if isinstance(array_type, ArrayType) or isinstance(array_type, PaddingArrayType) or isinstance(array_type, ZeroArrayType): + return PointerType(array_type.base) + return array_type + def cpp_reference(self, accessor, addr): name = self.declaration_name(forward=False, c_export=False,full_qualified_name=True) if addr == self.addr: @@ -92,6 +98,14 @@ class ArbitraryData(Symbol): offset = addr - self.addr return f"(((char*)&{name})+0x{offset:X})" + def cpp_load(self, accessor, addr): + name = self.declaration_name(forward=False, c_export=False,full_qualified_name=True) + if addr == self.addr: + return f"{name}" + else: + offset = addr - self.addr + return f"*(((char*)&{name})+0x{offset:X})" + def declaration_name(self, forward: bool, c_export: bool, full_qualified_name: bool): diff --git a/tools/libdol2asm/data/function/ret.py b/tools/libdol2asm/data/function/ret.py index bf15e02e9b..aed96c2315 100644 --- a/tools/libdol2asm/data/function/ret.py +++ b/tools/libdol2asm/data/function/ret.py @@ -6,16 +6,39 @@ from .base import * @dataclass(eq=False) class ReturnFunction(Function): - return_value: str = None - - def export_return_value(self): - return self.return_value + def export_return_value(self, symbol_table): + assert False async def export_function_body(self, exporter, builder: AsyncBuilder): - return_value = self.export_return_value() + return_value = self.export_return_value(exporter.gst) await builder.write(f" {{") if return_value: await builder.write(f"\treturn {return_value};") else: await builder.write(f"\t/* empty function */") await builder.write(f"}}") + +@dataclass(eq=False) +class CustomReturnFunction(ReturnFunction): + return_value: str = None + + def export_return_value(self, symbol_table): + return self.return_value + +@dataclass(eq=False) +class SymbolReturnFunction(ReturnFunction): + symbol_addr: int = 0 + load_or_reference: bool = True + + def gather_references(self, context, valid_range): + self.references = set([ self.symbol_addr ]) + + def export_return_value(self, symbol_table): + symbol = symbol_table[-1, self.symbol_addr] + assert symbol + name = symbol.cpp_reference(self, self.symbol_addr) + type = PointerType(self.return_type) + dereference = "" + if self.load_or_reference: + dereference = "*" + return f"{dereference}({type.type()})({name})" diff --git a/tools/libdol2asm/data/reference_array.py b/tools/libdol2asm/data/reference_array.py index 1b05b92342..d5d5fdf918 100644 --- a/tools/libdol2asm/data/reference_array.py +++ b/tools/libdol2asm/data/reference_array.py @@ -33,6 +33,7 @@ class ReferenceArray(ArbitraryData): def values(self): return Integer.u32_from(self.data) + def gather_references(self, context, valid_range): self.references = [ addr for addr in self.values() if addr in valid_range ] diff --git a/tools/libdol2asm/data/symbol.py b/tools/libdol2asm/data/symbol.py index 5a708fb361..9a75d16bb6 100644 --- a/tools/libdol2asm/data/symbol.py +++ b/tools/libdol2asm/data/symbol.py @@ -139,6 +139,12 @@ class Symbol: f"invalid reference addr 0x{addr:08X} for {type(self).__name__}\n{self}") return f"&{self.identifier.label}" + def cpp_load(self, accessor, addr): + if addr != self.addr: + raise Dol2ZelException( + f"invalid reference addr 0x{addr:08X} for {type(self).__name__}\n{self}") + return f"{self.identifier.label}" + def asm_reference(self, addr): if addr != self.addr: return None @@ -147,6 +153,9 @@ class Symbol: def gather_references(self, context, valid_range): pass + def get_reference_information(self, context, symbol_table): + pass + def types(self): return set() -- cgit v1.2.3