[Loader] Code formatting and minor logging improvements.

This commit is contained in:
Maschell
2018-02-24 12:35:00 +01:00
parent 409527fb21
commit 55dd57d62f
32 changed files with 1094 additions and 1131 deletions

View File

@@ -30,25 +30,29 @@
#include <utils/logger.h>
bool ElfTools::elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination) {
if (destination == NULL) { return false; }
if (destination == NULL) {
return false;
}
switch (shdr->sh_type) {
case SHT_SYMTAB:
case SHT_PROGBITS: {
Elf_Data *data;
size_t n;
case SHT_SYMTAB:
case SHT_PROGBITS: {
Elf_Data *data;
size_t n;
n = 0;
for (data = elf_getdata(scn, NULL); data != NULL; data = elf_getdata(scn, data)) {
memcpy((char *)destination + n, data->d_buf, data->d_size);
n += data->d_size;
}
return true;
} case SHT_NOBITS: {
memset(destination, 0, shdr->sh_size);
return true;
} default:
return false;
n = 0;
for (data = elf_getdata(scn, NULL); data != NULL; data = elf_getdata(scn, data)) {
memcpy((char *)destination + n, data->d_buf, data->d_size);
n += data->d_size;
}
return true;
}
case SHT_NOBITS: {
memset(destination, 0, shdr->sh_size);
return true;
}
default:
return false;
}
}
@@ -61,30 +65,30 @@ bool ElfTools::loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count,
Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn);
if (shdr == NULL){
if (shdr == NULL) {
continue;
}
if (shdr->sh_type == SHT_SYMTAB) {
size_t sym;
if (*symtab != NULL){
if (*symtab != NULL) {
continue;
}
*symtab = (Elf32_Sym *)malloc(shdr->sh_size);
if (*symtab == NULL){
if (*symtab == NULL) {
continue;
}
*symtab_count = shdr->sh_size / sizeof(Elf32_Sym);
*symtab_strndx = shdr->sh_link;
if (!elfLoadSection(elf, scn, shdr, *symtab)){
if (!elfLoadSection(elf, scn, shdr, *symtab)) {
goto exit_error;
}
for (sym = 0; sym < *symtab_count; sym++){
for (sym = 0; sym < *symtab_count; sym++) {
(*symtab)[sym].st_other = 0;
}
@@ -92,7 +96,7 @@ bool ElfTools::loadElfSymtab(Elf *elf, Elf32_Sym **symtab, size_t *symtab_count,
}
}
if (*symtab == NULL){
if (*symtab == NULL) {
goto exit_error;
}
@@ -109,7 +113,7 @@ void ElfTools::elfLoadSymbols(size_t shndx, const void *destination, Elf32_Sym *
* symbol address has been calculated. */
for (i = 0; i < symtab_count; i++) {
if (symtab[i].st_shndx == shndx &&
symtab[i].st_other == 0) {
symtab[i].st_other == 0) {
symtab[i].st_value += (Elf32_Addr)destination;
symtab[i].st_other = 1;
@@ -129,185 +133,192 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
continue;
switch (shdr->sh_type) {
case SHT_REL: {
const Elf32_Rel *rel;
Elf_Data *data;
size_t i;
case SHT_REL: {
const Elf32_Rel *rel;
Elf_Data *data;
size_t i;
if (shdr->sh_info != shndx){
continue;
}
data = elf_getdata(scn, NULL);
if (data == NULL){
continue;
}
rel = (const Elf32_Rel *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rel); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rel[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
} case SHN_COMMON: {
return false;
} case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
reloc->module = index;
reloc->address = destination;
reloc->offset = rel[i].r_offset;
reloc->type = ELF32_R_TYPE(rel[i].r_info);
reloc->addend = *(int *)((char *)destination + rel[i].r_offset);
continue;
*/
return false;
} else {
return false;
}
} default: {
if (symtab[symbol].st_other != 1) {
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, *(int *)((char *)destination + rel[i].r_offset), destination, symbol_addr)){
return false;
}
}
break;
} case SHT_RELA: {
const Elf32_Rela *rela;
Elf_Data *data;
size_t i;
if (shdr->sh_info != shndx)
continue;
data = elf_getdata(scn, NULL);
if (data == NULL)
continue;
rela = (const Elf32_Rela *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rela); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rela[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
} case SHN_COMMON: {
return false;
} case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
DEBUG_FUNCTION_LINE("Adding relocation!\n");
reloc->module = index;
reloc->address = destination;
reloc->offset = rela[i].r_offset;
reloc->type = ELF32_R_TYPE(rela[i].r_info);
reloc->addend = rela[i].r_addend;
continue;*/
return false;
} else
return false;
} default: {
if (symtab[symbol].st_other != 1){
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, symbol_addr)){
return false;
}
}
break;
if (shdr->sh_info != shndx) {
continue;
}
data = elf_getdata(scn, NULL);
if (data == NULL) {
continue;
}
rel = (const Elf32_Rel *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rel); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rel[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
}
case SHN_COMMON: {
return false;
}
case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
reloc->module = index;
reloc->address = destination;
reloc->offset = rel[i].r_offset;
reloc->type = ELF32_R_TYPE(rel[i].r_info);
reloc->addend = *(int *)((char *)destination + rel[i].r_offset);
continue;
*/
return false;
} else {
return false;
}
}
default: {
if (symtab[symbol].st_other != 1) {
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, *(int *)((char *)destination + rel[i].r_offset), destination, symbol_addr)) {
return false;
}
}
break;
}
case SHT_RELA: {
const Elf32_Rela *rela;
Elf_Data *data;
size_t i;
if (shdr->sh_info != shndx)
continue;
data = elf_getdata(scn, NULL);
if (data == NULL)
continue;
rela = (const Elf32_Rela *) data->d_buf;
for (i = 0; i < shdr->sh_size / sizeof(Elf32_Rela); i++) {
uint32_t symbol_addr;
size_t symbol;
symbol = ELF32_R_SYM(rela[i].r_info);
if (symbol > symtab_count)
return false;
switch (symtab[symbol].st_shndx) {
case SHN_ABS: {
symbol_addr = symtab[symbol].st_value;
break;
}
case SHN_COMMON: {
return false;
}
case SHN_UNDEF: {
if (allow_globals) {
DEBUG_FUNCTION_LINE("The elf still have unresolved relocations. This is not supported.");
/*
Not support and not needed.
module_unresolved_relocation_t *reloc;
char *name;
reloc = (module_unresolved_relocation_t *) Module_ListAllocate(
&module_relocations,
sizeof(module_unresolved_relocation_t), 1,
&module_relocations_capacity,
&module_relocations_count,
PLUGIN_RELOCATIONS_CAPCITY_DEFAULT);
if (reloc == NULL)
return false;
name = elf_strptr(
elf, symtab_strndx, symtab[symbol].st_name);
if (name == NULL) {
module_relocations_count--;
return false;
}
reloc->name = strdup(name);
if (reloc->name == NULL) {
module_relocations_count--;
return false;
}
DEBUG_FUNCTION_LINE("Adding relocation!\n");
reloc->module = index;
reloc->address = destination;
reloc->offset = rela[i].r_offset;
reloc->type = ELF32_R_TYPE(rela[i].r_info);
reloc->addend = rela[i].r_addend;
continue;*/
return false;
} else
return false;
}
default: {
if (symtab[symbol].st_other != 1) {
return false;
}
symbol_addr = symtab[symbol].st_value;
break;
}
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, symbol_addr)) {
return false;
}
}
break;
}
}
}
@@ -320,104 +331,118 @@ bool ElfTools::elfLinkOne(char type, size_t offset, int addend, void *destinatio
bool result = false;
switch (type) {
case R_PPC_ADDR32:
case R_PPC_ADDR24:
case R_PPC_ADDR16:
case R_PPC_ADDR16_HI:
case R_PPC_ADDR16_HA:
case R_PPC_ADDR16_LO:
case R_PPC_ADDR14:
case R_PPC_ADDR14_BRTAKEN:
case R_PPC_ADDR14_BRNTAKEN:
case R_PPC_UADDR32:
case R_PPC_UADDR16: {
value = (int)symbol_addr + addend;
break;
} case R_PPC_REL24:
case R_PPC_PLTREL24:
case R_PPC_LOCAL24PC:
case R_PPC_REL14:
case R_PPC_REL14_BRTAKEN:
case R_PPC_REL14_BRNTAKEN:
case R_PPC_REL32:
case R_PPC_ADDR30: {
value = (int)symbol_addr + addend - (int)target;
break;
} case R_PPC_SECTOFF:
case R_PPC_SECTOFF_LO:
case R_PPC_SECTOFF_HI:
case R_PPC_SECTOFF_HA: {
value = offset + addend;
break;
} case R_PPC_EMB_NADDR32:
case R_PPC_EMB_NADDR16:
case R_PPC_EMB_NADDR16_LO:
case R_PPC_EMB_NADDR16_HI:
case R_PPC_EMB_NADDR16_HA: {
value = addend - (int)symbol_addr;
break;
} default:
DEBUG_FUNCTION_LINE("Unknown relocation type: %02X\n",type);
goto exit_error;
case R_PPC_ADDR32:
case R_PPC_ADDR24:
case R_PPC_ADDR16:
case R_PPC_ADDR16_HI:
case R_PPC_ADDR16_HA:
case R_PPC_ADDR16_LO:
case R_PPC_ADDR14:
case R_PPC_ADDR14_BRTAKEN:
case R_PPC_ADDR14_BRNTAKEN:
case R_PPC_UADDR32:
case R_PPC_UADDR16: {
value = (int)symbol_addr + addend;
break;
}
case R_PPC_REL24:
case R_PPC_PLTREL24:
case R_PPC_LOCAL24PC:
case R_PPC_REL14:
case R_PPC_REL14_BRTAKEN:
case R_PPC_REL14_BRNTAKEN:
case R_PPC_REL32:
case R_PPC_ADDR30: {
value = (int)symbol_addr + addend - (int)target;
break;
}
case R_PPC_SECTOFF:
case R_PPC_SECTOFF_LO:
case R_PPC_SECTOFF_HI:
case R_PPC_SECTOFF_HA: {
value = offset + addend;
break;
}
case R_PPC_EMB_NADDR32:
case R_PPC_EMB_NADDR16:
case R_PPC_EMB_NADDR16_LO:
case R_PPC_EMB_NADDR16_HI:
case R_PPC_EMB_NADDR16_HA: {
value = addend - (int)symbol_addr;
break;
}
default:
DEBUG_FUNCTION_LINE("Unknown relocation type: %02X\n",type);
goto exit_error;
}
switch (type) {
case R_PPC_ADDR32:
case R_PPC_UADDR32:
case R_PPC_REL32:
case R_PPC_SECTOFF:
case R_PPC_EMB_NADDR32: {
*(int *)target = value;
break;
} case R_PPC_ADDR24:
case R_PPC_PLTREL24:
case R_PPC_LOCAL24PC:
case R_PPC_REL24: {
*(int *)target =
(*(int *)target & 0xfc000003) | (value & 0x03fffffc);
break;
} case R_PPC_ADDR16:
case R_PPC_UADDR16:
case R_PPC_EMB_NADDR16: {
*(short *)target = value;
break;
} case R_PPC_ADDR16_HI:
case R_PPC_SECTOFF_HI:
case R_PPC_EMB_NADDR16_HI: {
*(short *)target = value >> 16;
break;
} case R_PPC_ADDR16_HA:
case R_PPC_SECTOFF_HA:
case R_PPC_EMB_NADDR16_HA: {
*(short *)target = (value >> 16) + ((value >> 15) & 1);
break;
} case R_PPC_ADDR16_LO:
case R_PPC_SECTOFF_LO:
case R_PPC_EMB_NADDR16_LO: {
*(short *)target = value & 0xffff;
break;
} case R_PPC_ADDR14:
case R_PPC_REL14: {
*(int *)target =
(*(int *)target & 0xffff0003) | (value & 0x0000fffc);
break;
} case R_PPC_ADDR14_BRTAKEN:
case R_PPC_REL14_BRTAKEN: {
*(int *)target =
(*(int *)target & 0xffdf0003) | (value & 0x0000fffc) |
0x00200000;
break;
} case R_PPC_ADDR14_BRNTAKEN:
case R_PPC_REL14_BRNTAKEN: {
*(int *)target =
(*(int *)target & 0xffdf0003) | (value & 0x0000fffc);
break;
} case R_PPC_ADDR30: {
*(int *)target =
(*(int *)target & 0x00000003) | (value & 0xfffffffc);
break;
}default:
goto exit_error;
case R_PPC_ADDR32:
case R_PPC_UADDR32:
case R_PPC_REL32:
case R_PPC_SECTOFF:
case R_PPC_EMB_NADDR32: {
*(int *)target = value;
break;
}
case R_PPC_ADDR24:
case R_PPC_PLTREL24:
case R_PPC_LOCAL24PC:
case R_PPC_REL24: {
*(int *)target =
(*(int *)target & 0xfc000003) | (value & 0x03fffffc);
break;
}
case R_PPC_ADDR16:
case R_PPC_UADDR16:
case R_PPC_EMB_NADDR16: {
*(short *)target = value;
break;
}
case R_PPC_ADDR16_HI:
case R_PPC_SECTOFF_HI:
case R_PPC_EMB_NADDR16_HI: {
*(short *)target = value >> 16;
break;
}
case R_PPC_ADDR16_HA:
case R_PPC_SECTOFF_HA:
case R_PPC_EMB_NADDR16_HA: {
*(short *)target = (value >> 16) + ((value >> 15) & 1);
break;
}
case R_PPC_ADDR16_LO:
case R_PPC_SECTOFF_LO:
case R_PPC_EMB_NADDR16_LO: {
*(short *)target = value & 0xffff;
break;
}
case R_PPC_ADDR14:
case R_PPC_REL14: {
*(int *)target =
(*(int *)target & 0xffff0003) | (value & 0x0000fffc);
break;
}
case R_PPC_ADDR14_BRTAKEN:
case R_PPC_REL14_BRTAKEN: {
*(int *)target =
(*(int *)target & 0xffdf0003) | (value & 0x0000fffc) |
0x00200000;
break;
}
case R_PPC_ADDR14_BRNTAKEN:
case R_PPC_REL14_BRNTAKEN: {
*(int *)target =
(*(int *)target & 0xffdf0003) | (value & 0x0000fffc);
break;
}
case R_PPC_ADDR30: {
*(int *)target =
(*(int *)target & 0x00000003) | (value & 0xfffffffc);
break;
}
default:
goto exit_error;
}
result = true;

View File

@@ -36,7 +36,7 @@ extern "C" {
}
#endif
class ElfTools{
class ElfTools {
public:
static bool elfLoadSection(const Elf *elf, Elf_Scn *scn, const Elf32_Shdr *shdr,void *destination);

View File

@@ -21,28 +21,28 @@
#include <wups.h>
#include <string>
class HookData{
class HookData {
public:
HookData(void * function_pointer, wups_loader_hook_type_t type){
HookData(void * function_pointer, wups_loader_hook_type_t type) {
this->function_pointer = function_pointer;
this->type = type;
}
~HookData(){
~HookData() {
}
void * getFunctionPointer(){
void * getFunctionPointer() {
return function_pointer;
}
wups_loader_hook_type_t getType(){
wups_loader_hook_type_t getType() {
return this->type;
}
private:
void * function_pointer;
wups_loader_hook_type_t type;
void * function_pointer;
wups_loader_hook_type_t type;
};

View File

@@ -35,52 +35,52 @@ extern "C" {
}
#endif
class PluginData{
public:
PluginData(PluginInformation * pluginInformation){
this->pluginInformation = pluginInformation;
}
class PluginData {
public:
PluginData(PluginInformation * pluginInformation) {
this->pluginInformation = pluginInformation;
}
~PluginData(){
for(size_t i = 0;i< function_data_list.size();i++){
if(function_data_list[i] != NULL){
delete function_data_list[i];
}
}
for(size_t i = 0;i< hook_data_list.size();i++){
if(hook_data_list[i] != NULL){
delete hook_data_list[i];
}
~PluginData() {
for(size_t i = 0; i< function_data_list.size(); i++) {
if(function_data_list[i] != NULL) {
delete function_data_list[i];
}
}
void addFunctionData(FunctionData * function_data){
function_data_list.push_back(function_data);
for(size_t i = 0; i< hook_data_list.size(); i++) {
if(hook_data_list[i] != NULL) {
delete hook_data_list[i];
}
}
}
std::vector<FunctionData *> getFunctionDataList(){
return function_data_list;
}
void addFunctionData(FunctionData * function_data) {
function_data_list.push_back(function_data);
}
void addHookData(HookData * hook_data){
hook_data_list.push_back(hook_data);
}
std::vector<FunctionData *> getFunctionDataList() {
return function_data_list;
}
std::vector<HookData *> getHookDataList(){
return hook_data_list;
}
void addHookData(HookData * hook_data) {
hook_data_list.push_back(hook_data);
}
PluginInformation * getPluginInformation(){
return pluginInformation;
}
std::vector<HookData *> getHookDataList() {
return hook_data_list;
}
private:
PluginInformation * getPluginInformation() {
return pluginInformation;
}
PluginInformation * pluginInformation;
private:
std::vector<FunctionData *> function_data_list;
std::vector<HookData *> hook_data_list;
PluginInformation * pluginInformation;
std::vector<FunctionData *> function_data_list;
std::vector<HookData *> hook_data_list;
};

View File

@@ -37,27 +37,27 @@
#include "ElfTools.h"
bool PluginInformation::checkFileExtenstion(const char * path) {
if(path == NULL){
if(path == NULL) {
return false;
}
const char *extension;
/* find the file extension */
extension = strrchr(path, '.');
if (extension == NULL){
if (extension == NULL) {
extension = strchr(path, '\0');
}else{
} else {
extension++;
}
if(extension == NULL){
if(extension == NULL) {
return false;
}
if (strcmp(extension, "mod") == 0 ||
strcmp(extension, "o") == 0 ||
strcmp(extension, "a") == 0 ||
strcmp(extension, "elf") == 0) {
strcmp(extension, "o") == 0 ||
strcmp(extension, "a") == 0 ||
strcmp(extension, "elf") == 0) {
return true;
}
return false;
@@ -69,42 +69,42 @@ bool PluginInformation::openAndParseElf() {
Elf *elf = NULL;
/* check for compile errors */
if (elf_version(EV_CURRENT) == EV_NONE){
if (elf_version(EV_CURRENT) == EV_NONE) {
goto exit_error;
}
fd = open(getPath().c_str(), O_RDONLY, 0);
if (fd == -1){
if (fd == -1) {
DEBUG_FUNCTION_LINE("failed to open '%s' \n", getPath().c_str());
goto exit_error;
}
elf = elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL){
if (elf == NULL) {
DEBUG_FUNCTION_LINE("elf was NULL\n");
goto exit_error;
}
switch (elf_kind(elf)) {
case ELF_K_AR:
/* TODO */
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Archives not yet supported.\n", getPath().c_str());
goto exit_error;
case ELF_K_ELF:
result = this->parseElf(elf);
break;
default:
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF file.\n", getPath().c_str());
goto exit_error;
case ELF_K_AR:
/* TODO */
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Archives not yet supported.\n", getPath().c_str());
goto exit_error;
case ELF_K_ELF:
result = this->parseElf(elf);
break;
default:
DEBUG_FUNCTION_LINE("Warning: Ignoring '%s' - Invalid ELF file.\n", getPath().c_str());
goto exit_error;
}
exit_error:
if (elf != NULL){
if (elf != NULL) {
elf_end(elf);
}
if (fd != -1){
if (fd != -1) {
close(fd);
}
return result;
@@ -122,8 +122,12 @@ bool PluginInformation::parseElf( Elf *elf) {
const char * path_c = getPath().c_str();
if(elf == NULL){ goto exit_error; }
if(elf_kind(elf) != ELF_K_ELF){ goto exit_error; }
if(elf == NULL) {
goto exit_error;
}
if(elf_kind(elf) != ELF_K_ELF) {
goto exit_error;
}
ident = elf_getident(elf, &sz);
@@ -172,9 +176,11 @@ bool PluginInformation::parseElf( Elf *elf) {
goto exit_error;
}
if(symtab == NULL){ goto exit_error; }
if(symtab == NULL) {
goto exit_error;
}
if(!metadataRead(elf, symtab, symtab_count, symtab_strndx)){
if(!metadataRead(elf, symtab, symtab_count, symtab_strndx)) {
goto exit_error;
}
@@ -187,17 +193,17 @@ bool PluginInformation::parseElf( Elf *elf) {
Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn);
if (shdr == NULL){
if (shdr == NULL) {
continue;
}
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
(shdr->sh_flags & SHF_ALLOC)) {
(shdr->sh_flags & SHF_ALLOC)) {
const char *name;
name = elf_strptr(elf, shstrndx, shdr->sh_name);
if (name == NULL){
if (name == NULL) {
continue;
}
@@ -212,10 +218,10 @@ bool PluginInformation::parseElf( Elf *elf) {
} else {
cur_size += shdr->sh_size;
/* add alignment padding to size */
if (shdr->sh_addralign > 3){
if (shdr->sh_addralign > 3) {
/* roundup to multiple of sh_addralign */
cur_size += (-cur_size & (shdr->sh_addralign - 1));
}else{
} else {
/* roundup to multiple of 4 */
cur_size += (-cur_size & 3);
}
@@ -230,7 +236,7 @@ bool PluginInformation::parseElf( Elf *elf) {
res = true;
exit_error:
if (symtab != NULL){
if (symtab != NULL) {
free(symtab);
}
@@ -254,27 +260,27 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
const char *name;
shdr = elf32_getshdr(scn);
if (shdr == NULL){
if (shdr == NULL) {
continue;
}
name = elf_strptr(elf, shstrndx, shdr->sh_name);
if (name == NULL){
if (name == NULL) {
continue;
}
if (strcmp(name, ".wups.meta") == 0) {
if (shdr->sh_size == 0){
if (shdr->sh_size == 0) {
continue;
}
if (metadata != NULL){
if (metadata != NULL) {
continue;
}
metadata = (char*) malloc(shdr->sh_size);
if (metadata == NULL){
if (metadata == NULL) {
continue;
}
@@ -312,16 +318,16 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
char *eq;
if(metadata_cur < metadata || metadata_cur >= metadata_end){
if(metadata_cur < metadata || metadata_cur >= metadata_end) {
goto exit_error;
}
if (*metadata_cur == '\0'){
if (*metadata_cur == '\0') {
continue;
}
eq = strchr(metadata_cur, '=');
if (eq == NULL){
if (eq == NULL) {
continue;
}
@@ -370,7 +376,7 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
}
}
if (description == NULL){
if (description == NULL) {
description = "";
}
@@ -410,7 +416,7 @@ bool PluginInformation::metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_
exit_error:
if (metadata != NULL){
if (metadata != NULL) {
free(metadata);
}
return false;

View File

@@ -42,109 +42,109 @@ extern "C" {
}
#endif
class PluginInformation{
public:
/**
class PluginInformation {
public:
/**
returns PluginInformation* if a valid plugin was found at the given path. Otherwise returns NULL
**/
static PluginInformation * loadPluginInformation(std::string path){
if(PluginInformation::checkFileExtenstion(path.c_str())){
DEBUG_FUNCTION_LINE("Checkfile successfully, loading now Plugin Information\n");
PluginInformation * pluginInformation = new PluginInformation(path);
if(pluginInformation->openAndParseElf()){
return pluginInformation;
}else{
delete pluginInformation;
return NULL;
}
returns PluginInformation* if a valid plugin was found at the given path. Otherwise returns NULL
**/
static PluginInformation * loadPluginInformation(std::string path) {
if(PluginInformation::checkFileExtenstion(path.c_str())) {
DEBUG_FUNCTION_LINE("Checkfile successfully, loading now Plugin Information\n");
PluginInformation * pluginInformation = new PluginInformation(path);
if(pluginInformation->openAndParseElf()) {
return pluginInformation;
} else {
delete pluginInformation;
return NULL;
}
} else {
return NULL;
}
}
std::string getName(){
return this->name;
}
std::string getName() {
return this->name;
}
std::string getAuthor(){
return this->author;
}
std::string getAuthor() {
return this->author;
}
std::string getVersion(){
return this->version;
}
std::string getVersion() {
return this->version;
}
std::string getLicense(){
return this->license;
}
std::string getLicense() {
return this->license;
}
std::string getBuildTimestamp(){
return this->buildtimestamp;
}
std::string getBuildTimestamp() {
return this->buildtimestamp;
}
std::string getDescription(){
return this->description;
}
std::string getDescription() {
return this->description;
}
std::string getPath(){
return path;
}
std::string getPath() {
return path;
}
size_t getSize(){
return this->size;
}
private:
PluginInformation(std::string path){
this->path = path;
}
size_t getSize() {
return this->size;
}
private:
PluginInformation(std::string path) {
this->path = path;
}
void setName(const char * name){
this->name = name;
}
void setName(const char * name) {
this->name = name;
}
void setAuthor(const char * author){
this->author = author;
}
void setAuthor(const char * author) {
this->author = author;
}
void setVersion(const char * version){
this->version = version;
}
void setVersion(const char * version) {
this->version = version;
}
void setLicense(const char * license){
this->license = license;
}
void setLicense(const char * license) {
this->license = license;
}
void setBuildTimestamp(const char * buildtimestamp){
this->buildtimestamp = buildtimestamp;
}
void setBuildTimestamp(const char * buildtimestamp) {
this->buildtimestamp = buildtimestamp;
}
void setDescription(const char * description){
this->description = description;
}
void setDescription(const char * description) {
this->description = description;
}
void setSize(size_t size){
this->size = size;
}
void setSize(size_t size) {
this->size = size;
}
static bool checkFileExtenstion(const char * path);
static bool checkFileExtenstion(const char * path);
bool openAndParseElf();
bool openAndParseElf();
bool parseElf(Elf *elf);
bool parseElf(Elf *elf);
bool metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx);
bool metadataRead(Elf *elf, Elf32_Sym *symtab, size_t symtab_count, size_t symtab_strndx);
bool loadedSuccessfully = false;
bool loadedSuccessfully = false;
std::string path;
std::string name;
std::string author;
std::string version;
std::string license;
std::string buildtimestamp;
std::string description;
size_t size;
std::string path;
std::string name;
std::string author;
std::string version;
std::string license;
std::string buildtimestamp;
std::string description;
size_t size;
};

View File

@@ -36,36 +36,36 @@
PluginLoader * PluginLoader::instance = NULL;
std::vector<PluginInformation *> PluginLoader::getPluginInformation(const char * path){
std::vector<PluginInformation *> PluginLoader::getPluginInformation(const char * path) {
std::vector<PluginInformation *> result;
struct dirent *dp;
DIR *dfd = NULL;
if(path == NULL){
if(path == NULL) {
DEBUG_FUNCTION_LINE("Path was NULL");
return result;
}
if ((dfd = opendir(path)) == NULL){
if ((dfd = opendir(path)) == NULL) {
DEBUG_FUNCTION_LINE("Couldn't open dir %s",path);
return result;
}
while ((dp = readdir(dfd)) != NULL){
while ((dp = readdir(dfd)) != NULL) {
struct stat stbuf ;
std::string full_file_path = StringTools::strfmt("%s/%s",path,dp->d_name);
StringTools::RemoveDoubleSlashs(full_file_path);
if( stat(full_file_path.c_str(),&stbuf ) == -1 ){
if( stat(full_file_path.c_str(),&stbuf ) == -1 ) {
DEBUG_FUNCTION_LINE("Unable to stat file: %s\n",full_file_path.c_str()) ;
continue;
}
if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR ){ // Skip directories
if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR ) { // Skip directories
continue;
}else{
} else {
DEBUG_FUNCTION_LINE("Found file: %s\n",full_file_path.c_str()) ;
PluginInformation * plugin = PluginInformation::loadPluginInformation(full_file_path);
if(plugin != NULL){
if(plugin != NULL) {
DEBUG_FUNCTION_LINE("Found plugin %s by %s. Built on %s Size: %d kb \n",plugin->getName().c_str(),plugin->getAuthor().c_str(),plugin->getBuildTimestamp().c_str(),plugin->getSize()/1024) ;
DEBUG_FUNCTION_LINE("Description: %s \n",plugin->getDescription().c_str()) ;
result.push_back(plugin);
@@ -78,24 +78,24 @@ std::vector<PluginInformation *> PluginLoader::getPluginInformation(const char *
return result;
}
std::vector<PluginInformation *> PluginLoader::getPluginsLoadedInMemory(){
std::vector<PluginInformation *> PluginLoader::getPluginsLoadedInMemory() {
std::vector<PluginInformation *> pluginInformation;
for(s32 i = 0; i < gbl_replacement_data.number_used_plugins; i++){
for(s32 i = 0; i < gbl_replacement_data.number_used_plugins; i++) {
replacement_data_plugin_t * pluginInfo = &gbl_replacement_data.plugin_data[i];
PluginInformation * curPlugin = PluginInformation::loadPluginInformation(pluginInfo->path);
if(curPlugin != NULL){
if(curPlugin != NULL) {
pluginInformation.push_back(curPlugin);
}
}
return pluginInformation;
}
void PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInformation){
void PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInformation) {
std::vector<PluginData *> loadedPlugins;
for(size_t i = 0;i < pluginInformation.size(); i++){
for(size_t i = 0; i < pluginInformation.size(); i++) {
PluginInformation * cur_info = pluginInformation[i];
PluginData * pluginData = loadAndLinkPlugin(cur_info);
if(pluginData == NULL){
if(pluginData == NULL) {
DEBUG_FUNCTION_LINE("loadAndLinkPlugins failed for %d\n",i) ;
continue;
} else {
@@ -107,81 +107,81 @@ void PluginLoader::loadAndLinkPlugins(std::vector<PluginInformation *> pluginInf
clearPluginData(loadedPlugins);
}
void PluginLoader::clearPluginData(std::vector<PluginData *> pluginData){
for(size_t i = 0;i < pluginData.size(); i++){
void PluginLoader::clearPluginData(std::vector<PluginData *> pluginData) {
for(size_t i = 0; i < pluginData.size(); i++) {
PluginData * curPluginData = pluginData[i];
if(curPluginData != NULL){
if(curPluginData != NULL) {
delete curPluginData;
}
}
}
void PluginLoader::clearPluginInformation(std::vector<PluginInformation *> pluginInformation){
for(size_t i = 0;i < pluginInformation.size(); i++){
void PluginLoader::clearPluginInformation(std::vector<PluginInformation *> pluginInformation) {
for(size_t i = 0; i < pluginInformation.size(); i++) {
PluginInformation * curPluginInformation = pluginInformation[i];
if(curPluginInformation != NULL){
if(curPluginInformation != NULL) {
delete curPluginInformation;
}
}
}
PluginData * PluginLoader::loadAndLinkPlugin(PluginInformation * pluginInformation){
PluginData * PluginLoader::loadAndLinkPlugin(PluginInformation * pluginInformation) {
PluginData * result = NULL;
int fd = -1;
Elf *elf = NULL;
if(pluginInformation == NULL){
if(pluginInformation == NULL) {
DEBUG_FUNCTION_LINE("pluginInformation was NULL\n");
goto exit_error;
}
if(pluginInformation->getSize() > ((u32) this->getCurrentStoreAddress() - (u32) this->startAddress)){
if(pluginInformation->getSize() > ((u32) this->getCurrentStoreAddress() - (u32) this->startAddress)) {
DEBUG_FUNCTION_LINE("Not enough space left to loader the plugin into memory\n");
goto exit_error;
}
/* check for compile errors */
if (elf_version(EV_CURRENT) == EV_NONE){
if (elf_version(EV_CURRENT) == EV_NONE) {
goto exit_error;
}
fd = open(pluginInformation->getPath().c_str(), O_RDONLY, 0);
if (fd == -1){
if (fd == -1) {
DEBUG_FUNCTION_LINE("failed to open '%s' \n", pluginInformation->getPath().c_str());
goto exit_error;
}
elf = elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL){
if (elf == NULL) {
DEBUG_FUNCTION_LINE("elf was NULL\n");
goto exit_error;
}
result = new PluginData(pluginInformation);
if(result == NULL){
if(result == NULL) {
DEBUG_FUNCTION_LINE("Failed to create object\n");
goto exit_error;
}
if(!this->loadAndLinkElf(result, elf, this->getCurrentStoreAddress())){
if(!this->loadAndLinkElf(result, elf, this->getCurrentStoreAddress())) {
delete result;
result = NULL;
}
exit_error:
if (elf != NULL){
if (elf != NULL) {
elf_end(elf);
}
if (fd != -1){
if (fd != -1) {
close(fd);
}
return result;
}
bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endAddress) {
if(pluginData == NULL || elf == NULL || endAddress == NULL){
if(pluginData == NULL || elf == NULL || endAddress == NULL) {
return false;
}
@@ -203,18 +203,18 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
std::vector<FunctionData *> function_data_list;
std::vector<HookData *> hook_data_list;
if (!ElfTools::loadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx)){
if (!ElfTools::loadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx)) {
goto exit_error;
}
if(symtab == NULL){
goto exit_error;
}
if (elf_getshdrnum(elf, &section_count) != 0){
if(symtab == NULL) {
goto exit_error;
}
if (elf_getshdrstrndx(elf, &shstrndx) != 0){
if (elf_getshdrnum(elf, &section_count) != 0) {
goto exit_error;
}
if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
goto exit_error;
}
@@ -224,85 +224,85 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn);
if (shdr == NULL){
if (shdr == NULL) {
continue;
}
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
(shdr->sh_flags & SHF_ALLOC)) {
(shdr->sh_flags & SHF_ALLOC)) {
const char *name;
destinations[elf_ndxscn(scn)] = NULL;
name = elf_strptr(elf, shstrndx, shdr->sh_name);
if (name == NULL){
if (name == NULL) {
continue;
}
if (strcmp(name, ".wups.meta") == 0) {
continue;
} else if (strcmp(name, ".wups.load") == 0) {
if (entries != NULL){
if (entries != NULL) {
goto exit_error;
}
entries_count = shdr->sh_size / sizeof(wups_loader_entry_t);
entries = (wups_loader_entry_t *) malloc(sizeof(wups_loader_entry_t) * entries_count);
if (entries == NULL){
if (entries == NULL) {
goto exit_error;
}
destinations[elf_ndxscn(scn)] = (uint8_t *)entries;
if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)){
if (!ElfTools::elfLoadSection(elf, scn, shdr, entries)) {
goto exit_error;
}
ElfTools::elfLoadSymbols(elf_ndxscn(scn), entries, symtab, symtab_count);
for(size_t i = 0;i< entries_count;i++){
for(size_t i = 0; i< entries_count; i++) {
entry_t_list.push_back(&entries[i]);
}
}else if (strcmp(name, ".wups.hooks") == 0) {
if (hooks != NULL){
} else if (strcmp(name, ".wups.hooks") == 0) {
if (hooks != NULL) {
goto exit_error;
}
hooks_count = shdr->sh_size / sizeof(wups_loader_hook_t);
hooks = (wups_loader_hook_t *) malloc(sizeof(wups_loader_hook_t) * hooks_count);
if (hooks == NULL){
if (hooks == NULL) {
goto exit_error;
}
destinations[elf_ndxscn(scn)] = (uint8_t *)hooks;
if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)){
if (!ElfTools::elfLoadSection(elf, scn, shdr, hooks)) {
goto exit_error;
}
ElfTools::elfLoadSymbols(elf_ndxscn(scn), hooks, symtab, symtab_count);
for(size_t i = 0;i< hooks_count;i++){
for(size_t i = 0; i< hooks_count; i++) {
hook_t_list.push_back(&hooks[i]);
}
} else {
curAddress -= shdr->sh_size;
if (shdr->sh_addralign > 3){
curAddress = (u32)((int)curAddress & ~(shdr->sh_addralign - 1));
if (shdr->sh_addralign > 3) {
curAddress = (u32)((int)curAddress & ~(shdr->sh_addralign - 1));
} else {
curAddress = (u32)((int)curAddress & ~3);
}
destinations[elf_ndxscn(scn)] = (uint8_t *) curAddress;
if((u32) curAddress < (u32) this->startAddress){
if((u32) curAddress < (u32) this->startAddress) {
DEBUG_FUNCTION_LINE("Not enough space to load function %s into memory at %08X.\n",name,curAddress);
goto exit_error;
}
//DEBUG_FUNCTION_LINE("Copy section %s to %08X\n",name,curAddress);
if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) curAddress)){
if (!ElfTools::elfLoadSection(elf, scn, shdr, (void*) curAddress)) {
goto exit_error;
}
ElfTools::elfLoadSymbols(elf_ndxscn(scn), (void*) curAddress, symtab, symtab_count);
@@ -314,21 +314,21 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
Elf32_Shdr *shdr;
shdr = elf32_getshdr(scn);
if (shdr == NULL){
if (shdr == NULL) {
continue;
}
if ((shdr->sh_type == SHT_PROGBITS || shdr->sh_type == SHT_NOBITS) &&
(shdr->sh_flags & SHF_ALLOC) &&
destinations[elf_ndxscn(scn)] != NULL) {
(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)) {
goto exit_error;
}
}
}
for(size_t j=0;j<hook_t_list.size();j++){
for(size_t j=0; j<hook_t_list.size(); j++) {
wups_loader_hook_t * hook = hook_t_list[j];
DEBUG_FUNCTION_LINE("Saving hook of plugin \"%s\". Type: %08X, target: %08X\n",pluginData->getPluginInformation()->getName().c_str(),hook->type,(void*) hook->target);
@@ -336,7 +336,7 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
pluginData->addHookData(hook_data);
}
for(size_t j=0;j<entry_t_list.size();j++){
for(size_t j=0; j<entry_t_list.size(); j++) {
wups_loader_entry_t * cur_function = entry_t_list[j];
DEBUG_FUNCTION_LINE("Saving function \"%s\" of plugin \"%s\". Library: %08X, target: %08X, call_addr: %08X\n",cur_function->_function.name,pluginData->getPluginInformation()->getName().c_str(),cur_function->_function.library,cur_function->_function.target, (void *) cur_function->_function.call_addr);
FunctionData * function_data = new FunctionData(cur_function->_function.name,cur_function->_function.library, (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr);
@@ -348,41 +348,41 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * endA
result = true;
exit_error:
if (!result) DEBUG_FUNCTION_LINE("exit_error\n");
if (destinations != NULL){
if (destinations != NULL) {
free(destinations);
}
if (symtab != NULL){
if (symtab != NULL) {
free(symtab);
}
if (hooks != NULL){
if (hooks != NULL) {
free(hooks);
}
if (entries != NULL){
if (entries != NULL) {
free(entries);
}
return result;
}
void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins){
void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins) {
// Reset data
memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data));
int plugin_index = 0;
// Copy data to global struct.
for(size_t i = 0; i< plugins.size();i++){
for(size_t i = 0; i< plugins.size(); i++) {
PluginData * cur_plugin = plugins.at(i);
PluginInformation * cur_pluginInformation = cur_plugin->getPluginInformation();
std::vector<FunctionData *> function_data_list = cur_plugin->getFunctionDataList();
std::vector<HookData *> hook_data_list = cur_plugin->getHookDataList();
if(plugin_index >= MAXIMUM_PLUGINS ){
if(plugin_index >= MAXIMUM_PLUGINS ) {
DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!\n",MAXIMUM_PLUGINS,cur_pluginInformation->getName().c_str());
continue;
}
if(function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN){
if(function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),function_data_list.size(),MAXIMUM_FUNCTION_PER_PLUGIN);
continue;
}
if(hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN){
if(hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would set too many hooks (%d, maximum is %d). It won't be loaded.\n",cur_pluginInformation->getName().c_str(),hook_data_list.size(),MAXIMUM_HOOKS_PER_PLUGIN);
continue;
}
@@ -392,7 +392,7 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
strncpy(plugin_data->plugin_name,cur_pluginInformation->getName().c_str(),MAXIMUM_PLUGIN_NAME_LENGTH-1);
strncpy(plugin_data->path,cur_pluginInformation->getPath().c_str(),MAXIMUM_PLUGIN_PATH_NAME_LENGTH-1);
for(size_t j = 0; j < function_data_list.size();j++){
for(size_t j = 0; j < function_data_list.size(); j++) {
replacement_data_function_t * function_data = &plugin_data->functions[j];
FunctionData * cur_function = function_data_list[j];
@@ -410,7 +410,7 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
DEBUG_FUNCTION_LINE("Entries for plugin \"%s\": %d\n",plugin_data->plugin_name,plugin_data->number_used_functions);
for(size_t j = 0; j < hook_data_list.size();j++){
for(size_t j = 0; j < hook_data_list.size(); j++) {
replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
HookData * hook_entry = hook_data_list[j];

View File

@@ -44,18 +44,18 @@ extern "C" {
#define PLUGIN_LOCATION_END_ADDRESS 0x01000000
class PluginLoader{
class PluginLoader {
public:
static PluginLoader *getInstance() {
if(!instance){
if(!instance) {
instance = new PluginLoader((void*)getApplicationEndAddr(),(void *)PLUGIN_LOCATION_END_ADDRESS);
}
return instance;
}
static void destroyInstance() {
if(instance){
if(instance) {
delete instance;
instance = NULL;
}
@@ -95,27 +95,27 @@ public:
**/
void clearPluginInformation(std::vector<PluginInformation*> PluginInformation);
size_t getTotalSpace(){
size_t getTotalSpace() {
return ((u32) this->endAddress - (u32) this->startAddress);
}
size_t getAvailableSpace(){
size_t getAvailableSpace() {
return ((u32) this->currentStoreAddress - (u32) this->startAddress);
}
size_t getUsedSpace(){
size_t getUsedSpace() {
return getTotalSpace() - getAvailableSpace();
}
private:
PluginLoader(void * startAddress, void * endAddress){
PluginLoader(void * startAddress, void * endAddress) {
// TODO: Check if endAddress > startAddress.
this->startAddress = startAddress;
this->endAddress = endAddress;
this->currentStoreAddress = endAddress;
}
~PluginLoader(){
~PluginLoader() {
}
@@ -147,19 +147,19 @@ private:
**/
bool loadAndLinkElf(PluginData * pluginData, Elf *elf, void * storeAddressEnd);
/**
\brief Copies the needed information into a global, persistent struct. This struct holds information on which
function should be override in which order and which hook should be called.
\param plugins list of plugins that should be used.
/**
\brief Copies the needed information into a global, persistent struct. This struct holds information on which
function should be override in which order and which hook should be called.
\param plugins list of plugins that should be used.
**/
void copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plugins);
void * getCurrentStoreAddress(){
void * getCurrentStoreAddress() {
return this->currentStoreAddress;
}
void setCurrentStoreAddress(void * addr){
void setCurrentStoreAddress(void * addr) {
this->currentStoreAddress = addr;
}