diff options
| author | Wiimm <wiimm@wiimm.de> | 2021-05-08 11:35:32 +0200 |
|---|---|---|
| committer | Wiimm <wiimm@wiimm.de> | 2021-05-08 11:35:32 +0200 |
| commit | 9ae8841ec4720e74173e2f72fac33f0848bbf435 (patch) | |
| tree | cdce547c82e5f4e0078e908ad1b86a152bd24c45 /project/src/lib-staticr.c | |
| parent | f33ad95520f6c6bb8f192c8bcd1c17cf40ba6b6b (diff) | |
SZS v2.26a
Diffstat (limited to '')
| -rw-r--r-- | project/src/lib-staticr.c | 707 |
1 files changed, 632 insertions, 75 deletions
diff --git a/project/src/lib-staticr.c b/project/src/lib-staticr.c index afbd6b4..10e0ff1 100644 --- a/project/src/lib-staticr.c +++ b/project/src/lib-staticr.c @@ -35,6 +35,8 @@ * * ***************************************************************************/ +#include <time.h> + #include "lib-staticr.h" #include "crypt.h" #include "db-dol.h" @@ -53,7 +55,6 @@ static const u32 pal_track_offset[] = { 0x37fcd0, - // 0x380ee0, // original has an alternative order here 0x384f58, 0x397da8, 0x398130, @@ -75,7 +76,6 @@ static const u32 pal_arena_offset[] = static const u32 usa_track_offset[] = { 0x37fbe0, - // 0x380b70, // original has an alternative order here 0x3839e0, 0x397450, 0x3977d8, @@ -97,7 +97,6 @@ static const u32 usa_arena_offset[] = static const u32 jap_track_offset[] = { 0x37f9a0, - // 0x380bb0, // original has an alternative order here 0x384c28, 0x397588, 0x397910, @@ -119,7 +118,6 @@ static const u32 jap_arena_offset[] = static const u32 kor_track_offset[] = { 0x3800b0, - // 0x3812c8, // original has an alternative order here 0x385348, 0x3981e8, 0x398570, @@ -733,7 +731,127 @@ const str_server_patch_t ServerPatch[217+1] = #include "addr_port.inc" -#define N_ADDR_PORT (sizeof(addr_port)/sizeof(*addr_port)) +static const addr_port_t *addr_port = addr_port_0; +static int addr_port_records = sizeof(addr_port_0)/sizeof(*addr_port_0); + +//----------------------------------------------------------------------------- + +enumError LoadAddrPortDB ( ccp path1, int silent ) +{ + if ( !path1 || !*path1 ) + return ERR_NOTHING_TO_DO; + + char pathbuf[PATH_MAX]; + ccp path = PathCatDirP(pathbuf,sizeof(pathbuf),path1,"port-db.bin"); + BZ2Manager_t mgr = {0}; + + u8 *data = 0; + size_t size; + enumError err = LoadFileAlloc(path,0,0,&data,&size,1000000,silent,0,false); + if (err) + goto error; + if ( size < 100 ) + goto invalid; + + const addr_port_version_t *version = (addr_port_version_t*)data; + if (memcmp(version->magic,ADDR_PORT_MAGIC,sizeof(version->magic))) + goto invalid; + #if IS_LITTLE_ENDIAN + be32n((u32*)version,(u32*)version,sizeof(*version)/sizeof(u32)); + #endif + + mgr.src_data = data + sizeof(addr_port_version_t); + mgr.src_size = size - sizeof(addr_port_version_t); + err = DecodeBZIP2Manager(&mgr); + if (err) + goto error; + + if ( mgr.size % sizeof(addr_port_t) ) + goto invalid; + + const int n_records = mgr.size / sizeof(addr_port_t); + if ( version->n_records != n_records || mgr.size != n_records * sizeof(addr_port_t) ) + goto invalid; + + #if IS_LITTLE_ENDIAN + be32n((u32*)mgr.data,(u32*)mgr.data,mgr.size/sizeof(u32)); + #endif + + const addr_port_t *ptr = (addr_port_t*)mgr.data; + for ( int n = n_records-1; n-- > 0; ptr++ ) + { + const u32 size1 = ptr[0].size1 & ASM_M_SIZE; + const u32 size2 = ptr[0].size2 & ASM_M_SIZE; + if ( ptr[0].addr[0] >= ptr[1].addr[0] || !size1 || size1 > size2 ) + goto invalid; + } + + if ( version->db_version != ADDR_PORT_DB_VERSION ) + { + if ( !silent || verbose > 0 ) + ERROR0(ERR_WARNING,"Porting DB is not compatible (have v%u, need v%u): %s\n", + version->db_version, ADDR_PORT_DB_VERSION, path ); + goto abort; + } + + if ( version->timestamp < BINTIME || version->revision < REVISION_NUM ) + { + if ( !silent || verbose > 0 ) + ERROR0(ERR_WARNING,"Porting DB is outdated and ignored: %s (%s, rev %u)\n", + path, + PrintTimeByFormat("%F",version->timestamp), + version->revision ); + goto abort; + } + + if ( verbose > 0 ) + fprintf(stdlog,"# Porting DB updated: %s (%s, rev %u)\n", + path, + PrintTimeByFormat("%F",version->timestamp), + version->revision ); + + addr_port_records = n_records; + addr_port = (addr_port_t*)mgr.data; + memcpy(&addr_port_version,version,sizeof(addr_port_version)); + FREE(data); + return ERR_OK; + + invalid:; + err = ERR_INVALID_DATA; + error:; + if (!silent) + ERROR0(err,"Porting DB invalid: %s\n",opt_port_db); + abort:; + FREE(data); + FREE(mgr.data); + return err; +} + +//----------------------------------------------------------------------------- + +void SetupAddrPortDB() +{ + static bool done = false; + if (!done) + { + addr_port_version.revision = REVISION_NUM; + if ( addr_port_version.timestamp < BINTIME ) + addr_port_version.timestamp = BINTIME; + + done = true; + if (opt_port_db) + LoadAddrPortDB(opt_port_db,0); + else + LoadAddrPortDB(share_path,2); + } +} + +//----------------------------------------------------------------------------- + +const addr_port_version_t * GetAddrPortVersion() +{ + return &addr_port_version; +} // /////////////////////////////////////////////////////////////////////////////// @@ -814,38 +932,30 @@ static char * GetIdPointer ( const staticr_t * str ) /////////////////////////////////////////////////////////////////////////////// -const u32 * GetTrackOffsetTab ( const staticr_t * str ) +const u32 * GetTrackOffsetTab ( str_mode_t mode ) { - if (str) + switch (mode) { - switch (str->mode) - { - case STR_M_PAL: return pal_track_offset; - case STR_M_USA: return usa_track_offset; - case STR_M_JAP: return jap_track_offset; - case STR_M_KOR: return kor_track_offset; - default: return 0; - } + case STR_M_PAL: return pal_track_offset; + case STR_M_USA: return usa_track_offset; + case STR_M_JAP: return jap_track_offset; + case STR_M_KOR: return kor_track_offset; + default: return 0; } - return 0; } /////////////////////////////////////////////////////////////////////////////// -const u32 * GetArenaOffsetTab ( const staticr_t * str ) +const u32 * GetArenaOffsetTab ( str_mode_t mode ) { - if (str) + switch (mode) { - switch (str->mode) - { - case STR_M_PAL: return pal_arena_offset; - case STR_M_USA: return usa_arena_offset; - case STR_M_JAP: return jap_arena_offset; - case STR_M_KOR: return kor_arena_offset; - default: return 0; - } + case STR_M_PAL: return pal_arena_offset; + case STR_M_USA: return usa_arena_offset; + case STR_M_JAP: return jap_arena_offset; + case STR_M_KOR: return kor_arena_offset; + default: return 0; } - return 0; } /////////////////////////////////////////////////////////////////////////////// @@ -1695,6 +1805,234 @@ static BZ2Manager_t codehandler_mgr // /////////////////////////////////////////////////////////////////////////////// +/////////////// struct rel_info_t /////////////// +/////////////////////////////////////////////////////////////////////////////// + +const char rel_section_name[REL_SECT__N+1][5] = +{ + "RELH", + "REL1", + "REL2", + "REL3", + "REL4", + "REL5", + "RELX", + "REL", +}; + +//----------------------------------------------------------------------------- + +static rel_info_t rel_info_pal = +{ + 0xd4, // offset_sect + 0x3cd104, // fix_size + 0x78b0, // bss_size + 0x805102e0, // load_addr + + { + // sect { index, name, off,addr,size, 3*valid, data, hash } + { 0, "RH", 0,0,0, 1 }, + { 1, "R1", 0xd4,0,0, 1 }, + { 2, "R2", 0x37f120,0,0, 1 }, + { 3, "R3", 0x37f424,0,0, 1 }, + { 4, "R4", 0x37f440,0,0, 1 }, + { 5, "R5", 0x3a28f0,0,0, 1 }, + { 6, "RX", 0x3cd0f4,0,0, 0 }, + { -1, "--", 0x4ad3c4,0,0, 0 }, + } +}; + +//----------------------------------------------------------------------------- + +static rel_info_t rel_info_usa = +{ + 0xd4, // offset_sect + 0x3ccd2c, // fix_size + 0x78b0, // bss_size + 0x8050bf60, // load_addr + + { + // sect { index, name, off, addr, size, 3*valid, data, hash } + { 0, "RH", 0,0,0, 1 }, + { 1, "R1", 0xd4,0,0, 1 }, + { 2, "R2", 0x37f070,0,0, 1 }, + { 3, "R3", 0x37f374,0,0, 1 }, + { 4, "R4", 0x37f380,0,0, 1 }, + { 5, "R5", 0x3a25c0,0,0, 1 }, + { 6, "RX", 0x3ccd1c,0,0, 1 }, + { -1, "--", 0x4acf94,0,0, 0 }, + } +}; + +//----------------------------------------------------------------------------- + +static rel_info_t rel_info_jap = +{ + 0xd4, // offset_sect + 0x3cc8d4, // fix_size + 0x78b0, // bss_size + 0x8050fc60, // load_addr + + { + // sect { index, name, off, addr, size, 3*valid, data, hash } + { 0, "RH", 0,0,0, 1 }, + { 1, "R1", 0xd4,0,0, 1 }, + { 2, "R2", 0x37ee0c,0,0, 1 }, + { 3, "R3", 0x37f110,0,0, 1 }, + { 4, "R4", 0x37f120,0,0, 1 }, + { 5, "R5", 0x3a20d0,0,0, 1 }, + { 6, "RX", 0x3cc8c4,0,0, 1 }, + { -1, "--", 0x4acabc,0,0, 0 }, + } +}; + +//----------------------------------------------------------------------------- + +static rel_info_t rel_info_kor = +{ + 0xd4, // offset_sect + 0x3cd57c, // fix_size + 0x78b0, // bss_size + 0x804fe300, // load_addr + + { + // sect { index, name, off, addr, size, 3*valid, data, hash } + { 0, "RH", 0,0,0, 1 }, + { 1, "R1", 0xd4,0,0, 1 }, + { 2, "R2", 0x37f4c0,0,0, 1 }, + { 3, "R3", 0x37f7c4,0,0, 1 }, + { 4, "R4", 0x37f7e0,0,0, 1 }, + { 5, "R5", 0x3a2d30,0,0, 1 }, + { 6, "RX", 0x3cd0f4,0,0, 1 }, + { -1, "--", 0x4ad9fc,0,0, 0 }, + } +}; + +//----------------------------------------------------------------------------- + +const rel_info_t * GetInfoREL ( str_mode_t mode ) +{ + rel_info_t *ri; + switch (mode) + { + case STR_M_PAL: ri = &rel_info_pal; break; + case STR_M_USA: ri = &rel_info_usa; break; + case STR_M_JAP: ri = &rel_info_jap; break; + case STR_M_KOR: ri = &rel_info_kor; break; + default: return 0; + } + + DASSERT(ri) + if (!ri->sect[0].addr) + { + for ( dol_sect_info_t *ptr = ri->sect; ptr->section >= 0; ptr++ ) + { + ptr->size = ptr[1].off - ptr->off; + ptr->addr = ri->load_addr + ptr->off; + } + } + return ri; +} + +/////////////////////////////////////////////////////////////////////////////// + +int GetRelOffsetByAddrM +( + str_mode_t mode, // region mode + u32 addr, // address to search + u32 size, // >0: wanted size + u32 *valid_size // not NULL: return valid size +) +{ + const rel_info_t *ri = GetInfoREL(mode); + if (ri) + { + addr &= ~0x40000000; // remove mirror bit + + if ( addr >= ri->load_addr && addr < ri->load_addr + ri->offset_sect ) + return addr - ri->load_addr; + + const dol_sect_info_t *sect; + for ( sect = ri->sect; sect->section >= 0; sect++ ) + { + if ( addr >= sect->addr && addr < sect->addr + sect->size ) + { + u32 max_size = sect->addr + sect->size - addr; + if (!size) + { + if (valid_size) + *valid_size = max_size; + } + else if ( size <= max_size ) + { + if (valid_size) + *valid_size = size; + } + else if (valid_size) + *valid_size = max_size; + else + return 0; + + return sect->off + addr - sect->addr; + } + } + } + + if (valid_size) + *valid_size = 0; + return ~0; +} + +//----------------------------------------------------------------------------- + +u32 GetRelAddrByOffsetM +( + str_mode_t mode, // region mode + u32 off, // offset to search + u32 size, // >0: wanted size + u32 *valid_size // not NULL: return valid size +) +{ + const rel_info_t *ri = GetInfoREL(mode); + if (ri) + { + if ( off < ri->sect[0].off ) + return ri->load_addr + off; + + const dol_sect_info_t *sect; + for ( sect = ri->sect; sect->section >= 0; sect++ ) + { + if ( off >= sect->off && off < sect->off + sect->size ) + { + u32 max_size = sect->off + sect->size - off; + if (!size) + { + if (valid_size) + *valid_size = max_size; + } + else if ( size <= max_size ) + { + if (valid_size) + *valid_size = size; + } + else if (valid_size) + *valid_size = max_size; + else + return 0; + + return sect->addr + off - sect->off; + } + } + + } + + if (valid_size) + *valid_size = 0; + return 0; +} + +// +/////////////////////////////////////////////////////////////////////////////// /////////////// struct staticr_t /////////////// /////////////////////////////////////////////////////////////////////////////// @@ -2089,6 +2427,85 @@ const DolSectionMap_t * FindSectionDOL ( uint size, u8 *hash ) // /////////////////////////////////////////////////////////////////////////////// +/////////////// dol header /////////////// +/////////////////////////////////////////////////////////////////////////////// + +static const u8 dol_header_bz2[] = +{ + // decompressed size: 0x400 = 1024 bytes + 0x00,0x00,0x04,0x00, + + // bzipped data + 0x42,0x5a,0x68,0x39, 0x31,0x41,0x59,0x26, 0x53,0x59,0x84,0xf7, 0x10,0x70,0x00,0x00, + 0x22,0xff,0xff,0xef, 0x71,0xfa,0x54,0x6e, 0x74,0x25,0xd0,0x4f, 0x07,0xf0,0x00,0x44, + 0x30,0x90,0x10,0xda, 0x00,0x00,0x02,0x44, 0x00,0x00,0x12,0x40, 0x00,0x20,0x19,0x60, + 0x00,0x02,0x16,0xb0, 0x01,0x3b,0x16,0x02, 0x54,0xd5,0x34,0xda, 0x1a,0xa3,0xd4,0xf4, + 0xd0,0x8d,0x32,0x30, 0xd0,0x46,0x41,0x8d, 0x4f,0x53,0x4c,0x46, 0x02,0x33,0xd4,0x6a, + 0x09,0x12,0xa9,0xfe, 0xa9,0xe9,0x26,0x9a, 0x19,0x00,0xd0,0x06, 0x80,0xd0,0x19,0x31, + 0x00,0x00,0x00,0x25, 0x4d,0x28,0xf5,0x1a, 0x68,0x00,0x1a,0x00, 0x00,0x03,0x40,0x00, + 0x00,0x01,0xab,0x7c, 0xb4,0x09,0x0b,0x17, 0xcd,0x46,0x50,0x5d, 0xb7,0xcc,0xe2,0x0d, + 0x00,0xae,0x28,0x0d, 0x03,0x60,0xd0,0x39, 0x61,0x8a,0x53,0x01, 0x11,0xfb,0x7a,0x01, + 0x52,0x48,0x41,0xf3, 0x0a,0xde,0x9e,0xa5, 0x60,0xb4,0xd1,0x9a, 0x0d,0x94,0x84,0x05, + 0xa6,0xd8,0x25,0x6c, 0x2c,0x58,0x99,0x99, 0x8a,0xa8,0xe2,0x93, 0x35,0xaa,0x97,0x49, + 0xa0,0x42,0x98,0xaa, 0x66,0x01,0x1b,0x90, 0x17,0xf0,0x1c,0x58, 0x2b,0x85,0xd1,0xb6, + 0x17,0x9d,0x76,0x99, 0x74,0x1c,0x25,0xcc, 0xd1,0x0c,0x18,0xc2, 0x61,0x28,0x04,0xd3, + 0x08,0x61,0x8b,0xde, 0xc6,0xfc,0xb0,0x1d, 0xa1,0x79,0xc7,0x77, 0x06,0xde,0x4d,0x01, + 0x88,0x10,0x01,0xc0, 0x56,0x10,0x58,0x0b, 0x04,0x11,0x14,0x88, 0xa4,0x3e,0x6a,0xe0, + 0x07,0x00,0xab,0xc6, 0x6f,0x7b,0xf1,0xe7, 0x6e,0x86,0x42,0x0c, 0x92,0x4a,0x9c,0x21, + 0x29,0x22,0x5b,0x50, 0x53,0x88,0x28,0x2a, 0x88,0x20,0x4b,0x26, 0xc0,0xbb,0xc2,0x20, + 0x18,0x80,0x88,0x1e, 0xd0,0x32,0xb7,0x9f, 0xa2,0xf5,0xe6,0x3e, 0x93,0x47,0x45,0x69, + 0x09,0x41,0xe0,0x7c, 0x44,0x83,0x2b,0x92, 0xfc,0x3a,0xb4,0xa2, 0xb1,0x6c,0x0a,0x0e, + 0x3b,0x7d,0x68,0x38, 0xef,0xf6,0xda,0x6a, 0xfc,0x6e,0xb0,0xfd, 0xe6,0xf8,0x72,0x9e, + 0xe4,0xde,0x51,0x85, 0x92,0x6e,0x2d,0x0a, 0x80,0xf8,0x73,0x25, 0x53,0x6f,0x49,0x0c, + 0xf8,0xe2,0x85,0xa1, 0x04,0x70,0x13,0xbd, 0xd0,0x7a,0x75,0x23, 0xe7,0xf8,0xbb,0x92, + 0x29,0xc2,0x84,0x84, 0x27,0xb8,0x83,0x80, + // 0x168 = 360 data bytes (36%) +}; + +static BZ2Manager_t dol_header_mgr + = { dol_header_bz2, sizeof(dol_header_bz2), 0, 0 }; + +//----------------------------------------------------------------------------- + +const dol_header_t * GetDolHeader ( str_mode_t mode ) +{ + if ( mode < STR_M_PAL || mode >= STR_M__N ) + return 0; + + DecodeBZIP2Manager(&dol_header_mgr); + return (dol_header_t*)dol_header_mgr.data + ( mode - STR_M_PAL ); +} + +//----------------------------------------------------------------------------- + +u32 GetDolOffsetByAddrM +( + str_mode_t mode, // region mode + u32 addr, // address to search + u32 size, // >0: wanted size + u32 *valid_size // not NULL: return valid size +) +{ + const dol_header_t *dh = GetDolHeader(mode); + return dh ? GetDolOffsetByAddr(dh,addr,size,valid_size) : 0; +} + +//----------------------------------------------------------------------------- + +u32 GetDolAddrByOffsetM +( + str_mode_t mode, // region mode + u32 off, // offset to search + u32 size, // >0: wanted size + u32 *valid_size // not NULL: return valid size +) +{ + const dol_header_t *dh = GetDolHeader(mode); + return dh ? GetDolAddrByOffset(dh,off,size,valid_size) : 0; +} + +// +/////////////////////////////////////////////////////////////////////////////// /////////////// ct-code dol extensions /////////////// /////////////////////////////////////////////////////////////////////////////// // [[ct_dol_ext_t]] @@ -2364,8 +2781,10 @@ ccp GetAddressSizeColor ( const ColorSet_t *cs, addr_size_mode_t asmode ) const addr_port_t * GetPortingRecordPAL ( u32 addr ) { + SetupAddrPortDB(); + int beg = 0; - int end = N_ADDR_PORT - 1; + int end = addr_port_records - 1; const int region = STR_M_PAL - STR_ZBI_FIRST; while ( beg <= end ) @@ -2406,6 +2825,8 @@ static int sort_addr_port_kor ( const addr_port_t **a, const addr_port_t **b ) const addr_port_t * GetPortingRecord ( str_mode_t mode, u32 addr ) { + SetupAddrPortDB(); + static const addr_port_t **usa = 0; static const addr_port_t **jap = 0; static const addr_port_t **kor = 0; @@ -2425,12 +2846,12 @@ const addr_port_t * GetPortingRecord ( str_mode_t mode, u32 addr ) if (!*list_ptr) { u_nsec_t start = GetTimerNSec(); - *list_ptr = MALLOC(sizeof(**list_ptr)*N_ADDR_PORT); + *list_ptr = MALLOC(sizeof(**list_ptr)*addr_port_records); const addr_port_t *src = addr_port; const addr_port_t **dest = *list_ptr; - for ( int i = 0; i < N_ADDR_PORT; i++ ) + for ( int i = 0; i < addr_port_records; i++ ) *dest++ = src++; - qsort( *list_ptr, N_ADDR_PORT, sizeof(**list_ptr), func ); + qsort( *list_ptr, addr_port_records, sizeof(**list_ptr), func ); if ( logging >= 3 ) fprintf(stdlog,"# Porting list for %s in %.1f µsec calculated.\n", GetStrModeName(mode), (GetTimerNSec()-start)*1e-3 ); @@ -2447,7 +2868,7 @@ const addr_port_t * GetPortingRecord ( str_mode_t mode, u32 addr ) } int beg = 0; - int end = N_ADDR_PORT - 1; + int end = addr_port_records - 1; const int region = mode - STR_ZBI_FIRST; const addr_port_t **base = *list_ptr; @@ -2474,7 +2895,7 @@ addr_type_t GetAddressType ( str_mode_t mode, u32 addr ) { if (!addr) return ADDRT_NULL; - + if (IsMirroredAddress(addr)) return GetAddressType(mode,addr-MIRRORED_ADDRESS_DELTA) + (ADDRT_MIRROR_BEGIN-ADDRT_MEMORY_BEGIN); @@ -2487,18 +2908,30 @@ addr_type_t GetAddressType ( str_mode_t mode, u32 addr ) return sect + ADDRT_DOL; } + const rel_info_t *ri = GetInfoREL(mode); + if (ri) + { + const dol_sect_info_t *dsi = ri->sect; + for ( int sect = 0; sect < REL_SECT__N; sect++, dsi++ ) + if ( addr >= dsi->addr && addr < dsi->addr + dsi->size ) + return sect + ADDRT_REL_SECT; + } + +//---------------------------------------------------------------- +// mountpoint file size fix size end of rel end of fixed +//---------------------------------------------------------------- +// PAL 0x805102e0 0x4ad3c4 0x3cd104 0x809bd6a4 0x808dd3e4 +// USA 0x8050bf60 0x4acf94 0x3ccd2c 0x809b8ef4 0x808d8c8c +// JAP 0x8050fc60 0x4acabc 0x3cc8d4 0x809bc71c 0x808dc534 +// KOR 0x804fe300 0x4ad9fc 0x3cd57c 0x809abcfc 0x808cb87c +//---------------------------------------------------------------- + struct data_t { u32 rel1; // first REL address u32 rel2; // last REL address+1 }; -// mountpoint file size fix size end of rel end of fixed -// PAL 805102E0 0x4ad3c4 0x3cd104 809BD6A4 808DD3E4 -// USA 8050BF60 0x4acf94 0x3ccd2c 809B8EF4 808D8C8C -// JAP 8050FC60 0x4acabc 0x3cc8d4 809BC71C 808DC534 -// KOR 804FE300 0x4ad9fc 0x3cd57c 809ABCFC 808CB87C - static const struct data_t pal = { 0x805102e0,0x808dd3e4 }; static const struct data_t usa = { 0x8050bf60,0x808d8c8c }; static const struct data_t jap = { 0x8050fc60,0x808dc534 }; @@ -2515,7 +2948,7 @@ addr_type_t GetAddressType ( str_mode_t mode, u32 addr ) } if ( addr >= data->rel1 && addr < data->rel2 ) - return ADDRT_STATICR; + return ADDRT_REL; struct mem_layout_t { @@ -2523,13 +2956,13 @@ addr_type_t GetAddressType ( str_mode_t mode, u32 addr ) u32 end; u32 mode; }; - + static const struct mem_layout_t tab[] = { { 0x80000000, 0x80004000, ADDRT_HEAD }, { 0x80000000, 0x81800000, ADDRT_MEM1 }, { 0x90000000, 0x94000000, ADDRT_MEM2 }, - { 0xcd000000, 0xcd008000, ADDRT_HOLLYWOOD }, + { 0xcd000000, 0xcd008000, ADDRT_GPU }, {0,0,0} }; @@ -2542,62 +2975,110 @@ addr_type_t GetAddressType ( str_mode_t mode, u32 addr ) /////////////////////////////////////////////////////////////////////////////// -ccp GetAddressTypeName ( addr_type_t type ) +ccp GetAddressTypeName ( addr_type_t atype ) { - if (IsMirroredAddressType(type)) + if (IsMirroredAddressType(atype)) { - ccp res = GetAddressTypeName(type-(ADDRT_MIRROR_BEGIN-ADDRT_MEMORY_BEGIN)); + ccp res = GetAddressTypeName(atype-(ADDRT_MIRROR_BEGIN-ADDRT_MEMORY_BEGIN)); const uint size = strlen(res)+1; char *buf = GetCircBuf(size); StringLowerS(buf,size,res); return buf; } - if ( type >= ADDRT_DOL && type <= ADDRT_BSS ) - return dol_section_name[ type - ADDRT_DOL ]; + if (IsAddrTypeDOL(atype)) + return dol_section_name[ atype - ADDRT_DOL ]; - switch (type) + if (IsAddrTypeREL(atype)) + return rel_section_name[ atype - ADDRT_REL_SECT ]; + + switch (atype) { case ADDRT_NULL: return "null"; case ADDRT_INVALID: return "invalid"; - case ADDRT_STATICR: return "REL"; case ADDRT_HEAD: return "HEAD"; case ADDRT_MEM1: return "MEM1"; case ADDRT_MEM2: return "MEM2"; - case ADDRT_HOLLYWOOD: return "HLWD"; - default: return PrintCircBuf("?%02u?",type); + case ADDRT_GPU: return "GPU"; + default: return PrintCircBuf("?%02u?",atype); } } /////////////////////////////////////////////////////////////////////////////// -ccp GetAddressTypeColor ( const ColorSet_t *col, addr_type_t type ) +ccp GetAddressTypeColor ( const ColorSet_t *col, addr_type_t atype ) { if ( !col || !col->colorize ) return EmptyString; - if (IsMirroredAddressType(type)) - type -= ADDRT_MIRROR_BEGIN - ADDRT_MEMORY_BEGIN; + if (IsMirroredAddressType(atype)) + atype -= ADDRT_MIRROR_BEGIN - ADDRT_MEMORY_BEGIN; + + if (IsAddrTypeDOL(atype)) + return atype < ADDRT_DOL + DOL_N_TEXT_SECTIONS ? col->b_green : col->b_yellow; - if ( type >= ADDRT_DOL && type < ADDRT_BSS ) - return type < ADDRT_DOL + DOL_N_TEXT_SECTIONS ? col->b_green : col->b_yellow; + if (IsAddrTypeREL(atype)) + return col->b_cyan; - switch (type) + switch (atype) { case ADDRT_BSS: return col->b_magenta_blue; case ADDRT_NULL: return EmptyString; case ADDRT_INVALID: return col->b_orange; - case ADDRT_STATICR: return col->b_cyan; case ADDRT_HEAD: case ADDRT_MEM1: return col->b_blue_cyan; case ADDRT_MEM2: return col->b_blue; - case ADDRT_HOLLYWOOD: return col->yellow; + case ADDRT_GPU: return col->yellow; default: return col->error; } } +/////////////////////////////////////////////////////////////////////////////// + +const dol_sect_info_t * GetAddressTypeSection ( str_mode_t mode, addr_type_t atype ) +{ + if (IsMirroredAddressType(atype)) + atype -= ADDRT_MIRROR_BEGIN - ADDRT_MEMORY_BEGIN; + + if (IsAddrTypeDOL(atype)) + { + const dol_sect_info_t *di = GetInfoDOL(mode); + return di ? di + (atype-ADDRT_DOL) : 0; + } + + if (IsAddrTypeRELSect(atype)) + { + const rel_info_t *ri = GetInfoREL(mode); + return ri ? ri->sect + (atype-ADDRT_REL_SECT) : 0; + } + + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +int GetOffsetByAddrM ( str_mode_t mode, addr_type_t atype, u32 addr ) +{ + // if !atype: Calculate it by 'addr' + // return -1 if invalid + + if (!atype) + atype = GetAddressType(mode,addr); + + if (IsAddrTypeDOL(atype)) + { + const u32 aoff = GetDolOffsetByAddrM(mode,addr,0,0); + return aoff ? aoff : -1; + } + + if (IsAddrTypeREL(atype)) + return GetRelOffsetByAddrM(mode,addr,0,0); + + return -1; +} + // /////////////////////////////////////////////////////////////////////////////// /////////////// main.dol support /////////////// @@ -2758,7 +3239,7 @@ void AnalyzeDOL str->dol_info_flags |= DIF_ORIG; } - #if defined(TEST) && 0 || 1 + #if defined(TEST) && 0 if (vbi_addr) { dol_header_t *dh = (dol_header_t*)str->data; @@ -3785,7 +4266,7 @@ void PrintStatusSTR if ( long_mode > 1 || long_mode > 0 && st & STR_S_TRACK_ORDER__FAIL ) { fprintf(f,"%*s- Track assigning tables:\n", indent,"" ); - const u32 *tab = GetTrackOffsetTab(str); + const u32 *tab = GetTrackOffsetTab(str->mode); DASSERT(tab); for(;;) { @@ -3816,7 +4297,7 @@ void PrintStatusSTR if ( long_mode > 1 || long_mode > 0 && st & STR_S_ARENA_ORDER__FAIL ) { fprintf(f,"%*s- Arena assigning tables:\n", indent,"" ); - const u32 *tab = GetArenaOffsetTab(str); + const u32 *tab = GetArenaOffsetTab(str->mode); DASSERT(tab); for(;;) { @@ -4165,14 +4646,14 @@ uint PatchSTR if (opt_tracks) { - const u32 *tab = GetTrackOffsetTab(str); + const u32 *tab = GetTrackOffsetTab(str->mode); if (tab) count += PatchTracks( str, tab, track_pos, MKW_TRACK_BEG, MKW_N_TRACKS ); } if (opt_arenas) { - const u32 *tab = GetArenaOffsetTab(str); + const u32 *tab = GetArenaOffsetTab(str->mode); if (tab) count += PatchTracks( str, tab, arena_pos, MKW_ARENA_BEG, MKW_N_ARENAS ); } @@ -6492,7 +6973,9 @@ char mkw_domain[100] = "mariokartwii.gs.wiimmfi.de"; ccp wifi_domain = mkw_domain + 16; bool wifi_domain_is_wiimmfi = false; wcode_t opt_wcode = WCODE_AUTO; +ccp opt_port_db = 0; ccp opt_order = 0; +bool opt_no_0x = false; /////////////////////////////////////////////////////////////////////////////// @@ -6918,6 +7401,8 @@ enumError DumpSTR DASSERT( str->data_size >= sizeof(rel_header_t) ); indent = NormalizeIndent(indent); + const rel_info_t *rinfo = GetInfoREL(str->mode); + const u32 load_off = rinfo ? rinfo->load_addr : 0; //----- dump header @@ -6929,13 +7414,14 @@ enumError DumpSTR if ( hd.mod_name && hd.mod_name + hd.mod_name_len < str->data_size ) mod_name = (ccp)str->data + hd.mod_name; + fprintf(f,"%*sId: %8u = 0x%x\n", indent,"", hd.id, hd.id ); + fprintf(f,"%*sN(sections): %8u\n", indent,"", hd.n_section ); + fprintf(f,"%*sModule Name: %8s\n", indent,"", mod_name ); + fprintf(f,"%*sReloc Offset: %8x\n", indent,"", hd.reloc_off ); + if (rinfo) + fprintf(f,"%*sLoad Address: %8x\n", indent,"", rinfo->load_addr ); - fprintf(f,"%*sId: %6u = 0x%x\n", indent,"", hd.id, hd.id ); - fprintf(f,"%*sN(sections): %6u\n", indent,"", hd.n_section ); - fprintf(f,"%*sModule Name: %6s\n", indent,"", mod_name ); - fprintf(f,"%*sReloc Offset: %6x\n", indent,"", hd.reloc_off ); - - fprintf(f,"\n%*sSection (0..%u):\n", indent,"", hd.n_section-1 ); + fprintf(f,"\n%*sSections (0..%u) [size:offset:address]:\n", indent,"", hd.n_section-1 ); rel_sect_info_t *si = (rel_sect_info_t*)( str->data + hd.section_off ); uint s; for ( s = 0; s < hd.n_section; s++, si++ ) @@ -6945,13 +7431,18 @@ enumError DumpSTR { u32 offset = be32(&si->offset); if (!offset) - fprintf(f,"%*s%4u. BSS %7x\n", indent,"", s, size ); + fprintf(f,"%*s%4u. BSS %#9x\n", indent,"", s, size ); else { ccp type = offset & 1 ? "TEXT" : "DATA"; offset &= ~1; - fprintf(f,"%*s%4u. %s %7x : %6x .. %6x\n", - indent,"", s, type, size, offset, offset + size - 1 ); + fprintf(f,"%*s%4u. %s %#9x : %#8x .. %#8x", + indent,"", s, type, size, offset, offset + size ); + if (rinfo) + fprintf(f," : %#10x .. %#10x\n", + load_off + offset, load_off + offset + size ); + else + fputc('\n',f); } } } @@ -7059,8 +7550,74 @@ enumError ExtractSTR if (str->is_dol) return ExtractDOL(str,dest_dir); - return ERROR0(ERR_WARNING, - "Extraction of StaticR.rel files is not implemented yet!\n"); + + //--- setup + + const rel_info_t *ri = GetInfoREL(str->mode); + if (!ri) + return ERROR0(ERR_INTERNAL,0); + + CreatePath(dest_dir,true); + + + //--- open log file + + char path_buf[PATH_MAX]; + ccp path = PathCatPP(path_buf,sizeof(path_buf),dest_dir,"rel-setup.txt"); + FILE *log = fopen(path,"wb"); + if (!log) + return ERROR0(ERR_CANT_CREATE, + "Can't create setup file: %s\n",path); + + static ccp sep = "#---------------------------------------------------------------------\n"; + fprintf(log,"\n%s#sect offset address size sha1 checksum\n%s",sep,sep); + + + //--- extract sections + + uint sect; + for ( sect = 0; sect < REL_SECT__N; sect++ ) + { + dol_sect_info_t info = ri->sect[sect]; + fprintf(log,"%-4s= %06x %08x %06x",info.name,info.off,info.addr,info.size); + + info.hash_valid = false; + info.data_valid = str->data && info.off + info.size <= str->data_size; + if (info.data_valid) + { + const u8 *data = str->data + info.off; + info.hash_valid = true; + SHA1( data, info.size, info.hash ); + + if (info.hash_valid) + { + fputc(' ',log); + uint i; + for ( i = 0; i < sizeof(info.hash); i++ ) + fprintf(log,"%02x",info.hash[i]); + } + + path = PathCatPPE(path_buf,sizeof(path_buf),dest_dir,info.name,".bin"); + FILE *f = fopen(path,"wb"); + if (!f) + { + fclose(log); + return ERROR0(ERR_CANT_CREATE, + "Can't create data file: %s\n",path); + } + fwrite(data,1,info.size,f); + fclose(f); + } + fputc('\n',log); + } + fputs(sep,log); + + + //--- close log and return + + fprintf(log,"\n"); + fclose(log); + return ERR_OK; } // |
