mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-16 03:38:30 +12:00
Add all the files
This commit is contained in:
parent
e3db07a16a
commit
d60742f52b
1445 changed files with 430238 additions and 0 deletions
129
src/Cafe/OS/RPL/elf.cpp
Normal file
129
src/Cafe/OS/RPL/elf.cpp
Normal 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
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
55
src/Cafe/OS/RPL/rpl.h
Normal 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);
|
21
src/Cafe/OS/RPL/rpl_debug_symbols.cpp
Normal file
21
src/Cafe/OS/RPL/rpl_debug_symbols.cpp
Normal 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;
|
||||
}
|
23
src/Cafe/OS/RPL/rpl_debug_symbols.h
Normal file
23
src/Cafe/OS/RPL/rpl_debug_symbols.h
Normal 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();
|
258
src/Cafe/OS/RPL/rpl_structs.h
Normal file
258
src/Cafe/OS/RPL/rpl_structs.h
Normal 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);
|
150
src/Cafe/OS/RPL/rpl_symbol_storage.cpp
Normal file
150
src/Cafe/OS/RPL/rpl_symbol_storage.cpp
Normal 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;
|
||||
}
|
18
src/Cafe/OS/RPL/rpl_symbol_storage.h
Normal file
18
src/Cafe/OS/RPL/rpl_symbol_storage.h
Normal 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();
|
Loading…
Add table
Add a link
Reference in a new issue