aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Puccinelli2010-08-06 23:30:27 +0000
committerTony Puccinelli2010-08-06 23:30:27 +0000
commit646587f79a4249e25e47af74d36c72602f00dd0f (patch)
tree1fe8447d711d17971eaa5a7e6e2e8e93210e14d4
parent66225374b2f75f8c5b4406564c35ca476242aa81 (diff)
downloadscummvm-rg350-646587f79a4249e25e47af74d36c72602f00dd0f.tar.gz
scummvm-rg350-646587f79a4249e25e47af74d36c72602f00dd0f.tar.bz2
scummvm-rg350-646587f79a4249e25e47af74d36c72602f00dd0f.zip
got rid of gp2xwiz loader (anything useful from it is already incorporated into the ARM loader in the plugins directory at this point) and implemented ARMDLObject as a subtype of DLObject
svn-id: r51813
-rw-r--r--backends/platform/gp2xwiz/elf32.h192
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-loader.cpp485
-rw-r--r--backends/platform/gp2xwiz/gp2xwiz-loader.h79
-rw-r--r--backends/platform/gp2xwiz/plugin.ld182
-rw-r--r--backends/platform/gp2xwiz/plugin.syms8
-rw-r--r--backends/plugins/arm-loader.cpp9
-rw-r--r--backends/plugins/ds/ds-provider.cpp7
-rw-r--r--backends/plugins/ds/ds-provider.h3
-rw-r--r--backends/plugins/elf-loader.h22
-rw-r--r--backends/plugins/elf-provider.cpp33
-rw-r--r--backends/plugins/elf-provider.h6
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;