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;  | 
