Cemu/src/Cafe/OS/RPL/rpl_structs.h
2024-12-07 10:26:17 +01:00

242 lines
6.6 KiB
C++

#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 minimumToolkitVersion;
/* +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?
uint32 padding14;
uint32 padding18;
rplHeaderNew_t rplHeader;
rplSectionEntryNew_t* sectionTablePtr; // copy of section table
uint32 entrypoint;
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;
uint32 exportDCount;
rplExportTableEntry_t* exportDDataPtr;
uint32 exportFCount;
rplExportTableEntry_t* exportFDataPtr;
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 };
};
struct RPLDependency
{
char modulename[RPL_MODULE_NAME_LENGTH];
char filepath[RPL_MODULE_PATH_LENGTH];
bool loadAttempted;
bool isCafeOSModule; // name is a known Cafe OS RPL
RPLModule* rplLoaderContext; // context of loaded module, can be nullptr for HLE COS modules
sint32 referenceCount;
uint32 coreinitHandle; // fake handle for coreinit
sint16 tlsModuleIndex; // tls module index assigned to this dependency
};
RPLModule* RPLLoader_FindModuleByCodeAddr(uint32 addr);
RPLModule* RPLLoader_FindModuleByDataAddr(uint32 addr);
RPLModule* RPLLoader_FindModuleByName(std::string module);