aboutsummaryrefslogtreecommitdiff
path: root/backends/plugins/elf/elf-loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/plugins/elf/elf-loader.cpp')
-rw-r--r--backends/plugins/elf/elf-loader.cpp67
1 files changed, 57 insertions, 10 deletions
diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp
index f7b151ecee..43477e06e2 100644
--- a/backends/plugins/elf/elf-loader.cpp
+++ b/backends/plugins/elf/elf-loader.cpp
@@ -28,6 +28,7 @@
#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER)
#include "backends/plugins/elf/elf-loader.h"
+#include "backends/plugins/elf/memory-manager.h"
#include "common/debug.h"
#include "common/file.h"
@@ -52,7 +53,7 @@ DLObject::DLObject() :
DLObject::~DLObject() {
discardSymtab();
- free(_segment);
+ ELFMemMan.pluginDeallocate(_segment);
_segment = 0;
}
@@ -71,7 +72,7 @@ void DLObject::discardSymtab() {
void DLObject::unload() {
discardSymtab();
- free(_segment);
+ ELFMemMan.pluginDeallocate(_segment);
_segment = 0;
_segmentSize = 0;
@@ -165,7 +166,7 @@ bool DLObject::readProgramHeaders(Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half
}
bool DLObject::loadSegment(Elf32_Phdr *phdr) {
- _segment = (byte *)memalign(phdr->p_align, phdr->p_memsz);
+ _segment = (byte *)ELFMemMan.pluginAllocate(phdr->p_align, phdr->p_memsz);
if (!_segment) {
warning("elfloader: Out of memory.");
@@ -222,19 +223,27 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Elf32_Ehdr *ehdr) {
return shdr;
}
-int DLObject::loadSymbolTable(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) {
- assert(_file);
-
+int DLObject::findSymbolTableSection(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) {
+ int SymbolTableSection = -1;
+
// Loop over sections, looking for symbol table linked to a string table
for (uint32 i = 0; i < ehdr->e_shnum; i++) {
if (shdr[i].sh_type == SHT_SYMTAB &&
shdr[i].sh_entsize == sizeof(Elf32_Sym) &&
shdr[i].sh_link < ehdr->e_shnum &&
- shdr[shdr[i].sh_link].sh_type == SHT_STRTAB &&
- _symtab_sect < 0) {
- _symtab_sect = i;
+ shdr[shdr[i].sh_link].sh_type == SHT_STRTAB) {
+ SymbolTableSection = i;
+ break;
}
}
+
+ return SymbolTableSection;
+}
+
+int DLObject::loadSymbolTable(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) {
+ assert(_file);
+
+ _symtab_sect = findSymbolTableSection(ehdr, shdr);
// Check for no symbol table
if (_symtab_sect < 0) {
@@ -308,6 +317,43 @@ void DLObject::relocateSymbols(ptrdiff_t offset) {
}
}
+// Track the size of the plugin through memory manager without loading
+// the plugin into memory.
+//
+void DLObject::trackSize(const char *path) {
+
+ _file = Common::FSNode(path).createReadStream();
+
+ if (!_file) {
+ warning("elfloader: File %s not found.", path);
+ return;
+ }
+
+ Elf32_Ehdr ehdr;
+ Elf32_Phdr phdr;
+
+ if (!readElfHeader(&ehdr))
+ return;
+
+ ELFMemMan.trackPlugin(true); // begin tracking the plugin size
+
+ // Load the segments
+ for (uint32 i = 0; i < ehdr.e_phnum; i++) {
+ debug(2, "elfloader: Loading segment %d", i);
+
+ if (!readProgramHeaders(&ehdr, &phdr, i))
+ return;
+
+ if (phdr.p_flags & PF_X) { // check for executable, allocated segment
+ ELFMemMan.trackAlloc(phdr.p_align, phdr.p_memsz);
+ }
+ }
+
+ ELFMemMan.trackPlugin(false); // we're done tracking the plugin size
+
+ // No need to track the symbol table sizes -- they get discarded
+}
+
bool DLObject::load() {
Elf32_Ehdr ehdr;
Elf32_Phdr phdr;
@@ -315,7 +361,8 @@ bool DLObject::load() {
if (readElfHeader(&ehdr) == false)
return false;
- for (uint32 i = 0; i < ehdr.e_phnum; i++) { //Load our segments
+ //Load the segments
+ for (uint32 i = 0; i < ehdr.e_phnum; i++) {
debug(2, "elfloader: Loading segment %d", i);
if (readProgramHeaders(&ehdr, &phdr, i) == false)