diff options
| author | Julgodis <> | 2021-04-08 01:47:05 +0200 |
|---|---|---|
| committer | Julgodis <> | 2021-04-08 01:47:05 +0200 |
| commit | a23a10639979ee10cbea5ffdadadc490d9e60227 (patch) | |
| tree | 75a86f6d6760a9f4183f3e97606eb7747399a0a8 /tools/libdol2asm/data | |
| parent | dca1d2a1c032f239c65aa1b7767132c12e89f628 (diff) | |
demangle data-symbols
Diffstat (limited to 'tools/libdol2asm/data')
| -rw-r--r-- | tools/libdol2asm/data/base.py | 114 | ||||
| -rw-r--r-- | tools/libdol2asm/data/function/base.py | 33 | ||||
| -rw-r--r-- | tools/libdol2asm/data/symbol.py | 15 |
3 files changed, 96 insertions, 66 deletions
diff --git a/tools/libdol2asm/data/base.py b/tools/libdol2asm/data/base.py index 17fc8db82a..6ceada5eb9 100644 --- a/tools/libdol2asm/data/base.py +++ b/tools/libdol2asm/data/base.py @@ -40,6 +40,17 @@ class ArbitraryData(Symbol): return True @property + def is_class_symbol(self): + # @!game + # don't generate static class variables for 'cNullVec__6Z2Calc', because it will not compile. + # Z2Calc::cNullVec seems to be static data that is initialized in the class definition, thus, + # every translation unit which uses Z2Calc will have a copy of the Z2Calc::cNullVec in the data + # section. Could not find a way to make this compile without easily. + if self.identifier.name == "cNullVec__6Z2Calc": + return False + return self.demangled_name and self.has_class and not self.has_template + + @property def element_size(self): return 1 @@ -67,18 +78,42 @@ class ArbitraryData(Symbol): def array_type(self): if self.zero_length: - return ZeroArrayType.create(self.element_type()) + return ZeroArrayType.create(self.element_type()) return PaddingArrayType.create( self.element_type(), self.size // self.element_size, self.padding // self.element_size) def cpp_reference(self, accessor, addr): + name = self.declaration_name(forward=False, c_export=False,full_qualified_name=True) if addr == self.addr: - return f"&{self.identifier.label}" + return f"&{name}" else: offset = addr - self.addr - return f"(((char*)&{self.identifier.label})+0x{offset:X})" + return f"(((char*)&{name})+0x{offset:X})" + + def declaration_name(self, forward: bool, + c_export: bool, + full_qualified_name: bool): + if not self.is_class_symbol or c_export: + return self.identifier.label + + if full_qualified_name: + return self.demangled_name.to_str() + else: + return self.demangled_name.last.to_str() + + async def export_declaration_header(self, exporter, + builder: AsyncBuilder, + forward: bool, + c_export: bool, + full_qualified_name: bool): + name = self.declaration_name(c_export=c_export, + forward=forward, + full_qualified_name=full_qualified_name) + + decl_type = self.array_type() + await builder.write_nonewline(decl_type.decl(name)) async def export_forward_references(self, exporter, @@ -86,54 +121,53 @@ class ArbitraryData(Symbol): c_export: bool = False): if not c_export: return - - if self.is_static and self.export_static: - if not self.require_forward_reference: - return - await self.export_section_header(builder) + if not self.is_class_symbol: + if self.is_static and self.export_static: + if not self.require_forward_reference: + return - if not (self.is_static and self.export_static): - await self.export_extern(builder) + await self.export_section_header(builder) - name = self.identifier.label - if self.demangled_name: - name = self.demangled_name.to_str(specialize_templates=False, - without_template=False) + if not self.is_class_symbol: + if not (self.is_static and self.export_static): + await self.export_extern(builder) - decl_type = self.array_type() - await builder.write_nonewline(decl_type.decl(name)) + await self.export_declaration_header(exporter, builder, + forward=True, + c_export=c_export, + full_qualified_name=False) await builder.write(";") async def export_declaration_head(self, exporter, builder: AsyncBuilder): - if self.demangled_name: - name = self.demangled_name.to_str(specialize_templates=False, - without_template=False) - else: - name = self.identifier.label + name = self.declaration_name(c_export=False, + forward=False, + full_qualified_name=True) decl_type = self.array_type() - # for empty symbols that should be exported, we need to double declare it. - # otherwise, the compiler thinks that we're not actual declaring it. - is_extern = not (self.is_static and self.export_as_static) - if not self.data and is_extern: - await self.export_section(builder) - if self.force_section: - await self.export_section_header(builder) + if not self.is_class_symbol: + # for empty symbols that should be exported, we need to double declare it. + # otherwise, the compiler thinks that we're not actual declaring it. + is_extern = not (self.is_static and self.export_as_static) + if not self.data and is_extern: + await self.export_section(builder) + if self.force_section: + await self.export_section_header(builder) - await self.export_extern(builder) - await builder.write_nonewline(decl_type.decl(name)) - await builder.write(";") + await self.export_extern(builder) + await builder.write_nonewline(decl_type.decl(name)) + await builder.write(";") await self.export_section(builder) if self.force_section: await self.export_section_header(builder) - if not is_extern: - await self.export_static(builder) - elif self.data and is_extern: - await self.export_extern(builder) + if not self.is_class_symbol: + if not is_extern: + await self.export_static(builder) + elif self.data and is_extern: + await self.export_extern(builder) await builder.write_nonewline(decl_type.decl(name)) @@ -168,11 +202,11 @@ class ArbitraryData(Symbol): if self._section == ".rodata": await builder.write(f"COMPILER_STRIP_GATE({self.addr:08X}, {self.cpp_reference(None, self.addr)});") - #await builder.write_nonewline("SECTION_DEAD ") - #await builder.write_nonewline("void* const ") - #await builder.write_nonewline(f"cg_{self.addr:08X} = (void*)(") - #await builder.write_nonewline(self.cpp_reference(None, self.addr)) - #await builder.write(f");") + # await builder.write_nonewline("SECTION_DEAD ") + # await builder.write_nonewline("void* const ") + # await builder.write_nonewline(f"cg_{self.addr:08X} = (void*)(") + # await builder.write_nonewline(self.cpp_reference(None, self.addr)) + # await builder.write(f");") if self.requires_force_active: await builder.write(f"#pragma pop") diff --git a/tools/libdol2asm/data/function/base.py b/tools/libdol2asm/data/function/base.py index e74d2aeaa6..0eda461881 100644 --- a/tools/libdol2asm/data/function/base.py +++ b/tools/libdol2asm/data/function/base.py @@ -18,15 +18,13 @@ special_func_no_return = set([ class Function(Symbol): return_type: Type = None argument_types: List[Type] = field(default_factory=list) - func_name: libdemangle.QualifiedName = None special_func_name: str = None func_is_const: bool = False - template_index: int = -1 asm: bool = False @property def uses_any_templates(self): - if self.func_name and self.func_name.has_template: + if self.demangled_name and self.demangled_name.has_template: return True is_templated = [False] @@ -45,10 +43,6 @@ class Function(Symbol): return is_templated[0] @property - def uses_class_template(self): - return self.func_name and self.func_name.has_template - - @property def is_static(self): s = self.reference_count.static e = self.reference_count.extern @@ -57,7 +51,7 @@ class Function(Symbol): if not static_by_references: return False - if not self.func_name: + if not self.demangled_name: # very arbitrary, but function begining with __ are often special if self.identifier.name and self.identifier.name.startswith("__"): return False @@ -70,13 +64,13 @@ class Function(Symbol): return self.identifier.label def function_name(self, c_export: bool, full_qualified_name: bool): - if not self.func_name or c_export: + if not self.demangled_name or c_export: return self.identifier.label - if self.func_name.require_specialization: + if self.demangled_name.require_specialization: return self.identifier.label - name = self.func_name + name = self.demangled_name if self.special_func_name and self.has_class: # fix up the constructor and destructor if the function is template specialized special_name = None @@ -87,16 +81,13 @@ class Function(Symbol): if special_name: name = NamedType( - self.func_name.names[:-1] + [ClassName(special_name, [])]) + self.demangled_name.names[:-1] + [ClassName(special_name, [])]) if full_qualified_name: return name.to_str() else: return name.last.to_str() - def is_demangled(self): - return self.func_name != None - def valid_reference(self, addr): return addr % 4 == 0 @@ -115,14 +106,6 @@ class Function(Symbol): def types(self): return set() - @property - def has_class(self): - return self.func_name and self.func_name.has_class - - @property - def has_template(self): - return self.func_name and self.func_name.has_template - async def export_function_header(self, exporter, builder: AsyncBuilder, forward: bool, @@ -158,7 +141,7 @@ class Function(Symbol): if self._section == ".init": await builder.write_nonewline(f"SECTION_INIT ") - elif c_export or (self.func_name and self.func_name.require_specialization and full_qualified_name): + elif c_export or (self.demangled_name and self.demangled_name.require_specialization and full_qualified_name): await builder.write_nonewline(f"extern \"C\" ") if self.is_static and not self.has_class: @@ -173,7 +156,7 @@ class Function(Symbol): is_special_function = ( self.special_func_name in special_func_no_return) specialized = ( - self.func_name and self.func_name.require_specialization) + self.demangled_name and self.demangled_name.require_specialization) if c_export: await builder.write_nonewline(f"{return_type.type()} ") await builder.write_nonewline(f"{self.function_name(c_export=True,full_qualified_name=full_qualified_name)}") diff --git a/tools/libdol2asm/data/symbol.py b/tools/libdol2asm/data/symbol.py index 8c4c2dccb4..5a708fb361 100644 --- a/tools/libdol2asm/data/symbol.py +++ b/tools/libdol2asm/data/symbol.py @@ -62,6 +62,7 @@ class Symbol: _section: str = None alignment: int = 0 relative_addr: int = -1 + template_index: int = -1 demangled_name: NamedType = None references: Set[int] = field(default_factory=set) @@ -101,8 +102,20 @@ class Symbol: return True @property + def has_class(self): + return self.demangled_name and self.demangled_name.has_class + + @property + def has_template(self): + return self.demangled_name and self.demangled_name.has_template + + @property def uses_class_template(self): - return False + return self.demangled_name and self.demangled_name.has_template + + @property + def is_demangled(self): + return self.demangled_name != None @property def requires_force_active(self): |
