mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2026-10-21 23:11:13 -05:00
Add support for plugins that use wut libraries.
Add the requirement to have wut installed Modify the plugin makefile, now you need to enable malloc wrapping manually Change the calling behaviour of the "WUPS_APP_STATUS_CLOSED" hook. PPCExit does NOT get called when opening an application from the system menu. Add error output to the UDPLogger on failure.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include "retain_vars.h"
|
||||
#include "myutils/overlay_helper.h"
|
||||
replacement_data_t gbl_replacement_data __attribute__((section(".data")));
|
||||
dyn_linking_relocation_data_t gbl_dyn_linking_data __attribute__((section(".data")));
|
||||
|
||||
u8 gAppStatus __attribute__((section(".data"))) = 0;
|
||||
u64 gGameTitleID __attribute__((section(".data"))) = 0;
|
||||
volatile u8 gSDInitDone __attribute__((section(".data"))) = 0;
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#ifndef RETAINS_VARS_H_
|
||||
#define RETAINS_VARS_H_
|
||||
#include "patcher/function_patcher.h"
|
||||
#include "plugin/dynamic_linking_defines.h"
|
||||
|
||||
extern replacement_data_t gbl_replacement_data;
|
||||
extern dyn_linking_relocation_data_t gbl_dyn_linking_data;
|
||||
|
||||
extern u8 gAppStatus;
|
||||
extern u64 gGameTitleID;
|
||||
extern volatile u8 gSDInitDone;
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "common/common.h"
|
||||
#include "plugin/PluginLoader.h"
|
||||
#include "plugin/PluginInformation.h"
|
||||
#include "plugin/DynamicLinkingHelper.h"
|
||||
|
||||
#include <wups.h>
|
||||
#include <iosuhax.h>
|
||||
@@ -51,6 +52,7 @@
|
||||
#include "Application.h"
|
||||
#include "patcher/function_patcher.h"
|
||||
#include "patcher/hooks_patcher.h"
|
||||
#include "plugin/dynamic_linking_defines.h"
|
||||
#include "myutils/mocha.h"
|
||||
#include "myutils/libntfs.h"
|
||||
#include "myutils/libfat.h"
|
||||
@@ -87,6 +89,7 @@ extern "C" int Menu_Main(int argc, char **argv) {
|
||||
setup_os_exceptions();
|
||||
|
||||
DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION);
|
||||
DEBUG_FUNCTION_LINE("Sizeof dyn_linking_relocation_data_t %d\n",sizeof(dyn_linking_relocation_data_t));
|
||||
Init();
|
||||
|
||||
init_kernel_syscalls();
|
||||
@@ -101,6 +104,9 @@ extern "C" int Menu_Main(int argc, char **argv) {
|
||||
CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN);
|
||||
// Restore patches as the patched functions could change.
|
||||
RestorePatches();
|
||||
|
||||
DynamicLinkingHelper::getInstance()->clearAll();
|
||||
|
||||
PluginLoader * pluginLoader = PluginLoader::getInstance();
|
||||
std::vector<PluginInformation *> pluginList = pluginLoader->getPluginInformation("sd:/wiiu/plugins/");
|
||||
pluginLoader->loadAndLinkPlugins(pluginList);
|
||||
@@ -130,11 +136,18 @@ extern "C" int Menu_Main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("Do relocations\n");
|
||||
|
||||
std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations();
|
||||
DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size()) ;
|
||||
DynamicLinkingHelper::getInstance()->fillRelocations(relocations);
|
||||
|
||||
|
||||
if(!isInMiiMakerHBL()) {
|
||||
DEBUG_FUNCTION_LINE("Apply patches.\n");
|
||||
ApplyPatchesAndCallHookStartingApp();
|
||||
|
||||
|
||||
if(MemoryMapping::isMemoryMapped()) {
|
||||
DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID);
|
||||
readAndPrintSegmentRegister(NULL,NULL);
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
DECL(void, __PPCExit, void) {
|
||||
// Only continue if we are in the "right" application.
|
||||
if(OSGetTitleID() == gGameTitleID) {
|
||||
DEBUG_FUNCTION_LINE("__PPCExit\n");
|
||||
CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
|
||||
DeInit();
|
||||
}
|
||||
//if(OSGetTitleID() == gGameTitleID) {
|
||||
//DEBUG_FUNCTION_LINE("__PPCExit\n");
|
||||
//CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
|
||||
//DeInit();
|
||||
//}
|
||||
|
||||
real___PPCExit();
|
||||
}
|
||||
@@ -26,6 +26,10 @@ DECL(u32, ProcUIProcessMessages, u32 u) {
|
||||
DEBUG_FUNCTION_LINE("App status changed from %d to %d \n",gAppStatus,res);
|
||||
gAppStatus = res;
|
||||
CallHook(WUPS_LOADER_HOOK_APP_STATUS_CHANGED);
|
||||
if(gAppStatus == WUPS_APP_STATUS_CLOSED) {
|
||||
CallHook(WUPS_LOADER_HOOK_ENDING_APPLICATION);
|
||||
DeInit();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -63,7 +67,7 @@ DECL(int, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error) {
|
||||
if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
|
||||
if(MemoryMapping::isMemoryMapped()) {
|
||||
MemoryMapping::readTestValuesFromMemory();
|
||||
}else{
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n");
|
||||
}
|
||||
vpadPressCooldown = 0x3C;
|
||||
|
||||
170
loader/src/plugin/DynamicLinkingHelper.cpp
Normal file
170
loader/src/plugin/DynamicLinkingHelper.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
#include "DynamicLinkingHelper.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include "utils/logger.h"
|
||||
#include "ElfTools.h"
|
||||
#include "PluginLoader.h"
|
||||
|
||||
DynamicLinkingHelper * DynamicLinkingHelper::instance = NULL;
|
||||
|
||||
dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(const char* functionName) {
|
||||
if(functionName == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
dyn_linking_function_t * result = NULL;
|
||||
for(int i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) {
|
||||
dyn_linking_function_t * curEntry = &gbl_dyn_linking_data.functions[i];
|
||||
if(strlen(curEntry->functionName) == 0) {
|
||||
strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH);
|
||||
result = curEntry;
|
||||
break;
|
||||
}
|
||||
if(strncmp(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH) == 0) {
|
||||
result = curEntry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
dyn_linking_import_t * DynamicLinkingHelper::getOrAddFunctionImportByName(const char* importName) {
|
||||
return getOrAddImport(importName, false);
|
||||
|
||||
}
|
||||
|
||||
dyn_linking_import_t * DynamicLinkingHelper::getOrAddDataImportByName(const char* importName) {
|
||||
return getOrAddImport(importName, true);
|
||||
|
||||
}
|
||||
|
||||
dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(const char* importName, bool isData) {
|
||||
if(importName == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
dyn_linking_import_t * result = NULL;
|
||||
for(int i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) {
|
||||
dyn_linking_import_t * curEntry = &gbl_dyn_linking_data.imports[i];
|
||||
if(strlen(curEntry->importName) == 0) {
|
||||
strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH);
|
||||
curEntry->isData = isData;
|
||||
result = curEntry;
|
||||
break;
|
||||
}
|
||||
if(strncmp(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) {
|
||||
return curEntry;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DynamicLinkingHelper::addReloationEntry(RelocationData * relocationData){
|
||||
return addReloationEntry(relocationData->getType(), relocationData->getOffset(), relocationData->getAddend(), relocationData->getDestination(), relocationData->getName(), relocationData->getImportRPLInformation());
|
||||
}
|
||||
|
||||
bool DynamicLinkingHelper::addReloationEntry(char type, size_t offset, int addend, void *destination, std::string name, ImportRPLInformation * rplInfo){
|
||||
dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(rplInfo->getName().c_str(),rplInfo->isData());
|
||||
if(importInfoGbl == NULL){
|
||||
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(name.c_str());
|
||||
if(functionInfo == NULL){
|
||||
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n",DYN_LINK_FUNCTION_LIST_LENGTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
return addReloationEntry(type, offset, addend, destination, functionInfo, importInfoGbl);
|
||||
}
|
||||
|
||||
bool DynamicLinkingHelper::addReloationEntry(char type, size_t offset, int addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo){
|
||||
for(int i = 0; i < DYN_LINK_RELOCATION_LIST_LENGTH; i++) {
|
||||
dyn_linking_relocation_entry_t * curEntry = &gbl_dyn_linking_data.entries[i];
|
||||
if(curEntry->functionEntry != NULL) {
|
||||
continue;
|
||||
}
|
||||
curEntry->type = type;
|
||||
curEntry->offset = offset;
|
||||
curEntry->addend = addend;
|
||||
curEntry->destination = destination;
|
||||
curEntry->functionEntry = functionName;
|
||||
curEntry->importEntry = importInfo;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<dyn_linking_relocation_entry_t *> DynamicLinkingHelper::getAllValidDynamicLinkingRelocations() {
|
||||
std::vector<dyn_linking_relocation_entry_t *> result;
|
||||
for(int i = 0; i < DYN_LINK_RELOCATION_LIST_LENGTH; i++) {
|
||||
if(gbl_dyn_linking_data.entries[i].functionEntry == NULL) {
|
||||
break;
|
||||
}
|
||||
result.push_back(&gbl_dyn_linking_data.entries[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DynamicLinkingHelper::fillRelocations(std::vector<dyn_linking_relocation_entry_t *> entries ) {
|
||||
for(size_t i = 0; i < entries.size(); i++) {
|
||||
dyn_linking_relocation_entry_t * curEntry = entries[i];
|
||||
dyn_linking_function_t * functionEntry = curEntry->functionEntry;
|
||||
void * destination = curEntry->destination;
|
||||
if(functionEntry == NULL) {
|
||||
DEBUG_FUNCTION_LINE("FunctionEntry was NULL\n");
|
||||
return false;
|
||||
}
|
||||
if(destination == NULL) {
|
||||
DEBUG_FUNCTION_LINE("destination was NULL\n");
|
||||
return false;
|
||||
}
|
||||
if(functionEntry->address == NULL) {
|
||||
dyn_linking_import_t * importEntry = curEntry->importEntry;
|
||||
|
||||
if(importEntry == NULL) {
|
||||
DEBUG_FUNCTION_LINE("importEntry was NULL\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(importEntry->handle != 0) {
|
||||
//DEBUG_FUNCTION_LINE("We cached import handle for %s\n",importEntry->importName);
|
||||
} else {
|
||||
OSDynLoad_Acquire(importEntry->importName, &importEntry->handle);
|
||||
}
|
||||
int isData = 0;
|
||||
if(importEntry->isData) {
|
||||
isData = 1;
|
||||
//DEBUG_FUNCTION_LINE("isData\n");
|
||||
}
|
||||
OSDynLoad_FindExport(importEntry->handle, isData, functionEntry->functionName, &functionEntry->address);
|
||||
|
||||
if(!functionEntry->address) {
|
||||
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s on import %s\n", functionEntry->functionName,importEntry->importName);
|
||||
return false;
|
||||
}else{
|
||||
//DEBUG_FUNCTION_LINE("OSDynLoad_FindExport successful for %s on import %s: %08X\n",functionEntry->functionName,importEntry->importName,functionEntry->address);
|
||||
}
|
||||
} else {
|
||||
//DEBUG_FUNCTION_LINE("We cached the address of function %s :%08X\n",functionEntry->functionName,functionEntry->address);
|
||||
}
|
||||
//DEBUG_FUNCTION_LINE("We would link now: type: %02X offset: %08X addend: %d destination: %08X target: %08X for %s\n",curEntry->type, curEntry->offset, curEntry->addend, curEntry->destination, functionEntry->address,functionEntry->functionName);
|
||||
DEBUG_FUNCTION_LINE("Resolving relocation to %s\n",functionEntry->functionName);
|
||||
ElfTools::elfLinkOne(curEntry->type, curEntry->offset, curEntry->addend, curEntry->destination, (u32) functionEntry->address);
|
||||
}
|
||||
|
||||
PluginLoader::flushCache();
|
||||
|
||||
DEBUG_FUNCTION_LINE("Clearing cache.\n");
|
||||
for(size_t i = 0; i < entries.size(); i++) {
|
||||
dyn_linking_relocation_entry_t * curEntry = entries[i];
|
||||
curEntry->functionEntry->address = 0;
|
||||
curEntry->importEntry->handle = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DynamicLinkingHelper::clearAll() {
|
||||
memset((void*)&gbl_dyn_linking_data,0,sizeof(gbl_dyn_linking_data));
|
||||
}
|
||||
94
loader/src/plugin/DynamicLinkingHelper.h
Normal file
94
loader/src/plugin/DynamicLinkingHelper.h
Normal file
@@ -0,0 +1,94 @@
|
||||
#ifndef DYNAMICLINKINGHELPER_H
|
||||
#define DYNAMICLINKINGHELPER_H
|
||||
|
||||
#include "common/retain_vars.h"
|
||||
#include "dynamic_linking_defines.h"
|
||||
#include "utils/logger.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "RelocationData.h"
|
||||
|
||||
class DynamicLinkingHelper {
|
||||
public:
|
||||
static DynamicLinkingHelper *getInstance() {
|
||||
if(!instance) {
|
||||
instance = new DynamicLinkingHelper();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if(instance) {
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Gets the function entry for a given function name. If the function name is not present in the list, it will be added.
|
||||
|
||||
\param functionName Name of the function
|
||||
\return Returns a pointer to the entry which contains the functionName. Null on error or if the list full.
|
||||
**/
|
||||
dyn_linking_function_t * getOrAddFunctionEntryByName(const char * functionName);
|
||||
|
||||
/**
|
||||
Gets the function import entry for a given function name. If the import is not present in the list, it will be added.
|
||||
This will return entries for _function_ imports.
|
||||
|
||||
\param importName Name of the function
|
||||
\return Returns a pointer to the function import entry which contains the importName. Null on error or if the list full.
|
||||
**/
|
||||
dyn_linking_import_t * getOrAddFunctionImportByName(const char * importName);
|
||||
|
||||
|
||||
/**
|
||||
Gets the data import entry for a given data name. If the import is not present in the list, it will be added.
|
||||
This will return entries for _data_ imports.
|
||||
|
||||
\param importName Name of the data
|
||||
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
|
||||
**/
|
||||
dyn_linking_import_t * getOrAddDataImportByName(const char * importName);
|
||||
|
||||
|
||||
/**
|
||||
Gets the import entry for a given data name and type. If the import is not present in the list, it will be added.
|
||||
This will return entries for _data_ and _function_ imports, depending on the isData parameter.
|
||||
|
||||
\param importName Name of the data
|
||||
\param isData Set this to true to return a data import
|
||||
|
||||
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
|
||||
**/
|
||||
dyn_linking_import_t * getOrAddImport(const char * importName, bool isData);
|
||||
|
||||
|
||||
bool addReloationEntry(RelocationData * relocationData);
|
||||
|
||||
bool addReloationEntry(char type, size_t offset, int addend, void *destination, std::string name, ImportRPLInformation * rplInfo);
|
||||
|
||||
bool addReloationEntry(char type, size_t offset, int addend, void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo);
|
||||
|
||||
std::vector<dyn_linking_relocation_entry_t *> getAllValidDynamicLinkingRelocations();
|
||||
|
||||
bool fillRelocations(std::vector<dyn_linking_relocation_entry_t *> entries );
|
||||
|
||||
void clearAll();
|
||||
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
DynamicLinkingHelper() {
|
||||
}
|
||||
|
||||
~DynamicLinkingHelper() {
|
||||
|
||||
}
|
||||
|
||||
static DynamicLinkingHelper *instance;
|
||||
};
|
||||
|
||||
#endif // DYNAMICLINKINGHELPER_H
|
||||
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
|
||||
#include "ElfTools.h"
|
||||
#include "RelocationData.h"
|
||||
#include "ImportRPLInformation.h"
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <libelf.h>
|
||||
@@ -122,7 +124,7 @@ void ElfTools::elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym *
|
||||
}
|
||||
|
||||
|
||||
bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals) {
|
||||
bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals, PluginData * pluginData) {
|
||||
Elf_Scn *scn;
|
||||
|
||||
for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) {
|
||||
@@ -155,8 +157,10 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
|
||||
symbol = ELF32_R_SYM(rel[i].r_info);
|
||||
|
||||
if (symbol > symtab_count)
|
||||
if (symbol > symtab_count) {
|
||||
DEBUG_FUNCTION_LINE("symbol > symtab_count\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (symtab[symbol].st_shndx) {
|
||||
case SHN_ABS: {
|
||||
@@ -164,6 +168,7 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
break;
|
||||
}
|
||||
case SHN_COMMON: {
|
||||
DEBUG_FUNCTION_LINE("case SHN_COMMON\n");
|
||||
return false;
|
||||
}
|
||||
case SHN_UNDEF: {
|
||||
@@ -209,11 +214,14 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
*/
|
||||
return false;
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("case SHN_UNDEF with !allow_globals\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
if (symtab[symbol].st_other != 1) {
|
||||
|
||||
DEBUG_FUNCTION_LINE("symtab[symbol].st_other != 1. it's %d %08X\n",symtab[symbol].st_other,symtab[symbol].st_other);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -223,6 +231,7 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
}
|
||||
|
||||
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, *(int *)((char *)destination + rel[i].r_offset), destination, symbol_addr)) {
|
||||
DEBUG_FUNCTION_LINE("elfLinkOne failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -248,8 +257,10 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
|
||||
symbol = ELF32_R_SYM(rela[i].r_info);
|
||||
|
||||
if (symbol > symtab_count)
|
||||
if (symbol > symtab_count) {
|
||||
DEBUG_FUNCTION_LINE("symbol > symtab_count\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (symtab[symbol].st_shndx) {
|
||||
case SHN_ABS: {
|
||||
@@ -257,12 +268,19 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
break;
|
||||
}
|
||||
case SHN_COMMON: {
|
||||
DEBUG_FUNCTION_LINE("case SHN_COMMON\n");
|
||||
return false;
|
||||
}
|
||||
case SHN_UNDEF: {
|
||||
if (allow_globals) {
|
||||
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
|
||||
char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name);
|
||||
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported: %s \n",name);
|
||||
|
||||
/*
|
||||
|
||||
char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name);
|
||||
DEBUG_FUNCTION_LINE("%s %08X\n",name,symtab[symbol].st_value);
|
||||
|
||||
Not support and not needed.
|
||||
module_unresolved_relocation_t *reloc;
|
||||
char *name;
|
||||
@@ -299,14 +317,29 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
reloc->addend = rela[i].r_addend;
|
||||
|
||||
continue;*/
|
||||
continue;
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("case SHN_UNDEF with !allow_global\n");
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
|
||||
if (symtab[symbol].st_other != 1) {
|
||||
return false;
|
||||
char *name = elf_strptr(elf, symtab_strndx, symtab[symbol].st_name);
|
||||
if(pluginData == NULL) {
|
||||
DEBUG_FUNCTION_LINE("No plugin data provided, but we (probably) need it.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ImportRPLInformation * rplInfo = pluginData->getImportRPLInformationBySectionHeaderIndex(symtab[symbol].st_shndx);
|
||||
if(rplInfo == NULL) {
|
||||
DEBUG_FUNCTION_LINE("Couldn't find ImportRPLInformation for section header index %d \n", symtab[symbol].st_shndx);
|
||||
return false;
|
||||
}
|
||||
RelocationData * relocationData = new RelocationData(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, name, rplInfo);
|
||||
pluginData->addRelocationData(relocationData);
|
||||
|
||||
continue;
|
||||
}
|
||||
symbol_addr = symtab[symbol].st_value;
|
||||
break;
|
||||
@@ -314,6 +347,7 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
|
||||
}
|
||||
|
||||
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, symbol_addr)) {
|
||||
DEBUG_FUNCTION_LINE("elfLinkOne failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,13 +36,16 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#include "PluginData.h"
|
||||
|
||||
class ElfTools {
|
||||
|
||||
public:
|
||||
static bool elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination);
|
||||
static bool loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count, size_t *symtab_strndx);
|
||||
static void elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym *symtab, size_t symtab_count);
|
||||
static bool elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals);
|
||||
static bool elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx, bool allow_globals, PluginData * pluginData = NULL);
|
||||
static bool elfLinkOne(char type, size_t offset, int addend, void *destination, uint32_t symbol_addr);
|
||||
};
|
||||
|
||||
|
||||
79
loader/src/plugin/ImportRPLInformation.h
Normal file
79
loader/src/plugin/ImportRPLInformation.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _IMPORT_RPL_INFORMATION_H_
|
||||
#define _IMPORT_RPL_INFORMATION_H_
|
||||
|
||||
#include <wups.h>
|
||||
#include <string>
|
||||
|
||||
class ImportRPLInformation {
|
||||
|
||||
public:
|
||||
ImportRPLInformation(int section_header_index, std::string name, bool isData = false) {
|
||||
this->name = name;
|
||||
this->section_header_index = section_header_index;
|
||||
this->_isData = isData;
|
||||
}
|
||||
|
||||
~ImportRPLInformation() {
|
||||
|
||||
}
|
||||
|
||||
static ImportRPLInformation * createImportRPLInformation(int section_header_index, std::string rawSectionName) {
|
||||
std::string fimport = ".fimport_";
|
||||
std::string dimport = ".dimport_";
|
||||
|
||||
bool data = false;
|
||||
|
||||
std::string rplName = "";
|
||||
|
||||
if(rawSectionName.size() < fimport.size()) {
|
||||
return NULL;
|
||||
} else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) {
|
||||
rplName = rawSectionName.substr(fimport.size());
|
||||
} else if (std::equal(dimport.begin(), dimport.end(), rawSectionName.begin())) {
|
||||
rplName = rawSectionName.substr(dimport.size());
|
||||
data = true;
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("invalid section name\n");
|
||||
return NULL;
|
||||
}
|
||||
DEBUG_FUNCTION_LINE("Adding %s of section index %02X. %d\n",rplName.c_str(),section_header_index,data);
|
||||
return new ImportRPLInformation(section_header_index, rplName, data);
|
||||
}
|
||||
|
||||
std::string getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
int getSectionHeaderIndex() {
|
||||
return section_header_index;
|
||||
}
|
||||
|
||||
bool isData() {
|
||||
return _isData;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
bool _isData = false;
|
||||
int section_header_index = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "FunctionData.h"
|
||||
#include "HookData.h"
|
||||
#include "PluginInformation.h"
|
||||
#include "RelocationData.h"
|
||||
#include "ImportRPLInformation.h"
|
||||
#include <utils/logger.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -53,6 +55,18 @@ public:
|
||||
delete hook_data_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i< relocation_data_list.size(); i++) {
|
||||
if(relocation_data_list[i] != NULL) {
|
||||
delete relocation_data_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i< importRPLInformation_list.size(); i++) {
|
||||
if(importRPLInformation_list[i] != NULL) {
|
||||
delete importRPLInformation_list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addFunctionData(FunctionData * function_data) {
|
||||
@@ -71,6 +85,38 @@ public:
|
||||
return hook_data_list;
|
||||
}
|
||||
|
||||
void addRelocationData(RelocationData * relocation_data) {
|
||||
relocation_data_list.push_back(relocation_data);
|
||||
}
|
||||
|
||||
std::vector<RelocationData *> getRelocationDataList() {
|
||||
return relocation_data_list;
|
||||
}
|
||||
|
||||
void addImportRPLInformation(ImportRPLInformation * importRPLInformation) {
|
||||
importRPLInformation_list.push_back(importRPLInformation);
|
||||
}
|
||||
|
||||
std::vector<ImportRPLInformation *> getImportRPLInformationList() {
|
||||
return importRPLInformation_list;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a ImportRPLInformation for a given section header index.
|
||||
|
||||
\param section_header_index: ID of section in elf, started counting at 1.
|
||||
|
||||
\return A pointer to the corresponding ImportRPLInformation, return NULL if no corresponding information was found.
|
||||
**/
|
||||
ImportRPLInformation * getImportRPLInformationBySectionHeaderIndex(int section_header_index) {
|
||||
for(size_t i = 0; i< importRPLInformation_list.size(); i++) {
|
||||
if(importRPLInformation_list[i] != NULL && importRPLInformation_list[i]->getSectionHeaderIndex() == section_header_index) {
|
||||
return importRPLInformation_list[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PluginInformation * getPluginInformation() {
|
||||
return pluginInformation;
|
||||
}
|
||||
@@ -81,6 +127,8 @@ private:
|
||||
|
||||
std::vector<FunctionData *> function_data_list;
|
||||
std::vector<HookData *> hook_data_list;
|
||||
std::vector<RelocationData *> relocation_data_list;
|
||||
std::vector<ImportRPLInformation *> importRPLInformation_list;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "ElfTools.h"
|
||||
#include "PluginData.h"
|
||||
#include "PluginLoader.h"
|
||||
#include "DynamicLinkingHelper.h"
|
||||
#include "utils/StringTools.h"
|
||||
#include "common/retain_vars.h"
|
||||
|
||||
@@ -105,11 +106,11 @@ bool PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInf
|
||||
}
|
||||
}
|
||||
|
||||
PluginLoader::flushCache();
|
||||
|
||||
copyPluginDataIntoGlobalStruct(loadedPlugins);
|
||||
clearPluginData(loadedPlugins);
|
||||
|
||||
DCFlushRange((void*)this->startAddress,(u32)this->endAddress - (u32)this->startAddress);
|
||||
ICInvalidateRange((void*)this->startAddress,(u32)this->endAddress - (u32)this->startAddress);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -141,8 +142,8 @@ PluginData * PluginLoader::loadAndLinkPlugin(PluginInformation * pluginInformati
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
if(pluginInformation->getSize() > ((u32) this->getCurrentStoreAddress() - (u32) this->startAddress)) {
|
||||
DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory\n");
|
||||
if(pluginInformation->getSize() > ((u32) getAvailableSpace())) {
|
||||
DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory %08X %08X\n",pluginInformation->getSize(),getAvailableSpace());
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
@@ -201,6 +202,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
wups_loader_hook_t *hooks = NULL;
|
||||
bool result = false;
|
||||
|
||||
int i = 1;
|
||||
|
||||
std::vector<wups_loader_entry_t *> entry_t_list;
|
||||
std::vector<wups_loader_hook_t *> hook_t_list;
|
||||
|
||||
@@ -241,6 +244,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
|
||||
name = elf_strptr(elf, shstrndx, shdr->sh_name);
|
||||
if (name == NULL) {
|
||||
DEBUG_FUNCTION_LINE("name is null\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -248,6 +252,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
continue;
|
||||
} else if (strcmp(name, ".wups.load") == 0) {
|
||||
if (entries != NULL) {
|
||||
DEBUG_FUNCTION_LINE("entries != NULL\n");
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
@@ -255,11 +260,13 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
entries = (wups_loader_entry_t *) malloc(sizeof(wups_loader_entry_t) * entries_count);
|
||||
|
||||
if (entries == NULL) {
|
||||
DEBUG_FUNCTION_LINE("entries == NULL\n");
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
destinations[elf_ndxscn(scn)] = (uint8_t *)entries;
|
||||
if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)) {
|
||||
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
@@ -270,6 +277,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
}
|
||||
} else if (strcmp(name, ".wups.hooks") == 0) {
|
||||
if (hooks != NULL) {
|
||||
DEBUG_FUNCTION_LINE("hooks != NULL\n");
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
@@ -277,11 +285,13 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
hooks = (wups_loader_hook_t *) malloc(sizeof(wups_loader_hook_t) * hooks_count);
|
||||
|
||||
if (hooks == NULL) {
|
||||
DEBUG_FUNCTION_LINE("hooks == NULL\n");
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
destinations[elf_ndxscn(scn)] = (uint8_t *)hooks;
|
||||
if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)) {
|
||||
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
||||
goto exit_error;
|
||||
}
|
||||
ElfTools::elfLoadSymbols(elf_ndxscn(scn), hooks, symtab, symtab_count);
|
||||
@@ -305,13 +315,39 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,curAddress);
|
||||
if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) curAddress)) {
|
||||
DEBUG_FUNCTION_LINE("elfLoadSection failed\n");
|
||||
goto exit_error;
|
||||
}
|
||||
ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) curAddress, symtab, symtab_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) {
|
||||
Elf32_Shdr *shdr;
|
||||
|
||||
shdr = elf32_getshdr(scn);
|
||||
if (shdr == NULL) {
|
||||
continue;
|
||||
}
|
||||
const char *name;
|
||||
|
||||
name = elf_strptr(elf, shstrndx, shdr->sh_name);
|
||||
if (name == NULL) {
|
||||
DEBUG_FUNCTION_LINE("name is null\n");
|
||||
continue;
|
||||
}
|
||||
if(shdr->sh_type == 0x80000002) {
|
||||
ImportRPLInformation * info = ImportRPLInformation::createImportRPLInformation(i,name);
|
||||
if(info != NULL) {
|
||||
pluginData->addImportRPLInformation(info);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
|
||||
|
||||
for (scn = elf_nextscn(elf, NULL); scn != NULL; scn = elf_nextscn(elf, scn)) {
|
||||
Elf32_Shdr *shdr;
|
||||
@@ -324,8 +360,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
|
||||
(shdr->sh_flags & SHF_ALLOC) &&
|
||||
destinations[elf_ndxscn(scn)] != NULL) {
|
||||
|
||||
if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true)) {
|
||||
if (!ElfTools::elfLink(elf, elf_ndxscn(scn), destinations[elf_ndxscn(scn)], symtab, symtab_count, symtab_strndx, true, pluginData)) {
|
||||
DEBUG_FUNCTION_LINE("elfLink failed\n");
|
||||
goto exit_error;
|
||||
}
|
||||
}
|
||||
@@ -348,8 +384,6 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
|
||||
|
||||
this->setCurrentStoreAddress((void *) curAddress);
|
||||
|
||||
DEBUG_FUNCTION_LINE("Copied plugin %s to %08X\n",pluginData->getPluginInformation()->getName().c_str(),curAddress);
|
||||
|
||||
result = true;
|
||||
exit_error:
|
||||
if (!result) DEBUG_FUNCTION_LINE("exit_error\n");
|
||||
@@ -371,12 +405,27 @@ exit_error:
|
||||
void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins) {
|
||||
// Reset data
|
||||
memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data));
|
||||
DynamicLinkingHelper::getInstance()->clearAll();
|
||||
int plugin_index = 0;
|
||||
// Copy data to global struct.
|
||||
for(size_t i = 0; i< plugins.size(); i++) {
|
||||
PluginData * cur_plugin = plugins.at(i);
|
||||
PluginInformation * cur_pluginInformation = cur_plugin->getPluginInformation();
|
||||
|
||||
// Relocation
|
||||
std::vector<RelocationData *> relocationData = cur_plugin->getRelocationDataList();
|
||||
for(size_t j = 0; j < relocationData.size(); j++) {
|
||||
if(!DynamicLinkingHelper::getInstance()->addReloationEntry(relocationData[j])) {
|
||||
DEBUG_FUNCTION_LINE("Adding relocation for %s failed. It won't be loaded.\n",cur_pluginInformation->getName().c_str());
|
||||
continue;
|
||||
} else {
|
||||
//relocationData[j]->printInformation();
|
||||
}
|
||||
}
|
||||
|
||||
// Other
|
||||
|
||||
|
||||
std::vector<FunctionData *> function_data_list = cur_plugin->getFunctionDataList();
|
||||
std::vector<HookData *> hook_data_list = cur_plugin->getHookDataList();
|
||||
if(plugin_index >= MAXIMUM_PLUGINS ) {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "PluginInformation.h"
|
||||
#include "PluginData.h"
|
||||
#include "dynamic_libs/os_types.h"
|
||||
#include "dynamic_libs/os_functions.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -49,7 +50,7 @@ class PluginLoader {
|
||||
public:
|
||||
static PluginLoader *getInstance() {
|
||||
if(!instance) {
|
||||
instance = new PluginLoader((void*)getApplicationEndAddr(),(void *)PLUGIN_LOCATION_END_ADDRESS);
|
||||
instance = new PluginLoader((void*)getApplicationEndAddr(),(void *)PLUGIN_LOCATION_END_ADDRESS);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@@ -90,6 +91,15 @@ public:
|
||||
**/
|
||||
bool loadAndLinkPlugins(std::vector<PluginInformation *> pluginInformation);
|
||||
|
||||
|
||||
static void flushCache() {
|
||||
u32 startAddress = getApplicationEndAddr();
|
||||
u32 endAddress = PLUGIN_LOCATION_END_ADDRESS;
|
||||
|
||||
DCFlushRange((void*)startAddress,(u32)endAddress - (u32)startAddress);
|
||||
ICInvalidateRange((void*)startAddress,(u32)endAddress - (u32)startAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Iterates through the vector and delete all it's elements
|
||||
|
||||
|
||||
79
loader/src/plugin/RelocationData.h
Normal file
79
loader/src/plugin/RelocationData.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _RELOCATION_DATA_H_
|
||||
#define _RELOCATION_DATA_H_
|
||||
|
||||
#include <wups.h>
|
||||
#include <string>
|
||||
#include "ImportRPLInformation.h"
|
||||
|
||||
class RelocationData {
|
||||
|
||||
public:
|
||||
RelocationData(char type, size_t offset, int addend, void *destination, std::string name, ImportRPLInformation * rplInfo) {
|
||||
this->type = type;
|
||||
this->offset = offset;
|
||||
this->addend = addend;
|
||||
this->destination = destination;
|
||||
this->name = name;
|
||||
this->rplInfo = rplInfo;
|
||||
}
|
||||
|
||||
~RelocationData() {
|
||||
|
||||
}
|
||||
|
||||
char getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
size_t getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
int getAddend() {
|
||||
return addend;
|
||||
}
|
||||
|
||||
void * getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
std::string getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
ImportRPLInformation * getImportRPLInformation() {
|
||||
return rplInfo;
|
||||
}
|
||||
|
||||
void printInformation() {
|
||||
DEBUG_FUNCTION_LINE("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n",name.c_str(), destination, offset, type, addend, rplInfo->getName().c_str(), rplInfo->isData() );
|
||||
}
|
||||
|
||||
private:
|
||||
char type;
|
||||
size_t offset;
|
||||
int addend;
|
||||
void *destination;
|
||||
std::string name;
|
||||
ImportRPLInformation * rplInfo;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
65
loader/src/plugin/dynamic_linking_defines.h
Normal file
65
loader/src/plugin/dynamic_linking_defines.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2018 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _DYNAMIC_LINKING_DEFINES_H_
|
||||
#define _DYNAMIC_LINKING_DEFINES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <dynamic_libs/os_functions.h>
|
||||
#include <wups.h>
|
||||
|
||||
#define DYN_LINK_FUNCTION_NAME_LENGTH 255
|
||||
#define DYN_LINK_IMPORT_NAME_LENGTH 150
|
||||
|
||||
#define DYN_LINK_FUNCTION_LIST_LENGTH 500
|
||||
#define DYN_LINK_IMPORT_LIST_LENGTH 50
|
||||
#define DYN_LINK_RELOCATION_LIST_LENGTH 50000
|
||||
|
||||
typedef struct _dyn_linking_function_t {
|
||||
char functionName[DYN_LINK_FUNCTION_NAME_LENGTH+1];
|
||||
void * address;
|
||||
} dyn_linking_function_t;
|
||||
|
||||
typedef struct _dyn_linking_import_t {
|
||||
char importName[DYN_LINK_IMPORT_NAME_LENGTH+1];
|
||||
bool isData = false;
|
||||
u32 handle = 0;
|
||||
} dyn_linking_import_t;
|
||||
|
||||
typedef struct _dyn_linking_relocation_entry_t {
|
||||
dyn_linking_function_t* functionEntry = NULL;
|
||||
dyn_linking_import_t* importEntry = NULL;
|
||||
void * destination = NULL;
|
||||
char type;
|
||||
size_t offset;
|
||||
int addend;
|
||||
} dyn_linking_relocation_entry_t;
|
||||
|
||||
typedef struct _dyn_linking_relocation_data_t {
|
||||
dyn_linking_relocation_entry_t entries[DYN_LINK_RELOCATION_LIST_LENGTH];
|
||||
dyn_linking_function_t functions[DYN_LINK_FUNCTION_LIST_LENGTH];
|
||||
dyn_linking_import_t imports[DYN_LINK_IMPORT_LIST_LENGTH];
|
||||
} dyn_linking_relocation_data_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DYNAMIC_LINKING_DEFINES_H_ */
|
||||
Reference in New Issue
Block a user