Enforce function pointers types in dynos
Some checks failed
Build coop / build-linux (push) Has been cancelled
Build coop / build-steamos (push) Has been cancelled
Build coop / build-windows-opengl (push) Has been cancelled
Build coop / build-windows-directx (push) Has been cancelled
Build coop / build-macos-arm (push) Has been cancelled
Build coop / build-macos-intel (push) Has been cancelled

geo layouts -> geo_* functions only
behaviors -> bhv_* functions only
level scripts -> lvl_* functions only
other -> no function allowed

thanks maniscat for reporting the issue
This commit is contained in:
PeachyPeachSM64 2025-08-17 19:27:41 +02:00
parent 7405ae7244
commit b671458f81
9 changed files with 765 additions and 669 deletions

View file

@ -17,6 +17,10 @@ extern "C" {
#define LUA_VAR_CODE (u32) 0x5641554C
#define TEX_REF_CODE (u32) 0x52584554
#define FUNCTION_GEO 1
#define FUNCTION_BHV 2
#define FUNCTION_LVL 3
#define MOD_PACK_INDEX 99
//
@ -864,10 +868,13 @@ const char* DynOS_Builtin_Tex_GetFromData(const Texture* aData);
const char* DynOS_Builtin_Tex_GetNameFromFileName(const char* aDataName);
const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromName(const char* aDataName);
const struct BuiltinTexInfo* DynOS_Builtin_Tex_GetInfoFromData(const Texture* aData);
const void* DynOS_Builtin_Func_GetFromName(const char* aDataName);
const void* DynOS_Builtin_Func_GetFromIndex(s32 aIndex);
const char * DynOS_Builtin_Func_GetNameFromIndex(s64 aIndex);
s32 DynOS_Builtin_Func_GetIndexFromData(const void* aData);
const void* DynOS_Builtin_Func_GetFromName(const char* aDataName, u8 aFuncType);
const void* DynOS_Builtin_Func_GetFromIndex(s32 aIndex, u8 aFuncType);
const char * DynOS_Builtin_Func_GetNameFromIndex(s32 aIndex, u8 aFuncType);
s32 DynOS_Builtin_Func_GetIndexFromData(const void* aData, u8 aFuncType);
String DynOS_Builtin_Func_CheckMisuse(s32 aIndex, u8 aFuncType);
String DynOS_Builtin_Func_CheckMisuse(const char* aDataName, u8 aFuncType);
String DynOS_Builtin_Func_CheckMisuse(const void* aData, u8 aFuncType);
const Gfx * DynOS_Builtin_Gfx_GetFromName(const char *aDataName);
const char * DynOS_Builtin_Gfx_GetFromData(const Gfx *aData);
@ -1100,8 +1107,8 @@ void DynOS_Vtx_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Vtx> *aNode);
void DynOS_Vtx_Load(BinFile *aFile, GfxData *aGfxData);
void DynOS_Pointer_Lua_Write(BinFile* aFile, u32 index, GfxData* aGfxData);
void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData);
void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags);
void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData, u8 aFuncType);
void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8 aFuncType, u8* outFlags);
void DynOS_GfxDynCmd_Load(BinFile *aFile, GfxData *aGfxData);

View file

@ -1937,10 +1937,16 @@ static BehaviorScript ParseBehaviorScriptSymbolArgInternal(GfxData *aGfxData, Da
}
// Built-in functions
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin());
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin(), FUNCTION_BHV);
if (_FunctionPtr != NULL) {
return (s64) _FunctionPtr;
}
String error = DynOS_Builtin_Func_CheckMisuse(_Arg.begin(), FUNCTION_BHV);
if (!error.Empty()) {
PrintDataError(" ERROR: %s", error.begin());
*found = false;
return 0;
}
// Built-in actors
auto builtinActor = DynOS_Builtin_Actor_GetFromName(_Arg.begin());
@ -2490,7 +2496,7 @@ static void DynOS_Bhv_Write(BinFile* aFile, GfxData* aGfxData, DataNode<Behavior
for (u32 i = 0; i != aNode->mSize; ++i) {
BehaviorScript *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData);
DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData, FUNCTION_BHV);
} else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData);
} else {
@ -2578,7 +2584,7 @@ static DataNode<BehaviorScript> *DynOS_Bhv_Load(BinFile *aFile, GfxData *aGfxDat
break;
}
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_BHV, &_Node->mFlags);
if (_Ptr) {
_Node->mData[i] = (uintptr_t) _Ptr;
} else {

View file

@ -105,10 +105,15 @@ static s64 ParseGeoSymbolArg(GfxData* aGfxData, DataNode<GeoLayout>* aNode, u64&
}
// Built-in functions
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin());
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin(), FUNCTION_GEO);
if (_FunctionPtr != NULL) {
return (s64) _FunctionPtr;
}
String error = DynOS_Builtin_Func_CheckMisuse(_Arg.begin(), FUNCTION_GEO);
if (!error.Empty()) {
PrintDataError(" ERROR: %s", error.begin());
return 0;
}
// Constants
bool constantFound = false;
@ -321,13 +326,18 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay
s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex);
const String& _Arg1 = aNode->mTokens[aTokenIndex++];
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin());
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin(), FUNCTION_GEO);
if (_FunctionPtr != NULL) {
aGfxData->mPointerList.Add(aHead + 1);
GeoLayout _Gl[] = { GEO_ASM(_Arg0, _FunctionPtr) };
memcpy(aHead, _Gl, sizeof(_Gl));
aHead += (sizeof(_Gl) / sizeof(_Gl[0]));
} else {
String error = DynOS_Builtin_Func_CheckMisuse(_Arg1.begin(), FUNCTION_GEO);
if (!error.Empty()) {
PrintDataError(" ERROR: %s", error.begin());
return;
}
u32 _FuncIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, _Arg1);
GeoLayout _Gl[] = { GEO_ASM_EXT(_Arg0, _FuncIndex) };
memcpy(aHead, _Gl, sizeof(_Gl));
@ -345,13 +355,18 @@ static void ParseGeoSymbol(GfxData* aGfxData, DataNode<GeoLayout>* aNode, GeoLay
s64 _Arg0 = ParseGeoSymbolArg(aGfxData, aNode, aTokenIndex);
const String& _Arg1 = aNode->mTokens[aTokenIndex++];
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin());
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg1.begin(), FUNCTION_GEO);
if (_FunctionPtr != NULL) {
aGfxData->mPointerList.Add(aHead + 1);
GeoLayout _Gl[] = { GEO_SWITCH_CASE(_Arg0, _FunctionPtr) };
memcpy(aHead, _Gl, sizeof(_Gl));
aHead += (sizeof(_Gl) / sizeof(_Gl[0]));
} else {
String error = DynOS_Builtin_Func_CheckMisuse(_Arg1.begin(), FUNCTION_GEO);
if (!error.Empty()) {
PrintDataError(" ERROR: %s", error.begin());
return;
}
u32 _FuncIndex = DynOS_Lua_RememberVariable(aGfxData, aHead + 1, _Arg1);
GeoLayout _Gl[] = { GEO_SWITCH_CASE_EXT(_Arg0, _FuncIndex) };
memcpy(aHead, _Gl, sizeof(_Gl));
@ -471,7 +486,7 @@ void DynOS_Geo_Write(BinFile *aFile, GfxData *aGfxData, DataNode<GeoLayout> *aNo
for (u32 i = 0; i != aNode->mSize; ++i) {
GeoLayout *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData);
DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData, FUNCTION_GEO);
} else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData);
} else {
@ -495,7 +510,7 @@ void DynOS_Geo_Load(BinFile *aFile, GfxData *aGfxData) {
_Node->mData = New<GeoLayout>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_GEO, &_Node->mFlags);
if (_Ptr) {
_Node->mData[i] = (uintptr_t) _Ptr;
} else {

View file

@ -1104,7 +1104,7 @@ void DynOS_Gfx_Write(BinFile *aFile, GfxData *aGfxData, DataNode<Gfx> *aNode) {
Gfx *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
aFile->Write<u32>(_Head->words.w0);
DynOS_Pointer_Write(aFile, (const void *) _Head->words.w1, aGfxData);
DynOS_Pointer_Write(aFile, (const void *) _Head->words.w1, aGfxData, 0);
} else {
aFile->Write<u32>(_Head->words.w0);
aFile->Write<u32>(_Head->words.w1);
@ -1127,7 +1127,7 @@ void DynOS_Gfx_Load(BinFile *aFile, GfxData *aGfxData) {
for (u32 i = 0; i != _Node->mSize; ++i) {
u32 _WordsW0 = aFile->Read<u32>();
u32 _WordsW1 = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _WordsW1, &_Node->mFlags);
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _WordsW1, 0, &_Node->mFlags);
if (_Ptr) {
_Node->mData[i].words.w0 = (uintptr_t) _WordsW0;
_Node->mData[i].words.w1 = (uintptr_t) _Ptr;

View file

@ -409,10 +409,16 @@ static LevelScript ParseLevelScriptSymbolArgInternal(GfxData* aGfxData, DataNode
}
// Built-in functions
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin());
const void *_FunctionPtr = DynOS_Builtin_Func_GetFromName(_Arg.begin(), FUNCTION_LVL);
if (_FunctionPtr != NULL) {
return (s64) _FunctionPtr;
}
String error = DynOS_Builtin_Func_CheckMisuse(_Arg.begin(), FUNCTION_LVL);
if (!error.Empty()) {
PrintDataError(" ERROR: %s", error.begin());
*found = false;
return 0;
}
bool constantFound = false;
s64 constantValue = DynOS_Lvl_ParseLevelScriptConstants(_Arg, &constantFound);
@ -926,7 +932,7 @@ static void DynOS_Lvl_Write(BinFile* aFile, GfxData* aGfxData, DataNode<LevelScr
for (u32 i = 0; i != aNode->mSize; ++i) {
LevelScript *_Head = &aNode->mData[i];
if (aGfxData->mPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData);
DynOS_Pointer_Write(aFile, (const void *) (*_Head), aGfxData, FUNCTION_LVL);
} else if (aGfxData->mLuaPointerList.Find((void *) _Head) != -1) {
DynOS_Pointer_Lua_Write(aFile, *(u32 *)_Head, aGfxData);
} else {
@ -1055,7 +1061,7 @@ static DataNode<LevelScript>* DynOS_Lvl_Load(BinFile *aFile, GfxData *aGfxData)
bool requirePointer = DynOS_Lvl_Validate_RequirePointer(_Value);
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, FUNCTION_LVL, &_Node->mFlags);
if (_Ptr) {
if (!requirePointer) {
PrintError("Didn't expect a pointer while reading level script: %s, %u", _Node->mName.begin(), _Value);

View file

@ -64,7 +64,7 @@ void DynOS_MovtexQC_Write(BinFile* aFile, GfxData* aGfxData, DataNode<MovtexQC>
aFile->Write<u32>(aNode->mSize);
for (u32 i = 0; i != aNode->mSize; ++i) {
aFile->Write<s16>(aNode->mData[i].id);
DynOS_Pointer_Write(aFile, (const void *) (aNode->mData[i].quadArraySegmented), aGfxData);
DynOS_Pointer_Write(aFile, (const void *) (aNode->mData[i].quadArraySegmented), aGfxData, 0);
}
}
@ -84,7 +84,7 @@ DataNode<MovtexQC>* DynOS_MovtexQC_Load(BinFile *aFile, GfxData *aGfxData) {
for (u32 i = 0; i != _Node->mSize; ++i) {
_Node->mData[i].id = aFile->Read<s16>();
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, 0, &_Node->mFlags);
_Node->mData[i].quadArraySegmented = (Movtex*)_Ptr;
}

View file

@ -209,7 +209,7 @@ void DynOS_Pointer_Lua_Write(BinFile* aFile, u32 index, GfxData* aGfxData) {
token.Write(aFile);
}
void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData) {
void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData, u8 aFuncType) {
// NULL
if (!aPtr) {
@ -229,10 +229,15 @@ void DynOS_Pointer_Write(BinFile* aFile, const void* aPtr, GfxData* aGfxData) {
}
// Built-in functions
s32 _GeoFunctionIndex = DynOS_Builtin_Func_GetIndexFromData(aPtr);
if (_GeoFunctionIndex != -1) {
s32 _FunctionIndex = DynOS_Builtin_Func_GetIndexFromData(aPtr, aFuncType);
if (_FunctionIndex != -1) {
aFile->Write<u32>(FUNCTION_CODE);
aFile->Write<s32>(_GeoFunctionIndex);
aFile->Write<s32>(_FunctionIndex);
return;
}
String error = DynOS_Builtin_Func_CheckMisuse(aPtr, aFuncType);
if (!error.Empty()) {
PrintDataError(" ERROR: %s", error.begin());
return;
}
@ -451,7 +456,7 @@ static void *GetPointerFromData(GfxData *aGfxData, const String &aPtrName, u32 a
return NULL;
}
void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outFlags) {
void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8 aFuncType, u8* outFlags) {
// LUAV
if (aValue == LUA_VAR_CODE) {
@ -469,13 +474,23 @@ void *DynOS_Pointer_Load(BinFile *aFile, GfxData *aGfxData, u32 aValue, u8* outF
// FUNC
if (aValue == FUNCTION_CODE) {
s32 _FunctionIndex = aFile->Read<s32>();
return (void*) DynOS_Builtin_Func_GetFromIndex(_FunctionIndex);
void *_FunctionPtr = (void*) DynOS_Builtin_Func_GetFromIndex(_FunctionIndex, aFuncType);
if (_FunctionPtr) {
return _FunctionPtr;
}
String error = DynOS_Builtin_Func_CheckMisuse(_FunctionIndex, aFuncType);
if (!error.Empty()) {
sys_fatal(error.begin());
return NULL;
}
sys_fatal("Invalid function index: %d", _FunctionIndex);
return NULL;
}
// PNTR
if (aValue == POINTER_CODE) {
String _PtrName; _PtrName.Read(aFile);
u32 _PtrData = aFile->Read<u32>();
u32 _PtrData = aFile->Read<u32>();
return GetPointerFromData(aGfxData, _PtrName, _PtrData, outFlags);
}

View file

@ -50,7 +50,7 @@ void DynOS_TexList_Write(BinFile* aFile, GfxData* aGfxData, DataNode<TexData*> *
bool found = false;
for (auto& _Node : aGfxData->mTextures) {
if (_Node->mData == aNode->mData[i]) {
DynOS_Pointer_Write(aFile, (const void *) (_Node), aGfxData);
DynOS_Pointer_Write(aFile, (const void *) (_Node), aGfxData, 0);
found = true;
break;
}
@ -76,7 +76,7 @@ DataNode<TexData*>* DynOS_TexList_Load(BinFile *aFile, GfxData *aGfxData) {
_Node->mData = New<TexData*>(_Node->mSize);
for (u32 i = 0; i != _Node->mSize; ++i) {
u32 _Value = aFile->Read<u32>();
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, &_Node->mFlags);
void *_Ptr = DynOS_Pointer_Load(aFile, aGfxData, _Value, 0, &_Node->mFlags);
if (_Ptr == NULL) {
PrintDataError("Could not read texture in texlist");
} else {

File diff suppressed because it is too large Load diff