Fixes known undefined behaviour from DmaMgr and Lib_Ptr taking u32 rather than void*

This commit is contained in:
Kenix3 2020-06-04 21:41:44 -04:00
parent dfbcac539e
commit 664182c289
9 changed files with 61 additions and 51 deletions

View File

@ -22,8 +22,8 @@ s32 Dmamgr_FindDmaIndex(u32 vromAddr); // func_800809BC
char* func_800809F4(u32 param_1); // func_800809F4
void DmaMgr_ProcessMsg(DmaRequest* request); // func_80080A08
void Dmamgr_ThreadEntry(void* arg); // func_80080B84
s32 DmaMgr_SendRequestImpl(DmaRequest* request, u32 vramStart, u32 vromStart, u32 size, UNK_TYPE4 unused, OSMesgQueue* callback, void* callbackMesg); // func_80080C04
s32 DmaMgr_SendRequest0(u32 vramStart, u32 vromStart, u32 size); // func_80080C90
s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, u32 vromStart, u32 size, UNK_TYPE4 unused, OSMesgQueue* callback, void* callbackMesg); // func_80080C04
s32 DmaMgr_SendRequest0(void* vramStart, u32 vromStart, u32 size); // func_80080C90
void Dmamgr_Start(void); // func_80080D0C
void Dmamgr_Stop(void); // func_80080E00
u8* Yaz0_LoadFirstChunk(void); // func_80080E30
@ -1864,10 +1864,10 @@ void Lib_TranslateAndRotateYVec3f(Vec3f* translation, s16 rotation, Vec3f* src,
void Lib_LerpRGB(RGB* a, RGB* b, f32 t, RGB* dst); // func_801001B8
f32 Lib_PushAwayVec3f(Vec3f* start, Vec3f* pusher, f32 distanceToApproach); // func_80100448
void Lib_Nop801004FC(void); // func_801004FC
u32 Lib_PtrSegToVirt(void* ptr); // func_80100504
u32 Lib_PtrSegToVirtNull(void* ptr); // func_8010053C
u32 Lib_PtrSegToK0(void* ptr); // func_80100584
u32 Lib_PtrSegToK0Null(void* ptr); // func_801005A0
void* Lib_PtrSegToVirt(void* ptr); // func_80100504
void* Lib_PtrSegToVirtNull(void* ptr); // func_8010053C
void* Lib_PtrSegToK0(void* ptr); // func_80100584
void* Lib_PtrSegToK0Null(void* ptr); // func_801005A0
void LifeMeter_Init(GlobalContext* ctxt); // func_801005C0
void LifeMeter_UpdateColors(GlobalContext* ctxt); // func_8010069C
UNK_TYPE4 func_80100A80(GlobalContext* ctxt); // func_80100A80

View File

@ -1893,7 +1893,7 @@ typedef struct {
/* 0x30 */ u8 activeMemPage; // 0 - First page in memory, 1 - Second page
/* 0x31 */ s8 unk31;
/* 0x32 */ UNK_TYPE1 pad32[0x2];
/* 0x34 */ u32 activeRoomVram;
/* 0x34 */ void* activeRoomVram;
/* 0x38 */ DmaRequest dmaRequest;
/* 0x58 */ OSMesgQueue loadQueue;
/* 0x70 */ OSMesg loadMsg[1];

View File

@ -4109,7 +4109,7 @@ extern UNK_TYPE1 D_801F80F8; // D_801F80F8
extern u64 lastRenderFrameTimestamp; // D_801F8150
extern OSMesgQueue siEventCallbackQueue; // D_801F8160
extern OSMesg siEventCallbackBuffer[1]; // D_801F8178
extern u32 gRspSegmentPhysAddrs[16]; // D_801F8180
extern void* gRspSegmentPhysAddrs[16]; // D_801F8180
extern SchedThreadStruct schedContext; // D_801F81C0
extern OSMesgQueueListNode mainIrqmgrCallbackNode; // D_801F84F8
extern OSMesgQueue mainIrqmgrCallbackQueue; // D_801F8500

View File

@ -159,13 +159,13 @@ void Dmamgr_ThreadEntry(void* a0) {
}
}
s32 DmaMgr_SendRequestImpl(DmaRequest* request, u32 vramStart, u32 vromStart, u32 size, UNK_TYPE4 unused, OSMesgQueue* callback, void* callbackMesg) {
s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, u32 vromStart, u32 size, UNK_TYPE4 unused, OSMesgQueue* callback, void* callbackMesg) {
if (gIrqMgrResetStatus >= 2) {
return -2;
}
request->vromStart = vromStart;
request->dramAddr = (void*)vramStart;
request->dramAddr = vramStart;
request->size = size;
request->unk14 = 0;
request->notifyQueue = callback;
@ -176,7 +176,7 @@ s32 DmaMgr_SendRequestImpl(DmaRequest* request, u32 vramStart, u32 vromStart, u3
return 0;
}
s32 DmaMgr_SendRequest0(u32 a0, u32 a1, u32 a2) {
s32 DmaMgr_SendRequest0(void* vramStart, u32 vromStart, u32 size) {
DmaRequest sp48;
OSMesgQueue sp30;
OSMesg sp2C;
@ -184,7 +184,7 @@ s32 DmaMgr_SendRequest0(u32 a0, u32 a1, u32 a2) {
osCreateMesgQueue(&sp30, &sp2C, 1);
ret = DmaMgr_SendRequestImpl(&sp48, a0, a1, a2, 0, &sp30, 0);
ret = DmaMgr_SendRequestImpl(&sp48, vramStart, vromStart, size, 0, &sp30, 0);
if (ret == -1) {
return ret;

View File

@ -215,7 +215,9 @@ void Actor_SetScale(Actor* actor, f32 scale) {
}
void Actor_SetObjectSegment(GlobalContext* ctxt, Actor* actor) {
gRspSegmentPhysAddrs[6] = (u32) ctxt->sceneContext.objects[actor->objBankIndex].vramAddr + 0x80000000;
// TODO: PHYSICAL_TO_VIRTUAL macro
// TODO: Segment number enum
gRspSegmentPhysAddrs[6] = (void*)((u32)ctxt->sceneContext.objects[actor->objBankIndex].vramAddr + 0x80000000);
}
#ifdef NON_MATCHING

View File

@ -4,26 +4,29 @@
void Kanfont_Nop800F4F40(GlobalContext* ctxt, UNK_TYPE param_2, UNK_TYPE param_3) {}
void Kanfont_LoadAsciiChar(GlobalContext* ctxt, u8 character, s32 iParm3) {
DmaMgr_SendRequest0((u32)ctxt->msgCtx.font.unk0[(ctxt->msgCtx).unk11EF0] + iParm3,
// UB to convert pointer to u32
DmaMgr_SendRequest0((void*)((u32)&ctxt->msgCtx.font.unk0[(ctxt->msgCtx).unk11EF0] + iParm3),
(u32)&nes_font_static_vrom_start + character * 0x80 - 0x1000,
0x80);
}
void Kanfont_LoadMessageBoxEnd(Font* font, u16 type) {
DmaMgr_SendRequest0((u32)font->unk7800, type * 0x80 + (u32)&message_static_vrom_start + 0x5000, 0x80);
// UB to convert pointer to u32
DmaMgr_SendRequest0(&font->unk7800[0][0], type * 0x80 + (u32)&message_static_vrom_start + 0x5000, 0x80);
}
void Kanfont_LoadOrderedFont(Font* font) {
u32 loadOffset;
s32 codePointIndex = 0;
u32 writeLocation;
void* writeLocation;
while (1) {
writeLocation = (u32)&font->unk7800[codePointIndex + 1];
writeLocation = &font->unk7800[codePointIndex + 1];
loadOffset = kanfontOrdering[codePointIndex] * 128;
if (kanfontOrdering[codePointIndex] == 0) {
loadOffset = 0;
}
// UB to convert pointer to u32
DmaMgr_SendRequest0(writeLocation, (u32)&nes_font_static_vrom_start + loadOffset, 0x80);
if (kanfontOrdering[codePointIndex] == 140) break;
codePointIndex++;

View File

@ -606,30 +606,37 @@ f32 Lib_PushAwayVec3f(Vec3f* start, Vec3f* pusher, f32 distanceToApproach) {
void Lib_Nop801004FC(void) {}
u32 Lib_PtrSegToVirt(void* ptr) {
return(gRspSegmentPhysAddrs[((u32)ptr << 4) >> 28] + ((u32)ptr & 0xFFFFFF)) + 0x80000000;
void* Lib_PtrSegToVirt(void* ptr) {
// TODO: PHYSICAL_TO_VIRTUAL macro
// UB to cast the pointer to u32
return (void*)(((u32)gRspSegmentPhysAddrs[((u32)ptr << 4) >> 28] + ((u32)ptr & 0xFFFFFF)) + 0x80000000);
}
u32 Lib_PtrSegToVirtNull(void* ptr) {
void* Lib_PtrSegToVirtNull(void* ptr) {
// UB to cast the pointer to u32 in order to bitshift.
if (((u32)ptr >> 28) == 0) {
return (u32)ptr;
return ptr;
}
return(gRspSegmentPhysAddrs[((u32)ptr << 4) >> 28] + ((u32)ptr & 0xFFFFFF)) + 0x80000000;
// TODO: PHYSICAL_TO_VIRTUAL macro
// UB to cast the pointer to u32
return (void*)(((u32)gRspSegmentPhysAddrs[((u32)ptr << 4) >> 28] + ((u32)ptr & 0xFFFFFF)) + 0x80000000);
}
u32 Lib_PtrSegToK0(void* ptr) {
void* Lib_PtrSegToK0(void* ptr) {
if (ptr == NULL) {
return 0;
return NULL;
} else {
return (u32)ptr + 0x80000000;
// TODO: PHYSICAL_TO_VIRTUAL macro
return (void*)((u32)ptr + 0x80000000);
}
}
u32 Lib_PtrSegToK0Null(void* ptr) {
void* Lib_PtrSegToK0Null(void* ptr) {
if (ptr == NULL) {
return 0;
return NULL;
} else {
return (u32)ptr + 0x80000000;
// TODO: PHYSICAL_TO_VIRTUAL macro
return (void*)((u32)ptr + 0x80000000);
}
}

View File

@ -86,7 +86,7 @@ s32 Room_StartRoomTransition(GlobalContext* ctxt, RoomContext* roomCtxt, s32 ind
roomCtxt->unk31 = 1;
size = ctxt->roomAddrs[index].vromEnd - ctxt->roomAddrs[index].vromStart;
roomCtxt->activeRoomVram = ((s32)roomCtxt->roomMemPages[roomCtxt->activeMemPage] - (size + 8) * roomCtxt->activeMemPage + 8) & 0xfffffff0;
roomCtxt->activeRoomVram = (void*)((s32)roomCtxt->roomMemPages[roomCtxt->activeMemPage] - (size + 8) * roomCtxt->activeMemPage + 8) & 0xfffffff0;
osCreateMesgQueue(&roomCtxt->loadQueue, roomCtxt->loadMsg, 1);
DmaMgr_SendRequestImpl(&roomCtxt->dmaRequest, roomCtxt->activeRoomVram, ctxt->roomAddrs[index].vromStart, size,
@ -108,8 +108,10 @@ s32 Room_HandleLoadCallbacks(GlobalContext* ctxt, RoomContext* roomCtxt) {
if (!osRecvMesg(&roomCtxt->loadQueue, NULL, OS_MESG_NOBLOCK))
{
roomCtxt->unk31 = 0;
roomCtxt->currRoom.segment = (void*)(roomCtxt->activeRoomVram);
gRspSegmentPhysAddrs[3] = roomCtxt->activeRoomVram + 0x80000000;
roomCtxt->currRoom.segment = roomCtxt->activeRoomVram;
// TODO: PHYSICAL_TO_VIRTUAL macro
// TODO: Segment number enum
gRspSegmentPhysAddrs[3] = (void*)((u32)roomCtxt->activeRoomVram + 0x80000000);
Scene_ProcessHeader(ctxt, (SceneCmd*)roomCtxt->currRoom.segment);
func_80123140(ctxt, (ActorPlayer*)ctxt->actorCtx.actorList[2].first);
@ -133,7 +135,9 @@ s32 Room_HandleLoadCallbacks(GlobalContext* ctxt, RoomContext* roomCtxt) {
void Room_Draw(GlobalContext* ctxt, Room* room, u32 flags) {
if (room->segment != NULL) {
gRspSegmentPhysAddrs[3] = (u32)room->segment + 0x80000000;
// TODO: PHYSICAL_TO_VIRTUAL macro
// TODO: Segment number enum
gRspSegmentPhysAddrs[3] = (void*)((u32)room->segment + 0x80000000);
roomDrawFuncs[room->mesh->type0.type](ctxt, room, flags);
}
return;

View File

@ -2,14 +2,13 @@
#include <global.h>
/*
TODO: There are a few issues left with this file, but rely on larger structural project changes.
TODO:
There are a few issues left with this file, but many rely on larger structural project changes.
I am avoiding these in the mean time in order to not break the Ghidra project structures.
We need a header file for just z_scene. Including OBJECT_EXCHANGE_BANK_MAX and relevant structs, Scene, and Object enums.
We need a macro header file for ALIGN16, PHYSICAL_TO_VIRTUAL and other global macros.
We need to convert a lot of u32 struct members to void* to avoid UB.
u32 -> void*: gRspSegmentPhysAddrs, Lib_PtrSegToVirt, DmaMgr_SendRequest0, DmaMgr_SendRequestImpl
We need a header file for just z_scene. Including relevant structs, Scene, and Object enums.
The .data, .bss, and .rodata sections are not migrated to this file yet.
Additionally, the .data, .bss, and .rodata sections are not migrated to this file yet.
Additionally we need a macro header file for ALIGN16, PHYSICAL_TO_VIRTUAL, OBJECT_EXCHANGE_BANK_MAX and other global macros.
*/
s32 Scene_LoadObject(SceneContext* sceneCtxt, s16 id) {
@ -21,9 +20,7 @@ s32 Scene_LoadObject(SceneContext* sceneCtxt, s16 id) {
if (sceneCtxt) {}
if (size) {
// TODO: UB to convert vramAddr to u32
DmaMgr_SendRequest0((u32)sceneCtxt->objects[sceneCtxt->objectCount].vramAddr,
objectFileTable[id].vromStart, size);
DmaMgr_SendRequest0(sceneCtxt->objects[sceneCtxt->objectCount].vramAddr, objectFileTable[id].vromStart, size);
}
// TODO: This 0x22 is OBJECT_EXCHANGE_BANK_MAX - 1 in OOT
@ -71,7 +68,7 @@ void Scene_Init(GlobalContext* ctxt, SceneContext* sceneCtxt) {
sceneCtxt->mainKeepIndex = Scene_LoadObject(sceneCtxt, 1);
// TODO: PHYSICAL_TO_VIRTUAL macro
// TODO: Segment number enum
gRspSegmentPhysAddrs[4] = (u32)sceneCtxt->objects[sceneCtxt->mainKeepIndex].vramAddr + 0x80000000;
gRspSegmentPhysAddrs[4] = (void*)((u32)sceneCtxt->objects[sceneCtxt->mainKeepIndex].vramAddr + 0x80000000);
}
void Scene_ReloadUnloadedObjects(SceneContext* sceneCtxt) {
@ -92,8 +89,7 @@ void Scene_ReloadUnloadedObjects(SceneContext* sceneCtxt) {
status->id = 0;
} else {
osCreateMesgQueue(&status->loadQueue, &status->loadMsg, 1);
// TODO: UB to cast pointer to u32
DmaMgr_SendRequestImpl(&status->dmaReq, (u32)status->vramAddr, objectFile->vromStart,
DmaMgr_SendRequestImpl(&status->dmaReq, status->vramAddr, objectFile->vromStart,
size, 0, &status->loadQueue, NULL);
}
} else if (!osRecvMesg(&status->loadQueue, NULL, OS_MESG_NOBLOCK)) {
@ -135,8 +131,7 @@ void Scene_DmaAllObjects(SceneContext* sceneCtxt) {
continue;
}
// TODO: UB to cast void* to u32
DmaMgr_SendRequest0((u32)sceneCtxt->objects[i].vramAddr, objectFileTable[id].vromStart, vromSize);
DmaMgr_SendRequest0(sceneCtxt->objects[i].vramAddr, objectFileTable[id].vromStart, vromSize);
}
}
@ -242,9 +237,9 @@ void Scene_HeaderCommand07(GlobalContext* ctxt, SceneCmd* entry) {
ctxt->sceneContext.keepObjectId = Scene_LoadObject(&ctxt->sceneContext,
entry->specialFiles.keepObjectId);
// TODO: PHYSICAL_TO_VIRTUAL macro
// TODO: Segment number enum
gRspSegmentPhysAddrs[5] = (u32)(ctxt->sceneContext.objects[ctxt->sceneContext.keepObjectId].vramAddr)
+ 0x80000000;
// TODO: Segment number enum
gRspSegmentPhysAddrs[5] = (void*)((u32)(ctxt->sceneContext.objects[ctxt->sceneContext.keepObjectId].vramAddr)
+ 0x80000000);
}
if (entry->specialFiles.cUpElfMsgNum != 0) {
@ -358,8 +353,7 @@ s32 func_8012FF10(GlobalContext* ctxt, s32 fileIndex) {
if (fileSize) {
ctxt->roomContext.unk74 = GameStateHeap_AllocFromEnd(&ctxt->state.heap, fileSize);
// TODO: UB to cast pointer to u32
return DmaMgr_SendRequest0((u32)ctxt->roomContext.unk74, vromStart, fileSize);
return DmaMgr_SendRequest0(ctxt->roomContext.unk74, vromStart, fileSize);
}
// UB: Undefined behaviour to not have a return statement here, but it breaks matching to add one.