diff options
-rw-r--r-- | backends/platform/gp2xwiz/elf32.h | 192 | ||||
-rw-r--r-- | backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 485 | ||||
-rw-r--r-- | backends/platform/gp2xwiz/gp2xwiz-loader.h | 79 | ||||
-rw-r--r-- | backends/platform/gp2xwiz/plugin.ld | 182 | ||||
-rw-r--r-- | backends/platform/gp2xwiz/plugin.syms | 8 | ||||
-rw-r--r-- | backends/plugins/arm-loader.cpp | 9 | ||||
-rw-r--r-- | backends/plugins/ds/ds-provider.cpp | 7 | ||||
-rw-r--r-- | backends/plugins/ds/ds-provider.h | 3 | ||||
-rw-r--r-- | backends/plugins/elf-loader.h | 22 | ||||
-rw-r--r-- | backends/plugins/elf-provider.cpp | 33 | ||||
-rw-r--r-- | backends/plugins/elf-provider.h | 6 |
11 files changed, 22 insertions, 1004 deletions
diff --git a/backends/platform/gp2xwiz/elf32.h b/backends/platform/gp2xwiz/elf32.h deleted file mode 100644 index 4ec4455a4f..0000000000 --- a/backends/platform/gp2xwiz/elf32.h +++ /dev/null @@ -1,192 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef BACKENDS_ELF_H -#define BACKENDS_ELF_H - -/* ELF stuff */ - -typedef unsigned short Elf32_Half, Elf32_Section; -typedef unsigned int Elf32_Word, Elf32_Addr, Elf32_Off; -typedef signed int Elf32_Sword; -typedef Elf32_Half Elf32_Versym; - -#define EI_NIDENT (16) -#define SELFMAG 6 - -/* ELF File format structures. Look up ELF structure for more details */ - -// ELF header (contains info about the file) -typedef struct { - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ - Elf32_Half e_type; /* Object file type */ - Elf32_Half e_machine; /* Architecture */ - Elf32_Word e_version; /* Object file version */ - Elf32_Addr e_entry; /* Entry point virtual address */ - Elf32_Off e_phoff; /* Program header table file offset */ - Elf32_Off e_shoff; /* Section header table file offset */ - Elf32_Word e_flags; /* Processor-specific flags */ - Elf32_Half e_ehsize; /* ELF header size in bytes */ - Elf32_Half e_phentsize; /* Program header table entry size */ - Elf32_Half e_phnum; /* Program header table entry count */ - Elf32_Half e_shentsize; /* Section header table entry size */ - Elf32_Half e_shnum; /* Section header table entry count */ - Elf32_Half e_shstrndx; /* Section header string table index */ -} Elf32_Ehdr; - -// Should be in e_ident -#define ELFMAG "\177ELF\1\1" /* ELF Magic number */ - -// e_type values -#define ET_NONE 0 /* no file type */ -#define ET_REL 1 /* relocatable */ -#define ET_EXEC 2 /* executable */ -#define ET_DYN 3 /* shared object */ -#define ET_CORE 4 /* core file */ - -// e_machine values -#define EM_ARM 40 - -// Program header (contains info about segment) -typedef struct { - Elf32_Word p_type; /* Segment type */ - Elf32_Off p_offset; /* Segment file offset */ - Elf32_Addr p_vaddr; /* Segment virtual address */ - Elf32_Addr p_paddr; /* Segment physical address */ - Elf32_Word p_filesz; /* Segment size in file */ - Elf32_Word p_memsz; /* Segment size in memory */ - Elf32_Word p_flags; /* Segment flags */ - Elf32_Word p_align; /* Segment alignment */ -} Elf32_Phdr; - -// p_type values -#define PT_NULL 0 /* ignored */ -#define PT_LOAD 1 /* loadable segment */ -#define PT_DYNAMIC 2 /* dynamic linking info */ -#define PT_INTERP 3 /* info about interpreter */ -#define PT_NOTE 4 /* note segment */ -#define PT_SHLIB 5 /* reserved */ -#define PT_PHDR 6 /* Program header table */ -#define PT_ARM_ARCHEXT 0x70000000 /* Platform architecture compatibility information */ -#define PT_ARM_EXIDX 0x70000001 /* Exception unwind tables */ - -// p_flags value -#define PF_X 1 /* execute */ -#define PF_W 2 /* write */ -#define PF_R 4 /* read */ - -// Section header (contains info about section) -typedef struct { - Elf32_Word sh_name; /* Section name (string tbl index) */ - Elf32_Word sh_type; /* Section type */ - Elf32_Word sh_flags; /* Section flags */ - Elf32_Addr sh_addr; /* Section virtual addr at execution */ - Elf32_Off sh_offset; /* Section file offset */ - Elf32_Word sh_size; /* Section size in bytes */ - Elf32_Word sh_link; /* Link to another section */ - Elf32_Word sh_info; /* Additional section information */ - Elf32_Word sh_addralign; /* Section alignment */ - Elf32_Word sh_entsize; /* Entry size if section holds table */ -} Elf32_Shdr; - -// sh_type values -#define SHT_NULL 0 /* Inactive section */ -#define SHT_PROGBITS 1 /* Proprietary */ -#define SHT_SYMTAB 2 /* Symbol table */ -#define SHT_STRTAB 3 /* String table */ -#define SHT_RELA 4 /* Relocation entries with addend */ -#define SHT_HASH 5 /* Symbol hash table */ -#define SHT_DYNAMIC 6 /* Info for dynamic linking */ -#define SHT_NOTE 7 /* Note section */ -#define SHT_NOBITS 8 /* Occupies no space */ -#define SHT_REL 9 /* Relocation entries without addend */ -#define SHT_SHLIB 10 /* Reserved */ -#define SHT_DYNSYM 11 /* Minimal set of dynamic linking symbols */ -#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table */ -#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map */ -#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes */ - -// sh_flags values -#define SHF_WRITE 0 /* writable section */ -#define SHF_ALLOC 2 /* section occupies memory */ -#define SHF_EXECINSTR 4 /* machine instructions */ - -// Symbol entry (contain info about a symbol) -typedef struct { - Elf32_Word st_name; /* Symbol name (string tbl index) */ - Elf32_Addr st_value; /* Symbol value */ - Elf32_Word st_size; /* Symbol size */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ - Elf32_Section st_shndx; /* Section index */ -} Elf32_Sym; - -// Extract from the st_info -#define SYM_TYPE(x) ((x)&0xF) -#define SYM_BIND(x) ((x)>>4) - -// Symbol binding values from st_info -#define STB_LOCAL 0 /* Symbol not visible outside object */ -#define STB_GLOBAL 1 /* Symbol visible to all object files */ -#define STB_WEAK 2 /* Similar to STB_GLOBAL */ - -// Symbol type values from st_info -#define STT_NOTYPE 0 /* Not specified */ -#define STT_OBJECT 1 /* Data object e.g. variable */ -#define STT_FUNC 2 /* Function */ -#define STT_SECTION 3 /* Section */ -#define STT_FILE 4 /* Source file associated with object file */ - -// Special section header index values from st_shndex -#define SHN_UNDEF 0 -#define SHN_LOPROC 0xFF00 /* Extended values */ -#define SHN_ABS 0xFFF1 /* Absolute value: don't relocate */ -#define SHN_COMMON 0xFFF2 /* Common block. Not allocated yet */ -#define SHN_HIPROC 0xFF1F -#define SHN_HIRESERVE 0xFFFF - -// Relocation entry (info about how to relocate) -typedef struct { - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ - Elf32_Sword r_addend; /* Addend */ -} Elf32_Rela; - -// Access macros for the relocation info -#define REL_TYPE(x) ((unsigned char) (x)) /* Extract relocation type */ -#define REL_INDEX(x) ((x)>>8) /* Extract relocation index into symbol table */ - -// ARM relocation types -#define R_ARM_NONE 0 -#define R_ARM_PC24 1 -#define R_ARM_ABS32 2 -#define R_ARM_COPY 20 -#define R_ARM_GLOB_DAT 21 -#define R_ARM_JUMP_SLOT 22 -#define R_ARM_BASE_PREL 25 -#define R_ARM_GOT_BREL 26 -#define R_ARM_PLT32 27 - -#endif /* BACKENDS_ELF_H */ diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp deleted file mode 100644 index 22aa45fa30..0000000000 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#if defined(DYNAMIC_MODULES) && defined(GP2XWIZ) - -#include <string.h> -#include <stdarg.h> -#include <stdarg.h> -#include <stdio.h> -#include <malloc.h> -#include <unistd.h> -#include <sys/fcntl.h> - - -#include "backends/platform/gp2xwiz/gp2xwiz-loader.h" - -#define __WIZ_DEBUG_PLUGINS__ - -#ifdef __WIZ_DEBUG_PLUGINS__ -#define DBG(x,...) printf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__) - -// Expel the symbol table from memory -void DLObject::discard_symtab() { - free(_symtab); - free(_strtab); - _symtab = NULL; - _strtab = NULL; - _symbol_cnt = 0; -} - -// Unload all objects from memory -void DLObject::unload() { - discard_symtab(); - free(_segment); - _segment = NULL; -} - -/** - * Follow the instruction of a relocation section. - * - * @param fd File Descriptor - * @param offset Offset into the File - * @param size Size of relocation section - * - */ -bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rela *rela; //relocation entry - - // Allocate memory for relocation table - if (!(rela = (Elf32_Rela *)malloc(size))) { - seterror("Out of memory."); - return false; - } - - // Read in our relocation table - if (lseek(fd, offset, SEEK_SET) < 0 || - read(fd, rela, size) != (ssize_t)size) { - seterror("Relocation table load failed."); - free(rela); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rela); - - // TODO: Loop over relocation entries - for (int i = 0; i < cnt; i++) { - - DBG("attempting to relocate!"); - - //Elf32_Sym *sym = ???; - - //void *target = ???; - - /*switch (REL_TYPE()) {*/ - //case ??? : - //TODO: Cases for each relocation type. - //break; - // default: - //seterror("Unknown relocation type %d.", ?? ?); - free(rela); - return false; - // } - - } - - free(rela); - return true; -} - -bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { - - // Start reading the elf header. Check for errors - if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || - memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC - ehdr->e_type != ET_EXEC || // Check for executable - ehdr->e_machine != EM_ARM || // Check for ARM machine type - ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header - ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header - seterror("Invalid file type."); - return false; - } - - DBG("phoff = %d, phentsz = %d, phnum = %d\n", - ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); - - return true; -} - -bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { - - // Read program header - if (lseek(fd, ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || - read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) { - seterror("Program header load failed."); - return false; - } - - // Check program header values - if (phdr->p_type != PT_LOAD || phdr->p_filesz > phdr->p_memsz) { - seterror("Invalid program header."); - return false; - } - - DBG("offs = %x, filesz = %x, memsz = %x, align = %x\n", - phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); - - return true; - -} - -bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { - - char *baseAddress = 0; - - // Attempt to allocate memory for segment - int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here - DBG("extra mem is %x\n", extra); - - if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { - seterror("Out of memory.\n"); - return false; - } - DBG("allocated segment @ %p\n", _segment); - - // Get offset to load segment into - baseAddress = (char *)_segment + phdr->p_vaddr; - _segmentSize = phdr->p_memsz + extra; - - // Set bss segment to 0 if necessary (assumes bss is at the end) - if (phdr->p_memsz > phdr->p_filesz) { - DBG("Setting %p to %p to 0 for bss\n", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); - memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); - } - // Read the segment into memory - if (lseek(fd, phdr->p_offset, SEEK_SET) < 0 || - read(fd, baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { - seterror("Segment load failed."); - return false; - } - - return true; -} - -Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { - - Elf32_Shdr *shdr = NULL; - - // Allocate memory for section headers - if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { - seterror("Out of memory."); - return NULL; - } - - // Read from file into section headers - if (lseek(fd, ehdr->e_shoff, SEEK_SET) < 0 || - read(fd, shdr, ehdr->e_shnum * sizeof(*shdr)) != - (ssize_t)(ehdr->e_shnum * sizeof(*shdr))) { - seterror("Section headers load failed."); - return NULL; - } - - return shdr; -} - -int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { - - // Loop over sections, looking for symbol table linked to a string table - for (int 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; - } - } - - // Check for no symbol table - if (_symtab_sect < 0) { - seterror("No symbol table."); - return -1; - } - - DBG("Symbol section at section %d, size %x\n", _symtab_sect, shdr[_symtab_sect].sh_size); - - // Allocate memory for symbol table - if (!(_symtab = malloc(shdr[_symtab_sect].sh_size))) { - seterror("Out of memory."); - return -1; - } - - // Read symbol table into memory - if (lseek(fd, shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || - read(fd, _symtab, shdr[_symtab_sect].sh_size) != - (ssize_t)shdr[_symtab_sect].sh_size) { - seterror("Symbol table load failed."); - return -1; - } - - // Set number of symbols - _symbol_cnt = shdr[_symtab_sect].sh_size / sizeof(Elf32_Sym); - DBG("Loaded %d symbols.\n", _symbol_cnt); - - return _symtab_sect; - -} - -bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { - - int string_sect = shdr[_symtab_sect].sh_link; - - // Allocate memory for string table - if (!(_strtab = (char *)malloc(shdr[string_sect].sh_size))) { - seterror("Out of memory."); - return false; - } - - // Read string table into memory - if (lseek(fd, shdr[string_sect].sh_offset, SEEK_SET) < 0 || - read(fd, _strtab, shdr[string_sect].sh_size) != - (ssize_t)shdr[string_sect].sh_size) { - seterror("Symbol table strings load failed."); - return false; - } - - return true; -} - -void DLObject::relocateSymbols(Elf32_Addr offset) { - - int relocCount = 0; - DBG("Relocating symbols by %x\n", offset); - - // Loop over symbols, add relocation offset - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) { - // Make sure we don't relocate special valued symbols - if (s->st_shndx < SHN_LOPROC) { - relocCount++; - s->st_value += offset; - if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) - seterror("Symbol out of bounds! st_value = %x\n", s->st_value); - - } - - } - - DBG("Relocated %d symbols.\n",relocCount); -} - -bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { - - // Loop over sections, finding relocation sections - for (int i = 0; i < ehdr->e_shnum; i++) { - - Elf32_Shdr *curShdr = &(shdr[i]); - //Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]); - - if (curShdr->sh_type == SHT_REL && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rela) && // Check for proper relocation size - (int)curShdr->sh_link == _symtab_sect && // Check that the sh_link connects to our symbol table - curShdr->sh_info < ehdr->e_shnum && // Check that the relocated section exists - (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory - - if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, _segment)) { - return false; - } - - } - } - - return true; -} - -bool DLObject::load(int fd) { - Elf32_Ehdr ehdr; - Elf32_Phdr phdr; - Elf32_Shdr *shdr; - bool ret = true; - - //int symtab_sect = -1; - - if (readElfHeader(fd, &ehdr) == false) { - return false; - } - - for (int i = 0; i < ehdr.e_phnum; i++) { // Load our 2 segments - - fprintf(stderr, "Loading segment %d\n", i); - - if (readProgramHeaders(fd, &ehdr, &phdr, i) == false) - return false; - - if (!loadSegment(fd, &phdr)) - return false; - } - - if ((shdr = loadSectionHeaders(fd, &ehdr)) == NULL) - ret = false; - - if (ret && ((_symtab_sect = loadSymbolTable(fd, &ehdr, shdr)) < 0)) - ret = false; - - if (ret && (loadStringTable(fd, shdr) == false)) - ret = false; - - if (ret) - relocateSymbols((Elf32_Addr)_segment); // Offset by our segment allocated address - - if (ret && (relocateRels(fd, &ehdr, shdr) == false)) - ret = false; - - free(shdr); - - return ret; - -} - -bool DLObject::open(const char *path) { - int fd; - void *ctors_start, *ctors_end; - - DBG(("open(\"%s\")\n", path)); - - if ((fd = ::open(path, O_RDONLY)) < 0) { - seterror("%s not found.", path); - return false; - } - - // Try to load and relocate - if (!load(fd)) { - ::close(fd); - unload(); - return false; - } - - ::close(fd); - - //TODO: flush data cache - - ctors_start = symbol("___plugin_ctors"); - ctors_end = symbol("___plugin_ctors_end"); - _dtors_start = symbol("___plugin_dtors"); - _dtors_end = symbol("___plugin_dtors_end"); - - if (ctors_start == NULL || ctors_end == NULL || _dtors_start == NULL || - _dtors_end == NULL) { - seterror("Missing ctors/dtors."); - _dtors_start = _dtors_end = NULL; - unload(); - return false; - } - - DBG(("Calling constructors.\n")); - for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) - (**f)(); - - DBG(("%s opened ok.\n", path)); - return true; -} - -bool DLObject::close() { - if (_dtors_start != NULL && _dtors_end != NULL) - for (void (**f)(void) = (void (**)(void))_dtors_start; f != _dtors_end; f++) - (**f)(); - _dtors_start = _dtors_end = NULL; - unload(); - return true; -} - -void *DLObject::symbol(const char *name) { - DBG(("symbol(\"%s\")\n", name)); - - if (_symtab == NULL || _strtab == NULL || _symbol_cnt < 1) { - seterror("No symbol table loaded."); - return NULL; - } - - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) - - //TODO: Figure out which symbols should be detected here - if ((s->st_info >> 4 == 1 || s->st_info >> 4 == 2) && - _strtab[s->st_name] == '_' && !strcmp(name, _strtab + s->st_name + 1)) { - - // We found the symbol - DBG("=> %p\n", (void*)s->st_value); - return (void*)s->st_value; - } - - // We didn't find the symbol - seterror("Symbol \"%s\" not found.", name); - return NULL; -} - - -static char dlerr[MAXDLERRLEN]; - -void *dlopen(const char *filename, int flags) { - DLObject *obj = new DLObject(dlerr); - if (obj->open(filename)) - return (void *)obj; - delete obj; - return NULL; -} - -int dlclose(void *handle) { - DLObject *obj = (DLObject *)handle; - if (obj == NULL) { - strcpy(dlerr, "Handle is NULL."); - return -1; - } - if (obj->close()) { - delete obj; - return 0; - } - return -1; -} - -void *dlsym(void *handle, const char *symbol) { - if (handle == NULL) { - strcpy(dlerr, "Handle is NULL."); - return NULL; - } - return ((DLObject *)handle)->symbol(symbol); -} - -const char *dlerror() { - return dlerr; -} - -void dlforgetsyms(void *handle) { - if (handle != NULL) - ((DLObject *)handle)->discard_symtab(); -} - -#endif /* DYNAMIC_MODULES && GP2XWIZ */ diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.h b/backends/platform/gp2xwiz/gp2xwiz-loader.h deleted file mode 100644 index d3812c3d8a..0000000000 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.h +++ /dev/null @@ -1,79 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * 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 2 - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef GP2XWIZ_LOADER_H -#define GP2XWIZ_LOADER_H - -#include "elf32.h" - -#define MAXDLERRLEN 80 - -class DLObject { - protected: - char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */ - - void *_segment, *_symtab; - char *_strtab; - int _symbol_cnt; - int _symtab_sect; - void *_dtors_start, *_dtors_end; - - int _segmentSize; - - void seterror(const char *fmt, ...); - void unload(); - bool relocate(int fd, unsigned long offset, unsigned long size, void *relSegment); - bool load(int fd); - - bool readElfHeader(int fd, Elf32_Ehdr *ehdr); - bool readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - bool loadSegment(int fd, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(int fd, Elf32_Ehdr *ehdr); - int loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(int fd, Elf32_Shdr *shdr); - void relocateSymbols(Elf32_Addr offset); - bool relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - - public: - bool open(const char *path); - bool close(); - void *symbol(const char *name); - void discard_symtab(); - - DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _segment(NULL),_symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _dtors_start(NULL), _dtors_end(NULL) {} -}; - -#define RTLD_LAZY 0 - -extern "C" { - void *dlopen(const char *filename, int flags); - int dlclose(void *handle); - void *dlsym(void *handle, const char *symbol); - const char *dlerror(); - void dlforgetsyms(void *handle); -} - -#endif /* GP2XWIZ_LOADER_H */ diff --git a/backends/platform/gp2xwiz/plugin.ld b/backends/platform/gp2xwiz/plugin.ld deleted file mode 100644 index 9e491087de..0000000000 --- a/backends/platform/gp2xwiz/plugin.ld +++ /dev/null @@ -1,182 +0,0 @@ -/* Script for -z combreloc: combine and sort reloc sections */ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", - "elf32-littlearm") -OUTPUT_ARCH(arm) -PHDRS -{ - plugin PT_LOAD ; -} -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - .interp : { *(.interp) } : plugin - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.dyn : - { - *(.rel.init) - *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) - *(.rel.fini) - *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) - *(.rel.data.rel.ro*) - *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) - *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) - *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) - *(.rel.ctors) - *(.rel.dtors) - *(.rel.got) - *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) - } - .rela.dyn : - { - *(.rela.init) - *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) - *(.rela.fini) - *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) - *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) - *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) - *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) - *(.rela.ctors) - *(.rela.dtors) - *(.rela.got) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .text : - { - *(.text .stub .text.* .gnu.linkonce.t.*) - KEEP (*(.text.*personality*)) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.glue_7t) *(.glue_7) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN (0x8000) - ((0x8000 - .) & (0x8000 - 1)); . = DATA_SEGMENT_ALIGN (0x8000, 0x1000); - /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } - /* Thread Local Storage sections */ - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - /* Ensure the __preinit_array_start label is properly aligned. We - could instead move the label definition inside the section, but - the linker would then create the section even if it turns out to - be empty, which isn't pretty. */ - . = ALIGN(32 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { KEEP (*(.preinit_array)) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { KEEP (*(.init_array)) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { KEEP (*(.fini_array)) } - PROVIDE (__fini_array_end = .); - .ctors : - { - ___plugin_ctors = .; - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - ___plugin_ctors_end = .; - } - .dtors : - { - ___plugin_dtors = .; - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - ___plugin_dtors_end = .; - } - .jcr : { KEEP (*(.jcr)) } - .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } - .dynamic : { *(.dynamic) } - . = DATA_SEGMENT_RELRO_END (0, .); - .got : { *(.got.plt) *(.got) } - .data : - { - __data_start = . ; - *(.data .data.* .gnu.linkonce.d.*) - KEEP (*(.gnu.linkonce.d.*personality*)) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - __bss_start__ = .; - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ - . = ALIGN(32 / 8); - } - . = ALIGN(32 / 8); - _end = .; - _bss_end__ = . ; __bss_end__ = . ; __end__ = . ; - PROVIDE (end = .); - . = DATA_SEGMENT_END (.); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } - /DISCARD/ : { *(.note.GNU-stack) } -} diff --git a/backends/platform/gp2xwiz/plugin.syms b/backends/platform/gp2xwiz/plugin.syms deleted file mode 100644 index 24ee1a19dc..0000000000 --- a/backends/platform/gp2xwiz/plugin.syms +++ /dev/null @@ -1,8 +0,0 @@ -PLUGIN_getVersion -PLUGIN_getType -PLUGIN_getTypeVersion -PLUGIN_getObject -___plugin_ctors -___plugin_ctors_end -___plugin_dtors -___plugin_dtors_end diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index 8ceccfb7e8..61d7c73236 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -23,9 +23,12 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(ARM) + #include "backends/fs/ds/ds-fs.h" #include "elf-loader.h" #include "dsmain.h" +#include "arm-loader.h" #define __DEBUG_PLUGINS__ @@ -45,7 +48,7 @@ * @param size Size of relocation section * */ -bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { +bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { Elf32_Rel *rel = NULL; //relocation entry // Allocate memory for relocation table @@ -135,7 +138,7 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset return true; } -bool DLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Loop over sections, finding relocation sections for (int i = 0; i < ehdr->e_shnum; i++) { @@ -162,3 +165,5 @@ bool DLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr return true; } + +#endif /* defined(DYNAMIC_MODULES) && defined(ARM) */ diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp index 999781754b..c83f198b5e 100644 --- a/backends/plugins/ds/ds-provider.cpp +++ b/backends/plugins/ds/ds-provider.cpp @@ -23,15 +23,18 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(__DS__) + /*#include "base/plugins.h" #include "backends/plugins/dynamic-plugin.h" #include "common/fs.h" #include "backends/plugins/elf-loader.h"*/ +#include "backends/plugins/arm-loader.h" #include "backends/plugins/elf-provider.h" #include "backends/plugins/ds/ds-provider.h" -#if defined(DYNAMIC_MODULES) && defined(__DS__) + class DSPlugin : public ELFPlugin { public: @@ -50,7 +53,7 @@ public: bool DSPlugin::loadPlugin() { assert(!_dlHandle); - DLObject *obj = new DLObject(NULL); + DLObject *obj = new ARMDLObject(); if (obj->open(_filename.c_str())) { _dlHandle = obj; } else { diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h index d9b1ee9cf4..462c3e3b63 100644 --- a/backends/plugins/ds/ds-provider.h +++ b/backends/plugins/ds/ds-provider.h @@ -25,11 +25,8 @@ #include "backends/plugins/elf-provider.h" -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - class DSPluginProvider : public ELFPluginProvider { Plugin* createPlugin(const Common::FSNode &node) const; }; -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 0a84d9c0b9..423a97bc42 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -28,6 +28,7 @@ #include "elf32.h" #include "common/stream.h" +#include "backends/plugins/dynamic-plugin.h" #if defined(__PLAYSTATION2__) || defined(__PSP__) #define MIPS_TARGET @@ -38,12 +39,8 @@ #define ARM_TARGET #endif -#define MAXDLERRLEN 80 - class DLObject { protected: - char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */ - void *_segment, *_symtab; char *_strtab; int _symbol_cnt; @@ -57,9 +54,9 @@ protected: unsigned int _gpVal; // Value of Global Pointer #endif - void seterror(const char *fmt, ...); + //void seterror(const char *fmt, ...); void unload(); - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; bool load(Common::SeekableReadStream* DLFile); bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); @@ -69,7 +66,7 @@ protected: int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); void relocateSymbols(Elf32_Addr offset); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; public: bool open(const char *path); @@ -77,15 +74,6 @@ public: void *symbol(const char *name); void discard_symtab(); - DLObject(char *errbuf = NULL) : _errbuf(errbuf), _segment(NULL), _symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), - _segmentSize(0) { -#ifdef MIPS_TARGET - _shortsSegment = NULL; - _gpVal = 0; -#endif - } - }; -#endif /* LOADER_H */ +#endif /* ELF_LOADER_H */ diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 22e365130b..03218130fb 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -23,14 +23,14 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) + #include "backends/plugins/elf-provider.h" #include "backends/plugins/dynamic-plugin.h" #include "common/fs.h" #include "backends/plugins/elf-loader.h" -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { void *func; bool handleNull; @@ -58,30 +58,6 @@ DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { return tmp; } -bool ELFPlugin::loadPlugin() { - assert(!_dlHandle); - DLObject *obj = new DLObject(NULL); - if (obj->open(_filename.c_str())) { - _dlHandle = obj; - } else { - delete obj; - _dlHandle = NULL; - } - - if (!_dlHandle) { - warning("Failed loading plugin '%s'", _filename.c_str()); - return false; - } - - bool ret = DynamicPlugin::loadPlugin(); - - if (ret && _dlHandle) { - _dlHandle->discard_symtab(); - } - - return ret; -} - void ELFPlugin::unloadPlugin() { DynamicPlugin::unloadPlugin(); if (_dlHandle) { @@ -93,11 +69,6 @@ void ELFPlugin::unloadPlugin() { } } - -Plugin* ELFPluginProvider::createPlugin(const Common::FSNode &node) const { - return new ELFPlugin(node.getPath()); -} - bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { // Check the plugin suffix Common::String filename = node.getName(); diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index eb0ea5d51d..fd047fd0d3 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -53,14 +53,14 @@ public: unloadPlugin(); } - virtual bool loadPlugin(); - virtual void unloadPlugin(); + virtual bool loadPlugin() = 0; + void unloadPlugin(); }; class ELFPluginProvider : public FilePluginProvider { protected: - virtual Plugin* createPlugin(const Common::FSNode &node) const; + virtual Plugin* createPlugin(const Common::FSNode &node) const = 0; bool isPluginFilename(const Common::FSNode &node) const; |