Add support SHN_COMMON relocations (not tested)

This commit is contained in:
Maschell 2018-06-19 16:12:47 +02:00
parent 9a15e549c7
commit 8c04d34d39
6 changed files with 89 additions and 11 deletions

View File

@ -12,3 +12,7 @@ int ntfs_mount_count __attribute__((section(".data"))) = 0;
struct buffer_store drc_store __attribute__((section(".data"))); struct buffer_store drc_store __attribute__((section(".data")));
struct buffer_store tv_store __attribute__((section(".data"))); struct buffer_store tv_store __attribute__((section(".data")));
char gbl_common_data[0x20000] __attribute__((section(".data")));
char * gbl_common_data_ptr __attribute__((section(".data"))) = gbl_common_data;

View File

@ -268,8 +268,21 @@ bool ElfTools::elfLink(Elf *elf, size_t shndx, void *destination, Elf32_Sym *sym
break; break;
} }
case SHN_COMMON: { case SHN_COMMON: {
DEBUG_FUNCTION_LINE("case SHN_COMMON\n"); u32 align = symtab[symbol].st_value;
return false; u32 size = symtab[symbol].st_size;
uint32_t address = pluginData->getMemoryForCommonBySymbol(symbol, align, size);
if(address == NULL){
DEBUG_FUNCTION_LINE("Failed to get memory for common relocation\n");
return false;
}
if (!ElfTools::elfLinkOne(ELF32_R_TYPE(rela[i].r_info), rela[i].r_offset,rela[i].r_addend, destination, address)) {
DEBUG_FUNCTION_LINE("elfLinkOne failed\n");
return false;
}
break;
} }
case SHN_UNDEF: { case SHN_UNDEF: {
if (allow_globals) { if (allow_globals) {

View File

@ -0,0 +1,43 @@
/****************************************************************************
* 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/>.
****************************************************************************/
#include <string>
#include <vector>
#include <map>
#include "PluginData.h"
#include "PluginLoader.h"
ImportRPLInformation * PluginData::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;
}
uint32_t PluginData::getMemoryForCommonBySymbol(size_t symbol, size_t align, size_t size) {
std::map<size_t,uint32_t>::iterator it = memoryBySymbol.find(symbol);
if(it == memoryBySymbol.end()) {
memoryBySymbol[symbol] = PluginLoader::getInstance()->getMemoryFromDataSection(align, size);
DEBUG_FUNCTION_LINE("Setting value %08X\n",memoryBySymbol.find(symbol)->second);
} else {
DEBUG_FUNCTION_LINE("Using cached value %08X\n",memoryBySymbol.find(symbol)->second);
}
return memoryBySymbol.find(symbol)->second;
}

View File

@ -20,6 +20,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
#include "FunctionData.h" #include "FunctionData.h"
#include "HookData.h" #include "HookData.h"
#include "PluginInformation.h" #include "PluginInformation.h"
@ -108,19 +109,15 @@ public:
\return A pointer to the corresponding ImportRPLInformation, return NULL if no corresponding information was found. \return A pointer to the corresponding ImportRPLInformation, return NULL if no corresponding information was found.
**/ **/
ImportRPLInformation * getImportRPLInformationBySectionHeaderIndex(int section_header_index) { 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() { PluginInformation * getPluginInformation() {
return pluginInformation; return pluginInformation;
} }
uint32_t getMemoryForCommonBySymbol(size_t symbol, size_t align, size_t size);
private: private:
PluginInformation * pluginInformation; PluginInformation * pluginInformation;
@ -129,6 +126,8 @@ private:
std::vector<HookData *> hook_data_list; std::vector<HookData *> hook_data_list;
std::vector<RelocationData *> relocation_data_list; std::vector<RelocationData *> relocation_data_list;
std::vector<ImportRPLInformation *> importRPLInformation_list; std::vector<ImportRPLInformation *> importRPLInformation_list;
std::map<size_t, uint32_t> memoryBySymbol;
}; };

View File

@ -489,3 +489,18 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
DCFlushRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data)); DCFlushRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data));
ICInvalidateRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data)); ICInvalidateRange((void*)&gbl_replacement_data,sizeof(gbl_replacement_data));
} }
uint32_t PluginLoader::getMemoryFromDataSection(size_t align, size_t size) {
uint32_t ptr = (u32)gbl_common_data_ptr;
ptr = (ptr + (align - 1)) & -align; // Round up to align boundary
uint32_t result = ptr;
if((result + size) >= (ptr + sizeof(gbl_common_data))) {
DEBUG_FUNCTION_LINE("No more space =( %08X > %08X\n",(result + size),(ptr + sizeof(gbl_common_data)));
return 0;
}
ptr += size;
gbl_common_data_ptr = (char *) ptr;
return result;
}

View File

@ -27,8 +27,8 @@
#define _PLUGIN_LOADER_H_ #define _PLUGIN_LOADER_H_
#include <vector> #include <vector>
#include "PluginInformation.h"
#include "PluginData.h" #include "PluginData.h"
#include "PluginInformation.h"
#include "dynamic_libs/os_types.h" #include "dynamic_libs/os_types.h"
#include "dynamic_libs/os_functions.h" #include "dynamic_libs/os_functions.h"
@ -42,6 +42,8 @@ extern "C" {
} }
#endif #endif
extern char gbl_common_data[0x20000];
extern char * gbl_common_data_ptr;
#define PLUGIN_LOCATION_END_ADDRESS 0x01000000 #define PLUGIN_LOCATION_END_ADDRESS 0x01000000
@ -123,6 +125,8 @@ public:
this->currentStoreAddress = endAddress; this->currentStoreAddress = endAddress;
} }
uint32_t getMemoryFromDataSection(size_t align, size_t size);
private: private:
PluginLoader(void * startAddress, void * endAddress) { PluginLoader(void * startAddress, void * endAddress) {
// TODO: Check if endAddress > startAddress. // TODO: Check if endAddress > startAddress.