Add all the files

This commit is contained in:
Exzap 2022-08-22 22:21:23 +02:00
parent e3db07a16a
commit d60742f52b
1445 changed files with 430238 additions and 0 deletions

129
src/Cafe/OS/RPL/elf.cpp Normal file
View file

@ -0,0 +1,129 @@
#include <zlib.h>
#include "Cafe/OS/RPL/rpl.h"
#include "Cafe/OS/RPL/rpl_structs.h"
#include "util/VirtualHeap/VirtualHeap.h"
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
#include "Cafe/HW/Espresso/Debugger/Debugger.h"
typedef struct
{
/* +0x00 */ uint32be magic;
/* +0x04 */ uint8 eiClass;
/* +0x05 */ uint8 eiData;
/* +0x06 */ uint8 eiVersion;
/* +0x07 */ uint8 eiOSABI;
/* +0x08 */ uint8 eiOSABIVersion;
/* +0x09 */ uint8 eiPadding[7];
/* +0x10 */ uint16be eType;
/* +0x12 */ uint16be eMachine;
/* +0x14 */ uint32be eVersion;
/* +0x18 */ uint32be entrypoint;
/* +0x1C */ uint32be phOffset;
/* +0x20 */ uint32be shOffset;
/* +0x24 */ uint32be eFlags;
/* +0x28 */ uint16be eHeaderSize;
/* +0x2A */ uint16be ePHEntrySize;
/* +0x2C */ uint16be ePHNum;
/* +0x2E */ uint16be eSHEntrySize;
/* +0x30 */ uint16be eSHNum;
/* +0x32 */ uint16be eShStrIndex;
}elfHeader_t;
static_assert(sizeof(elfHeader_t) == 0x34, "");
typedef struct
{
/* +0x00 */ uint32be nameOffset;
/* +0x04 */ uint32be shType;
/* +0x08 */ uint32be shFlags;
/* +0x0C */ uint32be shAddr;
/* +0x10 */ uint32be shOffset;
/* +0x14 */ uint32be shSize;
/* +0x18 */ uint32be shLink;
/* +0x1C */ uint32be shInfo;
/* +0x20 */ uint32be shAddrAlign;
/* +0x24 */ uint32be shEntSize;
}elfSectionEntry_t;
static_assert(sizeof(elfSectionEntry_t) == 0x28, "");
// Map elf into memory
uint32 ELF_LoadFromMemory(uint8* elfData, sint32 size, const char* name)
{
elfHeader_t* header = (elfHeader_t*)elfData;
uint32 sectionCount = header->eSHNum;
uint32 sectionTableOffset = header->shOffset;
uint32 sectionTableEntrySize = header->eSHEntrySize;
elfSectionEntry_t* sectionTable = (elfSectionEntry_t*)(elfData + (uint32)header->shOffset);
memory_enableHBLELFCodeArea();
for (uint32 i = 0; i < sectionCount; i++)
{
debug_printf("%02d Addr %08x Size %08x Offs %08x Flags %08x Type %08x EntSize %08x\n", i, (uint32)sectionTable[i].shAddr, (uint32)sectionTable[i].shSize, (uint32)sectionTable[i].shOffset, (uint32)sectionTable[i].shFlags, (uint32)sectionTable[i].shType, (uint32)sectionTable[i].shEntSize);
uint32 shAddr = (uint32)sectionTable[i].shAddr;
uint32 shSize = (uint32)sectionTable[i].shSize;
uint32 shOffset = (uint32)sectionTable[i].shOffset;
uint32 shType = (uint32)sectionTable[i].shType;
if (shOffset > (uint32)size)
{
forceLog_printf("ELF section %d out of bounds", i);
continue;
}
uint32 copySize = std::min(shSize, size - shOffset);
// 0x00802000
if (shAddr != 0)
{
if (shType == SHT_NOBITS)
{
memset(memory_getPointerFromVirtualOffset(shAddr), 0, shSize);
}
else
{
memcpy(memory_getPointerFromVirtualOffset(shAddr), elfData + shOffset, copySize);
}
// SHT_NOBITS
}
}
return header->entrypoint;
}
// From Homebrew Launcher:
//#define MEM_BASE (0x00800000)
//#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00))
//#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04))
//#define HBL_CHANNEL (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x08))
//#define RPX_MAX_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x0C))
//#define RPX_MAX_CODE_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x10))
//#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00))
//#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04))
//
//#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500))
//
//#define MEM_AREA_TABLE ((s_mem_area*)(MEM_BASE + 0x1600))
//typedef struct _OsSpecifics
//{
// unsigned int addr_OSDynLoad_Acquire;
// unsigned int addr_OSDynLoad_FindExport;
// unsigned int addr_OSTitle_main_entry;
//
// unsigned int addr_KernSyscallTbl1;
// unsigned int addr_KernSyscallTbl2;
// unsigned int addr_KernSyscallTbl3;
// unsigned int addr_KernSyscallTbl4;
// unsigned int addr_KernSyscallTbl5;
//
// int(*LiWaitIopComplete)(int, int *);
// int(*LiWaitIopCompleteWithInterrupts)(int, int *);
// unsigned int addr_LiWaitOneChunk;
// unsigned int addr_PrepareTitle_hook;
// unsigned int addr_sgIsLoadingBuffer;
// unsigned int addr_gDynloadInitialized;
// unsigned int orig_LiWaitOneChunkInstr;
//} OsSpecifics;

2389
src/Cafe/OS/RPL/rpl.cpp Normal file

File diff suppressed because it is too large Load diff

55
src/Cafe/OS/RPL/rpl.h Normal file
View file

@ -0,0 +1,55 @@
#pragma once
struct RPLModule;
#define RPL_INVALID_HANDLE (0xFFFFFFFF)
void RPLLoader_InitState();
void RPLLoader_ResetState();
uint8* RPLLoader_AllocateTrampolineCodeSpace(sint32 size);
MPTR RPLLoader_AllocateCodeSpace(uint32 size, uint32 alignment);
uint32 RPLLoader_GetMaxCodeOffset();
uint32 RPLLoader_GetDataAllocatorAddr();
__declspec(dllexport) RPLModule* rpl_loadFromMem(uint8* rplData, sint32 size, char* name);
uint32 rpl_mapHLEImport(RPLModule* rplLoaderContext, const char* rplName, const char* funcName, bool functionMustExist);
void RPLLoader_Link();
MPTR RPLLoader_FindRPLExport(RPLModule* rplLoaderContext, const char* symbolName, bool isData);
uint32 RPLLoader_GetModuleEntrypoint(RPLModule* rplLoaderContext);
void RPLLoader_SetMainModule(RPLModule* rplLoaderContext);
uint32 RPLLoader_GetMainModuleHandle();
void RPLLoader_CallEntrypoints();
void RPLLoader_NotifyControlPassedToApplication();
void RPLLoader_AddDependency(const char* name);
void RPLLoader_RemoveDependency(uint32 handle);
void RPLLoader_UpdateDependencies();
uint32 RPLLoader_GetHandleByModuleName(const char* name);
uint32 RPLLoader_GetMaxTLSModuleIndex();
bool RPLLoader_GetTLSDataByTLSIndex(sint16 tlsModuleIndex, uint8** tlsData, sint32* tlsSize);
uint32 RPLLoader_FindModuleOrHLEExport(uint32 moduleHandle, bool isData, const char* exportName);
uint32 RPLLoader_GetSDA1Base();
uint32 RPLLoader_GetSDA2Base();
sint32 RPLLoader_GetModuleCount();
RPLModule** RPLLoader_GetModuleList();
MEMPTR<void> RPLLoader_AllocateCodeCaveMem(uint32 alignment, uint32 size);
void RPLLoader_ReleaseCodeCaveMem(MEMPTR<void> addr);
// exports
uint32 RPLLoader_MakePPCCallable(void(*ppcCallableExport)(struct PPCInterpreter_t* hCPU));
// elf loader
uint32 ELF_LoadFromMemory(uint8* elfData, sint32 size, const char* name);

View file

@ -0,0 +1,21 @@
#include "Cafe/OS/RPL/rpl_debug_symbols.h"
std::map<MPTR, rplDebugSymbolBase*> map_DebugSymbols;
void rplDebugSymbol_createComment(MPTR address, const wchar_t* comment)
{
auto new_comment = new rplDebugSymbolComment();
new_comment->type = RplDebugSymbolComment;
new_comment->comment = comment;
map_DebugSymbols[address] = new_comment;
}
rplDebugSymbolBase* rplDebugSymbol_getForAddress(MPTR address)
{
return map_DebugSymbols[address];
}
const std::map<MPTR, rplDebugSymbolBase*>& rplDebugSymbol_getSymbols()
{
return map_DebugSymbols;
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <map>
enum RplDebugSymbolType : uint8
{
RplDebugSymbolComment = 0,
};
struct rplDebugSymbolBase
{
RplDebugSymbolType type;
rplDebugSymbolBase* next;
};
struct rplDebugSymbolComment : rplDebugSymbolBase
{
std::wstring comment;
};
void rplDebugSymbol_createComment(MPTR address, const wchar_t* comment);
rplDebugSymbolBase* rplDebugSymbol_getForAddress(MPTR address);
const std::map<MPTR, rplDebugSymbolBase*>& rplDebugSymbol_getSymbols();

View file

@ -0,0 +1,258 @@
#pragma once
#include "util/ChunkedHeap/ChunkedHeap.h"
#define RPL_MODULE_NAME_LENGTH 64
#define RPL_MODULE_PATH_LENGTH 256
// types
#define SHT_RPL_EXPORTS (0x80000001)
#define SHT_RPL_IMPORTS (0x80000002)
#define SHT_RPL_CRCS (0x80000003)
#define SHT_RPL_FILEINFO (0x80000004)
#define SHT_PROGBITS (0x00000001)
#define SHT_SYMTAB (0x00000002)
#define SHT_STRTAB (0x00000003)
#define SHT_RELA (0x00000004)
#define SHT_HASH (0x00000005)
#define SHT_DYNAMIC (0x00000006)
#define SHT_NOTE (0x00000007)
#define SHT_NOBITS (0x00000008) // this section contains no data
#define SHT_REL (0x00000009)
#define SHT_SHLIB (0x0000000A)
#define SHT_DYNSYM (0x0000000B)
// flags
#define SHF_EXECUTE 0x00000004
#define SHF_RPL_COMPRESSED 0x08000000
#define SHF_TLS 0x04000000
// relocs
#define RPL_RELOC_ADDR32 1
#define RPL_RELOC_LO16 4
#define RPL_RELOC_HI16 5
#define RPL_RELOC_HA16 6
#define RPL_RELOC_REL24 10
#define RPL_RELOC_REL14 11
#define R_PPC_DTPMOD32 68
#define R_PPC_DTPREL32 78
#define R_PPC_REL16_HA 251
#define R_PPC_REL16_HI 252
#define R_PPC_REL16_LO 253
#define HLE_MODULE_PTR ((RPLModule*)-1)
typedef struct
{
/* +0x00 */ uint32be relocOffset;
/* +0x04 */ uint32be symbolIndexAndType;
/* +0x08 */ uint32be relocAddend;
}rplRelocNew_t;
typedef struct
{
/* +0x00 */ uint32be nameOffset;
/* +0x04 */ uint32be type;
/* +0x08 */ uint32be flags;
/* +0x0C */ uint32be virtualAddress;
/* +0x10 */ uint32be fileOffset;
/* +0x14 */ uint32be sectionSize;
/* +0x18 */ uint32be symtabSectionIndex;
/* +0x1C */ uint32be relocTargetSectionIndex;
/* +0x20 */ uint32be alignment;
/* +0x24 */ uint32be ukn24; // for symtab: Size of each symbol entry
}rplSectionEntryNew_t;
typedef struct
{
/* +0x00 */ uint32be magic1;
/* +0x04 */ uint8 version04; // probably version?
/* +0x05 */ uint8 ukn05; // probably version?
/* +0x06 */ uint8 ukn06; // probably version?
/* +0x07 */ uint8 magic2_0; // part of second magic
/* +0x08 */ uint8 magic2_1; // part of second magic
/* +0x09 */ uint8 ukn09;
/* +0x0A */ uint8 ukn0A;
/* +0x0B */ uint8 ukn0B;
/* +0x0C */ uint32be dataRegionSize;
/* +0x10 */ uint8 ukn10;
/* +0x11 */ uint8 ukn11;
/* +0x12 */ uint16be ukn12;
/* +0x14 */ uint32be ukn14;
/* +0x18 */ uint32be entrypoint;
/* +0x1C */ uint32be ukn1C;
/* +0x20 */ uint32be sectionTableOffset;
/* +0x24 */ uint32be ukn24;
/* +0x28 */ uint16be ukn28;
/* +0x2A */ uint16be programHeaderTableEntrySize;
/* +0x2C */ uint16be programHeaderTableEntryCount;
/* +0x2E */ uint16be sectionTableEntrySize;
/* +0x30 */ uint16be sectionTableEntryCount;
/* +0x32 */ uint16be nameSectionIndex;
}rplHeaderNew_t;
static_assert(offsetof(rplHeaderNew_t, dataRegionSize) == 0xC);
static_assert(offsetof(rplHeaderNew_t, programHeaderTableEntrySize) == 0x2A);
typedef struct
{
/* +0x00 */ uint32be fileInfoMagic; // always 0xCAFE0402
/* +0x04 */ uint32be textRegionSize; // text region size
/* +0x08 */ uint32be ukn08; // base align text
/* +0x0C */ uint32be dataRegionSize; // size of data sections
/* +0x10 */ uint32be baseAlign; // base align data?
/* +0x14 */ uint32be ukn14;
/* +0x18 */ uint32be ukn18;
/* +0x1C */ uint32be ukn1C;
/* +0x20 */ uint32be trampolineAdjustment;
/* +0x24 */ uint32be sdataBase1;
/* +0x28 */ uint32be sdataBase2;
/* +0x2C */ uint32be ukn2C;
/* +0x30 */ uint32be ukn30;
/* +0x34 */ uint32be ukn34;
/* +0x38 */ uint32be ukn38;
/* +0x3C */ uint32be ukn3C;
/* +0x40 */ uint32be toolkitVersion;
/* +0x44 */ uint32be ukn44;
/* +0x48 */ uint32be ukn48;
/* +0x4C */ uint32be ukn4C;
/* +0x50 */ uint32be ukn50;
/* +0x54 */ uint32be ukn54;
/* +0x58 */ sint16be tlsModuleIndex;
}RPLFileInfoData;
static_assert(offsetof(RPLFileInfoData, tlsModuleIndex) == 0x58);
typedef struct
{
//uint32 address;
void* ptr;
}rplSectionAddressEntry_t;
typedef struct
{
uint32be virtualOffset;
uint32be nameOffset;
}rplExportTableEntry_t;
struct RPLModule
{
uint32 ukn00; // pointer to shared memory region? (0xEFE01000)
uint32 ukn04; // related to text region size?
char* moduleNamePtr__depr; // converted to lower case
uint32 moduleNameLength__depr; // length of module name
uint32 moduleNameSize; // aligned alloc size, not the same as actual length
uint32 padding14;
uint32 padding18;
rplHeaderNew_t rplHeader;
rplSectionEntryNew_t* sectionTablePtr; // copy of section table
RPLFileInfoData* fileInfoPtr__depr{}; // copy of fileinfo section
uint32 fileInfoSize__depr{}; // size of fileInfo section
uint32 fileInfoAllocSize__depr{}; // aligned alloc size
uint32be* crcTablePtr_depr{}; // copy of CRC section
uint32 crcTableAllocSize_depr{};
uint32 entrypoint;
uint8* rplData_depr; // Cemuhook might still read this
MPTR textRegionTemp; // temporary memory for text section?
MEMPTR<void> regionMappingBase_text; // base destination address for text region
MPTR regionMappingBase_data; // base destination address for data region
MPTR regionMappingBase_loaderInfo; // base destination address for loaderInfo region
uint8* tempRegionPtr;
uint32 tempRegionAllocSize;
rplSectionAddressEntry_t* sectionAddressTable__depr;
uint32 sectionAddressTableSize__depr;
uint32 exportDCount;
rplExportTableEntry_t* exportDDataPtr;
uint32 exportFCount;
rplExportTableEntry_t* exportFDataPtr;
/* above are hardcoded in Cemuhook */
std::string moduleName2;
std::vector<rplSectionAddressEntry_t> sectionAddressTable2;
uint32 tlsStartAddress;
uint32 tlsEndAddress;
uint32 regionSize_text;
uint32 regionSize_data;
uint32 regionSize_loaderInfo;
uint32 patchCRC; // Cemuhook style module crc for patches.txt
// trampoline management
ChunkedFlatAllocator<16 * 1024> heapTrampolineArea;
std::unordered_map<MPTR, MPTR> trampolineMap;
// section data
std::vector<uint8> sectionData_fileInfo;
std::vector<uint8> sectionData_crc;
// parsed FILEINFO
struct
{
uint32 textRegionSize; // size of region containing all text sections
//uint32 ukn08; // base align text?
uint32 dataRegionSize; // size of region containing all data sections
uint32 baseAlign;
uint32 ukn14;
uint32 trampolineAdjustment;
uint32 ukn4C;
sint16 tlsModuleIndex;
uint32 sdataBase1;
uint32 sdataBase2;
}fileInfo;
// parsed CRC
std::vector<uint32> crcTable;
uint32 GetSectionCRC(size_t sectionIndex) const
{
if (sectionIndex >= crcTable.size())
return 0;
return crcTable[sectionIndex];
}
// state
bool isLinked; // set to true if _linkModule was called on this module
bool entrypointCalled; // set if entrypoint was called
// allocator
betype<MPTR> funcAlloc;
betype<MPTR> funcFree;
// replaces rplData ptr
std::span<uint8> RPLRawData;
bool debugSectionLoadMask[128] = { false };
bool hasError{ false };
};
typedef struct
{
char modulename[RPL_MODULE_NAME_LENGTH];
char filepath[RPL_MODULE_PATH_LENGTH];
bool loadAttempted;
//bool isHLEModule; // determined to be a HLE module
RPLModule* rplLoaderContext; // context of loaded module
sint32 referenceCount;
uint32 coreinitHandle; // fake handle for coreinit
sint16 tlsModuleIndex; // tls module index assigned to this dependency
}rplDependency_t;
RPLModule* RPLLoader_FindModuleByCodeAddr(uint32 addr);
RPLModule* RPLLoader_FindModuleByDataAddr(uint32 addr);
RPLModule* RPLLoader_FindModuleByName(std::string module);

View file

@ -0,0 +1,150 @@
#include "Cafe/OS/RPL/rpl.h"
#include "Cafe/OS/RPL/rpl_symbol_storage.h"
struct rplSymbolLib_t
{
char* libName;
rplSymbolLib_t* next;
};
struct
{
rplSymbolLib_t* libs;
std::mutex m_symbolStorageMutex;
std::unordered_map<uint32, RPLStoredSymbol*> map_symbolByAddress;
// allocator for strings
char* strAllocatorBlock;
sint32 strAllocatorOffset;
std::vector<void*> list_strAllocatedBlocks;
}rplSymbolStorage = { 0 };
#define STR_ALLOC_BLOCK_SIZE (128*1024) // allocate 128KB blocks at once
char* rplSymbolStorage_allocDupString(const char* str)
{
sint32 len = (sint32)strlen(str);
if (rplSymbolStorage.strAllocatorBlock == nullptr || (rplSymbolStorage.strAllocatorOffset + len + 1) >= STR_ALLOC_BLOCK_SIZE)
{
// allocate new block
rplSymbolStorage.strAllocatorBlock = (char*)malloc(STR_ALLOC_BLOCK_SIZE);
rplSymbolStorage.strAllocatorOffset = 0;
rplSymbolStorage.list_strAllocatedBlocks.emplace_back(rplSymbolStorage.strAllocatorBlock);
}
cemu_assert_debug((rplSymbolStorage.strAllocatorOffset + len + 1) <= STR_ALLOC_BLOCK_SIZE);
char* allocatedStr = rplSymbolStorage.strAllocatorBlock + rplSymbolStorage.strAllocatorOffset;
rplSymbolStorage.strAllocatorOffset += len + 1;
strcpy(allocatedStr, str);
return allocatedStr;
}
char* rplSymbolStorage_storeLibname(const char* libName)
{
if (rplSymbolStorage.libs == NULL)
{
rplSymbolLib_t* libEntry = new rplSymbolLib_t();
libEntry->libName = rplSymbolStorage_allocDupString(libName);
libEntry->next = NULL;
rplSymbolStorage.libs = libEntry;
return libEntry->libName;
}
rplSymbolLib_t* libItr = rplSymbolStorage.libs;
while (libItr)
{
if (boost::iequals(libItr->libName, libName))
return libItr->libName;
// next
libItr = libItr->next;
}
// create new entry
rplSymbolLib_t* libEntry = new rplSymbolLib_t();
libEntry->libName = rplSymbolStorage_allocDupString(libName);
libEntry->next = rplSymbolStorage.libs;
rplSymbolStorage.libs = libEntry;
return libEntry->libName;
}
RPLStoredSymbol* rplSymbolStorage_store(const char* libName, const char* symbolName, MPTR address)
{
std::unique_lock<std::mutex> lck(rplSymbolStorage.m_symbolStorageMutex);
char* libNameStorage = rplSymbolStorage_storeLibname(libName);
char* symbolNameStorage = rplSymbolStorage_allocDupString(symbolName);
RPLStoredSymbol* storedSymbol = new RPLStoredSymbol();
storedSymbol->address = address;
storedSymbol->libName = libNameStorage;
storedSymbol->symbolName = symbolNameStorage;
storedSymbol->flags = 0;
rplSymbolStorage.map_symbolByAddress[address] = storedSymbol;
return storedSymbol;
}
RPLStoredSymbol* rplSymbolStorage_getByAddress(MPTR address)
{
std::unique_lock<std::mutex> lck(rplSymbolStorage.m_symbolStorageMutex);
return rplSymbolStorage.map_symbolByAddress[address];
}
void rplSymbolStorage_remove(RPLStoredSymbol* storedSymbol)
{
std::unique_lock<std::mutex> lck(rplSymbolStorage.m_symbolStorageMutex);
if (rplSymbolStorage.map_symbolByAddress[storedSymbol->address] == storedSymbol)
rplSymbolStorage.map_symbolByAddress[storedSymbol->address] = nullptr;
delete storedSymbol;
}
void rplSymbolStorage_removeRange(MPTR address, sint32 length)
{
while (length > 0)
{
RPLStoredSymbol* symbol = rplSymbolStorage_getByAddress(address);
if (symbol)
rplSymbolStorage_remove(symbol);
address += 4;
length -= 4;
}
}
void rplSymbolStorage_createJumpProxySymbol(MPTR jumpAddress, MPTR destAddress)
{
RPLStoredSymbol* destSymbol = rplSymbolStorage_getByAddress(destAddress);
if (destSymbol)
rplSymbolStorage_store((char*)destSymbol->libName, (char*)destSymbol->symbolName, jumpAddress);
}
std::unordered_map<uint32, RPLStoredSymbol*>& rplSymbolStorage_lockSymbolMap()
{
rplSymbolStorage.m_symbolStorageMutex.lock();
return rplSymbolStorage.map_symbolByAddress;
}
void rplSymbolStorage_unlockSymbolMap()
{
rplSymbolStorage.m_symbolStorageMutex.unlock();
}
void rplSymbolStorage_init()
{
cemu_assert_debug(rplSymbolStorage.map_symbolByAddress.empty());
cemu_assert_debug(rplSymbolStorage.strAllocatorBlock == nullptr);
}
void rplSymbolStorage_unloadAll()
{
// free symbols
for (auto& it : rplSymbolStorage.map_symbolByAddress)
delete it.second;
rplSymbolStorage.map_symbolByAddress.clear();
// free libs
rplSymbolLib_t* lib = rplSymbolStorage.libs;
while (lib)
{
rplSymbolLib_t* next = lib->next;
delete lib;
lib = next;
}
rplSymbolStorage.libs = nullptr;
// free strings
for (auto it : rplSymbolStorage.list_strAllocatedBlocks)
free(it);
rplSymbolStorage.strAllocatorBlock = nullptr;
rplSymbolStorage.strAllocatorOffset = 0;
}

View file

@ -0,0 +1,18 @@
struct RPLStoredSymbol
{
MPTR address;
void* libName;
void* symbolName;
uint32 flags;
};
void rplSymbolStorage_init();
void rplSymbolStorage_unloadAll();
RPLStoredSymbol* rplSymbolStorage_store(const char* libName, const char* symbolName, MPTR address);
void rplSymbolStorage_remove(RPLStoredSymbol* storedSymbol);
void rplSymbolStorage_removeRange(MPTR address, sint32 length);
RPLStoredSymbol* rplSymbolStorage_getByAddress(MPTR address);
void rplSymbolStorage_createJumpProxySymbol(MPTR jumpAddress, MPTR destAddress);
std::unordered_map<uint32, RPLStoredSymbol*>& rplSymbolStorage_lockSymbolMap();
void rplSymbolStorage_unlockSymbolMap();