OSLink done (#2038)

This commit is contained in:
TakaRikka
2024-01-20 02:53:06 -08:00
committed by GitHub
parent 5ad3727d17
commit 49a4319fb8
14 changed files with 460 additions and 1188 deletions
+8 -8
View File
@@ -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
View File
@@ -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;
}