diff options
| author | Roman971 <32455037+Roman971@users.noreply.github.com> | 2021-03-27 21:26:59 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-27 16:26:59 -0400 |
| commit | 97f80eeb3f79bafac383fa6dd17765ae291e05d7 (patch) | |
| tree | 80d2c33015ea51b871e35acf4bcac47e5158b3b2 | |
| parent | b8637848931a2e88cc5dfc73e70823e255ab1d09 (diff) | |
Update asm_processor and use static variables in En_Torch2 (#740)
* Update asm_processor to current master
* Update variables in En_Torch2 to actually be static
This is now possible because asm_processor was updated to handle static symbols in GLOBAL_ASM
* Update tutorial to reflect changes about static symbol limitations
| -rw-r--r-- | docs/tutorial/data.md | 6 | ||||
| -rw-r--r-- | src/overlays/actors/ovl_En_Torch2/z_en_torch2.c | 40 | ||||
| -rw-r--r-- | tools/asm_processor/asm_processor.py | 66 |
3 files changed, 85 insertions, 27 deletions
diff --git a/docs/tutorial/data.md b/docs/tutorial/data.md index d001f4149..986a47e1f 100644 --- a/docs/tutorial/data.md +++ b/docs/tutorial/data.md @@ -23,8 +23,6 @@ Both approaches have their advantages and disadvantages. <!-- Fig shows how to do this in his video. --> This way is good for smaller actors with little data. It is not really suitable for EnJj, for example, because of the enormous section of data labelled as `D_80A88164`. -An important thing to bear in mind is that data cannot be made static if it is used in an undecompiled file (i.e. one that is `#pragma`'d), so it is best to make everything static only after the whole actor is decompiled. - ### Example: `EnTg` We give a simple example of this approach with a small NPC actor, EnTg, that is, the spinning couple. @@ -165,10 +163,10 @@ static ColliderCylinderInit sCylinderInit = }; ``` -Copy this in below `D_80B18910`, delete the original words of data, and for now, remove `static` (in case it's used in other files that have not been decompiled), change the name back to `D_80B18910`, and put `sCylinderInit` commented out above it: +Copy this in below `D_80B18910`, delete the original words of data, change the name back to `D_80B18910`, and put `sCylinderInit` commented out above it: ```C // sCylinderInit -ColliderCylinderInit D_80B18910 = +static ColliderCylinderInit D_80B18910 = { { COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x20, COLSHAPE_CYLINDER }, { 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 }, diff --git a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c index fd9da83af..9d55460e9 100644 --- a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c +++ b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c @@ -66,26 +66,26 @@ const ActorInit En_Torch2_InitVars = { (ActorFunc)EnTorch2_Draw, }; -/* static */ f32 sStickTilt = 0.0f; -/* static */ s16 sStickAngle = 0; -/* static */ f32 sSwordJumpHeight = 0.0f; -/* static */ s32 sHoldShieldTimer = 0; -/* static */ u8 sZTargetFlag = false; -/* static */ u8 sDeathFlag = false; - -/* static */ Input sInput; -/* static */ u8 sSwordJumpState; -/* static */ Vec3f sSpawnPoint; -/* static */ u8 sJumpslashTimer; -/* static */ u8 sJumpslashFlag; -/* static */ u8 sActionState; -/* static */ u8 sSwordJumpTimer; -/* static */ u8 sCounterState; -/* static */ u8 sDodgeRollState; -/* static */ u8 sStaggerCount; -/* static */ u8 sStaggerTimer; -/* static */ s8 sLastSwordAnim; -/* static */ u8 sAlpha; +static f32 sStickTilt = 0.0f; +static s16 sStickAngle = 0; +static f32 sSwordJumpHeight = 0.0f; +static s32 sHoldShieldTimer = 0; +static u8 sZTargetFlag = false; +static u8 sDeathFlag = false; + +static Input sInput; +static u8 sSwordJumpState; +static Vec3f sSpawnPoint; +static u8 sJumpslashTimer; +static u8 sJumpslashFlag; +static u8 sActionState; +static u8 sSwordJumpTimer; +static u8 sCounterState; +static u8 sDodgeRollState; +static u8 sStaggerCount; +static u8 sStaggerTimer; +static s8 sLastSwordAnim; +static u8 sAlpha; static DamageTable sDamageTable = { /* Deku nut */ DMG_ENTRY(0, 0x1), diff --git a/tools/asm_processor/asm_processor.py b/tools/asm_processor/asm_processor.py index ea18c384b..9d5e6a749 100644 --- a/tools/asm_processor/asm_processor.py +++ b/tools/asm_processor/asm_processor.py @@ -81,6 +81,9 @@ R_MIPS_26 = 4 R_MIPS_HI16 = 5 R_MIPS_LO16 = 6 +MIPS_DEBUG_ST_STATIC = 2 +MIPS_DEBUG_ST_STATIC_PROC = 14 + class ElfHeader: """ @@ -132,14 +135,19 @@ class Symbol: } Elf32_Sym; """ - def __init__(self, data, strtab): + def __init__(self, data, strtab, name=None): self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx = struct.unpack('>IIIBBH', data) assert self.st_shndx != SHN_XINDEX, "too many sections (SHN_XINDEX not supported)" self.bind = st_info >> 4 self.type = st_info & 15 - self.name = strtab.lookup_str(self.st_name) + self.name = name if name is not None else strtab.lookup_str(self.st_name) self.visibility = self.st_other & 3 + @staticmethod + def from_parts(st_name, st_value, st_size, st_info, st_other, st_shndx, strtab, name): + header = struct.pack('>IIIBBH', st_name, st_value, st_size, st_info, st_other, st_shndx) + return Symbol(header, strtab, name) + def to_bin(self): st_info = (self.bind << 4) | self.type return struct.pack('>IIIBBH', self.st_name, self.st_value, self.st_size, st_info, self.st_other, self.st_shndx) @@ -913,6 +921,7 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc): asm_objfile = ElfFile(f.read()) # Remove some clutter from objdump output + mdebug_section = objfile.find_section('.mdebug') objfile.drop_irrelevant_sections() # Unify reginfo sections @@ -1014,7 +1023,7 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc): # Move over symbols, deleting the temporary function labels. # Sometimes this naive procedure results in duplicate symbols, or UNDEF # symbols that are also defined the same .o file. Hopefully that's fine. - # Skip over local symbols that aren't used relocated against, to avoid + # Skip over local symbols that aren't relocated against, to avoid # conflicts. new_local_syms = [s for s in objfile.symtab.local_symbols() if not is_temp_name(s.name)] new_global_syms = [s for s in objfile.symtab.global_symbols() if not is_temp_name(s.name)] @@ -1039,6 +1048,57 @@ def fixup_objfile(objfile_name, functions, asm_prelude, assembler, output_enc): new_local_syms.append(s) else: new_global_syms.append(s) + + # Add static symbols from .mdebug, so they can be referred to from GLOBAL_ASM + local_sym_replacements = {} + if mdebug_section: + strtab_index = len(objfile.symtab.strtab.data) + new_strtab_data = [] + ifd_max, cb_fd_offset = struct.unpack('>II', mdebug_section.data[18*4 : 20*4]) + cb_sym_offset, = struct.unpack('>I', mdebug_section.data[9*4 : 10*4]) + cb_ss_offset, = struct.unpack('>I', mdebug_section.data[15*4 : 16*4]) + for i in range(ifd_max): + offset = cb_fd_offset + 18*4*i + iss_base, _, isym_base, csym = struct.unpack('>IIII', objfile.data[offset + 2*4 : offset + 6*4]) + for j in range(csym): + offset2 = cb_sym_offset + 12 * (isym_base + j) + iss, value, st_sc_index = struct.unpack('>III', objfile.data[offset2 : offset2 + 12]) + st = (st_sc_index >> 26) + sc = (st_sc_index >> 21) & 0x1f + if st in [MIPS_DEBUG_ST_STATIC, MIPS_DEBUG_ST_STATIC_PROC]: + symbol_name_offset = cb_ss_offset + iss_base + iss + symbol_name_offset_end = objfile.data.find(b'\0', symbol_name_offset) + assert symbol_name_offset_end != -1 + symbol_name = objfile.data[symbol_name_offset : symbol_name_offset_end + 1] + symbol_name_str = symbol_name[:-1].decode('latin1') + section_name = ['', '.text', '.data', '.bss'][sc] + section = objfile.find_section(section_name) + symtype = STT_FUNC if sc == 1 else STT_OBJECT + sym = Symbol.from_parts( + st_name=strtab_index, + st_value=value, + st_size=0, + st_info=(STB_LOCAL << 4 | symtype), + st_other=STV_DEFAULT, + st_shndx=section.index, + strtab=objfile.symtab.strtab, + name=symbol_name_str) + local_sym_replacements[symbol_name_str] = len(new_local_syms) + strtab_index += len(symbol_name) + new_strtab_data.append(symbol_name) + new_local_syms.append(sym) + objfile.symtab.strtab.data += b''.join(new_strtab_data) + + # To get the linker to use the local symbols, we have to get rid of UNDEF + # global ones. + newer_global_syms = [] + for s in new_global_syms: + if s.st_shndx == SHN_UNDEF and s.name in local_sym_replacements: + s.new_index = local_sym_replacements[s.name] + else: + newer_global_syms.append(s) + new_global_syms = newer_global_syms + new_syms = new_local_syms + new_global_syms for i, s in enumerate(new_syms): s.new_index = i |
