mirror of
https://github.com/zeldaret/tp
synced 2026-08-15 21:00:11 -04:00
OSLink done (#2038)
This commit is contained in:
@@ -346,25 +346,25 @@ bool JUTException::searchPartialModule(u32 address, u32* module_id, u32* section
|
||||
|
||||
OSModuleInfo* module = *(OSModuleInfo**)0x800030C8;
|
||||
while (module) {
|
||||
OSSectionInfo* section = (OSSectionInfo*)module->info.sectionInfoOffset;
|
||||
for (u32 i = 0; i < module->mNumSections; section = section + 1, i++) {
|
||||
if (section->mSize) {
|
||||
u32 addr = ALIGN_PREV(section->mOffset, 2);
|
||||
if ((addr <= address) && (address < addr + section->mSize)) {
|
||||
OSSectionInfo* section = (OSSectionInfo*)module->sectionInfoOffset;
|
||||
for (u32 i = 0; i < module->numSections; section = section + 1, i++) {
|
||||
if (section->size) {
|
||||
u32 addr = ALIGN_PREV(section->offset, 2);
|
||||
if ((addr <= address) && (address < addr + section->size)) {
|
||||
if (module_id)
|
||||
*module_id = module->mId;
|
||||
*module_id = module->id;
|
||||
if (section_id)
|
||||
*section_id = i;
|
||||
if (section_offset)
|
||||
*section_offset = address - addr;
|
||||
if (name_offset)
|
||||
*name_offset = module->mModuleNameOffset;
|
||||
*name_offset = module->nameOffset;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module = (OSModuleInfo*)module->mNext;
|
||||
module = (OSModuleInfo*)module->link.next;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+344
-72
@@ -1,10 +1,4 @@
|
||||
//
|
||||
// Generated By: dol2asm
|
||||
// Translation Unit: OSLink
|
||||
//
|
||||
|
||||
#include "dolphin/os/OSLink.h"
|
||||
#include "dol2asm.h"
|
||||
#include "dolphin/os.h"
|
||||
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LORESERVE 0xff00
|
||||
@@ -113,101 +107,379 @@
|
||||
__prev->link.next = __next; \
|
||||
} while (0)
|
||||
|
||||
//
|
||||
// External References:
|
||||
//
|
||||
OSModuleQueue __OSModuleInfoList : (OS_BASE_CACHED | 0x30C8);
|
||||
|
||||
SECTION_INIT void memset();
|
||||
void OSReport();
|
||||
void DCFlushRange();
|
||||
void ICInvalidateRange();
|
||||
|
||||
//
|
||||
// Declarations:
|
||||
//
|
||||
#pragma dont_inline on
|
||||
|
||||
/* 8033DF60-8033DF64 3388A0 0004+00 1/1 0/0 0/0 .text OSNotifyLink */
|
||||
static void OSNotifyLink(void) {}
|
||||
__declspec(weak) void OSNotifyLink(OSModuleInfo* module) {}
|
||||
|
||||
/* 8033DF64-8033DF68 3388A4 0004+00 1/1 0/0 0/0 .text OSNotifyUnlink */
|
||||
static void OSNotifyUnlink(void) {}
|
||||
__declspec(weak) void OSNotifyUnlink(OSModuleInfo* module) {}
|
||||
|
||||
#pragma dont_inline reset
|
||||
|
||||
/* 8033DF68-8033DF74 3388A8 000C+00 0/0 1/1 0/0 .text OSSetStringTable */
|
||||
void OSSetStringTable(void* string_table) {
|
||||
__OSStringTable = string_table;
|
||||
}
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D0788-803D07B0 02D8A8 0025+03 1/1 0/0 0/0 .data @62 */
|
||||
SECTION_DATA static char lit_62[] = "OSLink: unknown relocation type %3d\n";
|
||||
|
||||
/* 8033DF74-8033E230 3388B4 02BC+00 1/1 0/0 0/0 .text Relocate */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm BOOL Relocate(OSModuleInfo* param_0, OSModuleInfo* param_1) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSLink/Relocate.s"
|
||||
static BOOL Relocate(OSModuleHeader* newModule, OSModuleHeader* module) {
|
||||
OSModuleID idNew;
|
||||
OSImportInfo* imp;
|
||||
OSRel* rel;
|
||||
OSSectionInfo* si;
|
||||
OSSectionInfo* siFlush;
|
||||
u32* p;
|
||||
u32 offset;
|
||||
u32 x;
|
||||
|
||||
idNew = newModule ? newModule->info.id : 0;
|
||||
for (imp = (OSImportInfo*)module->impOffset;
|
||||
imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++)
|
||||
{
|
||||
if (imp->id == idNew) {
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
Found:
|
||||
siFlush = 0;
|
||||
for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) {
|
||||
(u8*)p += rel->offset;
|
||||
if (idNew) {
|
||||
si = &OSGetSectionInfo(newModule)[rel->section];
|
||||
offset = OS_SECTIONINFO_OFFSET(si->offset);
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
switch (rel->type) {
|
||||
case R_PPC_NONE:
|
||||
break;
|
||||
case R_PPC_ADDR32:
|
||||
x = offset + rel->addend;
|
||||
*p = x;
|
||||
break;
|
||||
case R_PPC_ADDR24:
|
||||
x = offset + rel->addend;
|
||||
*p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
|
||||
break;
|
||||
case R_PPC_ADDR16:
|
||||
x = offset + rel->addend;
|
||||
*(u16*)p = (u16)(x & 0xffff);
|
||||
break;
|
||||
case R_PPC_ADDR16_LO:
|
||||
x = offset + rel->addend;
|
||||
*(u16*)p = (u16)(x & 0xffff);
|
||||
break;
|
||||
case R_PPC_ADDR16_HI:
|
||||
x = offset + rel->addend;
|
||||
*(u16*)p = (u16)(((x >> 16) & 0xffff));
|
||||
break;
|
||||
case R_PPC_ADDR16_HA:
|
||||
x = offset + rel->addend;
|
||||
*(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff);
|
||||
break;
|
||||
case R_PPC_ADDR14:
|
||||
case R_PPC_ADDR14_BRTAKEN:
|
||||
case R_PPC_ADDR14_BRNTAKEN:
|
||||
x = offset + rel->addend;
|
||||
*p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
|
||||
break;
|
||||
case R_PPC_REL24:
|
||||
x = offset + rel->addend - (u32)p;
|
||||
*p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
|
||||
break;
|
||||
case R_PPC_REL14:
|
||||
case R_PPC_REL14_BRTAKEN:
|
||||
case R_PPC_REL14_BRNTAKEN:
|
||||
x = offset + rel->addend - (u32)p;
|
||||
*p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
|
||||
break;
|
||||
case R_DOLPHIN_NOP:
|
||||
break;
|
||||
case R_DOLPHIN_SECTION:
|
||||
si = &OSGetSectionInfo(module)[rel->section];
|
||||
p = (u32*)OS_SECTIONINFO_OFFSET(si->offset);
|
||||
if (siFlush) {
|
||||
offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
|
||||
DCFlushRange((void*)offset, siFlush->size);
|
||||
ICInvalidateRange((void*)offset, siFlush->size);
|
||||
}
|
||||
siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0;
|
||||
break;
|
||||
default:
|
||||
OSReport("OSLink: unknown relocation type %3d\n", rel->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (siFlush) {
|
||||
offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
|
||||
DCFlushRange((void*)offset, siFlush->size);
|
||||
ICInvalidateRange((void*)offset, siFlush->size);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8033E230-8033E510 338B70 02E0+00 2/2 0/0 0/0 .text Link */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm BOOL Link(OSModuleInfo* module, u32 param_1) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSLink/Link.s"
|
||||
static BOOL Link(OSModuleInfo* newModule, void* bss, BOOL fixed) {
|
||||
u32 i;
|
||||
OSSectionInfo* si;
|
||||
OSModuleHeader* moduleHeader;
|
||||
OSModuleInfo* moduleInfo;
|
||||
OSImportInfo* imp;
|
||||
|
||||
moduleHeader = (OSModuleHeader*)newModule;
|
||||
moduleHeader->bssSection = 0;
|
||||
|
||||
if (OS_MODULE_VERSION < newModule->version ||
|
||||
2 <= newModule->version &&
|
||||
(moduleHeader->align && (u32)newModule % moduleHeader->align != 0 ||
|
||||
moduleHeader->bssAlign && (u32)bss % moduleHeader->bssAlign != 0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EnqueueTail(&__OSModuleInfoList, newModule, link);
|
||||
newModule->sectionInfoOffset += (u32)moduleHeader;
|
||||
moduleHeader->relOffset += (u32)moduleHeader;
|
||||
moduleHeader->impOffset += (u32)moduleHeader;
|
||||
if (3 <= newModule->version) {
|
||||
moduleHeader->fixSize += (u32)moduleHeader;
|
||||
}
|
||||
|
||||
for (i = 1; i < newModule->numSections; i++) {
|
||||
si = &OSGetSectionInfo(newModule)[i];
|
||||
if (si->offset != 0) {
|
||||
si->offset += (u32)moduleHeader;
|
||||
} else if (si->size != 0) {
|
||||
moduleHeader->bssSection = (u8)i;
|
||||
si->offset = (u32)bss;
|
||||
}
|
||||
}
|
||||
|
||||
for (imp = (OSImportInfo*)moduleHeader->impOffset;
|
||||
imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++)
|
||||
{
|
||||
imp->offset += (u32)moduleHeader;
|
||||
}
|
||||
|
||||
if (moduleHeader->prologSection != SHN_UNDEF) {
|
||||
moduleHeader->prolog +=
|
||||
OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->prologSection].offset);
|
||||
}
|
||||
|
||||
if (moduleHeader->epilogSection != SHN_UNDEF) {
|
||||
moduleHeader->epilog +=
|
||||
OS_SECTIONINFO_OFFSET(OSGetSectionInfo(newModule)[moduleHeader->epilogSection].offset);
|
||||
}
|
||||
|
||||
if (moduleHeader->unresolvedSection != SHN_UNDEF) {
|
||||
moduleHeader->unresolved += OS_SECTIONINFO_OFFSET(
|
||||
OSGetSectionInfo(newModule)[moduleHeader->unresolvedSection].offset);
|
||||
}
|
||||
|
||||
if (__OSStringTable) {
|
||||
newModule->nameOffset += (u32)__OSStringTable;
|
||||
}
|
||||
|
||||
Relocate(0, moduleHeader);
|
||||
|
||||
for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) {
|
||||
Relocate(moduleHeader, (OSModuleHeader*)moduleInfo);
|
||||
if (moduleInfo != newModule) {
|
||||
Relocate((OSModuleHeader*)moduleInfo, moduleHeader);
|
||||
}
|
||||
}
|
||||
|
||||
if (fixed) {
|
||||
for (imp = (OSImportInfo*)moduleHeader->impOffset;
|
||||
imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++)
|
||||
{
|
||||
if (imp->id == 0 || imp->id == newModule->id) {
|
||||
moduleHeader->impSize = (u32)((u8*)imp - (u8*)moduleHeader->impOffset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(bss, 0, moduleHeader->bssSize);
|
||||
|
||||
OSNotifyLink(newModule);
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8033E510-8033E534 338E50 0024+00 0/0 1/1 0/0 .text OSLink */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL OSLink(OSModuleInfo* module) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSLink/OSLink.s"
|
||||
BOOL OSLink(OSModuleInfo* newModule, void* bss) {
|
||||
return Link(newModule, bss, FALSE);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8033E534-8033E570 338E74 003C+00 0/0 1/1 0/0 .text OSLinkFixed */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL OSLinkFixed(OSModuleInfo* module, u32 param_1) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSLink/OSLinkFixed.s"
|
||||
BOOL OSLinkFixed(OSModuleInfo* newModule, void* bss) {
|
||||
if (OS_MODULE_VERSION < newModule->version || newModule->version < 3) {
|
||||
return FALSE;
|
||||
}
|
||||
return Link(newModule, bss, TRUE);
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* ############################################################################################## */
|
||||
/* 803D07B0-803D07D8 02D8D0 0027+01 1/1 0/0 0/0 .data @189 */
|
||||
SECTION_DATA static char lit_189[] = "OSUnlink: unknown relocation type %3d\n";
|
||||
|
||||
/* 8033E570-8033E7A8 338EB0 0238+00 1/1 0/0 0/0 .text Undo */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
static asm BOOL Undo(OSModuleInfo* param_0, OSModuleInfo* param_1) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSLink/Undo.s"
|
||||
static BOOL Undo(OSModuleHeader* newModule, OSModuleHeader* module) {
|
||||
OSModuleID idNew;
|
||||
OSImportInfo* imp;
|
||||
OSRel* rel;
|
||||
OSSectionInfo* si;
|
||||
OSSectionInfo* siFlush;
|
||||
u32* p;
|
||||
u32 offset;
|
||||
u32 x;
|
||||
|
||||
idNew = newModule->info.id;
|
||||
for (imp = (OSImportInfo*)module->impOffset;
|
||||
imp < (OSImportInfo*)(module->impOffset + module->impSize); imp++)
|
||||
{
|
||||
if (imp->id == idNew) {
|
||||
goto Found;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
Found:
|
||||
siFlush = 0;
|
||||
for (rel = (OSRel*)imp->offset; rel->type != R_DOLPHIN_END; rel++) {
|
||||
(u8*)p += rel->offset;
|
||||
si = &OSGetSectionInfo(newModule)[rel->section];
|
||||
offset = OS_SECTIONINFO_OFFSET(si->offset);
|
||||
x = 0;
|
||||
switch (rel->type) {
|
||||
case R_PPC_NONE:
|
||||
break;
|
||||
case R_PPC_ADDR32:
|
||||
*p = x;
|
||||
break;
|
||||
case R_PPC_ADDR24:
|
||||
*p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
|
||||
break;
|
||||
case R_PPC_ADDR16:
|
||||
*(u16*)p = (u16)(x & 0xffff);
|
||||
break;
|
||||
case R_PPC_ADDR16_LO:
|
||||
*(u16*)p = (u16)(x & 0xffff);
|
||||
break;
|
||||
case R_PPC_ADDR16_HI:
|
||||
*(u16*)p = (u16)(((x >> 16) & 0xffff));
|
||||
break;
|
||||
case R_PPC_ADDR16_HA:
|
||||
*(u16*)p = (u16)(((x >> 16) + ((x & 0x8000) ? 1 : 0)) & 0xffff);
|
||||
break;
|
||||
case R_PPC_ADDR14:
|
||||
case R_PPC_ADDR14_BRTAKEN:
|
||||
case R_PPC_ADDR14_BRNTAKEN:
|
||||
*p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
|
||||
break;
|
||||
case R_PPC_REL24:
|
||||
if (module->unresolvedSection != SHN_UNDEF) {
|
||||
x = (u32)module->unresolved - (u32)p;
|
||||
}
|
||||
*p = (*p & ~0x03fffffc) | (x & 0x03fffffc);
|
||||
break;
|
||||
case R_PPC_REL14:
|
||||
case R_PPC_REL14_BRTAKEN:
|
||||
case R_PPC_REL14_BRNTAKEN:
|
||||
*p = (*p & ~0x0000fffc) | (x & 0x0000fffc);
|
||||
break;
|
||||
case R_DOLPHIN_NOP:
|
||||
break;
|
||||
case R_DOLPHIN_SECTION:
|
||||
si = &OSGetSectionInfo(module)[rel->section];
|
||||
p = (u32*)OS_SECTIONINFO_OFFSET(si->offset);
|
||||
if (siFlush) {
|
||||
offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
|
||||
DCFlushRange((void*)offset, siFlush->size);
|
||||
ICInvalidateRange((void*)offset, siFlush->size);
|
||||
}
|
||||
siFlush = (si->offset & OS_SECTIONINFO_EXEC) ? si : 0;
|
||||
break;
|
||||
default:
|
||||
OSReport("OSUnlink: unknown relocation type %3d\n", rel->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (siFlush) {
|
||||
offset = OS_SECTIONINFO_OFFSET(siFlush->offset);
|
||||
DCFlushRange((void*)offset, siFlush->size);
|
||||
ICInvalidateRange((void*)offset, siFlush->size);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8033E7A8-8033E97C 3390E8 01D4+00 0/0 1/1 0/0 .text OSUnlink */
|
||||
#pragma push
|
||||
#pragma optimization_level 0
|
||||
#pragma optimizewithasm off
|
||||
asm BOOL OSUnlink(OSModuleInfo* module) {
|
||||
nofralloc
|
||||
#include "asm/dolphin/os/OSLink/OSUnlink.s"
|
||||
BOOL OSUnlink(OSModuleInfo* oldModule) {
|
||||
OSModuleHeader* moduleHeader;
|
||||
OSModuleInfo* moduleInfo;
|
||||
u32 i;
|
||||
OSSectionInfo* si;
|
||||
OSImportInfo* imp;
|
||||
|
||||
moduleHeader = (OSModuleHeader*)oldModule;
|
||||
|
||||
DequeueItem(&__OSModuleInfoList, oldModule, link);
|
||||
|
||||
for (moduleInfo = __OSModuleInfoList.head; moduleInfo; moduleInfo = moduleInfo->link.next) {
|
||||
Undo(moduleHeader, (OSModuleHeader*)moduleInfo);
|
||||
}
|
||||
|
||||
OSNotifyUnlink(oldModule);
|
||||
|
||||
if (__OSStringTable) {
|
||||
oldModule->nameOffset -= (u32)__OSStringTable;
|
||||
}
|
||||
|
||||
if (moduleHeader->prologSection != SHN_UNDEF) {
|
||||
moduleHeader->prolog -=
|
||||
OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->prologSection].offset);
|
||||
}
|
||||
|
||||
if (moduleHeader->epilogSection != SHN_UNDEF) {
|
||||
moduleHeader->epilog -=
|
||||
OS_SECTIONINFO_OFFSET(OSGetSectionInfo(oldModule)[moduleHeader->epilogSection].offset);
|
||||
}
|
||||
|
||||
if (moduleHeader->unresolvedSection != SHN_UNDEF) {
|
||||
moduleHeader->unresolved -= OS_SECTIONINFO_OFFSET(
|
||||
OSGetSectionInfo(oldModule)[moduleHeader->unresolvedSection].offset);
|
||||
}
|
||||
|
||||
for (imp = (OSImportInfo*)moduleHeader->impOffset;
|
||||
imp < (OSImportInfo*)(moduleHeader->impOffset + moduleHeader->impSize); imp++)
|
||||
{
|
||||
imp->offset -= (u32)moduleHeader;
|
||||
}
|
||||
|
||||
for (i = 1; i < oldModule->numSections; i++) {
|
||||
si = &OSGetSectionInfo(oldModule)[i];
|
||||
if (i == moduleHeader->bssSection) {
|
||||
moduleHeader->bssSection = 0;
|
||||
si->offset = 0;
|
||||
} else if (si->offset != 0) {
|
||||
si->offset -= (u32)moduleHeader;
|
||||
}
|
||||
}
|
||||
moduleHeader->relOffset -= (u32)moduleHeader;
|
||||
moduleHeader->impOffset -= (u32)moduleHeader;
|
||||
oldModule->sectionInfoOffset -= (u32)moduleHeader;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/* 8033E97C-8033E994 3392BC 0018+00 0/0 1/1 0/0 .text __OSModuleInit */
|
||||
void __OSModuleInit(void) {
|
||||
__OSModuleList.last = NULL;
|
||||
__OSModuleList.first = NULL;
|
||||
__OSModuleList.tail = NULL;
|
||||
__OSModuleList.head = NULL;
|
||||
__OSStringTable = NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user