From fab28cb74b1c5416ceb481e2351044cbe54d119c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 26 May 2010 23:22:45 +0000 Subject: minor initial commit for ps2 plugins. Added ps2-provider code svn-id: r49253 --- backends/plugins/ps2/ps2-provider.cpp | 83 +++++++++++++++++++++++++++++++++++ backends/plugins/ps2/ps2-provider.h | 18 ++++++++ 2 files changed, 101 insertions(+) create mode 100644 backends/plugins/ps2/ps2-provider.cpp create mode 100644 backends/plugins/ps2/ps2-provider.h (limited to 'backends') diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp new file mode 100644 index 0000000000..bba282557d --- /dev/null +++ b/backends/plugins/ps2/ps2-provider.cpp @@ -0,0 +1,83 @@ +#if defined(DYNAMIC_MODULES) && defined(__PS2__) + +#include "backends/plugins/ps2/ps2-provider.h" +#include "backends/plugins/dynamic-plugin.h" +#include "common/fs.h" + +#include "backends/platform/ps2/ps2loader.h" + + +class PS2Plugin : public DynamicPlugin { +protected: + void *_dlHandle; + Common::String _filename; + + virtual VoidFunc findSymbol(const char *symbol) { + void *func = dlsym(_dlHandle, symbol); + if (!func) + warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. . + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp; + } + +public: + PS2Plugin(const Common::String &filename) + : _dlHandle(0), _filename(filename) {} + + ~PS2Plugin() { + if (_dlHandle) unloadPlugin(); + } + + bool loadPlugin() { + assert(!_dlHandle); + _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); + + if (!_dlHandle) { + warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); + return false; + } + + bool ret = DynamicPlugin::loadPlugin(); + + if (ret) + dlforgetsyms(_dlHandle); + + return ret; + } + + void unloadPlugin() { + DynamicPlugin::unloadPlugin(); + if (_dlHandle) { + if (dlclose(_dlHandle) != 0) + warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); + _dlHandle = 0; + } + } +}; + + +Plugin* PS2PluginProvider::createPlugin(const Common::FSNode &node) const { + return new PS2Plugin(node.getPath()); +} + +bool PS2PluginProvider::isPluginFilename(const Common::FSNode &node) const { + // Check the plugin suffix + Common::String filename = node.getName(); + fprintf(stderr, "Testing name %s", filename.c_str()); + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg")) { + fprintf(stderr," fail.\n"); + return false; + } + + fprintf(stderr," success!\n"); + return true; +} + +#endif // defined(DYNAMIC_MODULES) && defined(__PS2__) diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h new file mode 100644 index 0000000000..bb78bf74b0 --- /dev/null +++ b/backends/plugins/ps2/ps2-provider.h @@ -0,0 +1,18 @@ +#ifndef BACKENDS_PLUGINS_PS2_PS2_PROVIDER_H +#define BACKENDS_PLUGINS_PS2_PS2_PROVIDER_H + +#include "base/plugins.h" + +#if defined(DYNAMIC_MODULES) && defined(__PS2__) + +class PS2PluginProvider : public FilePluginProvider { +protected: + Plugin* createPlugin(const Common::FSNode &node) const; + + bool isPluginFilename(const Common::FSNode &node) const; + +}; + +#endif // defined(DYNAMIC_MODULES) && defined(__PS2__) + +#endif /* BACKENDS_PLUGINS_PS2_PS2_PROVIDER_H */ -- cgit v1.2.3 From 0fdfd5d47b5a50b6125bfeca92d83d49b09a6ee1 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 27 May 2010 05:03:09 +0000 Subject: added files for ps2 loadable modules (mainly transplanted from psp code with VERY minor tweaks) svn-id: r49256 --- backends/platform/ps2/elf32.h | 209 ++++++++++ backends/platform/ps2/main_prog.ld | 253 ++++++++++++ backends/platform/ps2/plugin.ld | 239 +++++++++++ backends/platform/ps2/plugin.syms | 8 + backends/platform/ps2/ps2loader.cpp | 721 ++++++++++++++++++++++++++++++++++ backends/platform/ps2/ps2loader.h | 137 +++++++ backends/plugins/ps2/ps2-provider.cpp | 25 ++ backends/plugins/ps2/ps2-provider.h | 25 ++ 8 files changed, 1617 insertions(+) create mode 100644 backends/platform/ps2/elf32.h create mode 100644 backends/platform/ps2/main_prog.ld create mode 100644 backends/platform/ps2/plugin.ld create mode 100644 backends/platform/ps2/plugin.syms create mode 100644 backends/platform/ps2/ps2loader.cpp create mode 100644 backends/platform/ps2/ps2loader.h (limited to 'backends') diff --git a/backends/platform/ps2/elf32.h b/backends/platform/ps2/elf32.h new file mode 100644 index 0000000000..e024fcf5c4 --- /dev/null +++ b/backends/platform/ps2/elf32.h @@ -0,0 +1,209 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/platform/ps2/elf32.h $ + * $Id: elf32.h 49253 2010-05-12 05:26:54Z Toneman $ + * + */ + +#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_MIPS 8 + + +// 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_MIPS_REGINFO 0x70000000 /* register usage info */ + +// 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_MIPS_LIBLSIT 0x70000000 /* Info about dynamic shared object libs */ +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicts btw executables and shared objects */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global pointer table */ + +// sh_flags values +#define SHF_WRITE 0 /* writable section */ +#define SHF_ALLOC 2 /* section occupies memory */ +#define SHF_EXECINSTR 4 /* machine instructions */ +#define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area */ + + +// 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_Rel; + +// Access macros for the relocation info +#define REL_TYPE(x) ((x)&0xFF) /* Extract relocation type */ +#define REL_INDEX(x) ((x)>>8) /* Extract relocation index into symbol table */ + +// MIPS relocation types +#define R_MIPS_NONE 0 +#define R_MIPS_16 1 +#define R_MIPS_32 2 +#define R_MIPS_REL32 3 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_GPREL16 7 +#define R_MIPS_LITERAL 8 +#define R_MIPS_GOT16 9 +#define R_MIPS_PC16 10 +#define R_MIPS_CALL16 11 +#define R_MIPS_GPREL32 12 +#define R_MIPS_GOTHI16 13 +#define R_MIPS_GOTLO16 14 +#define R_MIPS_CALLHI16 15 +#define R_MIPS_CALLLO16 16 + +// Mock function to get value of global pointer +#define getGP() ({ \ + unsigned int __valgp; \ + __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ + __valgp; \ +}) + +#endif /* BACKENDS_ELF_H */ diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld new file mode 100644 index 0000000000..68ade38d1a --- /dev/null +++ b/backends/platform/ps2/main_prog.ld @@ -0,0 +1,253 @@ +OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", + "elf32-littlemips") +OUTPUT_ARCH(mips:allegrex) +ENTRY(_start) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = 0x08900000); . = 0x08900000; + .interp : { *(.interp) } + .reginfo : { *(.reginfo) } + .dynamic : { *(.dynamic) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + /* PSP-specific relocations. TODO: works for PS2 as well? */ + .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } + .rel.lib.ent.top : { *(.rel.lib.ent.top) } + .rel.lib.ent : { *(.rel.lib.ent) } + .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } + .rel.lib.stub.top : { *(.rel.lib.stub.top) } + .rel.lib.stub : { *(.rel.lib.stub) } + .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } + .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } + .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } + .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } + .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data.rel.ro : { *(.rel.data.rel.ro*) } + .rela.data.rel.ro : { *(.rel.data.rel.ro*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } + .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } + .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } + .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + _ftext = . ; + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.mips16.fn.*) *(.mips16.call.*) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + /* PSP library stub functions. TODO: works for PS2 as well? */ + .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + /* PSP library entry table and library stub table. TODO: works for PS2 as well? */ + .lib.ent.top : { *(.lib.ent.top) } + .lib.ent : { *(.lib.ent) } + .lib.ent.btm : { *(.lib.ent.btm) } + .lib.stub.top : { *(.lib.stub.top) } + .lib.stub : { *(.lib.stub) } + .lib.stub.btm : { *(.lib.stub.btm) } + /* PSP read-only data for module info, NIDs, and Vstubs. The + .rodata.sceModuleInfo section must appear before the .rodata section + otherwise it would get absorbed into .rodata and the PSP bootloader + would be unable to locate the module info structure. TODO: Works for PS2 as well? */ + .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } + .rodata.sceResident : { *(.rodata.sceResident) } + .rodata.sceNid : { *(.rodata.sceNid) } + .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .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(256) + (. & (256 - 1)); + /* 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 : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + . = .; + _gp = ALIGN(16) + 0x7ff0; + .got : { *(.got.plt) *(.got) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + _fbss = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + /* make a gap to put the plugins' short data here */ + __plugin_hole_start = .; + . = _gp + 0x7ff0; + __plugin_hole_end = .; + COMMON : + { + *(COMMON) + } + . = ALIGN(32 / 8); + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + /* 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 = .; + PROVIDE (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) } + /DISCARD/ : { *(.comment) *(.pdr) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld new file mode 100644 index 0000000000..b27432a2af --- /dev/null +++ b/backends/platform/ps2/plugin.ld @@ -0,0 +1,239 @@ +OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", + "elf32-littlemips") +OUTPUT_ARCH(mips:allegrex) +PHDRS +{ + plugin PT_LOAD ; + shorts PT_LOAD ; +} +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + .interp : { *(.interp) } : plugin + .reginfo : { *(.reginfo) } : plugin + .dynamic : { *(.dynamic) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + /* PSP-specific relocations. TODO: Do these work for PS2 as well? */ + .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } + .rel.lib.ent.top : { *(.rel.lib.ent.top) } + .rel.lib.ent : { *(.rel.lib.ent) } + .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } + .rel.lib.stub.top : { *(.rel.lib.stub.top) } + .rel.lib.stub : { *(.rel.lib.stub) } + .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } + .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } + .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } + .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } + .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data.rel.ro : { *(.rel.data.rel.ro*) } + .rela.data.rel.ro : { *(.rel.data.rel.ro*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } + .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } + .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } + .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + _ftext = . ; + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.mips16.fn.*) *(.mips16.call.*) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + /* PSP library stub functions. TODO: Work for PS2 as well? */ + .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + /* PSP library entry table and library stub table. TODO: Works for PS2 as well? */ + .lib.ent.top : { *(.lib.ent.top) } + .lib.ent : { *(.lib.ent) } + .lib.ent.btm : { *(.lib.ent.btm) } + .lib.stub.top : { *(.lib.stub.top) } + .lib.stub : { *(.lib.stub) } + .lib.stub.btm : { *(.lib.stub.btm) } + /* PSP read-only data for module info, NIDs, and Vstubs. The + .rodata.sceModuleInfo section must appear before the .rodata section + otherwise it would get absorbed into .rodata and the PSP bootloader + would be unable to locate the module info structure. TODO: Works for the ps2 as well? */ + .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } + .rodata.sceResident : { *(.rodata.sceResident) } + .rodata.sceNid : { *(.rodata.sceNid) } + .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .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(256) + (. & (256 - 1)); + /* 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*) } + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + . = .; + .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 = .; + PROVIDE (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) } + /DISCARD/ : { *(.comment) *(.pdr) } + /DISCARD/ : { *(.note.GNU-stack) } + + . = __plugin_hole_start; + .got : { *(.got.plt) *(.got) } : shorts + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + _fbss = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + + +} diff --git a/backends/platform/ps2/plugin.syms b/backends/platform/ps2/plugin.syms new file mode 100644 index 0000000000..24ee1a19dc --- /dev/null +++ b/backends/platform/ps2/plugin.syms @@ -0,0 +1,8 @@ +PLUGIN_getVersion +PLUGIN_getType +PLUGIN_getTypeVersion +PLUGIN_getObject +___plugin_ctors +___plugin_ctors_end +___plugin_dtors +___plugin_dtors_end diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp new file mode 100644 index 0000000000..ff6702de17 --- /dev/null +++ b/backends/platform/ps2/ps2loader.cpp @@ -0,0 +1,721 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/platform/ps2/ps2loader.cpp $ + * TODO: $ID + * + */ + +#if defined(DYNAMIC_MODULES) && defined(__PS2__) + +#include +#include +#include +#include +#include +#include + +#include + +#include "backends/platform/ps2/ps2loader.h" +//#include "backends/platform/ps2/powerman.h" //TODO + +//#define __PS2_DEBUG_PLUGINS__ + +#ifdef __PS2_DEBUG_PLUGINS__ +#define DBG(x,...) fprintf(stderr,x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__) + +extern char __plugin_hole_start; // Indicates start of hole in program file for shorts +extern char __plugin_hole_end; // Indicates end of hole in program file +extern char _gp[]; // Value of gp register + +DECLARE_SINGLETON(ShortSegmentManager) // For singleton + +// Get rid of symbol table in 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; + + if (_shortsSegment) { + ShortsMan.deleteSegment(_shortsSegment); + _shortsSegment = NULL; + } +} + +/** + * Follow the instruction of a relocation section. + * + * @param fd File Descriptor + * @param offset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) + * + */ +bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = NULL; // relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + seterror("Out of memory."); + return false; + } + + // Read in our relocation table + if (lseek(fd, offset, SEEK_SET) < 0 || + read(fd, rel, size) != (ssize_t)size) { + seterror("Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + bool seenHi16 = false; // For treating HI/LO16 commands + int firstHi16 = -1; // Mark the point of the first hi16 seen + Elf32_Addr ahl = 0; // Calculated addend + int a = 0; // Addend: taken from the target + + unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives + unsigned int relocation = 0; + int debugRelocs[10] = {0}; // For debugging + int extendedHi16 = 0; // Count extended hi16 treatments + Elf32_Addr lastHiSymVal = 0; + bool hi16InShorts = false; + +#define DEBUG_NUM 2 + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; // Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + + case R_MIPS_HI16: // Absolute addressing. + if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) + firstHi16 < 0) { // Only process first in block of HI16s + firstHi16 = i; // Keep the first Hi16 we saw + seenHi16 = true; + ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up + + lastHiSymVal = sym->st_value; + hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments + if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number + DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", + i, rel[i].r_offset, ahl, *target); + } + break; + + case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) + if (!seenHi16) { // We MUST have seen HI16 first + seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); + free(rel); + return false; + } + + // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) + // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section + // and will be screened out above + bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); + + // Correct the bug by getting the proper value in ahl (taken from the current symbol) + if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { + ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset + ahl += (sym->st_value & 0xffff0000); + } + + ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s + a = *target & 0xffff; // Take lower 16 bits of the target + a = (a << 16) >> 16; // Sign extend them + ahl += a; // Add lower 16 bits. AHL is now complete + + // Fix: we can have LO16 access to the short segment sometimes + if (lo16InShorts) { + relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset + } else // It's in the regular segment + relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment + + if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now + for (int j = firstHi16; j < i; j++) { + if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s + + lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target + *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target + *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation + if (relocation & 0x8000)(*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case + } + firstHi16 = -1; // Reset so we'll know we treated it + } else { + extendedHi16++; + } + + *target &= 0xffff0000; // Clear the lower 16 bits of current target + *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation + + if (debugRelocs[1]++ < DEBUG_NUM) + DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) + DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + } + break; + + case R_MIPS_26: // Absolute addressing (for jumps and branches only) + if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment + a = *target & 0x03ffffff; // Get 26 bits' worth of the addend + a = (a << 6) >> 6; // Sign extend a + relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset + *target &= 0xfc000000; // Clean lower 26 target bits + *target |= (relocation & 0x03ffffff); + + if (debugRelocs[3]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } else { + if (debugRelocs[4]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } + break; + + case R_MIPS_GPREL16: // GP Relative addressing + if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section + ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole + a = *target & 0xffff; // Get 16 bits' worth of the addend + a = (a << 16) >> 16; // Sign extend it + + relocation = a + _shortsSegment->getOffset(); + + *target &= 0xffff0000; // Clear the lower 16 bits of the target + *target |= relocation & 0xffff; + + if (debugRelocs[5]++ < DEBUG_NUM) + DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", + i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); + } + + break; + + case R_MIPS_32: // Absolute addressing + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + + if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment + relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset + else // We're in the main section + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + *target = relocation; + + if (debugRelocs[6]++ < DEBUG_NUM) + DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + default: + seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); + free(rel); + return false; + } + } + + DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); + + free(rel); + 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_MIPS || // Check for MIPS 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; + + // We need to take account of non-allocated segment for shorts + if (phdr->p_flags & PF_X) { // This is a relocated segment + + // 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 (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI + + 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; + } else { // This is a shorts section. + _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); + + baseAddress = _shortsSegment->getStart(); + DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", + _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + + } + + // 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++) { + //DBG("Section %d: type = %x, size = %x, entsize = %x, link = %x\n", + // i, shdr[i].sh_type, shdr[i].sh_size, shdr[i].sh_entsize, shdr[i].sh_link); + + 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, Elf32_Addr shortsOffset) { + + int shortsCount = 0, othersCount = 0; + DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); + + // 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) { + if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { + othersCount++; + 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); + } else { // shorts section + shortsCount++; + s->st_value += shortsOffset; + if (!_shortsSegment->inSegment((char *)s->st_value)) + seterror("Symbol out of bounds! st_value = %x\n", s->st_value); + } + + } + + } + + DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); +} + +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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment + if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, _segment)) { + return false; + } + } else { // In Shorts segment + if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { + return false; + } + } + + } + } + + return true; +} + + +bool DLObject::load(int fd) { + fprintf(stderr, "In DLObject::load\n"); + + Elf32_Ehdr ehdr; // ELF header + Elf32_Phdr phdr; // Program header + Elf32_Shdr *shdr; // Section header + bool ret = true; + + 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, _shortsSegment->getOffset()); // 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); + + // Get the address of the global pointer + _gpVal = (unsigned int) & _gp; + DBG("_gpVal is %x\n", _gpVal); + + PowerMan.beginCriticalSection(); + + 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); + + PowerMan.endCriticalSection(); + + // flush data cache + sceKernelDcacheWritebackAll(); + + // Get the symbols for the global constructors and destructors + 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++) { + + // We can only import symbols that are global or weak in the plugin + if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && + /*_strtab[s->st_name] == '_' && */ // Try to make this more efficient + !strcmp(name, _strtab + s->st_name)) { + + // We found the symbol + DBG("=> %p\n", (void*)s->st_value); + return (void*)s->st_value; + } + } + + seterror("Symbol \"%s\" not found.", name); + return NULL; +} + + + +ShortSegmentManager::ShortSegmentManager() { + _shortsStart = &__plugin_hole_start ; + _shortsEnd = &__plugin_hole_end; +} + +ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { + char *lastAddress = origAddr; + Common::List::iterator i; + + // Find a block that fits, starting from the beginning + for (i = _list.begin(); i != _list.end(); ++i) { + char *currAddress = (*i)->getStart(); + + if ((int)(currAddress - lastAddress) >= size) break; + + lastAddress = (*i)->getEnd(); + } + + if ((Elf32_Addr)lastAddress & 3) + lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 + + if (lastAddress + size > _shortsEnd) { + seterror("Error. No space in shorts segment for %x bytes. Last address is %p, max address is %p.\n", + size, lastAddress, _shortsEnd); + return NULL; + } + + Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment + + if (lastAddress + size > _highestAddress) _highestAddress = lastAddress + size; // Keep track of maximum + + _list.insert(i, seg); + + DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", + size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); + + return seg; +} + +void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { + DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); + _list.remove(seg); + delete seg; +} + +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 && __PS2__ */ diff --git a/backends/platform/ps2/ps2loader.h b/backends/platform/ps2/ps2loader.h new file mode 100644 index 0000000000..91916d755c --- /dev/null +++ b/backends/platform/ps2/ps2loader.h @@ -0,0 +1,137 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/platform/ps2/ps2loader.h $ + * TODO: $ID + * + */ + +#ifndef PS2LOADER_H +#define PS2LOADER_H + +#include "elf32.h" +#include "common/list.h" +#include "common/singleton.h" + +#define MAXDLERRLEN 80 + +#define ShortsMan ShortSegmentManager::instance() + +class ShortSegmentManager : public Common::Singleton { +private: + char *_shortsStart; + char *_shortsEnd; + +public: + char *getShortsStart() { + return _shortsStart; + } + bool inGeneralSegment(char *addr) { + return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); + } + + class Segment { + private: + friend class ShortSegmentManager; + Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} + ~Segment() {} + char *_startAddress; // Start of shorts segment in memory + int _size; // Size of shorts segment + char *_origAddress; // Original address this segment was supposed to be at + public: + char *getStart() { + return _startAddress; + } + char *getEnd() { + return (_startAddress + _size); + } + Elf32_Addr getOffset() { + return (Elf32_Addr)(_startAddress - _origAddress); + } + bool inSegment(char *addr) { + return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); + } + }; + + Segment *newSegment(int size, char *origAddr); + void deleteSegment(Segment *); + +private: + ShortSegmentManager(); + friend class Common::Singleton; + Common::List _list; + char *_highestAddress; +}; + + + + +class DLObject { +protected: + char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */ + + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + void *_segment, *_symtab; + char *_strtab; + int _symbol_cnt; + int _symtab_sect; + void *_dtors_start, *_dtors_end; + + unsigned int _gpVal; // Value of Global Pointer + int _segmentSize; + + void seterror(const char *fmt, ...); + void unload(); + bool relocate(int fd, unsigned long offset, unsigned long size, void *); + 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, Elf32_Addr shortsOffset); + 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), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), + _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , + _segmentSize(0) {} +}; + + + +#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 /* PS2LOADER_H */ diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp index bba282557d..d0f6d417c0 100644 --- a/backends/plugins/ps2/ps2-provider.cpp +++ b/backends/plugins/ps2/ps2-provider.cpp @@ -1,3 +1,28 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ps2/ps2-provider.cpp $ + * $Id: ps2-provider.cpp 49253 2010-05-26 5:17:18Z Toneman $ + * + */ + #if defined(DYNAMIC_MODULES) && defined(__PS2__) #include "backends/plugins/ps2/ps2-provider.h" diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index bb78bf74b0..fd49b9e74e 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -1,3 +1,28 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ps2/ps2-provider.h $ + * $Id: ps2-provider.h 49253 2010-05-26 5:17:18Z Toneman $ + * + */ + #ifndef BACKENDS_PLUGINS_PS2_PS2_PROVIDER_H #define BACKENDS_PLUGINS_PS2_PS2_PROVIDER_H -- cgit v1.2.3 From 7682a5f815e58aadb6c2d041705626218e83eaac Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 27 May 2010 23:47:31 +0000 Subject: was using the default linker for the psp. Now a modified version of the default linker for the ps2 compiler svn-id: r49278 --- backends/platform/ps2/main_prog.ld | 153 +++++++++++++++---------------------- 1 file changed, 61 insertions(+), 92 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld index 68ade38d1a..10b881cef9 100644 --- a/backends/platform/ps2/main_prog.ld +++ b/backends/platform/ps2/main_prog.ld @@ -1,66 +1,59 @@ +/* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", "elf32-littlemips") -OUTPUT_ARCH(mips:allegrex) +OUTPUT_ARCH(mips:5900) ENTRY(_start) /* Do we need any of these for elf? __DYNAMIC = 0; */ +_DYNAMIC_LINK = 0; SECTIONS { /* Read-only sections, merged into text segment: */ - PROVIDE (__executable_start = 0x08900000); . = 0x08900000; + . = 0x100000; .interp : { *(.interp) } - .reginfo : { *(.reginfo) } - .dynamic : { *(.dynamic) } + .reginfo : { *(.reginfo) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } - .rel.init : { *(.rel.init) } - .rela.init : { *(.rela.init) } - .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } - .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } - .rel.fini : { *(.rel.fini) } - .rela.fini : { *(.rela.fini) } - /* PSP-specific relocations. TODO: works for PS2 as well? */ - .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } - .rel.lib.ent.top : { *(.rel.lib.ent.top) } - .rel.lib.ent : { *(.rel.lib.ent) } - .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } - .rel.lib.stub.top : { *(.rel.lib.stub.top) } - .rel.lib.stub : { *(.rel.lib.stub) } - .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } - .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } - .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } - .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } - .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } - .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } - .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } - .rel.data.rel.ro : { *(.rel.data.rel.ro*) } - .rela.data.rel.ro : { *(.rel.data.rel.ro*) } - .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } - .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } - .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } - .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } - .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } - .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } - .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } - .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } - .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } - .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } - .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } - .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } - .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } - .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } - .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .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.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) + *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) + *(.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.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } .rel.plt : { *(.rel.plt) } .rela.plt : { *(.rela.plt) } .init : @@ -72,7 +65,6 @@ SECTIONS { _ftext = . ; *(.text .stub .text.* .gnu.linkonce.t.*) - KEEP (*(.text.*personality*)) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.mips16.fn.*) *(.mips16.call.*) @@ -81,56 +73,43 @@ SECTIONS { KEEP (*(.fini)) } =0 - /* PSP library stub functions. TODO: works for PS2 as well? */ - .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .); - /* PSP library entry table and library stub table. TODO: works for PS2 as well? */ - .lib.ent.top : { *(.lib.ent.top) } - .lib.ent : { *(.lib.ent) } - .lib.ent.btm : { *(.lib.ent.btm) } - .lib.stub.top : { *(.lib.stub.top) } - .lib.stub : { *(.lib.stub) } - .lib.stub.btm : { *(.lib.stub.btm) } - /* PSP read-only data for module info, NIDs, and Vstubs. The - .rodata.sceModuleInfo section must appear before the .rodata section - otherwise it would get absorbed into .rodata and the PSP bootloader - would be unable to locate the module info structure. TODO: Works for PS2 as well? */ - .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } - .rodata.sceResident : { *(.rodata.sceResident) } - .rodata.sceNid : { *(.rodata.sceNid) } - .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } .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(256) + (. & (256 - 1)); - /* 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) } + . = ALIGN(128) + (. & (128 - 1)); /* 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)) } + .preinit_array : { *(.preinit_array) } PROVIDE (__preinit_array_end = .); PROVIDE (__init_array_start = .); - .init_array : { KEEP (*(.init_array)) } + .init_array : { *(.init_array) } PROVIDE (__init_array_end = .); PROVIDE (__fini_array_start = .); - .fini_array : { KEEP (*(.fini_array)) } + .fini_array : { *(.fini_array) } PROVIDE (__fini_array_end = .); + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .dynamic : { *(.dynamic) } .ctors : { /* gcc uses crtbegin.o to find the start of @@ -159,18 +138,10 @@ SECTIONS KEEP (*(.dtors)) } .jcr : { KEEP (*(.jcr)) } - .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } - .data : - { - _fdata = . ; - *(.data .data.* .gnu.linkonce.d.*) - KEEP (*(.gnu.linkonce.d.*personality*)) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - . = .; _gp = ALIGN(16) + 0x7ff0; .got : { *(.got.plt) *(.got) } + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ @@ -178,8 +149,6 @@ SECTIONS { *(.sdata .sdata.* .gnu.linkonce.s.*) } - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } _edata = .; PROVIDE (edata = .); __bss_start = .; @@ -248,6 +217,6 @@ SECTIONS .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } - /DISCARD/ : { *(.comment) *(.pdr) } - /DISCARD/ : { *(.note.GNU-stack) } + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } } -- cgit v1.2.3 From 19f0b41f8786d6f62107cac16697dce144df79cd Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 28 May 2010 00:21:35 +0000 Subject: was using the modified linker for the psp for plugins.ld. Now it's a modified version of the default linker for the ps2 compiler svn-id: r49280 --- backends/platform/ps2/plugin.ld | 206 +++++++++++++++++----------------------- 1 file changed, 86 insertions(+), 120 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld index b27432a2af..f0cb12fa6c 100644 --- a/backends/platform/ps2/plugin.ld +++ b/backends/platform/ps2/plugin.ld @@ -1,70 +1,63 @@ +/* Script for -z combreloc: combine and sort reloc sections */ OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", "elf32-littlemips") -OUTPUT_ARCH(mips:allegrex) +OUTPUT_ARCH(mips:5900) PHDRS { - plugin PT_LOAD ; - shorts PT_LOAD ; + plugin PT_LOAD ; + shorts PT_LOAD ; } /* Do we need any of these for elf? __DYNAMIC = 0; */ +_DYNAMIC_LINK = 0; SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0; - .interp : { *(.interp) } : plugin - .reginfo : { *(.reginfo) } : plugin - .dynamic : { *(.dynamic) } + . = 0x100000; //TODO: Change to 0? + .interp : { *(.interp) } plugin + .reginfo : { *(.reginfo) } plugin .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } .gnu.version : { *(.gnu.version) } .gnu.version_d : { *(.gnu.version_d) } .gnu.version_r : { *(.gnu.version_r) } - .rel.init : { *(.rel.init) } - .rela.init : { *(.rela.init) } - .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } - .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } - .rel.fini : { *(.rel.fini) } - .rela.fini : { *(.rela.fini) } - /* PSP-specific relocations. TODO: Do these work for PS2 as well? */ - .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } - .rel.lib.ent.top : { *(.rel.lib.ent.top) } - .rel.lib.ent : { *(.rel.lib.ent) } - .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } - .rel.lib.stub.top : { *(.rel.lib.stub.top) } - .rel.lib.stub : { *(.rel.lib.stub) } - .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } - .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } - .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } - .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } - .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } - .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } - .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } - .rel.data.rel.ro : { *(.rel.data.rel.ro*) } - .rela.data.rel.ro : { *(.rel.data.rel.ro*) } - .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } - .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } - .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } - .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } - .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } - .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } - .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } - .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } - .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } - .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } - .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } - .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } - .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } - .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } - .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .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.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) + *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) + *(.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.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } .rel.plt : { *(.rel.plt) } .rela.plt : { *(.rela.plt) } .init : @@ -76,7 +69,6 @@ SECTIONS { _ftext = . ; *(.text .stub .text.* .gnu.linkonce.t.*) - KEEP (*(.text.*personality*)) /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.mips16.fn.*) *(.mips16.call.*) @@ -85,62 +77,49 @@ SECTIONS { KEEP (*(.fini)) } =0 - /* PSP library stub functions. TODO: Work for PS2 as well? */ - .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .); - /* PSP library entry table and library stub table. TODO: Works for PS2 as well? */ - .lib.ent.top : { *(.lib.ent.top) } - .lib.ent : { *(.lib.ent) } - .lib.ent.btm : { *(.lib.ent.btm) } - .lib.stub.top : { *(.lib.stub.top) } - .lib.stub : { *(.lib.stub) } - .lib.stub.btm : { *(.lib.stub.btm) } - /* PSP read-only data for module info, NIDs, and Vstubs. The - .rodata.sceModuleInfo section must appear before the .rodata section - otherwise it would get absorbed into .rodata and the PSP bootloader - would be unable to locate the module info structure. TODO: Works for the ps2 as well? */ - .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } - .rodata.sceResident : { *(.rodata.sceResident) } - .rodata.sceNid : { *(.rodata.sceNid) } - .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } .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(256) + (. & (256 - 1)); - /* 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) } + . = ALIGN(128) + (. & (128 - 1)); /* 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)) } + .preinit_array : { *(.preinit_array) } PROVIDE (__preinit_array_end = .); PROVIDE (__init_array_start = .); - .init_array : { KEEP (*(.init_array)) } + .init_array : { *(.init_array) } PROVIDE (__init_array_end = .); PROVIDE (__fini_array_start = .); - .fini_array : { KEEP (*(.fini_array)) } + .fini_array : { *(.fini_array) } PROVIDE (__fini_array_end = .); + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .dynamic : { *(.dynamic) } .ctors : { ___plugin_ctors = .; KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) - ___plugin_ctors_end = .; + __plugin_ctors_end = .; } .dtors : { @@ -150,16 +129,31 @@ SECTIONS ___plugin_dtors_end = .; } .jcr : { KEEP (*(.jcr)) } - .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } - .data : + . = __plugin_hole_start; + .got : { *(.got.plt) *(.got) } shorts + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { - _fdata = . ; - *(.data .data.* .gnu.linkonce.d.*) - KEEP (*(.gnu.linkonce.d.*personality*)) - SORT(CONSTRUCTORS) + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + _fbss = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); } - .data1 : { *(.data1) } - . = .; .bss : { *(.dynbss) @@ -206,34 +200,6 @@ SECTIONS .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } - /DISCARD/ : { *(.comment) *(.pdr) } - /DISCARD/ : { *(.note.GNU-stack) } - - . = __plugin_hole_start; - .got : { *(.got.plt) *(.got) } : shorts - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : - { - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - _fbss = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - - + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } } -- cgit v1.2.3 From 2532c92fe135abda7ccdad1dba455ffa5cba71d9 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 28 May 2010 00:27:37 +0000 Subject: typo fix svn-id: r49281 --- backends/platform/ps2/plugin.ld | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld index f0cb12fa6c..1eceac4966 100644 --- a/backends/platform/ps2/plugin.ld +++ b/backends/platform/ps2/plugin.ld @@ -13,7 +13,7 @@ _DYNAMIC_LINK = 0; SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0x100000; //TODO: Change to 0? + . = 0; //Not sure this shouldn't be 0x100000 .interp : { *(.interp) } plugin .reginfo : { *(.reginfo) } plugin .hash : { *(.hash) } -- cgit v1.2.3 From df2ee91e45b75f7982f19bccb10a0600f5e051b7 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 28 May 2010 00:53:18 +0000 Subject: added svn keywords 'Id' and 'URL' to new files svn-id: r49282 --- backends/platform/ps2/Makefile.ps2 | 12 ++++++------ backends/platform/ps2/elf32.h | 4 ++-- backends/platform/ps2/ps2loader.cpp | 4 ++-- backends/platform/ps2/ps2loader.h | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index bf7ac0aca0..03f52b1a13 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -1,9 +1,9 @@ # $Header: Exp $ include $(PS2SDK)/Defs.make -PS2_EXTRA = /works/devel/ps2/sdk-extra -PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor -PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /tremor/tremor +PS2_EXTRA = /home/tony/GSOC/ps2/sdk-extra +PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /isjpcm/ee/src /vorbis +PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /isjpcm/ee/lib /vorbis /vorbis/tremor/.libs /vorbis/tremor ENABLED=STATIC_PLUGIN @@ -33,7 +33,7 @@ ENABLE_TOUCHE = $(ENABLED) HAVE_GCC3 = true -CC = ee-gcc +CC = ee-gcc CXX = ee-g++ AS = ee-gcc LD = ee-gcc @@ -48,7 +48,7 @@ VPATH = $(srcdir) INCDIR = ../../../ # DEPDIR = .deps -DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar +DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) @@ -80,7 +80,7 @@ include $(srcdir)/Makefile.common LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(PS2SDK)/ee/startup/linkfile LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) -LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ +LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ LDFLAGS += -s all: $(TARGET) diff --git a/backends/platform/ps2/elf32.h b/backends/platform/ps2/elf32.h index e024fcf5c4..616cc4b4d2 100644 --- a/backends/platform/ps2/elf32.h +++ b/backends/platform/ps2/elf32.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/platform/ps2/elf32.h $ - * $Id: elf32.h 49253 2010-05-12 05:26:54Z Toneman $ + * $URL$ + * $Id$ * */ diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp index ff6702de17..717d33d2cd 100644 --- a/backends/platform/ps2/ps2loader.cpp +++ b/backends/platform/ps2/ps2loader.cpp @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/platform/ps2/ps2loader.cpp $ - * TODO: $ID + * $URL$ + * $Id$ * */ diff --git a/backends/platform/ps2/ps2loader.h b/backends/platform/ps2/ps2loader.h index 91916d755c..7c412e7b05 100644 --- a/backends/platform/ps2/ps2loader.h +++ b/backends/platform/ps2/ps2loader.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/platform/ps2/ps2loader.h $ - * TODO: $ID + * $URL$ + * $Id$ * */ -- cgit v1.2.3 From f307436240e0a9fd2faa47a7ced802726e20ff00 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 28 May 2010 00:57:54 +0000 Subject: added svn keywords 'Id' and 'URL' to new files svn-id: r49283 --- backends/plugins/ps2/ps2-provider.cpp | 4 ++-- backends/plugins/ps2/ps2-provider.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'backends') diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp index d0f6d417c0..2676c56ae8 100644 --- a/backends/plugins/ps2/ps2-provider.cpp +++ b/backends/plugins/ps2/ps2-provider.cpp @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ps2/ps2-provider.cpp $ - * $Id: ps2-provider.cpp 49253 2010-05-26 5:17:18Z Toneman $ + * $URL$ + * $Id$ * */ diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index fd49b9e74e..3c6550776b 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ps2/ps2-provider.h $ - * $Id: ps2-provider.h 49253 2010-05-26 5:17:18Z Toneman $ + * $URL$ + * $Id$ * */ -- cgit v1.2.3 From 2712012d0eba3bf634a780d25c2556d0781d9b27 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 1 Jun 2010 00:57:45 +0000 Subject: minor modification to accomodate dynamic plugins for ps2 svn-id: r49367 --- backends/module.mk | 2 ++ 1 file changed, 2 insertions(+) (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index 257ae0db9c..46c9e166a6 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -35,11 +35,13 @@ MODULE_OBJS := \ plugins/sdl/sdl-provider.o \ plugins/win32/win32-provider.o \ plugins/psp/psp-provider.o \ + plugins/ps2/ps2-provider.o \ saves/savefile.o \ saves/default/default-saves.o \ saves/posix/posix-saves.o \ saves/psp/psp-saves.o \ timer/default/default-timer.o \ + timer/psp/timer.o \ vkeybd/image-map.o \ vkeybd/polygon.o \ vkeybd/virtual-keyboard.o \ -- cgit v1.2.3 From e04b6b7ea0fc4589c86b3d862f4f284c510a6243 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 1 Jun 2010 01:05:09 +0000 Subject: changed ps2 makefile and other files to use the ps2loader svn-id: r49368 --- backends/platform/ps2/Makefile.ps2 | 33 +++++++++++++++++++++++++-------- backends/platform/ps2/module.mk | 3 ++- backends/platform/ps2/systemps2.cpp | 6 ++++++ 3 files changed, 33 insertions(+), 9 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 03f52b1a13..03b9489368 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -2,10 +2,8 @@ include $(PS2SDK)/Defs.make PS2_EXTRA = /home/tony/GSOC/ps2/sdk-extra -PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /isjpcm/ee/src /vorbis -PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /isjpcm/ee/lib /vorbis /vorbis/tremor/.libs /vorbis/tremor - -ENABLED=STATIC_PLUGIN +PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor +PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /vorbis /tremor/tremor ENABLE_SCUMM = $(ENABLED) ENABLE_SCUMM_7_8 = $(ENABLED) @@ -50,7 +48,6 @@ INCDIR = ../../../ DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar - INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines @@ -71,17 +68,37 @@ OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/systemps2.o \ backends/platform/ps2/ps2mutex.o \ backends/platform/ps2/ps2time.o \ - backends/platform/ps2/ps2debug.o + backends/platform/ps2/ps2debug.o \ + backends/platform/ps2/ps2loader.o MODULE_DIRS += . include $(srcdir)/Makefile.common -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(PS2SDK)/ee/startup/linkfile +# Set to 1 to enable, 0 to disable dynamic modules +DYNAMIC_MODULES = 1 + +# Variables for dynamic plugin building +PLUGIN_PREFIX = +PLUGIN_SUFFIX = .plg +PLUGIN_EXTRA_DEPS = plugin.syms scummvm-ps2.elf +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-ps2.org.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc + +# Test for dynamic plugins +ifeq ($(DYNAMIC_MODULES),1) +ENABLED = DYNAMIC_PLUGIN +DEFINES += -DDYNAMIC_MODULES +PRE_OBJS_FLAGS = -Wl,--whole-archive +POST_OBJS_FLAGS = -Wl,--no-whole-archive +else +ENABLED = STATIC_PLUGIN +endif + +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Tmain_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ -LDFLAGS += -s +LDFLAGS += -s all: $(TARGET) diff --git a/backends/platform/ps2/module.mk b/backends/platform/ps2/module.mk index 86b12cb668..69a28b93c4 100644 --- a/backends/platform/ps2/module.mk +++ b/backends/platform/ps2/module.mk @@ -16,7 +16,8 @@ MODULE_OBJS := \ systemps2.o \ ps2mutex.o \ ps2time.o \ - ps2debug.o + ps2debug.o \ + ps2loader.o MODULE_DIRS += \ backends/platform/ps2/ diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index 49d583d1a1..cd80c2a9cb 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -59,6 +59,8 @@ #include "backends/platform/ps2/ps2debug.h" #include "backends/fs/ps2/ps2-fs-factory.h" +#include "backends/plugins/ps2/ps2-provider.h" + #include "backends/saves/default/default-saves.h" #include "common/config-manager.h" @@ -132,6 +134,10 @@ extern "C" int main(int argc, char *argv[]) { g_systemPs2->init(); +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new PS2PluginProvider()); +#endif + sioprintf("init done. starting ScummVM.\n"); int res = scummvm_main(argc, argv); sioprintf("scummvm_main terminated: %d\n", res); -- cgit v1.2.3 From d9e46078699af4b8be14d76cca6dcd24128d8b1c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 1 Jun 2010 05:27:35 +0000 Subject: makefile tweaked a bit more towards accomodating loadable modules for ps2 svn-id: r49371 --- backends/platform/ps2/Makefile.ps2 | 43 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 03b9489368..5ca695fbf4 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -5,6 +5,21 @@ PS2_EXTRA = /home/tony/GSOC/ps2/sdk-extra PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /vorbis /tremor/tremor +# Set to 1 to enable, 0 to disable dynamic modules +DYNAMIC_MODULES = 1 + +VERBOSE_BUILD=1 + +# Test for dynamic plugins +ifeq ($(DYNAMIC_MODULES),1) +ENABLED = DYNAMIC_PLUGIN +DEFINES += -DDYNAMIC_MODULES +PRE_OBJS_FLAGS = -Wl,--whole-archive +POST_OBJS_FLAGS = -Wl,--no-whole-archive +else +ENABLED = STATIC_PLUGIN +endif + ENABLE_SCUMM = $(ENABLED) ENABLE_SCUMM_7_8 = $(ENABLED) ENABLE_HE = $(ENABLED) @@ -49,7 +64,7 @@ INCDIR = ../../../ DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) -INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines +INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines -I $(srcdir)/backends/platform/ps2 TARGET = elf/scummvm.elf @@ -75,33 +90,19 @@ MODULE_DIRS += . include $(srcdir)/Makefile.common -# Set to 1 to enable, 0 to disable dynamic modules -DYNAMIC_MODULES = 1 - -# Variables for dynamic plugin building -PLUGIN_PREFIX = -PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.syms scummvm-ps2.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-ps2.org.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc - -# Test for dynamic plugins -ifeq ($(DYNAMIC_MODULES),1) -ENABLED = DYNAMIC_PLUGIN -DEFINES += -DDYNAMIC_MODULES -PRE_OBJS_FLAGS = -Wl,--whole-archive -POST_OBJS_FLAGS = -Wl,--no-whole-archive -else -ENABLED = STATIC_PLUGIN -endif - LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Tmain_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ LDFLAGS += -s +# Variables for dynamic plugin building +PLUGIN_PREFIX = +PLUGIN_SUFFIX = .plg +PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q, -Tplugin.ld, --retain-symbols-file,plugin.syms -lstdc++ -lc + all: $(TARGET) $(TARGET): $(OBJS) $(LD) $^ $(LDFLAGS) -o $@ - -- cgit v1.2.3 From f1ae25baa87c6c0fbbd7b78daf6c886d8a0e68ab Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 3 Jun 2010 00:46:24 +0000 Subject: compiles with modified linker when dynamic plugins turned off now svn-id: r49399 --- backends/platform/ps2/Makefile.ps2 | 31 ++++++++++++++++--------------- backends/platform/ps2/main_prog.ld | 6 ++++++ backends/platform/ps2/plugin.ld | 21 +++++++++++++++------ 3 files changed, 37 insertions(+), 21 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 5ca695fbf4..6f44b11ee7 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -6,9 +6,9 @@ PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /vorbis /tremor/tremor # Set to 1 to enable, 0 to disable dynamic modules -DYNAMIC_MODULES = 1 +DYNAMIC_MODULES = 0 -VERBOSE_BUILD=1 +VERBOSE_BUILD=0 # Test for dynamic plugins ifeq ($(DYNAMIC_MODULES),1) @@ -58,13 +58,14 @@ RM = rm -f srcdir = ../../.. VPATH = $(srcdir) -INCDIR = ../../../ -# DEPDIR = .deps +INCDIR = $(srcdir) +#DEPDIR = .deps +#CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d,-MQ,"$@",-MP DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar -INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) -INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines -I $(srcdir)/backends/platform/ps2 +INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) +INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines TARGET = elf/scummvm.elf @@ -86,23 +87,23 @@ OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/ps2debug.o \ backends/platform/ps2/ps2loader.o -MODULE_DIRS += . +MODULE_DIRS += ./ include $(srcdir)/Makefile.common -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Tmain_prog.ld +# Variables for dynamic plugin building +PLUGIN_PREFIX = +PLUGIN_SUFFIX = .plg +PLUGIN_EXTRA_DEPS = plugin.syms scummvm-ps2.elf +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-ps2.org.elf,-Tplugin.ld,--export-dynamic,--retain-symbols-file,plugin.syms -lstdc++ -lc + +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-Tmain_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ LDFLAGS += -s -# Variables for dynamic plugin building -PLUGIN_PREFIX = -PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q, -Tplugin.ld, --retain-symbols-file,plugin.syms -lstdc++ -lc - all: $(TARGET) $(TARGET): $(OBJS) - $(LD) $^ $(LDFLAGS) -o $@ + $(LD) $(PRE_OBJS_FLAGS) $(OBJS) $(POST_OBJS_FLAGS) $(LDFLAGS) -o $@ diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld index 10b881cef9..b968bee431 100644 --- a/backends/platform/ps2/main_prog.ld +++ b/backends/platform/ps2/main_prog.ld @@ -219,4 +219,10 @@ SECTIONS .debug_varnames 0 : { *(.debug_varnames) } .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); + } diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld index 1eceac4966..d6ca6dcfe6 100644 --- a/backends/platform/ps2/plugin.ld +++ b/backends/platform/ps2/plugin.ld @@ -2,20 +2,22 @@ OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", "elf32-littlemips") OUTPUT_ARCH(mips:5900) +SEARCH_DIR("/home/tony/GSOC/ps2/tools/ee/ee/lib"); PHDRS { plugin PT_LOAD ; shorts PT_LOAD ; } /* Do we need any of these for elf? - __DYNAMIC = 0; */ -_DYNAMIC_LINK = 0; + __DYNAMIC = 0; +_DYNAMIC_LINK = 0; */ SECTIONS { /* Read-only sections, merged into text segment: */ - . = 0; //Not sure this shouldn't be 0x100000 - .interp : { *(.interp) } plugin - .reginfo : { *(.reginfo) } plugin + . = 0x100000; + .interp : { *(.interp) } : plugin + .reginfo : { *(.reginfo) } : plugin + .dynamic : { *(.dynamic) } .hash : { *(.hash) } .dynsym : { *(.dynsym) } .dynstr : { *(.dynstr) } @@ -129,8 +131,10 @@ SECTIONS ___plugin_dtors_end = .; } .jcr : { KEEP (*(.jcr)) } + . = __plugin_hole_start; - .got : { *(.got.plt) *(.got) } shorts + + .got : { *(.got.plt) *(.got) } : shorts .lit8 : { *(.lit8) } .lit4 : { *(.lit4) } /* We want the small data sections together, so single-instruction offsets @@ -202,4 +206,9 @@ SECTIONS .debug_varnames 0 : { *(.debug_varnames) } .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + + /* Symbols needed by crt0.s */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); } -- cgit v1.2.3 From 3c1034dbbb129f5af908a11fe948288b92acfdcf Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 3 Jun 2010 02:36:18 +0000 Subject: modified linker now both compiles and runs when dynamic modules turned off svn-id: r49400 --- backends/platform/ps2/Makefile.ps2 | 20 ++- backends/platform/ps2/main_prog.ld | 334 ++++++++++++------------------------- 2 files changed, 119 insertions(+), 235 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 6f44b11ee7..b41103945c 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -17,6 +17,8 @@ DEFINES += -DDYNAMIC_MODULES PRE_OBJS_FLAGS = -Wl,--whole-archive POST_OBJS_FLAGS = -Wl,--no-whole-archive else +PRE_OBJS_FLAGS = +POST_OBJS_FLAGS = ENABLED = STATIC_PLUGIN endif @@ -58,10 +60,16 @@ RM = rm -f srcdir = ../../.. VPATH = $(srcdir) -INCDIR = $(srcdir) +INCDIR = ../../../ #DEPDIR = .deps #CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d,-MQ,"$@",-MP +# Variables for dynamic plugin building +PLUGIN_PREFIX = +PLUGIN_SUFFIX = .plg +PLUGIN_EXTRA_DEPS = plugin.syms scummvm-ps2.elf +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-ps2.org.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc + DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) @@ -87,17 +95,11 @@ OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/ps2debug.o \ backends/platform/ps2/ps2loader.o -MODULE_DIRS += ./ +MODULE_DIRS += . include $(srcdir)/Makefile.common -# Variables for dynamic plugin building -PLUGIN_PREFIX = -PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.syms scummvm-ps2.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-ps2.org.elf,-Tplugin.ld,--export-dynamic,--retain-symbols-file,plugin.syms -lstdc++ -lc - -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-Tmain_prog.ld +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog2.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld index b968bee431..fe693f5ba0 100644 --- a/backends/platform/ps2/main_prog.ld +++ b/backends/platform/ps2/main_prog.ld @@ -1,228 +1,110 @@ -/* Script for -z combreloc: combine and sort reloc sections */ -OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", - "elf32-littlemips") -OUTPUT_ARCH(mips:5900) -ENTRY(_start) -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -_DYNAMIC_LINK = 0; -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x100000; - .interp : { *(.interp) } - .reginfo : { *(.reginfo) } - .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.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) - *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) - *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) - *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) - *(.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.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) - *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) - *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) - *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .text : - { - _ftext = . ; - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.mips16.fn.*) *(.mips16.call.*) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } - .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - /* 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(128) + (. & (128 - 1)); - /* 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 : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .data : - { - _fdata = . ; - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .eh_frame : { KEEP (*(.eh_frame)) } - .gcc_except_table : { *(.gcc_except_table) } - .dynamic : { *(.dynamic) } - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin*.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } - .dtors : - { - KEEP (*crtbegin*.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - .jcr : { KEEP (*(.jcr)) } - _gp = ALIGN(16) + 0x7ff0; - .got : { *(.got.plt) *(.got) } - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : - { - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - _fbss = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - /* make a gap to put the plugins' short data here */ - __plugin_hole_start = .; - . = _gp + 0x7ff0; - __plugin_hole_end = .; - COMMON : - { - *(COMMON) - } - . = ALIGN(32 / 8); - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - /* 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 = .; - PROVIDE (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) } - .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } - .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } - - /* Symbols needed by crt0.s. */ - PROVIDE(_heap_size = -1); - PROVIDE(_stack = -1); - PROVIDE(_stack_size = 128 * 1024); +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright 2001-2004, ps2dev - http://www.ps2dev.org +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +# +# $Id: linkfile 798 2005-02-07 06:21:37Z herben $ +# Linkfile script for ee-ld +*/ +ENTRY(_start); + +SECTIONS { + .text 0x00100000: { + _ftext = . ; + *(.text) + *(.text.*) + *(.gnu.linkonce.t*) + KEEP(*(.init)) + KEEP(*(.fini)) + QUAD(0) + } + + PROVIDE(_etext = .); + PROVIDE(etext = .); + + .reginfo : { *(.reginfo) } + + /* Global/static constructors and deconstructors. */ + .ctors ALIGN(16): { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors ALIGN(16): { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + + /* Static data. */ + .rodata ALIGN(128): { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + } + + .data ALIGN(128): { + _fdata = . ; + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + SORT(CONSTRUCTORS) + } + + .rdata ALIGN(128): { *(.rdata) } + .gcc_except_table ALIGN(128): { *(.gcc_except_table) } + + _gp = ALIGN(128) + 0x7ff0; + .lit4 ALIGN(128): { *(.lit4) } + .lit8 ALIGN(128): { *(.lit8) } + + .sdata ALIGN(128): { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s*) + } + + _edata = .; + PROVIDE(edata = .); + + /* Uninitialized data. */ + .sbss ALIGN(128) : { + _fbss = . ; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb*) + *(.scommon) + } + + __plugin_hole_start = .; + . = _gp + 0x7ff0; + __plugin_hole_end = .; + + COMMON : + { + *(COMMON) + } + . = ALIGN(32 / 8); + + .bss ALIGN(128) : { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b*) + } + _end_bss = .; + + _end = . ; + PROVIDE(end = .); + + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); } -- cgit v1.2.3 From f47d5bd35a34c65827aca379c401c3ccb002a749 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 3 Jun 2010 02:39:11 +0000 Subject: minor correction to makefile svn-id: r49401 --- backends/platform/ps2/Makefile.ps2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index b41103945c..63a8289242 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -99,7 +99,7 @@ MODULE_DIRS += . include $(srcdir)/Makefile.common -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog2.ld +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ -- cgit v1.2.3 From 28e28a2fea9f6adf4967463024c609e6a01ac5b0 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 4 Jun 2010 07:46:07 +0000 Subject: further tweaks to Makefile and main linker svn-id: r49422 --- backends/platform/ps2/Makefile.ps2 | 69 ++++++++++++++++++++------------------ backends/platform/ps2/main_prog.ld | 15 +-------- 2 files changed, 37 insertions(+), 47 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 63a8289242..7d18782658 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -6,7 +6,7 @@ PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /vorbis /tremor/tremor # Set to 1 to enable, 0 to disable dynamic modules -DYNAMIC_MODULES = 0 +DYNAMIC_MODULES = 1 VERBOSE_BUILD=0 @@ -17,34 +17,32 @@ DEFINES += -DDYNAMIC_MODULES PRE_OBJS_FLAGS = -Wl,--whole-archive POST_OBJS_FLAGS = -Wl,--no-whole-archive else -PRE_OBJS_FLAGS = -POST_OBJS_FLAGS = ENABLED = STATIC_PLUGIN endif -ENABLE_SCUMM = $(ENABLED) -ENABLE_SCUMM_7_8 = $(ENABLED) -ENABLE_HE = $(ENABLED) -ENABLE_AGI = $(ENABLED) -ENABLE_AGOS = $(ENABLED) -ENABLE_CINE = $(ENABLED) -ENABLE_CRUISE = $(ENABLED) -ENABLE_DRASCULA = $(ENABLED) -ENABLE_GOB = $(ENABLED) -ENABLE_KYRA = $(ENABLED) -ENABLE_LURE = $(ENABLED) +#ENABLE_SCUMM = $(ENABLED) +#ENABLE_SCUMM_7_8 = $(ENABLED) +#ENABLE_HE = $(ENABLED) +#ENABLE_AGI = $(ENABLED) +#ENABLE_AGOS = $(ENABLED) +#ENABLE_CINE = $(ENABLED) +#ENABLE_CRUISE = $(ENABLED) +#ENABLE_DRASCULA = $(ENABLED) +#ENABLE_GOB = $(ENABLED) +#ENABLE_KYRA = $(ENABLED) +#ENABLE_LURE = $(ENABLED) # ENABLE_M4 = $(ENABLED) -ENABLE_MADE = $(ENABLED) -ENABLE_PARALLACTION = $(ENABLED) -ENABLE_QUEEN = $(ENABLED) -ENABLE_SAGA = $(ENABLED) -ENABLE_SAGA2 = $(ENABLED) -ENABLE_IHNM = $(ENABLED) -ENABLE_SKY = $(ENABLED) -ENABLE_SWORD1 = $(ENABLED) -ENABLE_SWORD2 = $(ENABLED) +#ENABLE_MADE = $(ENABLED) +#ENABLE_PARALLACTION = $(ENABLED) +#ENABLE_QUEEN = $(ENABLED) +#ENABLE_SAGA = $(ENABLED) +#ENABLE_SAGA2 = $(ENABLED) +#ENABLE_IHNM = $(ENABLED) +#ENABLE_SKY = $(ENABLED) +#ENABLE_SWORD1 = $(ENABLED) +#ENABLE_SWORD2 = $(ENABLED) # ENABLE_TINSEL = $(ENABLED) -ENABLE_TOUCHE = $(ENABLED) +#ENABLE_TOUCHE = $(ENABLED) HAVE_GCC3 = true @@ -62,20 +60,20 @@ srcdir = ../../.. VPATH = $(srcdir) INCDIR = ../../../ #DEPDIR = .deps -#CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d,-MQ,"$@",-MP +#CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.syms scummvm-ps2.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-ps2.org.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc +PLUGIN_EXTRA_DEPS = plugin.syms elf/scummvm.elf +PLUGIN_LDFLAGS = -nostartfiles -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-q,--just-symbols=elf/scummvm.org.elf,-Tlinkfile,--retain-symbols-file,plugin.syms -lstdc++ -lc DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines -TARGET = elf/scummvm.elf +TARGET = elf/scummvm OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/Gs2dScreen.o \ @@ -99,13 +97,18 @@ MODULE_DIRS += . include $(srcdir)/Makefile.common -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld -LDFLAGS += -L $(PS2SDK)/ee/lib -L . +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld #$(PS2SDK)/ee/startup/linkfile +LDFLAGS += -G 0 -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ -LDFLAGS += -s +LDFLAGS += -all: $(TARGET) +all: $(TARGET).ps2 -$(TARGET): $(OBJS) +$(TARGET).elf: $(OBJS) $(LD) $(PRE_OBJS_FLAGS) $(OBJS) $(POST_OBJS_FLAGS) $(LDFLAGS) -o $@ + cp $(TARGET).elf $(TARGET).org.elf + +$(TARGET).ps2: $(TARGET).elf + rm $(TARGET).elf + rm $(TARGET).org.elf diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld index fe693f5ba0..de4b534135 100644 --- a/backends/platform/ps2/main_prog.ld +++ b/backends/platform/ps2/main_prog.ld @@ -1,16 +1,3 @@ -/* -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Copyright 2001-2004, ps2dev - http://www.ps2dev.org -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. -# -# $Id: linkfile 798 2005-02-07 06:21:37Z herben $ -# Linkfile script for ee-ld -*/ - ENTRY(_start); SECTIONS { @@ -91,7 +78,7 @@ SECTIONS { { *(COMMON) } - . = ALIGN(32 / 8); + . = ALIGN(128); .bss ALIGN(128) : { *(.bss) -- cgit v1.2.3 From 78995328157d55581d639f808efa15bc93dc20f2 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sun, 6 Jun 2010 00:47:21 +0000 Subject: added dynamic plugins stuff to configure svn-id: r49446 --- backends/platform/ps2/Makefile.ps2 | 9 +++++++-- backends/platform/ps2/systemps2.cpp | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index d6ebc9bfc8..9a3c8ba7f1 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -44,6 +44,9 @@ ENABLE_AGI = $(ENABLED) # ENABLE_TINSEL = $(ENABLED) #ENABLE_TOUCHE = $(ENABLED) +TARGET = elf/scummvm +#EXECUTABLE = $(TARGET) + HAVE_GCC3 = true CC = ee-gcc @@ -68,13 +71,15 @@ PLUGIN_SUFFIX = .plg PLUGIN_EXTRA_DEPS = plugin.syms elf/scummvm.elf PLUGIN_LDFLAGS = -nostartfiles -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-q,--just-symbols=elf/scummvm.org.elf,-Tlinkfile,--retain-symbols-file,plugin.syms -lstdc++ -lc +#PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms scummvm-psp.elf +#PLUGIN_LDFLAGS = -Wl -Tplugin.ld --just-symbols=scummvm-psp.org.elf --retain-symbols-file plugin.syms + + DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar -fno-exceptions -fno-rtti INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines -TARGET = elf/scummvm - OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/Gs2dScreen.o \ backends/platform/ps2/irxboot.o \ diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index 120f6ee157..fda4d8feaa 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -132,11 +132,11 @@ extern "C" int main(int argc, char *argv[]) { sioprintf("Creating system\n"); g_system = g_systemPs2 = new OSystem_PS2(argv[0]); - g_systemPs2->init(); - #ifdef DYNAMIC_MODULES PluginManager::instance().addPluginProvider(new PS2PluginProvider()); #endif + + g_systemPs2->init(); sioprintf("init done. starting ScummVM.\n"); int res = scummvm_main(argc, argv); -- cgit v1.2.3 From 179dc6446d046143eb09975c28585d5172b28125 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sun, 6 Jun 2010 21:57:09 +0000 Subject: use modified version of a different linker for linking plugins for PS2 svn-id: r49462 --- backends/platform/ps2/plugin.ld | 298 ++++++++++++---------------------------- 1 file changed, 91 insertions(+), 207 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld index d6ca6dcfe6..10055338d0 100644 --- a/backends/platform/ps2/plugin.ld +++ b/backends/platform/ps2/plugin.ld @@ -1,214 +1,98 @@ -/* Script for -z combreloc: combine and sort reloc sections */ -OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", - "elf32-littlemips") -OUTPUT_ARCH(mips:5900) -SEARCH_DIR("/home/tony/GSOC/ps2/tools/ee/ee/lib"); PHDRS { - plugin PT_LOAD ; - shorts PT_LOAD ; + plugin PT_LOAD ; + shorts PT_LOAD ; } -/* Do we need any of these for elf? - __DYNAMIC = 0; -_DYNAMIC_LINK = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0x100000; - .interp : { *(.interp) } : plugin - .reginfo : { *(.reginfo) } : plugin - .dynamic : { *(.dynamic) } - .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.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) - *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) - *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) - *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) - *(.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.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) - *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) - *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) - *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .text : - { - _ftext = . ; - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.mips16.fn.*) *(.mips16.call.*) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } - .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - /* 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(128) + (. & (128 - 1)); - /* 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 : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .data : - { - _fdata = . ; - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .eh_frame : { KEEP (*(.eh_frame)) } - .gcc_except_table : { *(.gcc_except_table) } - .dynamic : { *(.dynamic) } - .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)) } +SECTIONS { + /* originally was 0x00100000 but might be 0 */ + .text 0: { + _ftext = . ; + *(.text) + *(.text.*) + *(.gnu.linkonce.t*) + KEEP(*(.init)) + KEEP(*(.fini)) + QUAD(0) + } + + PROVIDE(_etext = .); + PROVIDE(etext = .); + + /* interp may or may not be needed here */ + .interp : { *(.interp) } : plugin + .reginfo : { *(.reginfo) } : plugin + + /* Global/static constructors and deconstructors. */ + .ctors ALIGN(16): { + ___plugin_ctors = .; + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + ___plugin_ctors_end = .; + } + .dtors ALIGN(16): { + ___plugin_dtors = .; + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + ___plugin_dtors_end = .; + } + + /* Static data. */ + .rodata ALIGN(128): { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + } + + .data ALIGN(128): { + _fdata = . ; + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + SORT(CONSTRUCTORS) + } + + .rdata ALIGN(128): { *(.rdata) } + .gcc_except_table ALIGN(128): { *(.gcc_except_table) } + + /* _gp = ALIGN(128) + 0x7ff0; */ + . = __plugin_hole_start; + /* the .got line wasn't originally there */ + .got : { *(.got.plt) *(.got) } : shorts + + .lit4 ALIGN(128): { *(.lit4) } + .lit8 ALIGN(128): { *(.lit8) } + + .sdata ALIGN(128): { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s*) + } + + _edata = .; + PROVIDE(edata = .); + + /* Uninitialized data. */ + .sbss ALIGN(128) : { + _fbss = . ; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb*) + *(.scommon) + } - . = __plugin_hole_start; + .bss ALIGN(128) : { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b*) + *(COMMON) + } + _end_bss = .; - .got : { *(.got.plt) *(.got) } : shorts - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : - { - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - _fbss = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - .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 = .; - PROVIDE (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) } - .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } - .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + _end = . ; + PROVIDE(end = .); - /* Symbols needed by crt0.s */ - PROVIDE(_heap_size = -1); - PROVIDE(_stack = -1); - PROVIDE(_stack_size = 128 * 1024); + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); } -- cgit v1.2.3 From d4e33a92842cd35d08069650d8fd68022b0d9f08 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sun, 6 Jun 2010 22:24:33 +0000 Subject: Makefile tweaked so plugins build for PS2 and uncommented code from default-saves.cpp svn-id: r49463 --- backends/platform/ps2/Makefile.ps2 | 58 +++++++++++++++----------------- backends/saves/default/default-saves.cpp | 4 +-- 2 files changed, 29 insertions(+), 33 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 9a3c8ba7f1..8d31246ed8 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -20,39 +20,39 @@ else ENABLED = STATIC_PLUGIN endif -ENABLE_SCUMM = $(ENABLED) +#ENABLE_SCUMM = $(ENABLED) #ENABLE_SCUMM_7_8 = $(ENABLED) -#ENABLE_HE = $(ENABLED) +ENABLE_HE = $(ENABLED) ENABLE_AGI = $(ENABLED) -#ENABLE_AGOS = $(ENABLED) -#ENABLE_CINE = $(ENABLED) -#ENABLE_CRUISE = $(ENABLED) -#ENABLE_DRASCULA = $(ENABLED) +ENABLE_AGOS = $(ENABLED) +ENABLE_CINE = $(ENABLED) +ENABLE_CRUISE = $(ENABLED) +ENABLE_DRASCULA = $(ENABLED) #ENABLE_GOB = $(ENABLED) #ENABLE_KYRA = $(ENABLED) -#ENABLE_LURE = $(ENABLED) +ENABLE_LURE = $(ENABLED) # ENABLE_M4 = $(ENABLED) -#ENABLE_MADE = $(ENABLED) -#ENABLE_PARALLACTION = $(ENABLED) -#ENABLE_QUEEN = $(ENABLED) -#ENABLE_SAGA = $(ENABLED) -#ENABLE_SAGA2 = $(ENABLED) -#ENABLE_IHNM = $(ENABLED) -#ENABLE_SKY = $(ENABLED) -#ENABLE_SWORD1 = $(ENABLED) -#ENABLE_SWORD2 = $(ENABLED) +ENABLE_MADE = $(ENABLED) +ENABLE_PARALLACTION = $(ENABLED) +ENABLE_QUEEN = $(ENABLED) +ENABLE_SAGA = $(ENABLED) +ENABLE_SAGA2 = $(ENABLED) +ENABLE_IHNM = $(ENABLED) +ENABLE_SKY = $(ENABLED) +ENABLE_SWORD1 = $(ENABLED) +ENABLE_SWORD2 = $(ENABLED) # ENABLE_TINSEL = $(ENABLED) -#ENABLE_TOUCHE = $(ENABLED) +ENABLE_TOUCHE = $(ENABLED) -TARGET = elf/scummvm +TARGET = elf/scummvm.elf #EXECUTABLE = $(TARGET) HAVE_GCC3 = true -CC = ee-gcc -CXX = ee-g++ -AS = ee-gcc -LD = ee-gcc +CC = ee-gcc -G 0 +CXX = ee-g++ -G 0 +AS = ee-gcc -G 0 +LD = ee-gcc -G 0 AR = ee-ar cru RANLIB = ee-ranlib STRIP = ee-strip @@ -69,11 +69,7 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg PLUGIN_EXTRA_DEPS = plugin.syms elf/scummvm.elf -PLUGIN_LDFLAGS = -nostartfiles -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-q,--just-symbols=elf/scummvm.org.elf,-Tlinkfile,--retain-symbols-file,plugin.syms -lstdc++ -lc - -#PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms scummvm-psp.elf -#PLUGIN_LDFLAGS = -Wl -Tplugin.ld --just-symbols=scummvm-psp.org.elf --retain-symbols-file plugin.syms - +PLUGIN_LDFLAGS = -nostartfiles -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-q,--just-symbols=elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar -fno-exceptions -fno-rtti @@ -98,17 +94,17 @@ OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/ps2debug.o \ backends/platform/ps2/ps2loader.o -MODULE_DIRS += . +MODULE_DIRS += ./ include $(srcdir)/Makefile.common LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld #$(PS2SDK)/ee/startup/linkfile -LDFLAGS += -G 0 -L $(PS2SDK)/ee/lib -L . +LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ LDFLAGS += -all: $(TARGET).elf +all: $(TARGET) -$(TARGET).elf: $(OBJS) +$(TARGET): $(OBJS) $(LD) $(PRE_OBJS_FLAGS) $(OBJS) $(POST_OBJS_FLAGS) $(LDFLAGS) -o $@ diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp index 6a91f2cbe1..55aa469309 100644 --- a/backends/saves/default/default-saves.cpp +++ b/backends/saves/default/default-saves.cpp @@ -131,11 +131,11 @@ bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) { // There is a nicely portable workaround, too: Make this method overloadable. if (remove(file.getPath().c_str()) != 0) { #ifndef _WIN32_WCE - /* if (errno == EACCES) + if (errno == EACCES) setError(Common::kWritePermissionDenied, "Search or write permission denied: "+file.getName()); if (errno == ENOENT) - setError(Common::kPathDoesNotExist, "removeSavefile: '"+file.getName()+"' does not exist or path is invalid"); */ + setError(Common::kPathDoesNotExist, "removeSavefile: '"+file.getName()+"' does not exist or path is invalid"); #endif return false; } else { -- cgit v1.2.3 From dcdebf60b052f9609e543826741fe8f845fd3257 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 7 Jun 2010 19:54:14 +0000 Subject: rearranged Makefile for clarity and added comments svn-id: r49493 --- backends/platform/ps2/Makefile.ps2 | 81 ++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 38 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 8d31246ed8..67fc909ec5 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -1,27 +1,13 @@ # $Header: Exp $ include $(PS2SDK)/Defs.make +#These should point to the extra PS2 libs PS2_EXTRA = /home/tony/GSOC/ps2/sdk-extra PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /vorbis /tremor/tremor -# Set to 1 to enable, 0 to disable dynamic modules -DYNAMIC_MODULES = 1 - -VERBOSE_BUILD=0 - -# Test for dynamic plugins -ifeq ($(DYNAMIC_MODULES),1) -ENABLED = DYNAMIC_PLUGIN -DEFINES += -DDYNAMIC_MODULES -PRE_OBJS_FLAGS = -Wl,--whole-archive -POST_OBJS_FLAGS = -Wl,--no-whole-archive -else -ENABLED = STATIC_PLUGIN -endif - -#ENABLE_SCUMM = $(ENABLED) -#ENABLE_SCUMM_7_8 = $(ENABLED) +ENABLE_SCUMM = $(ENABLED) +ENABLE_SCUMM_7_8 = $(ENABLED) ENABLE_HE = $(ENABLED) ENABLE_AGI = $(ENABLED) ENABLE_AGOS = $(ENABLED) @@ -44,39 +30,63 @@ ENABLE_SWORD2 = $(ENABLED) # ENABLE_TINSEL = $(ENABLED) ENABLE_TOUCHE = $(ENABLED) +# Set to 1 to enable, 0 to disable dynamic modules +DYNAMIC_MODULES = 1 +# Set to 1 to enable, 0 to disable more detailed printing of gcc commands +VERBOSE_BUILD=0 +# -------------------------------------------------------------------- + +#General variables +srcdir = ../../.. +VPATH = $(srcdir) TARGET = elf/scummvm.elf #EXECUTABLE = $(TARGET) -HAVE_GCC3 = true +#Variables for common ScummVM makefile +CXX = ee-g++ -G 0 +CXXFLAGS = -O2 -Wall -Wno-multichar -fno-exceptions -fno-rtti +DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ +LDFLAGS := +INCDIR = ../../../ +INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) +INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines +DEPDIR = .deps +MODULE_DIRS += ./ +MKDIR = mkdir -p +RM = rm -f +RM_REC = rm -rf CC = ee-gcc -G 0 -CXX = ee-g++ -G 0 AS = ee-gcc -G 0 LD = ee-gcc -G 0 AR = ee-ar cru RANLIB = ee-ranlib +HAVE_GCC3 = true STRIP = ee-strip -MKDIR = mkdir -p -RM = rm -f - -srcdir = ../../.. -VPATH = $(srcdir) -INCDIR = ../../../ -DEPDIR = .deps CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.syms elf/scummvm.elf -PLUGIN_LDFLAGS = -nostartfiles -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-q,--just-symbols=elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc +PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms elf/scummvm.elf #comment out -mno? +PLUGIN_LDFLAGS = -nostartfiles -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc -DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar -fno-exceptions -fno-rtti +# Test for dynamic plugins +ifeq ($(DYNAMIC_MODULES),1) +ENABLED = DYNAMIC_PLUGIN +DEFINES += -DDYNAMIC_MODULES +PRE_OBJS_FLAGS = -Wl,--whole-archive +POST_OBJS_FLAGS = -Wl,--no-whole-archive +else +ENABLED = STATIC_PLUGIN +endif -INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) -INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines +LDFLAGS += -L $(PS2SDK)/ee/lib -L . +LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) +LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ +LDFLAGS += -s -OBJS := backends/platform/ps2/DmaPipe.o \ +OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/Gs2dScreen.o \ backends/platform/ps2/irxboot.o \ backends/platform/ps2/ps2input.o \ @@ -93,16 +103,11 @@ OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/ps2time.o \ backends/platform/ps2/ps2debug.o \ backends/platform/ps2/ps2loader.o - -MODULE_DIRS += ./ + include $(srcdir)/Makefile.common LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld #$(PS2SDK)/ee/startup/linkfile -LDFLAGS += -L $(PS2SDK)/ee/lib -L . -LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) -LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ -LDFLAGS += all: $(TARGET) -- cgit v1.2.3 From d6b194aaa8207e5127b7e68c7bdde780672a4647 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 9 Jun 2010 04:04:34 +0000 Subject: added tentative GDB flag to Makefile, changed calls to psp-functions to equivalent ps2-functions in ps2loader, minor rearrangement of code in systemps2 svn-id: r49530 --- backends/platform/ps2/Makefile.ps2 | 60 +++++++++++++++++++++++-------------- backends/platform/ps2/ps2loader.cpp | 13 ++++---- backends/platform/ps2/systemps2.cpp | 4 +-- 3 files changed, 48 insertions(+), 29 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 67fc909ec5..d1d2d5ebc8 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -6,34 +6,36 @@ PS2_EXTRA = /home/tony/GSOC/ps2/sdk-extra PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /vorbis /tremor/tremor -ENABLE_SCUMM = $(ENABLED) -ENABLE_SCUMM_7_8 = $(ENABLED) -ENABLE_HE = $(ENABLED) -ENABLE_AGI = $(ENABLED) -ENABLE_AGOS = $(ENABLED) -ENABLE_CINE = $(ENABLED) -ENABLE_CRUISE = $(ENABLED) -ENABLE_DRASCULA = $(ENABLED) +#ENABLE_SCUMM = $(ENABLED) +#ENABLE_SCUMM_7_8 = $(ENABLED) +#ENABLE_HE = $(ENABLED) +#ENABLE_AGI = $(ENABLED) +#ENABLE_AGOS = $(ENABLED) +#ENABLE_CINE = $(ENABLED) +#ENABLE_CRUISE = $(ENABLED) +#ENABLE_DRASCULA = $(ENABLED) #ENABLE_GOB = $(ENABLED) #ENABLE_KYRA = $(ENABLED) -ENABLE_LURE = $(ENABLED) +#ENABLE_LURE = $(ENABLED) # ENABLE_M4 = $(ENABLED) -ENABLE_MADE = $(ENABLED) -ENABLE_PARALLACTION = $(ENABLED) -ENABLE_QUEEN = $(ENABLED) -ENABLE_SAGA = $(ENABLED) -ENABLE_SAGA2 = $(ENABLED) -ENABLE_IHNM = $(ENABLED) +#ENABLE_MADE = $(ENABLED) +#ENABLE_PARALLACTION = $(ENABLED) +#ENABLE_QUEEN = $(ENABLED) +#ENABLE_SAGA = $(ENABLED) +#ENABLE_SAGA2 = $(ENABLED) +#ENABLE_IHNM = $(ENABLED) ENABLE_SKY = $(ENABLED) -ENABLE_SWORD1 = $(ENABLED) -ENABLE_SWORD2 = $(ENABLED) +#ENABLE_SWORD1 = $(ENABLED) +#ENABLE_SWORD2 = $(ENABLED) # ENABLE_TINSEL = $(ENABLED) -ENABLE_TOUCHE = $(ENABLED) +#ENABLE_TOUCHE = $(ENABLED) # Set to 1 to enable, 0 to disable dynamic modules DYNAMIC_MODULES = 1 # Set to 1 to enable, 0 to disable more detailed printing of gcc commands -VERBOSE_BUILD=0 +VERBOSE_BUILD=1 +# Set to 1 to enable, 0 to disable debugging support (This won't easily work "out of the box") +DEBUG=0 # -------------------------------------------------------------------- #General variables @@ -46,10 +48,16 @@ TARGET = elf/scummvm.elf CXX = ee-g++ -G 0 CXXFLAGS = -O2 -Wall -Wno-multichar -fno-exceptions -fno-rtti DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ +ifeq ($(DEBUG),1) +DEFINES += -D__PS2_DEBUG__ -g -Wall -Wno-multichar +endif LDFLAGS := INCDIR = ../../../ INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) +ifeq ($(DEBUG),1) +INCLUDES += -I $(PS2GDB)/ee +endif INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines DEPDIR = .deps MODULE_DIRS += ./ @@ -69,7 +77,8 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms elf/scummvm.elf #comment out -mno? -PLUGIN_LDFLAGS = -nostartfiles -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc +#PLUGIN_LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc # Test for dynamic plugins ifeq ($(DYNAMIC_MODULES),1) @@ -81,10 +90,17 @@ else ENABLED = STATIC_PLUGIN endif +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o +ifeq ($(DEBUG),1) +LDFLAGS += -L $(PS2GDB)/lib +endif LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) +ifeq ($(DEBUG),1) +LDFLAGS += -lps2gdbStub -lps2ip -ldebug +endif LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ -LDFLAGS += -s +LDFLAGS += OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/Gs2dScreen.o \ @@ -107,7 +123,7 @@ OBJS := backends/platform/ps2/DmaPipe.o \ include $(srcdir)/Makefile.common -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld #$(PS2SDK)/ee/startup/linkfile +LDFLAGS += -Wl,-G,0 -T main_prog.ld #$(PS2SDK)/ee/startup/linkfile all: $(TARGET) diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp index bea697bf07..6e38496b91 100644 --- a/backends/platform/ps2/ps2loader.cpp +++ b/backends/platform/ps2/ps2loader.cpp @@ -30,9 +30,9 @@ #include #include #include -#include +#include -#include +//#include do these exist? #include "backends/platform/ps2/ps2loader.h" //#include "backends/platform/ps2/powerman.h" //TODO @@ -552,7 +552,8 @@ bool DLObject::open(const char *path) { _gpVal = (unsigned int) & _gp; DBG("_gpVal is %x\n", _gpVal); - PowerMan.beginCriticalSection(); + //PS2 has no "PowerMan" for suspending the system. + //PowerMan.beginCriticalSection(); if ((fd = ::open(path, O_RDONLY)) < 0) { seterror("%s not found.", path); @@ -568,10 +569,12 @@ bool DLObject::open(const char *path) { ::close(fd); - PowerMan.endCriticalSection(); + //PS2 has no "PowerMan" for suspending the system. + //PowerMan.endCriticalSection(); // flush data cache - sceKernelDcacheWritebackAll(); + FlushCache(0); + FlushCache(2); // Get the symbols for the global constructors and destructors ctors_start = symbol("___plugin_ctors"); diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index fda4d8feaa..120f6ee157 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -132,11 +132,11 @@ extern "C" int main(int argc, char *argv[]) { sioprintf("Creating system\n"); g_system = g_systemPs2 = new OSystem_PS2(argv[0]); + g_systemPs2->init(); + #ifdef DYNAMIC_MODULES PluginManager::instance().addPluginProvider(new PS2PluginProvider()); #endif - - g_systemPs2->init(); sioprintf("init done. starting ScummVM.\n"); int res = scummvm_main(argc, argv); -- cgit v1.2.3 From a302fdb2c49d7e98a93a897cbe5cad889204c28e Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 11 Jun 2010 01:08:47 +0000 Subject: changed DBG to use sioprintf but temporarily commented out those statements svn-id: r49588 --- backends/platform/ps2/ps2loader.cpp | 90 ++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 45 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp index 6e38496b91..a48fef94cb 100644 --- a/backends/platform/ps2/ps2loader.cpp +++ b/backends/platform/ps2/ps2loader.cpp @@ -40,7 +40,7 @@ //#define __PS2_DEBUG_PLUGINS__ #ifdef __PS2_DEBUG_PLUGINS__ -#define DBG(x,...) fprintf(stderr,x, ## __VA_ARGS__) +#define DBG(x,...) sioprintf(x, ## __VA_ARGS__) #else #define DBG(x,...) #endif @@ -103,7 +103,7 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * // Treat each relocation entry. Loop over all of them int cnt = size / sizeof(*rel); - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + //DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); bool seenHi16 = false; // For treating HI/LO16 commands int firstHi16 = -1; // Mark the point of the first hi16 seen @@ -141,9 +141,9 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * lastHiSymVal = sym->st_value; hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments - if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number - DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", - i, rel[i].r_offset, ahl, *target); + //if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number + //DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", + //i, rel[i].r_offset, ahl, *target); } break; @@ -194,12 +194,12 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * *target &= 0xffff0000; // Clear the lower 16 bits of current target *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation - if (debugRelocs[1]++ < DEBUG_NUM) - DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + //if (debugRelocs[1]++ < DEBUG_NUM) + //DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + // i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + //if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) + //DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + // i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); } break; @@ -211,13 +211,13 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * *target &= 0xfc000000; // Clean lower 26 target bits *target |= (relocation & 0x03ffffff); - if (debugRelocs[3]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + //if (debugRelocs[3]++ < DEBUG_NUM) + //DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + // i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } else { - if (debugRelocs[4]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + //if (debugRelocs[4]++ < DEBUG_NUM) + //DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + // i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } break; @@ -232,9 +232,9 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * *target &= 0xffff0000; // Clear the lower 16 bits of the target *target |= relocation & 0xffff; - if (debugRelocs[5]++ < DEBUG_NUM) - DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", - i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); + //if (debugRelocs[5]++ < DEBUG_NUM) + //DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", + // i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); } break; @@ -249,8 +249,8 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * relocation = a + (Elf32_Addr)_segment; // Shift by main offset *target = relocation; - if (debugRelocs[6]++ < DEBUG_NUM) - DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + //if (debugRelocs[6]++ < DEBUG_NUM) + //DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); } break; @@ -261,7 +261,7 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * } } - DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); + //DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); free(rel); return true; @@ -279,8 +279,8 @@ bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { return false; } - DBG("phoff = %d, phentsz = %d, phnum = %d\n", - ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); + //DBG("phoff = %d, phentsz = %d, phnum = %d\n", + //ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); return true; } @@ -299,8 +299,8 @@ bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, in return false; } - DBG("offs = %x, filesz = %x, memsz = %x, align = %x\n", - phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); + //DBG("offs = %x, filesz = %x, memsz = %x, align = %x\n", + //phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); return true; @@ -315,7 +315,7 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { // 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); + //DBG("extra mem is %x\n", extra); if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI @@ -323,7 +323,7 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { seterror("Out of memory.\n"); return false; } - DBG("allocated segment @ %p\n", _segment); + //DBG("allocated segment @ %p\n", _segment); // Get offset to load segment into baseAddress = (char *)_segment + phdr->p_vaddr; @@ -332,14 +332,14 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); baseAddress = _shortsSegment->getStart(); - DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", - _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + //DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", + //_shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); } // 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); + //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 @@ -396,7 +396,7 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { return -1; } - DBG("Symbol section at section %d, size %x\n", _symtab_sect, shdr[_symtab_sect].sh_size); + //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))) { @@ -414,7 +414,7 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Set number of symbols _symbol_cnt = shdr[_symtab_sect].sh_size / sizeof(Elf32_Sym); - DBG("Loaded %d symbols.\n", _symbol_cnt); + //DBG("Loaded %d symbols.\n", _symbol_cnt); return _symtab_sect; @@ -443,7 +443,7 @@ bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { void DLObject::relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset) { int shortsCount = 0, othersCount = 0; - DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); + //DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); // Loop over symbols, add relocation offset Elf32_Sym *s = (Elf32_Sym *)_symtab; @@ -466,7 +466,7 @@ void DLObject::relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset) { } - DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); + //DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); } bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { @@ -546,11 +546,11 @@ bool DLObject::open(const char *path) { int fd; void *ctors_start, *ctors_end; - DBG("open(\"%s\")\n", path); + //DBG("open(\"%s\")\n", path); // Get the address of the global pointer _gpVal = (unsigned int) & _gp; - DBG("_gpVal is %x\n", _gpVal); + //DBG("_gpVal is %x\n", _gpVal); //PS2 has no "PowerMan" for suspending the system. //PowerMan.beginCriticalSection(); @@ -590,11 +590,11 @@ bool DLObject::open(const char *path) { return false; } - DBG("Calling constructors.\n"); + //DBG("Calling constructors.\n"); for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) (**f)(); - DBG("%s opened ok.\n", path); + //DBG("%s opened ok.\n", path); return true; } @@ -608,7 +608,7 @@ bool DLObject::close() { } void *DLObject::symbol(const char *name) { - DBG("symbol(\"%s\")\n", name); + //DBG("symbol(\"%s\")\n", name); if (_symtab == NULL || _strtab == NULL || _symbol_cnt < 1) { seterror("No symbol table loaded."); @@ -624,7 +624,7 @@ void *DLObject::symbol(const char *name) { !strcmp(name, _strtab + s->st_name)) { // We found the symbol - DBG("=> %p\n", (void*)s->st_value); + //DBG("=> %p\n", (void*)s->st_value); return (void*)s->st_value; } } @@ -668,14 +668,14 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or _list.insert(i, seg); - DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", - size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); + //DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", + //size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); return seg; } void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { - DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); + //DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); _list.remove(seg); delete seg; } -- cgit v1.2.3 From fb54698b373b1104989f9b8ce00672511c7ea20b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sun, 13 Jun 2010 05:57:24 +0000 Subject: loadable modules working for ps2 svn-id: r49617 --- backends/platform/ps2/Makefile.ps2 | 193 +++++++++++------------ backends/platform/ps2/main_prog.ld | 4 +- backends/platform/ps2/plugin.ld | 296 ++++++++++++++++++++++++------------ backends/platform/ps2/ps2loader.cpp | 98 ++++++------ backends/platform/ps2/systemps2.cpp | 5 +- 5 files changed, 348 insertions(+), 248 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index d1d2d5ebc8..15eb909107 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -1,131 +1,122 @@ # $Header: Exp $ include $(PS2SDK)/Defs.make -#These should point to the extra PS2 libs PS2_EXTRA = /home/tony/GSOC/ps2/sdk-extra PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor -PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /vorbis /tremor/tremor - -#ENABLE_SCUMM = $(ENABLED) -#ENABLE_SCUMM_7_8 = $(ENABLED) -#ENABLE_HE = $(ENABLED) -#ENABLE_AGI = $(ENABLED) -#ENABLE_AGOS = $(ENABLED) -#ENABLE_CINE = $(ENABLED) -#ENABLE_CRUISE = $(ENABLED) -#ENABLE_DRASCULA = $(ENABLED) -#ENABLE_GOB = $(ENABLED) -#ENABLE_KYRA = $(ENABLED) -#ENABLE_LURE = $(ENABLED) -# ENABLE_M4 = $(ENABLED) -#ENABLE_MADE = $(ENABLED) -#ENABLE_PARALLACTION = $(ENABLED) -#ENABLE_QUEEN = $(ENABLED) -#ENABLE_SAGA = $(ENABLED) -#ENABLE_SAGA2 = $(ENABLED) -#ENABLE_IHNM = $(ENABLED) -ENABLE_SKY = $(ENABLED) -#ENABLE_SWORD1 = $(ENABLED) -#ENABLE_SWORD2 = $(ENABLED) -# ENABLE_TINSEL = $(ENABLED) -#ENABLE_TOUCHE = $(ENABLED) +PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /tremor/tremor # Set to 1 to enable, 0 to disable dynamic modules DYNAMIC_MODULES = 1 # Set to 1 to enable, 0 to disable more detailed printing of gcc commands -VERBOSE_BUILD=1 -# Set to 1 to enable, 0 to disable debugging support (This won't easily work "out of the box") -DEBUG=0 -# -------------------------------------------------------------------- +VERBOSE_BUILD=0 -#General variables -srcdir = ../../.. -VPATH = $(srcdir) -TARGET = elf/scummvm.elf -#EXECUTABLE = $(TARGET) - -#Variables for common ScummVM makefile -CXX = ee-g++ -G 0 -CXXFLAGS = -O2 -Wall -Wno-multichar -fno-exceptions -fno-rtti -DEFINES = -DUSE_VORBIS -DUSE_MAD -DUSE_TREMOR -DUSE_ZLIB -DFORCE_RTL -D_EE -D__PLAYSTATION2__ -ifeq ($(DEBUG),1) -DEFINES += -D__PS2_DEBUG__ -g -Wall -Wno-multichar +# Test for dynamic plugins +ifeq ($(DYNAMIC_MODULES),1) +ENABLED = DYNAMIC_PLUGIN +DEFINES = -DDYNAMIC_MODULES +PRE_OBJS_FLAGS = -Wl,--whole-archive +POST_OBJS_FLAGS = -Wl,--no-whole-archive +else +ENABLED = STATIC_PLUGIN endif -LDFLAGS := -INCDIR = ../../../ -INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) -ifeq ($(DEBUG),1) -INCLUDES += -I $(PS2GDB)/ee -endif -INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines -DEPDIR = .deps -MODULE_DIRS += ./ -MKDIR = mkdir -p -RM = rm -f -RM_REC = rm -rf -CC = ee-gcc -G 0 -AS = ee-gcc -G 0 -LD = ee-gcc -G 0 +#control build +DISABLE_SCALERS = true +DISABLE_HQ_SCALERS = true + +ENABLE_SCUMM = $(ENABLED) +ENABLE_SCUMM_7_8 = $(ENABLED) +ENABLE_HE = $(ENABLED) +ENABLE_AGI = $(ENABLED) +ENABLE_AGOS = $(ENABLED) +ENABLE_AGOS2 = $(ENABLED) +ENABLE_CINE = $(ENABLED) +ENABLE_CRUISE = $(ENABLED) +ENABLE_DRACI = $(ENABLED) +ENABLE_DRASCULA = $(ENABLED) +ENABLE_GOB = $(ENABLED) +ENABLE_GROOVIE = $(ENABLED) +# ENABLE_GROOVIE2 = $(ENABLED) +ENABLE_IHNM = $(ENABLED) +ENABLE_KYRA = $(ENABLED) +# ENABLE_LOL = $(ENABLED) +ENABLE_LURE = $(ENABLED) +# ENABLE_M4 = $(ENABLED) +ENABLE_MADE = $(ENABLED) +ENABLE_PARALLACTION = $(ENABLED) +ENABLE_QUEEN = $(ENABLED) +ENABLE_SAGA = $(ENABLED) +ENABLE_SAGA2 = $(ENABLED) +ENABLE_SCI = $(ENABLED) +# ENABLE_SCI32 = $(ENABLED) +ENABLE_SKY = $(ENABLED) +ENABLE_SWORD1 = $(ENABLED) +ENABLE_SWORD2 = $(ENABLED) +ENABLE_TEENAGENT = $(ENABLED) +ENABLE_TINSEL = $(ENABLED) +ENABLE_TOUCHE = $(ENABLED) +ENABLE_TUCKER = $(ENABLED) + +HAVE_GCC3 = true +CC = ee-gcc +CXX = ee-g++ +AS = ee-gcc +LD = ee-gcc AR = ee-ar cru RANLIB = ee-ranlib -HAVE_GCC3 = true STRIP = ee-strip +MKDIR = mkdir -p +RM = rm -f +RM_REC = rm -rf +MODULE_DIRS = ./ + +srcdir = ../../.. +VPATH = $(srcdir) +INCDIR = ../../../ +DEPDIR = .deps + +TARGET = elf/scummvm.elf + +DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G0 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR + +INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) +INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines + CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms elf/scummvm.elf #comment out -mno? -#PLUGIN_LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc +PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms elf/scummvm.elf +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc -# Test for dynamic plugins -ifeq ($(DYNAMIC_MODULES),1) -ENABLED = DYNAMIC_PLUGIN -DEFINES += -DDYNAMIC_MODULES -PRE_OBJS_FLAGS = -Wl,--whole-archive -POST_OBJS_FLAGS = -Wl,--no-whole-archive -else -ENABLED = STATIC_PLUGIN -endif - -LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -ifeq ($(DEBUG),1) -LDFLAGS += -L $(PS2GDB)/lib -endif +LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . -LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) -ifeq ($(DEBUG),1) -LDFLAGS += -lps2gdbStub -lps2ip -ldebug -endif -LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ -LDFLAGS += - -OBJS := backends/platform/ps2/DmaPipe.o \ - backends/platform/ps2/Gs2dScreen.o \ - backends/platform/ps2/irxboot.o \ - backends/platform/ps2/ps2input.o \ - backends/platform/ps2/ps2pad.o \ - backends/platform/ps2/savefilemgr.o \ - backends/platform/ps2/fileio.o \ - backends/platform/ps2/asyncfio.o \ - backends/platform/ps2/icon.o \ - backends/platform/ps2/cd.o \ - backends/platform/ps2/eecodyvdfs.o \ - backends/platform/ps2/rpckbd.o \ - backends/platform/ps2/systemps2.o \ - backends/platform/ps2/ps2mutex.o \ - backends/platform/ps2/ps2time.o \ - backends/platform/ps2/ps2debug.o \ - backends/platform/ps2/ps2loader.o +LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) +LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ +OBJS := $(srcdir)/backends/platform/ps2/DmaPipe.o \ + $(srcdir)/backends/platform/ps2/Gs2dScreen.o \ + $(srcdir)/backends/platform/ps2/irxboot.o \ + $(srcdir)/backends/platform/ps2/ps2input.o \ + $(srcdir)/backends/platform/ps2/ps2pad.o \ + $(srcdir)/backends/platform/ps2/savefilemgr.o \ + $(srcdir)/backends/platform/ps2/fileio.o \ + $(srcdir)/backends/platform/ps2/asyncfio.o \ + $(srcdir)/backends/platform/ps2/icon.o \ + $(srcdir)/backends/platform/ps2/cd.o \ + $(srcdir)/backends/platform/ps2/eecodyvdfs.o \ + $(srcdir)/backends/platform/ps2/rpckbd.o \ + $(srcdir)/backends/platform/ps2/systemps2.o \ + $(srcdir)/backends/platform/ps2/ps2mutex.o \ + $(srcdir)/backends/platform/ps2/ps2time.o \ + $(srcdir)/backends/platform/ps2/ps2loader.o \ + $(srcdir)/backends/platform/ps2/ps2debug.o include $(srcdir)/Makefile.common -LDFLAGS += -Wl,-G,0 -T main_prog.ld #$(PS2SDK)/ee/startup/linkfile - all: $(TARGET) $(TARGET): $(OBJS) $(LD) $(PRE_OBJS_FLAGS) $(OBJS) $(POST_OBJS_FLAGS) $(LDFLAGS) -o $@ + diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld index de4b534135..12f273a3a6 100644 --- a/backends/platform/ps2/main_prog.ld +++ b/backends/platform/ps2/main_prog.ld @@ -70,8 +70,9 @@ SECTIONS { *(.scommon) } + /*current PS2 Makefile disables this gp-relative section*/ __plugin_hole_start = .; - . = _gp + 0x7ff0; + . = _gp + 0x7ff00; __plugin_hole_end = .; COMMON : @@ -84,6 +85,7 @@ SECTIONS { *(.bss) *(.bss.*) *(.gnu.linkonce.b*) + /* *(COMMON) May have to take this out*/ } _end_bss = .; diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld index 10055338d0..cc6b72340d 100644 --- a/backends/platform/ps2/plugin.ld +++ b/backends/platform/ps2/plugin.ld @@ -1,98 +1,206 @@ +OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", + "elf32-littlemips") +OUTPUT_ARCH(mips:5900) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +_DYNAMIC_LINK = 0; PHDRS { - plugin PT_LOAD ; - shorts PT_LOAD ; + plugin PT_LOAD ; + shorts PT_LOAD ; } -SECTIONS { - /* originally was 0x00100000 but might be 0 */ - .text 0: { - _ftext = . ; - *(.text) - *(.text.*) - *(.gnu.linkonce.t*) - KEEP(*(.init)) - KEEP(*(.fini)) - QUAD(0) - } - - PROVIDE(_etext = .); - PROVIDE(etext = .); - - /* interp may or may not be needed here */ - .interp : { *(.interp) } : plugin - .reginfo : { *(.reginfo) } : plugin - - /* Global/static constructors and deconstructors. */ - .ctors ALIGN(16): { - ___plugin_ctors = .; - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - ___plugin_ctors_end = .; - } - .dtors ALIGN(16): { - ___plugin_dtors = .; - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - ___plugin_dtors_end = .; - } - - /* Static data. */ - .rodata ALIGN(128): { - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r*) - } - - .data ALIGN(128): { - _fdata = . ; - *(.data) - *(.data.*) - *(.gnu.linkonce.d*) - SORT(CONSTRUCTORS) - } - - .rdata ALIGN(128): { *(.rdata) } - .gcc_except_table ALIGN(128): { *(.gcc_except_table) } - - /* _gp = ALIGN(128) + 0x7ff0; */ - . = __plugin_hole_start; - /* the .got line wasn't originally there */ - .got : { *(.got.plt) *(.got) } : shorts - - .lit4 ALIGN(128): { *(.lit4) } - .lit8 ALIGN(128): { *(.lit8) } - - .sdata ALIGN(128): { - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s*) - } - - _edata = .; - PROVIDE(edata = .); - - /* Uninitialized data. */ - .sbss ALIGN(128) : { - _fbss = . ; - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb*) - *(.scommon) - } - - .bss ALIGN(128) : { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b*) - *(COMMON) - } - _end_bss = .; - - _end = . ; - PROVIDE(end = .); - - /* Symbols needed by crt0.s. */ - PROVIDE(_heap_size = -1); - PROVIDE(_stack = -1); - PROVIDE(_stack_size = 128 * 1024); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + .interp : { *(.interp) } : plugin + .reginfo : { *(.reginfo) } : 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.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) + *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) + *(.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.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + _ftext = . ; + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.mips16.fn.*) *(.mips16.call.*) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + /* 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(128) + (. & (128 - 1)); + /* 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 : { *(.preinit_array) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE (__fini_array_end = .); + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .dynamic : { *(.dynamic) } + .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)) } + + . = __plugin_hole_start; + .got : { *(.got.plt) *(.got) } : shorts + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + _fbss = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + .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 = .; + PROVIDE (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) } + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } } + diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp index a48fef94cb..8cf6fbc528 100644 --- a/backends/platform/ps2/ps2loader.cpp +++ b/backends/platform/ps2/ps2loader.cpp @@ -35,7 +35,6 @@ //#include do these exist? #include "backends/platform/ps2/ps2loader.h" -//#include "backends/platform/ps2/powerman.h" //TODO //#define __PS2_DEBUG_PLUGINS__ @@ -45,13 +44,13 @@ #define DBG(x,...) #endif -#define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__) +#define seterror(x,...) sioprintf(x, ## __VA_ARGS__) extern char __plugin_hole_start; // Indicates start of hole in program file for shorts extern char __plugin_hole_end; // Indicates end of hole in program file extern char _gp[]; // Value of gp register -DECLARE_SINGLETON(ShortSegmentManager) // For singleton +DECLARE_SINGLETON(ShortSegmentManager); // For singleton // Get rid of symbol table in memory void DLObject::discard_symtab() { @@ -103,7 +102,7 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * // Treat each relocation entry. Loop over all of them int cnt = size / sizeof(*rel); - //DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); bool seenHi16 = false; // For treating HI/LO16 commands int firstHi16 = -1; // Mark the point of the first hi16 seen @@ -141,9 +140,9 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * lastHiSymVal = sym->st_value; hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments - //if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number - //DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", - //i, rel[i].r_offset, ahl, *target); + if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number + DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", + i, rel[i].r_offset, ahl, *target); } break; @@ -194,12 +193,12 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * *target &= 0xffff0000; // Clear the lower 16 bits of current target *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation - //if (debugRelocs[1]++ < DEBUG_NUM) - //DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - // i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - //if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - //DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - // i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + if (debugRelocs[1]++ < DEBUG_NUM) + DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) + DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); } break; @@ -211,13 +210,13 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * *target &= 0xfc000000; // Clean lower 26 target bits *target |= (relocation & 0x03ffffff); - //if (debugRelocs[3]++ < DEBUG_NUM) - //DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - // i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + if (debugRelocs[3]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } else { - //if (debugRelocs[4]++ < DEBUG_NUM) - //DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - // i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + if (debugRelocs[4]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } break; @@ -232,9 +231,9 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * *target &= 0xffff0000; // Clear the lower 16 bits of the target *target |= relocation & 0xffff; - //if (debugRelocs[5]++ < DEBUG_NUM) - //DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", - // i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); + if (debugRelocs[5]++ < DEBUG_NUM) + DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", + i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); } break; @@ -249,8 +248,8 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * relocation = a + (Elf32_Addr)_segment; // Shift by main offset *target = relocation; - //if (debugRelocs[6]++ < DEBUG_NUM) - //DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + if (debugRelocs[6]++ < DEBUG_NUM) + DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); } break; @@ -261,7 +260,7 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * } } - //DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); + DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); free(rel); return true; @@ -279,8 +278,8 @@ bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { return false; } - //DBG("phoff = %d, phentsz = %d, phnum = %d\n", - //ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); + DBG("phoff = %d, phentsz = %d, phnum = %d\n", + ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); return true; } @@ -299,8 +298,8 @@ bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, in return false; } - //DBG("offs = %x, filesz = %x, memsz = %x, align = %x\n", - //phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); + DBG("offs = %x, filesz = %x, memsz = %x, align = %x\n", + phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); return true; @@ -315,7 +314,7 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { // 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); + DBG("extra mem is %x\n", extra); if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI @@ -323,7 +322,7 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { seterror("Out of memory.\n"); return false; } - //DBG("allocated segment @ %p\n", _segment); + DBG("allocated segment @ %p\n", _segment); // Get offset to load segment into baseAddress = (char *)_segment + phdr->p_vaddr; @@ -332,14 +331,14 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); baseAddress = _shortsSegment->getStart(); - //DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", - //_shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", + _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); } // 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); + 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 @@ -378,8 +377,8 @@ 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++) { - //DBG("Section %d: type = %x, size = %x, entsize = %x, link = %x\n", - // i, shdr[i].sh_type, shdr[i].sh_size, shdr[i].sh_entsize, shdr[i].sh_link); + DBG("Section %d: type = %x, size = %x, entsize = %x, link = %x\n", + i, shdr[i].sh_type, shdr[i].sh_size, shdr[i].sh_entsize, shdr[i].sh_link); if (shdr[i].sh_type == SHT_SYMTAB && shdr[i].sh_entsize == sizeof(Elf32_Sym) && @@ -396,7 +395,7 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { return -1; } - //DBG("Symbol section at section %d, size %x\n", _symtab_sect, shdr[_symtab_sect].sh_size); + 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))) { @@ -414,7 +413,7 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Set number of symbols _symbol_cnt = shdr[_symtab_sect].sh_size / sizeof(Elf32_Sym); - //DBG("Loaded %d symbols.\n", _symbol_cnt); + DBG("Loaded %d symbols.\n", _symbol_cnt); return _symtab_sect; @@ -443,7 +442,7 @@ bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { void DLObject::relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset) { int shortsCount = 0, othersCount = 0; - //DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); + DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); // Loop over symbols, add relocation offset Elf32_Sym *s = (Elf32_Sym *)_symtab; @@ -466,7 +465,7 @@ void DLObject::relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset) { } - //DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); + DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); } bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { @@ -546,11 +545,11 @@ bool DLObject::open(const char *path) { int fd; void *ctors_start, *ctors_end; - //DBG("open(\"%s\")\n", path); + DBG("open(\"%s\")\n", path); // Get the address of the global pointer _gpVal = (unsigned int) & _gp; - //DBG("_gpVal is %x\n", _gpVal); + DBG("_gpVal is %x\n", _gpVal); //PS2 has no "PowerMan" for suspending the system. //PowerMan.beginCriticalSection(); @@ -573,6 +572,7 @@ bool DLObject::open(const char *path) { //PowerMan.endCriticalSection(); // flush data cache + DBG("Flushing data cache"); FlushCache(0); FlushCache(2); @@ -590,11 +590,11 @@ bool DLObject::open(const char *path) { return false; } - //DBG("Calling constructors.\n"); + DBG("Calling constructors.\n"); for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) (**f)(); - //DBG("%s opened ok.\n", path); + DBG("%s opened ok.\n", path); return true; } @@ -608,7 +608,7 @@ bool DLObject::close() { } void *DLObject::symbol(const char *name) { - //DBG("symbol(\"%s\")\n", name); + DBG("symbol(\"%s\")\n", name); if (_symtab == NULL || _strtab == NULL || _symbol_cnt < 1) { seterror("No symbol table loaded."); @@ -624,7 +624,7 @@ void *DLObject::symbol(const char *name) { !strcmp(name, _strtab + s->st_name)) { // We found the symbol - //DBG("=> %p\n", (void*)s->st_value); + DBG("=> %p\n", (void*)s->st_value); return (void*)s->st_value; } } @@ -668,14 +668,14 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or _list.insert(i, seg); - //DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", - //size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); + DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", + size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); return seg; } void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { - //DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); + DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); _list.remove(seg); delete seg; } diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index 120f6ee157..357404c5c4 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -107,7 +107,6 @@ extern "C" int scummvm_main(int argc, char *argv[]); extern "C" int main(int argc, char *argv[]) { SifInitRpc(0); - ee_thread_t thisThread; int tid = GetThreadId(); ReferThreadStatus(tid, &thisThread); @@ -132,12 +131,11 @@ extern "C" int main(int argc, char *argv[]) { sioprintf("Creating system\n"); g_system = g_systemPs2 = new OSystem_PS2(argv[0]); - g_systemPs2->init(); - #ifdef DYNAMIC_MODULES PluginManager::instance().addPluginProvider(new PS2PluginProvider()); #endif + g_systemPs2->init(); sioprintf("init done. starting ScummVM.\n"); int res = scummvm_main(argc, argv); sioprintf("scummvm_main terminated: %d\n", res); @@ -343,6 +341,7 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { } void OSystem_PS2::init(void) { + //msgPrintf(FOREVER, "got to init! Now restart your console... %d\n", res); sioprintf("Timer...\n"); _scummTimerManager = new DefaultTimerManager(); _scummMixer = new Audio::MixerImpl(this, 48000); -- cgit v1.2.3 From 819bbfba0104340f3313c570841e941633b24f9d Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sun, 13 Jun 2010 08:26:39 +0000 Subject: changed DBG to printf instead of sioprintf svn-id: r49626 --- backends/platform/ps2/ps2loader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp index 8cf6fbc528..9ed4a373b3 100644 --- a/backends/platform/ps2/ps2loader.cpp +++ b/backends/platform/ps2/ps2loader.cpp @@ -39,12 +39,12 @@ //#define __PS2_DEBUG_PLUGINS__ #ifdef __PS2_DEBUG_PLUGINS__ -#define DBG(x,...) sioprintf(x, ## __VA_ARGS__) +#define DBG(x,...) printf(x, ## __VA_ARGS__) #else #define DBG(x,...) #endif -#define seterror(x,...) sioprintf(x, ## __VA_ARGS__) +#define seterror(x,...) printf(x, ## __VA_ARGS__) extern char __plugin_hole_start; // Indicates start of hole in program file for shorts extern char __plugin_hole_end; // Indicates end of hole in program file -- cgit v1.2.3 From 02e136289570f9a4d7230cb1ee4067942bc7e737 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 14 Jun 2010 21:31:53 +0000 Subject: merged GP2x-Wiz debug build scripts from trunk into branch svn-id: r49671 --- backends/platform/gp2xwiz/build/build.sh | 4 +- backends/platform/gp2xwiz/build/bundle-debug.sh | 54 +++++++++++++++++++++++++ backends/platform/gp2xwiz/build/bundle.sh | 6 ++- backends/platform/gp2xwiz/build/clean.sh | 2 +- backends/platform/gp2xwiz/build/config.sh | 2 +- backends/platform/gp2xwiz/build/scummvm-gdb.gpe | 16 ++++++++ backends/platform/gp2xwiz/gp2xwiz-events.cpp | 1 + 7 files changed, 79 insertions(+), 6 deletions(-) create mode 100755 backends/platform/gp2xwiz/build/bundle-debug.sh create mode 100755 backends/platform/gp2xwiz/build/scummvm-gdb.gpe (limited to 'backends') diff --git a/backends/platform/gp2xwiz/build/build.sh b/backends/platform/gp2xwiz/build/build.sh index 1bdc020f17..876c3e378a 100755 --- a/backends/platform/gp2xwiz/build/build.sh +++ b/backends/platform/gp2xwiz/build/build.sh @@ -13,7 +13,7 @@ export ASFLAGS=-mfloat-abi=soft cd ../../../.. -echo Building ScummVM for GP2X. +echo Building ScummVM for GP2X Wiz. make -echo Build for GP2X - SDL - complete - Please check build logs. +echo Build for GP2X Wiz - complete - Please check build logs. diff --git a/backends/platform/gp2xwiz/build/bundle-debug.sh b/backends/platform/gp2xwiz/build/bundle-debug.sh new file mode 100755 index 0000000000..d275f681ea --- /dev/null +++ b/backends/platform/gp2xwiz/build/bundle-debug.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +echo Quick script to make building a distribution of the GP2X Wiz backend more consistent. + +echo Collecting files. +mkdir "scummvm-wiz-`date '+%Y-%m-%d'`" +mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm" +mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/saves" +mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins" +mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/engine-data" +mkdir "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib" + + +echo "Please put your save games in this dir" >> "scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/saves/PUT_SAVES_IN_THIS_DIR" + +cp ./scummvm-gdb.gpe ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/scummvm.gpe +cp ./scummvm.png ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ./README-GP2XWIZ ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ./scummvm.ini ./scummvm-wiz-`date '+%Y-%m-%d'`/ +cp ../../../../scummvm.wiz ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../AUTHORS ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../README ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../COPYING ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../COPYRIGHT ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../NEWS ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../gui/themes/scummmodern.zip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../backends/vkeybd/packs/vkeybd_default.zip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../dists/pred.dic ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/ +cp ../../../../dists/engine-data/* ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/engine-data +cp ../../../../plugins/* ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins + +# Copy over dynamic libs needed by the app (as the ones in the default filesystem are broken). +f=`which arm-open2x-linux-g++` +loc=`dirname "$f"` +cp $loc/../lib/libz.so.1.2.3 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libz.so.1 +cp $loc/../lib/libvorbisidec.so.1.0.2 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libvorbisidec.so.1 + +echo Building ZIP bundle. +if [ -f /usr/bin/zip ] + then + rm ./"scummvm-wiz-`date '+%Y-%m-%d'`.zip" + cd "scummvm-wiz-`date '+%Y-%m-%d'`" + zip -r -9 "../scummvm-wiz-`date '+%Y-%m-%d'`.zip" * + echo You should have a "scummvm-wiz-`date '+%Y-%m-%d'`.zip" for the GP2X Wiz backend ready to go. + cd .. + rm -R ./"scummvm-wiz-`date '+%Y-%m-%d'`" + else + echo - /usr/bin/zip not found, ZIP bundle not created. + echo All included files can also be found in ./"scummvm-wiz-`date '+%Y-%m-%d'`" + echo - Please use you preferred archive tool to bundle these files. +fi + +echo Please ensure GDB is installed somewhere in the path on your Wiz. + diff --git a/backends/platform/gp2xwiz/build/bundle.sh b/backends/platform/gp2xwiz/build/bundle.sh index 492ba9e1c6..065bd7a685 100755 --- a/backends/platform/gp2xwiz/build/bundle.sh +++ b/backends/platform/gp2xwiz/build/bundle.sh @@ -35,10 +35,12 @@ loc=`dirname "$f"` cp $loc/../lib/libz.so.1.2.3 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libz.so.1 cp $loc/../lib/libvorbisidec.so.1.0.2 ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/lib/libvorbisidec.so.1 - -echo Making Stripped exe. +echo Making Stripped Binary. arm-open2x-linux-strip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/scummvm.wiz +echo Making Stripped Plugins. +arm-open2x-linux-strip ./scummvm-wiz-`date '+%Y-%m-%d'`/scummvm/plugins/* + echo Building ZIP bundle. if [ -f /usr/bin/zip ] then diff --git a/backends/platform/gp2xwiz/build/clean.sh b/backends/platform/gp2xwiz/build/clean.sh index 2862887bb3..5ec1b9e62c 100755 --- a/backends/platform/gp2xwiz/build/clean.sh +++ b/backends/platform/gp2xwiz/build/clean.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh echo Quick script to make building all the time less painful. diff --git a/backends/platform/gp2xwiz/build/config.sh b/backends/platform/gp2xwiz/build/config.sh index 27c1fbf0bf..54c4795298 100755 --- a/backends/platform/gp2xwiz/build/config.sh +++ b/backends/platform/gp2xwiz/build/config.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh echo Quick script to make running configure all the time less painful echo and let all the build work be done from the backend/build folder. diff --git a/backends/platform/gp2xwiz/build/scummvm-gdb.gpe b/backends/platform/gp2xwiz/build/scummvm-gdb.gpe new file mode 100755 index 0000000000..64b6c8b974 --- /dev/null +++ b/backends/platform/gp2xwiz/build/scummvm-gdb.gpe @@ -0,0 +1,16 @@ +#!/bin/sh + +# Export the location of any libs ScummVM depends on +# (to avoid installing to the NAND and overwriting the broken ones there). +export LD_LIBRARY_PATH=`pwd`/lib:$LD_LIBRARY_PATH + +# Run ScummVM via GDB (so make sure you have a terminal open or serial). +# Oh, and GDB installed of course ;) +gdb --args ./scummvm.wiz --fullscreen --gfx-mode=1x --config=$(pwd)/.scummvmrc + +# Sync the SD card to check that everything is written. +sync + +# Return to the GPH menu screen +cd /usr/gp2x +exec /usr/gp2x/gp2xmenu diff --git a/backends/platform/gp2xwiz/gp2xwiz-events.cpp b/backends/platform/gp2xwiz/gp2xwiz-events.cpp index 2774efce1b..a69aa42967 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-events.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-events.cpp @@ -30,6 +30,7 @@ #include "backends/platform/gp2xwiz/gp2xwiz-sdl.h" #include "backends/platform/gp2xwiz/gp2xwiz-hw.h" +#include "graphics/scaler/aspect.h" #include "common/util.h" #include "common/events.h" -- cgit v1.2.3 From c49760d7808b673057ecbff6ddcd7d64dceee88a Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 14 Jun 2010 23:39:07 +0000 Subject: changed which modified linker to use for plugin.ld as loading from USB-drive seemed to break after last commit. Also added some comments to the linkers. svn-id: r49676 --- backends/platform/ps2/Makefile.ps2 | 3 +- backends/platform/ps2/main_prog.ld | 4 +- backends/platform/ps2/plugin.ld | 295 ++++++++++++------------------------- 3 files changed, 96 insertions(+), 206 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 15eb909107..b016929a9e 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -87,7 +87,8 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms elf/scummvm.elf +PLUGIN_EXTRA_DEPS = plugins.ld plugin.syms elf/scummvm.elf +PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld index 12f273a3a6..e807241cee 100644 --- a/backends/platform/ps2/main_prog.ld +++ b/backends/platform/ps2/main_prog.ld @@ -70,7 +70,9 @@ SECTIONS { *(.scommon) } - /*current PS2 Makefile disables this gp-relative section*/ + /*current PS2 Makefile disables data being put in the gp-relative section, + but ideally this "plugin hole" is so the plugins can all have global data + in the same place.*/ __plugin_hole_start = .; . = _gp + 0x7ff00; __plugin_hole_end = .; diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld index cc6b72340d..7198450538 100644 --- a/backends/platform/ps2/plugin.ld +++ b/backends/platform/ps2/plugin.ld @@ -1,206 +1,93 @@ -OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", - "elf32-littlemips") -OUTPUT_ARCH(mips:5900) -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -_DYNAMIC_LINK = 0; -PHDRS -{ - plugin PT_LOAD ; - shorts PT_LOAD ; -} -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - .interp : { *(.interp) } : plugin - .reginfo : { *(.reginfo) } : 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.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.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) - *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) - *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) - *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) - *(.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.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) - *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) - *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) - *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .text : - { - _ftext = . ; - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.mips16.fn.*) *(.mips16.call.*) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } - .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - /* 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(128) + (. & (128 - 1)); - /* 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 : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .data : - { - _fdata = . ; - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .eh_frame : { KEEP (*(.eh_frame)) } - .gcc_except_table : { *(.gcc_except_table) } - .dynamic : { *(.dynamic) } - .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)) } - - . = __plugin_hole_start; - .got : { *(.got.plt) *(.got) } : shorts - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : - { - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - _fbss = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - .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 = .; - PROVIDE (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) } - .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } - .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } +/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ +PHDRS { + plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ + shorts PT_LOAD ; /* Specifies that the shorts segment should be loaded from file */ } +SECTIONS { + .text 0: { + _ftext = . ; + *(.text) + *(.text.*) + *(.gnu.linkonce.t*) + KEEP(*(.init)) + KEEP(*(.fini)) + QUAD(0) + } : plugin /*The ": plugin" tells the linker to assign this and + the following sections to the "plugin" segment*/ + PROVIDE(_etext = .); + PROVIDE(etext = .); + + .reginfo : { *(.reginfo) } + + /* Global/static constructors and deconstructors. */ + .ctors ALIGN(16): { + ___plugin_ctors = .; + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + ___plugin_ctors_end = .; + } + .dtors ALIGN(16): { + ___plugin_dtors = .; + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + ___plugin_dtors_end = .; + } + + /* Static data. */ + .rodata ALIGN(128): { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + } + + .data ALIGN(128): { + _fdata = . ; + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + SORT(CONSTRUCTORS) + } + + .rdata ALIGN(128): { *(.rdata) } + .gcc_except_table ALIGN(128): { *(.gcc_except_table) } + + /*We assign the output location counter to the plugin hole made + in main_prog.ld, then assign the small data sections to the shorts segment*/ + . = __plugin_hole_start; + .lit4 ALIGN(128): { *(.lit4) } : shorts + .lit8 ALIGN(128): { *(.lit8) } + .sdata ALIGN(128): { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s*) + } + + _edata = .; + PROVIDE(edata = .); + + /* Uninitialized data. */ + .sbss ALIGN(128) : { + _fbss = . ; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb*) + *(.scommon) + } + + .bss ALIGN(128) : { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b*) + *(COMMON) + } + _end_bss = .; + + _end = . ; + PROVIDE(end = .); + + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); +} -- cgit v1.2.3 From ddf6019772ca2b9efe879240bc7539f58eab9861 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 16 Jun 2010 01:53:27 +0000 Subject: added initial plugin linker for GP2x Wiz ELF-loader svn-id: r49898 --- backends/platform/gp2xwiz/plugin.ld | 182 ++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 backends/platform/gp2xwiz/plugin.ld (limited to 'backends') diff --git a/backends/platform/gp2xwiz/plugin.ld b/backends/platform/gp2xwiz/plugin.ld new file mode 100644 index 0000000000..9e491087de --- /dev/null +++ b/backends/platform/gp2xwiz/plugin.ld @@ -0,0 +1,182 @@ +/* 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) } +} -- cgit v1.2.3 From 1d714c0694eaf7ac7290eab93f6f99e67439ca6b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 18 Jun 2010 00:18:26 +0000 Subject: added ELF loader header for gp2xwiz svn-id: r49977 --- backends/platform/gp2xwiz/gp2xwiz-loader.h | 67 ++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 backends/platform/gp2xwiz/gp2xwiz-loader.h (limited to 'backends') diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.h b/backends/platform/gp2xwiz/gp2xwiz-loader.h new file mode 100644 index 0000000000..066fc4d71d --- /dev/null +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.h @@ -0,0 +1,67 @@ +/* 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; + void *_dtors_start, *_dtors_end; + + void seterror(const char *fmt, ...); + void unload(); + bool relocate(int fd, unsigned long offset, unsigned long size); + bool load(int fd); + + 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 */ -- cgit v1.2.3 From df6359d7435e7410488fd29555996b7230b88ac0 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 19 Jun 2010 02:39:11 +0000 Subject: added pretty skeletal loader svn-id: r50036 --- backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 255 +++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 backends/platform/gp2xwiz/gp2xwiz-loader.cpp (limited to 'backends') diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp new file mode 100644 index 0000000000..7acc4ee0d0 --- /dev/null +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp @@ -0,0 +1,255 @@ +/* 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(__GP2X__) + +#include +#include +#include +#include +#include +#include + +#include "gp2xwiz-loader.h" + +#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) +{ + 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; ist_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 && __GP2X__WIZ__ */ -- cgit v1.2.3 From 8d2df5b7d9208bdcf43fa240b249fd7fbb6e3ffe Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 21 Jun 2010 07:20:16 +0000 Subject: fixed dependency typo svn-id: r50105 --- backends/platform/ps2/Makefile.ps2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index b016929a9e..7dd4fb9795 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -87,7 +87,7 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugins.ld plugin.syms elf/scummvm.elf +PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms elf/scummvm.elf PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc -- cgit v1.2.3 From 6c10a0062ad0bf61ea776d50c6788be484c6ad2b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 21 Jun 2010 22:33:30 +0000 Subject: added wiz plugins provider header svn-id: r50132 --- backends/plugins/gp2xwiz/gp2xwiz-provider.h | 43 +++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 backends/plugins/gp2xwiz/gp2xwiz-provider.h (limited to 'backends') diff --git a/backends/plugins/gp2xwiz/gp2xwiz-provider.h b/backends/plugins/gp2xwiz/gp2xwiz-provider.h new file mode 100644 index 0000000000..b9b8792225 --- /dev/null +++ b/backends/plugins/gp2xwiz/gp2xwiz-provider.h @@ -0,0 +1,43 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ps2/ps2-provider.h $ + * $Id: ps2-provider.h 49435 2010-06-05 01:05:19Z toneman1138 $ + * + */ + +#ifndef BACKENDS_PLUGINS_GP2XWIZ_GP2XWIZ_PROVIDER_H +#define BACKENDS_PLUGINS_GP2XWIZ_GP2XWIZ_PROVIDER_H + +#include "base/plugins.h" + +#if defined(DYNAMIC_MODULES) && defined(GP2XWIZ) + +class PS2PluginProvider : public FilePluginProvider { +protected: + Plugin* createPlugin(const Common::FSNode &node) const; + + bool isPluginFilename(const Common::FSNode &node) const; + +}; + +#endif // defined(DYNAMIC_MODULES) && defined(GP2XWIZ) + +#endif /* BACKENDS_PLUGINS_GP2XWIZ_GP2XWIZ_PROVIDER_H */ -- cgit v1.2.3 From b515cb1ed6411f9d71c3b3c138bb55ae60c3b1f5 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 21 Jun 2010 22:49:17 +0000 Subject: added loader to module.mk, added plugin.syms, and changed the '__GP2XWIZ__' flag to 'GP2XWIZ' in the wiz loader svn-id: r50133 --- backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 4 ++-- backends/platform/gp2xwiz/module.mk | 3 ++- backends/platform/gp2xwiz/plugin.syms | 8 ++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 backends/platform/gp2xwiz/plugin.syms (limited to 'backends') diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp index 7acc4ee0d0..bc2fd5df6e 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(__GP2X__) +#if defined(DYNAMIC_MODULES) && defined(GP2X) #include #include @@ -252,4 +252,4 @@ void dlforgetsyms(void *handle) ((DLObject *)handle)->discard_symtab(); } -#endif /* DYNAMIC_MODULES && __GP2X__WIZ__ */ +#endif /* DYNAMIC_MODULES && GP2X__WIZ */ diff --git a/backends/platform/gp2xwiz/module.mk b/backends/platform/gp2xwiz/module.mk index f457d51615..e162555493 100644 --- a/backends/platform/gp2xwiz/module.mk +++ b/backends/platform/gp2xwiz/module.mk @@ -4,7 +4,8 @@ MODULE_OBJS := \ gp2xwiz-events.o \ gp2xwiz-graphics.o \ gp2xwiz-hw.o \ - gp2xwiz-main.o + gp2xwiz-main.o \ + gp2xwiz-loader.o MODULE_DIRS += \ backends/platform/gp2xwiz/ diff --git a/backends/platform/gp2xwiz/plugin.syms b/backends/platform/gp2xwiz/plugin.syms new file mode 100644 index 0000000000..24ee1a19dc --- /dev/null +++ b/backends/platform/gp2xwiz/plugin.syms @@ -0,0 +1,8 @@ +PLUGIN_getVersion +PLUGIN_getType +PLUGIN_getTypeVersion +PLUGIN_getObject +___plugin_ctors +___plugin_ctors_end +___plugin_dtors +___plugin_dtors_end -- cgit v1.2.3 From 38b495aea2c393128ea5263b400b819efec0690e Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 22 Jun 2010 00:19:26 +0000 Subject: added elf32.h for gp2xwiz svn-id: r50135 --- backends/platform/gp2xwiz/elf32.h | 105 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 backends/platform/gp2xwiz/elf32.h (limited to 'backends') diff --git a/backends/platform/gp2xwiz/elf32.h b/backends/platform/gp2xwiz/elf32.h new file mode 100644 index 0000000000..842146e567 --- /dev/null +++ b/backends/platform/gp2xwiz/elf32.h @@ -0,0 +1,105 @@ +/* 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 */ + +// 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; + +// 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; + +// 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; + +// 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; + +#endif /* BACKENDS_ELF_H */ -- cgit v1.2.3 From fd507fdba08bb196d2b8430511aaf7cb6bc0c066 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 22 Jun 2010 09:55:40 +0000 Subject: fixed errors in linker scripts that were preventing GP-relative section for small data from working correctly svn-id: r50138 --- backends/platform/ps2/Makefile.ps2 | 2 +- backends/platform/ps2/main_prog.ld | 6 ++---- backends/platform/ps2/plugin.ld | 33 +++++++++++++++++---------------- 3 files changed, 20 insertions(+), 21 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 7dd4fb9795..c2cf30ed23 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -77,7 +77,7 @@ DEPDIR = .deps TARGET = elf/scummvm.elf -DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G0 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR +DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld index e807241cee..9dba69c50e 100644 --- a/backends/platform/ps2/main_prog.ld +++ b/backends/platform/ps2/main_prog.ld @@ -70,11 +70,10 @@ SECTIONS { *(.scommon) } - /*current PS2 Makefile disables data being put in the gp-relative section, - but ideally this "plugin hole" is so the plugins can all have global data + /*This "plugin hole" is so the plugins can all have global small data in the same place.*/ __plugin_hole_start = .; - . = _gp + 0x7ff00; + . = _gp + 0x7ff0; __plugin_hole_end = .; COMMON : @@ -87,7 +86,6 @@ SECTIONS { *(.bss) *(.bss.*) *(.gnu.linkonce.b*) - /* *(COMMON) May have to take this out*/ } _end_bss = .; diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld index 7198450538..9879413b98 100644 --- a/backends/platform/ps2/plugin.ld +++ b/backends/platform/ps2/plugin.ld @@ -51,7 +51,23 @@ SECTIONS { .rdata ALIGN(128): { *(.rdata) } .gcc_except_table ALIGN(128): { *(.gcc_except_table) } - /*We assign the output location counter to the plugin hole made + .bss ALIGN(128) : { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b*) + *(COMMON) + } + _end_bss = .; + + _end = . ; + PROVIDE(end = .); + + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); + + /*We assign the output location counter to the plugin hole made in main_prog.ld, then assign the small data sections to the shorts segment*/ . = __plugin_hole_start; .lit4 ALIGN(128): { *(.lit4) } : shorts @@ -75,19 +91,4 @@ SECTIONS { *(.scommon) } - .bss ALIGN(128) : { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b*) - *(COMMON) - } - _end_bss = .; - - _end = . ; - PROVIDE(end = .); - - /* Symbols needed by crt0.s. */ - PROVIDE(_heap_size = -1); - PROVIDE(_stack = -1); - PROVIDE(_stack_size = 128 * 1024); } -- cgit v1.2.3 From 8ec2c0714607ada24ace8f547c320155b4120678 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 22 Jun 2010 17:51:47 +0000 Subject: modified formatting to match ScummVM Code Formatting Conventions svn-id: r50156 --- backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 310 +++++++++++++-------------- 1 file changed, 149 insertions(+), 161 deletions(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp index bc2fd5df6e..2da2ee44bc 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp @@ -32,7 +32,7 @@ #include #include -#include "gp2xwiz-loader.h" +#include "backends/platform/gp2xwiz/gp2xwiz-loader.h" #ifdef __WIZ_DEBUG_PLUGINS__ #define DBG(x) printf(x, ## __VA_ARGS__) @@ -43,21 +43,19 @@ #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; +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; +void DLObject::unload() { + discard_symtab(); + free(_segment); + segment = NULL; } /** @@ -68,188 +66,178 @@ void DLObject::unload() * @param size Size of relocation section * */ -bool DLObject::relocate(int fd, unsigned long offset, unsigned long size) -{ - 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; ist_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; +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; +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; +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); +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; +const char *dlerror() { + return dlerr; } -void dlforgetsyms(void *handle) -{ - if (handle != NULL) - ((DLObject *)handle)->discard_symtab(); +void dlforgetsyms(void *handle) { + if (handle != NULL) + ((DLObject *)handle)->discard_symtab(); } #endif /* DYNAMIC_MODULES && GP2X__WIZ */ -- cgit v1.2.3 From 75c3c8bbae9d5cc1a0428c293f13821added1165 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 22 Jun 2010 18:33:17 +0000 Subject: changed PS2 to GP2X. svn-id: r50159 --- backends/plugins/gp2xwiz/gp2xwiz-provider.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/plugins/gp2xwiz/gp2xwiz-provider.h b/backends/plugins/gp2xwiz/gp2xwiz-provider.h index b9b8792225..929a9af1f6 100644 --- a/backends/plugins/gp2xwiz/gp2xwiz-provider.h +++ b/backends/plugins/gp2xwiz/gp2xwiz-provider.h @@ -30,7 +30,7 @@ #if defined(DYNAMIC_MODULES) && defined(GP2XWIZ) -class PS2PluginProvider : public FilePluginProvider { +class GP2XWIZPluginProvider : public FilePluginProvider { protected: Plugin* createPlugin(const Common::FSNode &node) const; -- cgit v1.2.3 From 0edd30de1cf415a33cf02e798bc1714ee91c61e1 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 22 Jun 2010 18:52:25 +0000 Subject: modified main to use ELF loader svn-id: r50161 --- backends/platform/gp2xwiz/gp2xwiz-main.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/gp2xwiz-main.cpp b/backends/platform/gp2xwiz/gp2xwiz-main.cpp index 394c3090c3..fa08cff9f7 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-main.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-main.cpp @@ -41,8 +41,8 @@ #include "common/file.h" #include "base/main.h" +#include "backends/plugins/gp2xwiz/gp2xwiz-provider.h" #include "backends/saves/default/default-saves.h" - #include "backends/timer/default/default-timer.h" #include "sound/mixer_intern.h" @@ -54,6 +54,9 @@ #include #include // for getTimeAndDate() +//comment this out to use POSIX plugins +#define ELF_LOADER + /* Dump console info to files. */ // #define DUMP_STDOUT @@ -63,8 +66,14 @@ int main(int argc, char *argv[]) { assert(g_system); #ifdef DYNAMIC_MODULES + +#ifdef ELF_LOADER + PluginManager::instance().addPluginProvider(new GP2XWIZPluginProvider()); +#else PluginManager::instance().addPluginProvider(new POSIXPluginProvider()); -#endif +#endif /* ELF_LOADER */ + +#endif /* DYNAMIC_MODULES */ // Invoke the actual ScummVM main entry point: int res = scummvm_main(argc, argv); -- cgit v1.2.3 From 2edc5063a0e6a096ef01e9f7d55c0bcbb39764a0 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 23 Jun 2010 23:30:15 +0000 Subject: defined various values in elf32.h and filled out load in wiz loader (including various helper procedures svn-id: r50196 --- backends/platform/gp2xwiz/elf32.h | 72 +++++++- backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 263 ++++++++++++++++++++++++++- 2 files changed, 325 insertions(+), 10 deletions(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/elf32.h b/backends/platform/gp2xwiz/elf32.h index 842146e567..1f4d7ba13a 100644 --- a/backends/platform/gp2xwiz/elf32.h +++ b/backends/platform/gp2xwiz/elf32.h @@ -59,6 +59,16 @@ typedef struct { // 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 ? + // Program header (contains info about segment) typedef struct { Elf32_Word p_type; /* Segment type */ @@ -71,6 +81,21 @@ typedef struct { 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_REGINFO 0x70000000 register usage info */ + +// p_flags value (don't think these are specific to architecture, but not certain) +#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) */ @@ -85,6 +110,26 @@ typedef struct { 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 */ + +// sh_flags values +#define SHF_WRITE 0 /* writable section */ +#define SHF_ALLOC 2 /* section occupies memory */ +#define SHF_EXECINSTR 4 /* machine instructions */ +#define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area */ + // Symbol entry (contain info about a symbol) typedef struct { Elf32_Word st_name; /* Symbol name (string tbl index) */ @@ -95,11 +140,34 @@ typedef struct { 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; +} Elf32_Rel; #endif /* BACKENDS_ELF_H */ diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp index 2da2ee44bc..f678db9258 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(GP2X) +#if defined(DYNAMIC_MODULES) && defined(GP2XWIZ) #include #include @@ -89,7 +89,7 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size) { // TODO: Loop over relocation entries for (int i = 0; i < cnt; i++) { - //Elf32_Sym *sym = ???; + //Elf32_Sym *sym = ???; //void *target = ???; @@ -109,17 +109,264 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size) { return true; } +bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { + + /* + if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr) || + memcmp(ehdr.e_ident, ELFMAG, SELFMAG) || + ehdr.e_type != 2 || ehdr.e_machine != 42 || + ehdr.e_phentsize < sizeof(phdr) || ehdr.e_shentsize != sizeof(*shdr) || + ehdr.e_phnum != 1) { + seterror("Invalid file type."); + return false; + } + */ + + // 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_MIPS || // Check for ARM machine type TODO: change EM_MIPS to ??_ARM and add to ELF32.H (figure out what ??_ARM should be) + 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) { + + 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_Rel) && // 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; // ELF header - Elf32_Phdr phdr; // Program header - Elf32_Shdr *shdr; // Section header + 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; - //TODO: fill this out! + if (ret) + relocateSymbols((Elf32_Addr)_segment); // Offset by our segment allocated address + + if (ret && (relocateRels(fd, &ehdr, shdr) == false)) + ret = false; free(shdr); - return true; + return ret; + } bool DLObject::open(const char *path) { @@ -240,4 +487,4 @@ void dlforgetsyms(void *handle) { ((DLObject *)handle)->discard_symtab(); } -#endif /* DYNAMIC_MODULES && GP2X__WIZ */ +#endif /* DYNAMIC_MODULES && GP2XWIZ */ -- cgit v1.2.3 From cb8ef9b56cf26234c085e799e568683e2fb73f42 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 24 Jun 2010 07:05:40 +0000 Subject: added EM_ARM and ARM relocation types svn-id: r50201 --- backends/platform/gp2xwiz/elf32.h | 135 +++++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/elf32.h b/backends/platform/gp2xwiz/elf32.h index 1f4d7ba13a..4a428fab19 100644 --- a/backends/platform/gp2xwiz/elf32.h +++ b/backends/platform/gp2xwiz/elf32.h @@ -67,7 +67,7 @@ typedef struct { #define ET_CORE 4 /* core file */ // e_machine values -//#define EM_ARM ? +#define EM_ARM 40 // Program header (contains info about segment) typedef struct { @@ -170,4 +170,137 @@ typedef struct { Elf32_Word r_info; /* Relocation type and symbol index */ } Elf32_Rel; +// ARM relocation types +#define R_ARM_NONE 0 +#define R_ARM_PC24 1 +#define R_ARM_ABS32 2 +#define R_ARM_REL32 3 +#define R_ARM_LDR_PC_G0 4 +#define R_ARM_ABS16 5 +#define R_ARM_ABS12 6 +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 +#define R_ARM_SBREL32 9 +#define R_ARM_THM_CALL 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_BREL_ADJ 12 +#define R_ARM_TLS_DESC 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_TLS_DTPMOD32 17 +#define R_ARM_TLS_DTPOFF32 18 +#define R_ARM_TLS_TPOFF32 19 +#define R_ARM_COPY 20 +#define R_ARM_GLOB_DAT 21 +#define R_ARM_JUMP_SLOT 22 +#define R_ARM_RELATIVE 23 +#define R_ARM_GOTOFF32 24 +#define R_ARM_BASE_PREL 25 +#define R_ARM_GOT_BREL 26 +#define R_ARM_PLT32 27 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_THM_JUMP24 30 +#define R_ARM_BASE_ABS 31 +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0_NC 35 +#define R_ARM_ALU_SBREL_19_12_NC 36 +#define R_ARM_ALU_SBREL_27_20_CK 37 +#define R_ARM_TARGET1 38 +#define R_ARM_SBREL31 39 +#define R_ARM_V4BX 40 +#define R_ARM_TARGET2 41 +#define R_ARM_PREL31 42 +#define R_ARM_MOVW_ABS_NC 43 +#define R_ARM_MOVT_ABS 44 +#define R_ARM_MOVW_PREL_NC 45 +#define R_ARM_MOVT_PREL 46 +#define R_ARM_THM_MOVW_ABS_NC 47 +#define R_ARM_THM_MOVT_ABS 48 +#define R_ARM_THM_MOVW_PREL_NC 49 +#define R_ARM_THM_MOVT_PREL 50 +#define R_ARM_THM_JUMP19 51 +#define R_ARM_THM_JUMP6 52 +#define R_ARM_THM_ALU_PREL_11_0 53 +#define R_ARM_THM_PC12 54 +#define R_ARM_ABS32_NOI 55 +#define R_ARM_REL32_NOI 56 +#define R_ARM_ALU_PC_G0_NC 57 +#define R_ARM_ALU_PC_G0 58 +#define R_ARM_ALU_PC_G1_NC 59 +#define R_ARM_ALU_PC_G1 60 +#define R_ARM_ALU_PC_G2 61 +#define R_ARM_LDR_PC_G1 62 +#define R_ARM_LDR_PC_G2 63 +#define R_ARM_LDRS_PC_G0 64 +#define R_ARM_LDRS_PC_G1 65 +#define R_ARM_LDRS_PC_G2 66 +#define R_ARM_LDC_PC_G0 67 +#define R_ARM_LDC_PC_G1 68 +#define R_ARM_LDC_PC_G2 69 +#define R_ARM_ALU_SB_G0_NC 70 +#define R_ARM_ALU_SB_G0 71 +#define R_ARM_ALU_SB_G1_NC 72 +#define R_ARM_ALU_SB_G1 73 +#define R_ARM_ALU_SB_G2 74 +#define R_ARM_LDR_SB_G0 75 +#define R_ARM_LDR_SB_G1 76 +#define R_ARM_LDR_SB_G2 77 +#define R_ARM_LDRS_SB_G0 78 +#define R_ARM_LDRS_SB_G1 79 +#define R_ARM_LDRS_SB_G2 80 +#define R_ARM_LDC_SB_G0 81 +#define R_ARM_LDC_SB_G1 82 +#define R_ARM_LDC_SB_G2 83 +#define R_ARM_MOVW_BREL_NC 84 +#define R_ARM_MOVT_BREL 85 +#define R_ARM_MOVW_BREL 86 +#define R_ARM_THM_MOVW_BREL_NC 87 +#define R_ARM_THM_MOVT_BREL 88 +#define R_ARM_THM_MOVW_BREL 89 +#define R_ARM_TLS_GOTDESC 90 +#define R_ARM_TLS_CALL 91 +#define R_ARM_TLS_DESCSEQ 92 +#define R_ARM_THM_TLS_CALL 93 +#define R_ARM_PLT32_ABS 94 +#define R_ARM_GOT_ABS 95 +#define R_ARM_GOT_PREL 96 +#define R_ARM_GOT_BREL12 97 +#define R_ARM_GOTOFF12 98 +#define R_ARM_GOTRELAX 99 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_JUMP11 102 +#define R_ARM_THM_JUMP8 103 +#define R_ARM_TLS_GD32 104 +#define R_ARM_TLS_LDM32 105 +#define R_ARM_TLS_LDO32 106 +#define R_ARM_TLS_IE32 107 +#define R_ARM_TLS_LE32 108 +#define R_ARM_TLS_LDO12 109 +#define R_ARM_TLS_LE12 110 +#define R_ARM_TLS_IE12GP 111 +#define R_ARM_PRIVATE_0 112 +#define R_ARM_PRIVATE_1 113 +#define R_ARM_PRIVATE_2 114 +#define R_ARM_PRIVATE_3 115 +#define R_ARM_PRIVATE_4 116 +#define R_ARM_PRIVATE_5 117 +#define R_ARM_PRIVATE_6 118 +#define R_ARM_PRIVATE_7 119 +#define R_ARM_PRIVATE_8 120 +#define R_ARM_PRIVATE_9 121 +#define R_ARM_PRIVATE_10 122 +#define R_ARM_PRIVATE_11 123 +#define R_ARM_PRIVATE_12 124 +#define R_ARM_PRIVATE_13 125 +#define R_ARM_PRIVATE_14 126 +#define R_ARM_PRIVATE_15 127 +#define R_ARM_ME_TOO 128 +#define R_ARM_THM_TLS_DESCSEQ16 129 +#define R_ARM_THM_TLS_DESCSEQ32 130 + #endif /* BACKENDS_ELF_H */ -- cgit v1.2.3 From 741940fd385db42fd6047ee12f17ee152fd6b748 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 25 Jun 2010 05:12:45 +0000 Subject: added ARM-specific defines to elf32.h and indented gp2xwiz-loader.h correctly svn-id: r50259 --- backends/platform/gp2xwiz/elf32.h | 22 ++++++++++--------- backends/platform/gp2xwiz/gp2xwiz-loader.h | 34 +++++++++++++++--------------- 2 files changed, 29 insertions(+), 27 deletions(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/elf32.h b/backends/platform/gp2xwiz/elf32.h index 4a428fab19..68d0be37bf 100644 --- a/backends/platform/gp2xwiz/elf32.h +++ b/backends/platform/gp2xwiz/elf32.h @@ -89,9 +89,10 @@ typedef struct { #define PT_NOTE 4 /* note segment */ #define PT_SHLIB 5 /* reserved */ #define PT_PHDR 6 /* Program header table */ -/* #define PT_REGINFO 0x70000000 register usage info */ +#define PT_ARM_ARCHEXT 0x70000000 /* Platform architecture compatibility information */ +#define PT_ARM_EXIDX 0x70000001 /* Exception unwind tables */ -// p_flags value (don't think these are specific to architecture, but not certain) +// p_flags value #define PF_X 1 /* execute */ #define PF_W 2 /* write */ #define PF_R 4 /* read */ @@ -123,12 +124,14 @@ typedef struct { #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 */ -#define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area */ // Symbol entry (contain info about a symbol) typedef struct { @@ -168,7 +171,12 @@ typedef struct { typedef struct { Elf32_Addr r_offset; /* Address */ Elf32_Word r_info; /* Relocation type and symbol index */ -} Elf32_Rel; + 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 @@ -185,9 +193,6 @@ typedef struct { #define R_ARM_THM_PC8 11 #define R_ARM_BREL_ADJ 12 #define R_ARM_TLS_DESC 13 -#define R_ARM_THM_SWI8 14 -#define R_ARM_XPC25 15 -#define R_ARM_THM_XPC22 16 #define R_ARM_TLS_DTPMOD32 17 #define R_ARM_TLS_DTPOFF32 18 #define R_ARM_TLS_TPOFF32 19 @@ -271,8 +276,6 @@ typedef struct { #define R_ARM_GOT_BREL12 97 #define R_ARM_GOTOFF12 98 #define R_ARM_GOTRELAX 99 -#define R_ARM_GNU_VTENTRY 100 -#define R_ARM_GNU_VTINHERIT 101 #define R_ARM_THM_JUMP11 102 #define R_ARM_THM_JUMP8 103 #define R_ARM_TLS_GD32 104 @@ -299,7 +302,6 @@ typedef struct { #define R_ARM_PRIVATE_13 125 #define R_ARM_PRIVATE_14 126 #define R_ARM_PRIVATE_15 127 -#define R_ARM_ME_TOO 128 #define R_ARM_THM_TLS_DESCSEQ16 129 #define R_ARM_THM_TLS_DESCSEQ32 130 diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.h b/backends/platform/gp2xwiz/gp2xwiz-loader.h index 066fc4d71d..26766167db 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.h +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.h @@ -31,27 +31,27 @@ #define MAXDLERRLEN 80 class DLObject { - protected: - char *errbuf; /* For error messages, at least MAXDLERRLEN in size */ + protected: + char *errbuf; /* For error messages, at least MAXDLERRLEN in size */ - void *_segment, *_symtab; - char *_strtab; - int _symbol_cnt; - void *_dtors_start, *_dtors_end; + void *_segment, *_symtab; + char *_strtab; + int _symbol_cnt; + void *_dtors_start, *_dtors_end; - void seterror(const char *fmt, ...); - void unload(); - bool relocate(int fd, unsigned long offset, unsigned long size); - bool load(int fd); + void seterror(const char *fmt, ...); + void unload(); + bool relocate(int fd, unsigned long offset, unsigned long size); + bool load(int fd); - public: - bool open(const char *path); - bool close(); - void *symbol(const char *name); - void discard_symtab(); + 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) {} + 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 -- cgit v1.2.3 From 32f2ef2a1337047643ff999d83a3b8e4cfa85e1a Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 26 Jun 2010 02:23:10 +0000 Subject: added gp2xwiz plugin provider code svn-id: r50299 --- backends/plugins/gp2xwiz/gp2xwiz-provider.cpp | 108 ++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 backends/plugins/gp2xwiz/gp2xwiz-provider.cpp (limited to 'backends') diff --git a/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp b/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp new file mode 100644 index 0000000000..2219f4275b --- /dev/null +++ b/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp @@ -0,0 +1,108 @@ +/* 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 "backends/plugins/gp2xwiz/gp2xwiz-provider.h" +#include "backends/plugins/dynamic-plugin.h" +#include "common/fs.h" + +#include "backends/platform/gp2xwiz/gp2xwiz-loader.h" + + +class GP2XWIZPlugin : public DynamicPlugin { +protected: + void *_dlHandle; + Common::String _filename; + + virtual VoidFunc findSymbol(const char *symbol) { + void *func = dlsym(_dlHandle, symbol); + if (!func) + warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. . + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp; + } + +public: + GP2XWIZPlugin(const Common::String &filename) + : _dlHandle(0), _filename(filename) {} + + ~GP2XWIZPlugin() { + if (_dlHandle) unloadPlugin(); + } + + bool loadPlugin() { + assert(!_dlHandle); + _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); + + if (!_dlHandle) { + warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); + return false; + } + + bool ret = DynamicPlugin::loadPlugin(); + + if (ret) + dlforgetsyms(_dlHandle); + + return ret; + } + + void unloadPlugin() { + DynamicPlugin::unloadPlugin(); + if (_dlHandle) { + if (dlclose(_dlHandle) != 0) + warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); + _dlHandle = 0; + } + } +}; + + +Plugin* GP2XWIZPluginProvider::createPlugin(const Common::FSNode &node) const { + return new GP2XWIZPlugin(node.getPath()); +} + +bool GP2XWIZPluginProvider::isPluginFilename(const Common::FSNode &node) const { + // Check the plugin suffix + Common::String filename = node.getName(); + printf("Testing name %s", filename.c_str()); + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg")) { + printf(" fail.\n"); + return false; + } + + printf(" success!\n"); + return true; +} + +#endif // defined(DYNAMIC_MODULES) && defined(GP2XWIZ) -- cgit v1.2.3 From 231a70ca43e3e48910f7966470a0b963cbe9ff9c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 26 Jun 2010 02:42:50 +0000 Subject: added wiz plugin provider to backends/module.mk svn-id: r50300 --- backends/module.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index 46c9e166a6..d5ae494a61 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -36,6 +36,7 @@ MODULE_OBJS := \ plugins/win32/win32-provider.o \ plugins/psp/psp-provider.o \ plugins/ps2/ps2-provider.o \ + plugins/gp2xwiz/gp2xwiz-provider.o \ saves/savefile.o \ saves/default/default-saves.o \ saves/posix/posix-saves.o \ -- cgit v1.2.3 From 21f2775458f8ab549bf91212f57bf3f910b08a00 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 26 Jun 2010 04:12:09 +0000 Subject: fixed detection of plugin filenames svn-id: r50304 --- backends/plugins/gp2xwiz/gp2xwiz-provider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp b/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp index 2219f4275b..859ac8fbc8 100644 --- a/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp +++ b/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp @@ -96,7 +96,7 @@ bool GP2XWIZPluginProvider::isPluginFilename(const Common::FSNode &node) const { // Check the plugin suffix Common::String filename = node.getName(); printf("Testing name %s", filename.c_str()); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg")) { + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { printf(" fail.\n"); return false; } -- cgit v1.2.3 From 7bb9e7062094c353087977ec67f9d9bbbb302971 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 26 Jun 2010 04:15:16 +0000 Subject: various fixes to the loader to allow compilation svn-id: r50305 --- backends/platform/gp2xwiz/elf32.h | 4 ++-- backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 36 +++++++++++++++------------- backends/platform/gp2xwiz/gp2xwiz-loader.h | 18 +++++++++++--- 3 files changed, 36 insertions(+), 22 deletions(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/elf32.h b/backends/platform/gp2xwiz/elf32.h index 68d0be37bf..bd9ae93332 100644 --- a/backends/platform/gp2xwiz/elf32.h +++ b/backends/platform/gp2xwiz/elf32.h @@ -175,8 +175,8 @@ typedef struct { } 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 */ +#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 diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp index f678db9258..9f2e663aff 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp @@ -34,10 +34,12 @@ #include "backends/platform/gp2xwiz/gp2xwiz-loader.h" +#define __WIZ_DEBUG_PLUGINS__ + #ifdef __WIZ_DEBUG_PLUGINS__ -#define DBG(x) printf(x, ## __VA_ARGS__) +#define DBG(x,...) printf(x, ## __VA_ARGS__) #else -#define DBG(x) +#define DBG(x,...) #endif #define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__) @@ -55,7 +57,7 @@ void DLObject::discard_symtab() { void DLObject::unload() { discard_symtab(); free(_segment); - segment = NULL; + _segment = NULL; } /** @@ -66,7 +68,7 @@ void DLObject::unload() { * @param size Size of relocation section * */ -bool DLObject::relocate(int fd, unsigned long offset, unsigned long size) { +bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void *relSegment) { Elf32_Rela *rela; //relocation entry // Allocate memory for relocation table @@ -93,15 +95,15 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size) { //void *target = ???; - switch (/*relocation type*/) { + // switch (/*relocation type*/) { //case ??? : //TODO: Cases for each relocation type. //break; - default: - seterror("Unknown relocation type %d.", ?? ?); + // default: + //seterror("Unknown relocation type %d.", ?? ?); free(rela); return false; - } + // } } @@ -126,7 +128,7 @@ bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { 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_MIPS || // Check for ARM machine type TODO: change EM_MIPS to ??_ARM and add to ELF32.H (figure out what ??_ARM should be) + 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."); @@ -281,7 +283,7 @@ bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { void DLObject::relocateSymbols(Elf32_Addr offset) { - relocCount = 0; + int relocCount = 0; DBG("Relocating symbols by %x\n", offset); // Loop over symbols, add relocation offset @@ -310,7 +312,7 @@ bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { //Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]); if (curShdr->sh_type == SHT_REL && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size + 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 @@ -331,7 +333,7 @@ bool DLObject::load(int fd) { Elf32_Shdr *shdr; bool ret = true; - int symtab_sect = -1; + //int symtab_sect = -1; if (readElfHeader(fd, &ehdr) == false) { return false; @@ -375,10 +377,10 @@ bool DLObject::open(const char *path) { DBG(("open(\"%s\")\n", path)); - if ((fd = ::open(path, O_RDONLY)) < 0) { + /*if ((fd = ::open(path, O_RDONLY)) < 0) { seterror("%s not found.", path); return false; - } + } TODO: reimplement this "attempt to open" code */ // Try to load and relocate if (!load(fd)) { @@ -430,14 +432,14 @@ void *DLObject::symbol(const char *name) { } Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = symbol_cnt; c--; s++) + 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)) { + _strtab[s->st_name] == '_' && !strcmp(name, _strtab + s->st_name + 1)) { // We found the symbol - DBG(("=> %p\n", (void*)s->st_value)); + DBG("=> %p\n", (void*)s->st_value); return (void*)s->st_value; } diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.h b/backends/platform/gp2xwiz/gp2xwiz-loader.h index 26766167db..d3812c3d8a 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.h +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.h @@ -32,25 +32,37 @@ class DLObject { protected: - char *errbuf; /* For error messages, at least MAXDLERRLEN in size */ + 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); + 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), + DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _segment(NULL),_symtab(NULL), _strtab(NULL), _symbol_cnt(0), _dtors_start(NULL), _dtors_end(NULL) {} }; -- cgit v1.2.3 From 11ee6014aa0584716fc8117f2d2b20106b1ab2f9 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sun, 27 Jun 2010 04:32:31 +0000 Subject: removed unneccessary relocation type definitions svn-id: r50362 --- backends/platform/gp2xwiz/elf32.h | 116 -------------------------------------- 1 file changed, 116 deletions(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/elf32.h b/backends/platform/gp2xwiz/elf32.h index bd9ae93332..4ec4455a4f 100644 --- a/backends/platform/gp2xwiz/elf32.h +++ b/backends/platform/gp2xwiz/elf32.h @@ -182,127 +182,11 @@ typedef struct { #define R_ARM_NONE 0 #define R_ARM_PC24 1 #define R_ARM_ABS32 2 -#define R_ARM_REL32 3 -#define R_ARM_LDR_PC_G0 4 -#define R_ARM_ABS16 5 -#define R_ARM_ABS12 6 -#define R_ARM_THM_ABS5 7 -#define R_ARM_ABS8 8 -#define R_ARM_SBREL32 9 -#define R_ARM_THM_CALL 10 -#define R_ARM_THM_PC8 11 -#define R_ARM_BREL_ADJ 12 -#define R_ARM_TLS_DESC 13 -#define R_ARM_TLS_DTPMOD32 17 -#define R_ARM_TLS_DTPOFF32 18 -#define R_ARM_TLS_TPOFF32 19 #define R_ARM_COPY 20 #define R_ARM_GLOB_DAT 21 #define R_ARM_JUMP_SLOT 22 -#define R_ARM_RELATIVE 23 -#define R_ARM_GOTOFF32 24 #define R_ARM_BASE_PREL 25 #define R_ARM_GOT_BREL 26 #define R_ARM_PLT32 27 -#define R_ARM_CALL 28 -#define R_ARM_JUMP24 29 -#define R_ARM_THM_JUMP24 30 -#define R_ARM_BASE_ABS 31 -#define R_ARM_ALU_PCREL_7_0 32 -#define R_ARM_ALU_PCREL_15_8 33 -#define R_ARM_ALU_PCREL_23_15 34 -#define R_ARM_LDR_SBREL_11_0_NC 35 -#define R_ARM_ALU_SBREL_19_12_NC 36 -#define R_ARM_ALU_SBREL_27_20_CK 37 -#define R_ARM_TARGET1 38 -#define R_ARM_SBREL31 39 -#define R_ARM_V4BX 40 -#define R_ARM_TARGET2 41 -#define R_ARM_PREL31 42 -#define R_ARM_MOVW_ABS_NC 43 -#define R_ARM_MOVT_ABS 44 -#define R_ARM_MOVW_PREL_NC 45 -#define R_ARM_MOVT_PREL 46 -#define R_ARM_THM_MOVW_ABS_NC 47 -#define R_ARM_THM_MOVT_ABS 48 -#define R_ARM_THM_MOVW_PREL_NC 49 -#define R_ARM_THM_MOVT_PREL 50 -#define R_ARM_THM_JUMP19 51 -#define R_ARM_THM_JUMP6 52 -#define R_ARM_THM_ALU_PREL_11_0 53 -#define R_ARM_THM_PC12 54 -#define R_ARM_ABS32_NOI 55 -#define R_ARM_REL32_NOI 56 -#define R_ARM_ALU_PC_G0_NC 57 -#define R_ARM_ALU_PC_G0 58 -#define R_ARM_ALU_PC_G1_NC 59 -#define R_ARM_ALU_PC_G1 60 -#define R_ARM_ALU_PC_G2 61 -#define R_ARM_LDR_PC_G1 62 -#define R_ARM_LDR_PC_G2 63 -#define R_ARM_LDRS_PC_G0 64 -#define R_ARM_LDRS_PC_G1 65 -#define R_ARM_LDRS_PC_G2 66 -#define R_ARM_LDC_PC_G0 67 -#define R_ARM_LDC_PC_G1 68 -#define R_ARM_LDC_PC_G2 69 -#define R_ARM_ALU_SB_G0_NC 70 -#define R_ARM_ALU_SB_G0 71 -#define R_ARM_ALU_SB_G1_NC 72 -#define R_ARM_ALU_SB_G1 73 -#define R_ARM_ALU_SB_G2 74 -#define R_ARM_LDR_SB_G0 75 -#define R_ARM_LDR_SB_G1 76 -#define R_ARM_LDR_SB_G2 77 -#define R_ARM_LDRS_SB_G0 78 -#define R_ARM_LDRS_SB_G1 79 -#define R_ARM_LDRS_SB_G2 80 -#define R_ARM_LDC_SB_G0 81 -#define R_ARM_LDC_SB_G1 82 -#define R_ARM_LDC_SB_G2 83 -#define R_ARM_MOVW_BREL_NC 84 -#define R_ARM_MOVT_BREL 85 -#define R_ARM_MOVW_BREL 86 -#define R_ARM_THM_MOVW_BREL_NC 87 -#define R_ARM_THM_MOVT_BREL 88 -#define R_ARM_THM_MOVW_BREL 89 -#define R_ARM_TLS_GOTDESC 90 -#define R_ARM_TLS_CALL 91 -#define R_ARM_TLS_DESCSEQ 92 -#define R_ARM_THM_TLS_CALL 93 -#define R_ARM_PLT32_ABS 94 -#define R_ARM_GOT_ABS 95 -#define R_ARM_GOT_PREL 96 -#define R_ARM_GOT_BREL12 97 -#define R_ARM_GOTOFF12 98 -#define R_ARM_GOTRELAX 99 -#define R_ARM_THM_JUMP11 102 -#define R_ARM_THM_JUMP8 103 -#define R_ARM_TLS_GD32 104 -#define R_ARM_TLS_LDM32 105 -#define R_ARM_TLS_LDO32 106 -#define R_ARM_TLS_IE32 107 -#define R_ARM_TLS_LE32 108 -#define R_ARM_TLS_LDO12 109 -#define R_ARM_TLS_LE12 110 -#define R_ARM_TLS_IE12GP 111 -#define R_ARM_PRIVATE_0 112 -#define R_ARM_PRIVATE_1 113 -#define R_ARM_PRIVATE_2 114 -#define R_ARM_PRIVATE_3 115 -#define R_ARM_PRIVATE_4 116 -#define R_ARM_PRIVATE_5 117 -#define R_ARM_PRIVATE_6 118 -#define R_ARM_PRIVATE_7 119 -#define R_ARM_PRIVATE_8 120 -#define R_ARM_PRIVATE_9 121 -#define R_ARM_PRIVATE_10 122 -#define R_ARM_PRIVATE_11 123 -#define R_ARM_PRIVATE_12 124 -#define R_ARM_PRIVATE_13 125 -#define R_ARM_PRIVATE_14 126 -#define R_ARM_PRIVATE_15 127 -#define R_ARM_THM_TLS_DESCSEQ16 129 -#define R_ARM_THM_TLS_DESCSEQ32 130 #endif /* BACKENDS_ELF_H */ -- cgit v1.2.3 From 54531aaf9824028c6641f6cce63adf601e147cab Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 28 Jun 2010 23:34:06 +0000 Subject: reimplemented DLObject::open svn-id: r50467 --- backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'backends') diff --git a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp index 9f2e663aff..22aa45fa30 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-loader.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-loader.cpp @@ -31,6 +31,8 @@ #include #include #include +#include + #include "backends/platform/gp2xwiz/gp2xwiz-loader.h" @@ -91,11 +93,13 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * // TODO: Loop over relocation entries for (int i = 0; i < cnt; i++) { + DBG("attempting to relocate!"); + //Elf32_Sym *sym = ???; //void *target = ???; - // switch (/*relocation type*/) { + /*switch (REL_TYPE()) {*/ //case ??? : //TODO: Cases for each relocation type. //break; @@ -113,17 +117,6 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { - /* - if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr) || - memcmp(ehdr.e_ident, ELFMAG, SELFMAG) || - ehdr.e_type != 2 || ehdr.e_machine != 42 || - ehdr.e_phentsize < sizeof(phdr) || ehdr.e_shentsize != sizeof(*shdr) || - ehdr.e_phnum != 1) { - seterror("Invalid file type."); - return false; - } - */ - // Start reading the elf header. Check for errors if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC @@ -377,10 +370,10 @@ bool DLObject::open(const char *path) { DBG(("open(\"%s\")\n", path)); - /*if ((fd = ::open(path, O_RDONLY)) < 0) { + if ((fd = ::open(path, O_RDONLY)) < 0) { seterror("%s not found.", path); return false; - } TODO: reimplement this "attempt to open" code */ + } // Try to load and relocate if (!load(fd)) { -- cgit v1.2.3 From dff291f12b6eb0426cf11d93ea734ee3437cbd8c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 30 Jun 2010 03:15:08 +0000 Subject: added dumped arm-eabi linker svn-id: r50513 --- backends/platform/ds/plugin.ld | 230 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 backends/platform/ds/plugin.ld (limited to 'backends') diff --git a/backends/platform/ds/plugin.ld b/backends/platform/ds/plugin.ld new file mode 100644 index 0000000000..dcb6a0ca3f --- /dev/null +++ b/backends/platform/ds/plugin.ld @@ -0,0 +1,230 @@ +/* Script for -z combreloc: combine and sort reloc sections */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SEARCH_DIR("/opt/devkitpro/devkitARM/arm-eabi/lib"); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000); + .interp : { *(.interp) } + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.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.gnu.linkonce.d.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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rel.plt : + { + *(.rel.plt) + } + .rela.plt : + { + *(.rela.plt) + } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.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(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__fini_array_end = .); + } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + 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. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + __end__ = . ; + _end = .; PROVIDE (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) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} -- cgit v1.2.3 From 82cbd13bce7a2e7e0556a538553ffe4b2a416c0f Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 2 Jul 2010 00:39:05 +0000 Subject: added elf32 header for ds svn-id: r50586 --- backends/platform/ds/elf32.h | 192 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 backends/platform/ds/elf32.h (limited to 'backends') diff --git a/backends/platform/ds/elf32.h b/backends/platform/ds/elf32.h new file mode 100644 index 0000000000..2b695c917d --- /dev/null +++ b/backends/platform/ds/elf32.h @@ -0,0 +1,192 @@ +/* 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 */ -- cgit v1.2.3 From a95b6e5c12596898dd6d8aaf6d34185417f7d25f Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 2 Jul 2010 00:55:30 +0000 Subject: added incomplete ds loader svn-id: r50587 --- backends/platform/ds/dsloader.cpp | 484 ++++++++++++++++++++++++++++++++++++++ backends/platform/ds/dsloader.h | 79 +++++++ 2 files changed, 563 insertions(+) create mode 100644 backends/platform/ds/dsloader.cpp create mode 100644 backends/platform/ds/dsloader.h (limited to 'backends') diff --git a/backends/platform/ds/dsloader.cpp b/backends/platform/ds/dsloader.cpp new file mode 100644 index 0000000000..5b207b42d9 --- /dev/null +++ b/backends/platform/ds/dsloader.cpp @@ -0,0 +1,484 @@ +/* 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(__DS__) + +#include +#include +#include +#include +#include +#include +#include + +#include "backends/platform/ds/dsloader.h" + +#define __DS_DEBUG_PLUGINS__ + +#ifdef __DS_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 && __DS__ */ diff --git a/backends/platform/ds/dsloader.h b/backends/platform/ds/dsloader.h new file mode 100644 index 0000000000..f8a3cdefa4 --- /dev/null +++ b/backends/platform/ds/dsloader.h @@ -0,0 +1,79 @@ +/* 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 DS_LOADER_H +#define DS_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 /* DS_LOADER_H */ -- cgit v1.2.3 From 3c6ef6424303fc03632220d6299e046a8eb455ca Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 2 Jul 2010 01:32:14 +0000 Subject: added ds plugin-provider svn-id: r50588 --- backends/plugins/ds/ds-provider.cpp | 108 ++++++++++++++++++++++++++++++++++++ backends/plugins/ds/ds-provider.h | 43 ++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 backends/plugins/ds/ds-provider.cpp create mode 100644 backends/plugins/ds/ds-provider.h (limited to 'backends') diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp new file mode 100644 index 0000000000..c200e212cc --- /dev/null +++ b/backends/plugins/ds/ds-provider.cpp @@ -0,0 +1,108 @@ +/* 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(__DS__) + +#include "backends/plugins/ds/ds-provider.h" +#include "backends/plugins/dynamic-plugin.h" +#include "common/fs.h" + +#include "backends/platform/ds/dsloader.h" + + +class DSPlugin : public DynamicPlugin { +protected: + void *_dlHandle; + Common::String _filename; + + virtual VoidFunc findSymbol(const char *symbol) { + void *func = dlsym(_dlHandle, symbol); + if (!func) + warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. . + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp; + } + +public: + DSPlugin(const Common::String &filename) + : _dlHandle(0), _filename(filename) {} + + ~DSPlugin() { + if (_dlHandle) unloadPlugin(); + } + + bool loadPlugin() { + assert(!_dlHandle); + _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); + + if (!_dlHandle) { + warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); + return false; + } + + bool ret = DynamicPlugin::loadPlugin(); + + if (ret) + dlforgetsyms(_dlHandle); + + return ret; + } + + void unloadPlugin() { + DynamicPlugin::unloadPlugin(); + if (_dlHandle) { + if (dlclose(_dlHandle) != 0) + warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); + _dlHandle = 0; + } + } +}; + + +Plugin* DSPluginProvider::createPlugin(const Common::FSNode &node) const { + return new DSPlugin(node.getPath()); +} + +bool DSPluginProvider::isPluginFilename(const Common::FSNode &node) const { + // Check the plugin suffix + Common::String filename = node.getName(); + printf("Testing name %s", filename.c_str()); + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { + printf(" fail.\n"); + return false; + } + + printf(" success!\n"); + return true; +} + +#endif // defined(DYNAMIC_MODULES) && defined(__DS__) diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h new file mode 100644 index 0000000000..096c1b87a9 --- /dev/null +++ b/backends/plugins/ds/ds-provider.h @@ -0,0 +1,43 @@ +/* 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_PLUGINS_DS_DS_PROVIDER_H +#define BACKENDS_PLUGINS_DS_DS_PROVIDER_H + +#include "base/plugins.h" + +#if defined(DYNAMIC_MODULES) && defined(__DS__) + +class DSPluginProvider : public FilePluginProvider { +protected: + Plugin* createPlugin(const Common::FSNode &node) const; + + bool isPluginFilename(const Common::FSNode &node) const; + +}; + +#endif // defined(DYNAMIC_MODULES) && defined(__DS__) + +#endif /* BACKENDS_PLUGINS_DS_DS_PROVIDER_H */ -- cgit v1.2.3 From 13948b8118b3a494cbd8f81a5bb9e9ca55a4c5f8 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 3 Jul 2010 03:46:21 +0000 Subject: modified default ds linker script for linking of engine plugins svn-id: r50612 --- backends/platform/ds/plugin.ld | 38 ++++++++++++-------------------------- 1 file changed, 12 insertions(+), 26 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/plugin.ld b/backends/platform/ds/plugin.ld index dcb6a0ca3f..65ba0496c7 100644 --- a/backends/platform/ds/plugin.ld +++ b/backends/platform/ds/plugin.ld @@ -1,14 +1,15 @@ -/* Script for -z combreloc: combine and sort reloc sections */ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", - "elf32-littlearm") +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) -ENTRY(_start) -SEARCH_DIR("/opt/devkitpro/devkitARM/arm-eabi/lib"); +/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ +PHDRS { + plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ +} SECTIONS { /* Read-only sections, merged into text segment: */ - PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x8000)); . = SEGMENT_START("text-segment", 0x8000); - .interp : { *(.interp) } + . = 0; + .interp : { *(.interp) } : plugin /*The ": plugin" tells the linker to assign this and + the following sections to the "plugin" segment*/ .note.gnu.build-id : { *(.note.gnu.build-id) } .hash : { *(.hash) } .gnu.hash : { *(.gnu.hash) } @@ -125,32 +126,17 @@ SECTIONS } .ctors : { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + ___plugin_ctors = .; KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) + ___plugin_ctors_end = .; } .dtors : { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + ___plugin_dtors = .; KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) + ___plugin_dtors_end = .; } .jcr : { KEEP (*(.jcr)) } .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } -- cgit v1.2.3 From 0b0bc1050bb0e70eca2f358511c021a6f7c59471 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 3 Jul 2010 03:47:39 +0000 Subject: added ds plugin provider to module.mk svn-id: r50613 --- backends/module.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index d5ae494a61..2f39c548a0 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -37,6 +37,7 @@ MODULE_OBJS := \ plugins/psp/psp-provider.o \ plugins/ps2/ps2-provider.o \ plugins/gp2xwiz/gp2xwiz-provider.o \ + plugins/ds/ds-provider.o \ saves/savefile.o \ saves/default/default-saves.o \ saves/posix/posix-saves.o \ -- cgit v1.2.3 From ffdfd3217fee63346589298844651a67a9230781 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 3 Jul 2010 04:01:39 +0000 Subject: changed main to use DS plugin provider if dynamic modules are turned on svn-id: r50615 --- backends/platform/ds/arm9/source/dsmain.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index 7eb02f9070..8b1ed32c67 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -702,7 +702,7 @@ void displayMode8Bit() { - consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 2, 0, true); + consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 2, 0, true, true); // Set this again because consoleinit resets it videoSetMode(MODE_5_2D | (consoleEnable? DISPLAY_BG0_ACTIVE: 0) | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_ACTIVE | DISPLAY_SPR_1D | DISPLAY_SPR_1D_BMP); @@ -940,7 +940,7 @@ void displayMode16Bit() { SUB_BG0_CR = BG_MAP_BASE(4) | BG_TILE_BASE(0); SUB_BG0_Y0 = 0; - consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 4, 0, false); + consoleInit(NULL, 0, BgType_Text4bpp, BgSize_T_256x256, 4, 0, false, true); // consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(4), (u16*)CHAR_BASE_BLOCK_SUB(0), 16); for (int r = 0; r < 32 * 32; r++) { @@ -3346,6 +3346,9 @@ int main(void) { const char *argv[] = {"/scummvmds", "--config=scummvmk.ini"}; #endif +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new DSPluginProvider()); +#endif while (1) { scummvm_main(ARRAYSIZE(argv), (char **) &argv); -- cgit v1.2.3 From 36435eecbf371acf938b9c38e5bb53341d3738ea Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 3 Jul 2010 04:42:34 +0000 Subject: moved loader to arm9/source and added it to module.mk svn-id: r50616 --- backends/platform/ds/arm9/source/dsloader.cpp | 484 ++++++++++++++++++++++++++ backends/platform/ds/arm9/source/dsloader.h | 79 +++++ backends/platform/ds/dsloader.cpp | 484 -------------------------- backends/platform/ds/dsloader.h | 79 ----- backends/platform/ds/module.mk | 4 + 5 files changed, 567 insertions(+), 563 deletions(-) create mode 100644 backends/platform/ds/arm9/source/dsloader.cpp create mode 100644 backends/platform/ds/arm9/source/dsloader.h delete mode 100644 backends/platform/ds/dsloader.cpp delete mode 100644 backends/platform/ds/dsloader.h (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp new file mode 100644 index 0000000000..5b207b42d9 --- /dev/null +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -0,0 +1,484 @@ +/* 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(__DS__) + +#include +#include +#include +#include +#include +#include +#include + +#include "backends/platform/ds/dsloader.h" + +#define __DS_DEBUG_PLUGINS__ + +#ifdef __DS_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 && __DS__ */ diff --git a/backends/platform/ds/arm9/source/dsloader.h b/backends/platform/ds/arm9/source/dsloader.h new file mode 100644 index 0000000000..f8a3cdefa4 --- /dev/null +++ b/backends/platform/ds/arm9/source/dsloader.h @@ -0,0 +1,79 @@ +/* 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 DS_LOADER_H +#define DS_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 /* DS_LOADER_H */ diff --git a/backends/platform/ds/dsloader.cpp b/backends/platform/ds/dsloader.cpp deleted file mode 100644 index 5b207b42d9..0000000000 --- a/backends/platform/ds/dsloader.cpp +++ /dev/null @@ -1,484 +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(__DS__) - -#include -#include -#include -#include -#include -#include -#include - -#include "backends/platform/ds/dsloader.h" - -#define __DS_DEBUG_PLUGINS__ - -#ifdef __DS_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 && __DS__ */ diff --git a/backends/platform/ds/dsloader.h b/backends/platform/ds/dsloader.h deleted file mode 100644 index f8a3cdefa4..0000000000 --- a/backends/platform/ds/dsloader.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 DS_LOADER_H -#define DS_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 /* DS_LOADER_H */ diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk index 16630dc070..bb874e7561 100644 --- a/backends/platform/ds/module.mk +++ b/backends/platform/ds/module.mk @@ -25,6 +25,10 @@ ifdef USE_PROFILER PORT_OBJS += arm9/source/profiler/cyg-profile.o endif +ifdef DYNAMIC_MODULES + PORT_OBJS += arm9/source/dsloader.o +endif + DATA_OBJS := \ arm9/data/icons.o \ arm9/data/keyboard.o \ -- cgit v1.2.3 From 41663da28211bad526752f187b141f40515ec75c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 3 Jul 2010 05:05:27 +0000 Subject: moved plugin linker and elf32 header file to arm9/source and modified ds makefile to use dynamic plugins svn-id: r50617 --- backends/platform/ds/arm9/makefile | 48 ++++--- backends/platform/ds/arm9/source/elf32.h | 192 +++++++++++++++++++++++++ backends/platform/ds/arm9/source/plugin.ld | 216 +++++++++++++++++++++++++++++ backends/platform/ds/elf32.h | 192 ------------------------- backends/platform/ds/plugin.ld | 216 ----------------------------- 5 files changed, 437 insertions(+), 427 deletions(-) create mode 100644 backends/platform/ds/arm9/source/elf32.h create mode 100644 backends/platform/ds/arm9/source/plugin.ld delete mode 100644 backends/platform/ds/elf32.h delete mode 100644 backends/platform/ds/plugin.ld (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index eca170ef96..948aade30e 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -1,10 +1,16 @@ srcdir ?= . DEPDIR := .deps -#DYNAMIC_MODULES = 1 +DYNAMIC_MODULES = 1 libndsdir = $(DEVKITPRO)/libnds #libndsdir = /home/neil/devkitpror21/libnds +ifdef DYNAMIC_MODULES + ENABLED = DYNAMIC_PLUGIN +else + ENABLED = STATIC_PLUGIN +endif + # Select the build by setting SCUMM_BUILD to a,b,c,d,e,f or g. # Anything else gets build a. @@ -112,8 +118,8 @@ USE_ARM_COSTUME_ASM = 1 ifdef DS_BUILD_A DEFINES = -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM LOGO = logoa.bmp - ENABLE_SCUMM = STATIC_PLUGIN - DEFINES += -DENABLE_SCUMM=STATIC_PLUGIN + ENABLE_SCUMM = $(ENABLED) + DEFINES += -DENABLE_SCUMM=$(ENABLED) MODULES += engines/scumm USE_ARM_GFX_ASM = 1 @@ -123,66 +129,66 @@ endif ifdef DS_BUILD_B DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_B LOGO = logob.bmp - ENABLE_SKY = STATIC_PLUGIN - ENABLE_QUEEN = STATIC_PLUGIN + ENABLE_SKY = $(ENABLED) + ENABLE_QUEEN = $(ENABLED) BUILD=scummvm-B endif ifdef DS_BUILD_C DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_C LOGO = logoc.bmp - ENABLE_AGOS = STATIC_PLUGIN + ENABLE_AGOS = $(ENABLED) BUILD=scummvm-C endif ifdef DS_BUILD_D DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_D LOGO = logod.bmp - ENABLE_GOB = STATIC_PLUGIN - ENABLE_CINE = STATIC_PLUGIN - ENABLE_AGI = STATIC_PLUGIN + ENABLE_GOB = $(ENABLED) + ENABLE_CINE = $(ENABLED) + ENABLE_AGI = $(ENABLED) BUILD=scummvm-D endif ifdef DS_BUILD_E DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_E LOGO = logoe.bmp - ENABLE_SAGA = STATIC_PLUGIN + ENABLE_SAGA = $(ENABLED) BUILD=scummvm-E endif ifdef DS_BUILD_F DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_F LOGO = logof.bmp - ENABLE_KYRA = STATIC_PLUGIN + ENABLE_KYRA = $(ENABLED) BUILD=scummvm-F endif ifdef DS_BUILD_G DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_G LOGO = logog.bmp - ENABLE_LURE = STATIC_PLUGIN + ENABLE_LURE = $(ENABLED) BUILD=scummvm-G endif ifdef DS_BUILD_H DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_H LOGO = logoh.bmp - ENABLE_PARALLACTION = STATIC_PLUGIN + ENABLE_PARALLACTION = $(ENABLED) BUILD=scummvm-H endif ifdef DS_BUILD_I DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_I LOGO = logoi.bmp - ENABLE_MADE = STATIC_PLUGIN + ENABLE_MADE = $(ENABLED) BUILD=scummvm-I endif ifdef DS_BUILD_K DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_K LOGO = logok.bmp - ENABLE_CRUISE = STATIC_PLUGIN + ENABLE_CRUISE = $(ENABLED) BUILD=scummvm-K endif @@ -190,14 +196,14 @@ endif #ifdef DS_BUILD_L # DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_L # LOGO = logog.bmp -# ENABLE_DRASCULA = STATIC_PLUGIN +# ENABLE_DRASCULA = $(ENABLED) # BUILD=scummvm-K #endif #ifdef DS_BUILD_M # DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_M # LOGO = logog.bmp -# ENABLE_TUCKER = STATIC_PLUGIN +# ENABLE_TUCKER = $(ENABLED) # BUILD=scummvm-K #endif @@ -276,8 +282,8 @@ endif EXECUTABLE = scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.x plugin.syms scummvm.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-Tplugin.x,--just-symbols,scummvm.elf,--retain-symbols-file,plugin.syms -L$(ronindir)/lib +PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms scummvm.elf +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-Tplugin.ld,--just-symbols,scummvm.elf,--retain-symbols-file,plugin.syms MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf @@ -299,6 +305,10 @@ PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(port $(portdir)/source/touchkeyboard.o $(portdir)/source/zipreader.o\ $(portdir)/source/dsoptions.o $(portdir)/source/keys.o $(portdir)/source/wordcompletion.o\ $(portdir)/source/interrupt.o + +ifdef DYNAMIC_MODULES + PORT_OBJS += $(portdir)/source/dsloader.o +endif ifdef USE_PROFILER PORT_OBJS += $(portdir)/source/profiler/cyg-profile.o diff --git a/backends/platform/ds/arm9/source/elf32.h b/backends/platform/ds/arm9/source/elf32.h new file mode 100644 index 0000000000..2b695c917d --- /dev/null +++ b/backends/platform/ds/arm9/source/elf32.h @@ -0,0 +1,192 @@ +/* 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/ds/arm9/source/plugin.ld b/backends/platform/ds/arm9/source/plugin.ld new file mode 100644 index 0000000000..65ba0496c7 --- /dev/null +++ b/backends/platform/ds/arm9/source/plugin.ld @@ -0,0 +1,216 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_ARCH(arm) +/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ +PHDRS { + plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ +} +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + .interp : { *(.interp) } : plugin /*The ": plugin" tells the linker to assign this and + the following sections to the "plugin" segment*/ + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.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.gnu.linkonce.d.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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rel.plt : + { + *(.rel.plt) + } + .rela.plt : + { + *(.rela.plt) + } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.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(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__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* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + 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. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + __end__ = . ; + _end = .; PROVIDE (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) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} diff --git a/backends/platform/ds/elf32.h b/backends/platform/ds/elf32.h deleted file mode 100644 index 2b695c917d..0000000000 --- a/backends/platform/ds/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/ds/plugin.ld b/backends/platform/ds/plugin.ld deleted file mode 100644 index 65ba0496c7..0000000000 --- a/backends/platform/ds/plugin.ld +++ /dev/null @@ -1,216 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") -OUTPUT_ARCH(arm) -/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ -PHDRS { - plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ -} -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - .interp : { *(.interp) } : plugin /*The ": plugin" tells the linker to assign this and - the following sections to the "plugin" segment*/ - .note.gnu.build-id : { *(.note.gnu.build-id) } - .hash : { *(.hash) } - .gnu.hash : { *(.gnu.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.gnu.linkonce.d.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.*) - PROVIDE_HIDDEN (__rel_iplt_start = .); - *(.rel.iplt) - PROVIDE_HIDDEN (__rel_iplt_end = .); - PROVIDE_HIDDEN (__rela_iplt_start = .); - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .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.*) - PROVIDE_HIDDEN (__rel_iplt_start = .); - PROVIDE_HIDDEN (__rel_iplt_end = .); - PROVIDE_HIDDEN (__rela_iplt_start = .); - *(.rela.iplt) - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .rel.plt : - { - *(.rel.plt) - } - .rela.plt : - { - *(.rela.plt) - } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .iplt : { *(.iplt) } - .text : - { - *(.text.unlikely .text.*_unlikely) - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } - __exidx_start = .; - .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } - __exidx_end = .; - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.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(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); - /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } - /* Thread Local Storage sections */ - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - } - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__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* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } - .dynamic : { *(.dynamic) } - .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } - .data : - { - __data_start = . ; - *(.data .data.* .gnu.linkonce.d.*) - 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. - FIXME: Why do we need it? When there is no .bss section, we don't - pad the .data section. */ - . = ALIGN(. != 0 ? 32 / 8 : 1); - } - _bss_end__ = . ; __bss_end__ = . ; - . = ALIGN(32 / 8); - . = ALIGN(32 / 8); - __end__ = . ; - _end = .; PROVIDE (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) } - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } - .debug_ranges 0 : { *(.debug_ranges) } - .stack 0x80000 : - { - _stack = .; - *(.stack) - } - .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } - .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } - /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } -} -- cgit v1.2.3 From 07faa734cedc04427820fbe0c7cdcb9c197567cd Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 7 Jul 2010 01:55:11 +0000 Subject: various fixes for ds dynamic plugins svn-id: r50732 --- backends/platform/ds/arm9/makefile | 29 ++++------ backends/platform/ds/arm9/source/dsloader.cpp | 2 +- backends/platform/ds/arm9/source/plugin.syms | 8 +++ backends/platform/ds/makefile | 2 - backends/platform/ds/module.mk | 76 +++++++++++++++++++++------ backends/plugins/ds/ds-provider.cpp | 2 +- 6 files changed, 82 insertions(+), 37 deletions(-) create mode 100644 backends/platform/ds/arm9/source/plugin.syms (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 948aade30e..ec1aa12dba 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -5,7 +5,7 @@ DYNAMIC_MODULES = 1 libndsdir = $(DEVKITPRO)/libnds #libndsdir = /home/neil/devkitpror21/libnds -ifdef DYNAMIC_MODULES +ifeq ($(DYNAMIC_MODULES),1) ENABLED = DYNAMIC_PLUGIN else ENABLED = STATIC_PLUGIN @@ -81,7 +81,7 @@ else ifdef DS_BUILD_K else - USE_MAD = 1 + #USE_MAD = 1 endif endif endif @@ -208,7 +208,6 @@ endif #endif ARM7BIN := -7 $(CURDIR)/../../arm7/arm7.bin -ICON := -b ../../../logo.bmp "ScummVM;By Neil Millstone;" CC = arm-eabi-gcc CXX = arm-eabi-g++ @@ -254,9 +253,6 @@ endif DEFINES += -DREDUCE_MEMORY_USAGE -# Removed, as these are done in portdefs.h -# -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE - LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections ifdef WRAP_MALLOC @@ -269,6 +265,7 @@ INCLUDES= -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/engines \ -I$(portdir)/source -I$(portdir)/source/mad -I$(portdir)/source/libcartreset \ -I$(libndsdir)/include -include $(srcdir)/common/scummsys.h +CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP LIBS = -lm -L$(libndsdir)/lib -L$(portdir)/lib -lnds9 ifdef USE_MAD @@ -282,8 +279,8 @@ endif EXECUTABLE = scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms scummvm.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-Tplugin.ld,--just-symbols,scummvm.elf,--retain-symbols-file,plugin.syms +PLUGIN_EXTRA_DEPS = $(portdir)/plugin.ld $(portdir)/plugin.syms $(EXECUTABLE) +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-T$(portdir)/plugin.ld,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(portdir)/plugin.syms -lstdc++ -lc MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf @@ -293,7 +290,7 @@ OBJCOPY = arm-eabi-objcopy AS = arm-eabi-as HAVE_GCC3 = true -ifdef DYNAMIC_MODULES +ifeq ($(DYNAMIC_MODULES),1) DEFINES += -DDYNAMIC_MODULES PRE_OBJS_FLAGS = -Wl,--whole-archive POST_OBJS_FLAGS = -Wl,--no-whole-archive @@ -301,14 +298,11 @@ endif PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(portdir)/source/dsmain.o \ $(portdir)/../../../fs/ds/ds-fs.o $(portdir)/source/gbampsave.o $(portdir)/source/scummhelp.o\ - $(portdir)/source/osystem_ds.o $(portdir)/source/portdefs.o $(portdir)/source/ramsave.o\ + $(portdir)/source/osystem_ds.o $(portdir)/source/ramsave.o\ $(portdir)/source/touchkeyboard.o $(portdir)/source/zipreader.o\ $(portdir)/source/dsoptions.o $(portdir)/source/keys.o $(portdir)/source/wordcompletion.o\ - $(portdir)/source/interrupt.o - -ifdef DYNAMIC_MODULES - PORT_OBJS += $(portdir)/source/dsloader.o -endif + $(portdir)/source/interrupt.o\ + $(portdir)/source/dsloader.o ifdef USE_PROFILER PORT_OBJS += $(portdir)/source/profiler/cyg-profile.o @@ -365,9 +359,7 @@ OPT_SIZE := -Os -mthumb OBJS := $(DATA_OBJS) $(LIBCARTRESET_OBJS) $(PORT_OBJS) $(COMPRESSOR_OBJS) $(FAT_OBJS) - - -MODULE_DIRS += . +MODULE_DIRS += ./ ndsall: @[ -d $(BUILD) ] || mkdir -p $(BUILD) @@ -489,6 +481,7 @@ endef #--------------------------------------------------------------------------------- # FIXME: The following rule hardcodes the input & output filename -- shouldn't it use $< and $@ instead? + %.bin: %.elf $(OBJCOPY) -S scummvm.elf scummvm-stripped.elf $(OBJCOPY) -O binary scummvm-stripped.elf scummvm.bin diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index 5b207b42d9..543d3648b5 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -33,7 +33,7 @@ #include #include -#include "backends/platform/ds/dsloader.h" +#include "backends/platform/ds/arm9/source/dsloader.h" #define __DS_DEBUG_PLUGINS__ diff --git a/backends/platform/ds/arm9/source/plugin.syms b/backends/platform/ds/arm9/source/plugin.syms new file mode 100644 index 0000000000..24ee1a19dc --- /dev/null +++ b/backends/platform/ds/arm9/source/plugin.syms @@ -0,0 +1,8 @@ +PLUGIN_getVersion +PLUGIN_getType +PLUGIN_getTypeVersion +PLUGIN_getObject +___plugin_ctors +___plugin_ctors_end +___plugin_dtors +___plugin_dtors_end diff --git a/backends/platform/ds/makefile b/backends/platform/ds/makefile index 58d6fd4c02..7bfd419c14 100644 --- a/backends/platform/ds/makefile +++ b/backends/platform/ds/makefile @@ -1,8 +1,6 @@ #SUBDIRS:= `ls | egrep -v '^(CVS|tools)$$'` - - export PATH := $(DEVKITARM)/bin:$(PATH) export portdir = $(CURDIR)/arm9 diff --git a/backends/platform/ds/module.mk b/backends/platform/ds/module.mk index bb874e7561..f2640c49e3 100644 --- a/backends/platform/ds/module.mk +++ b/backends/platform/ds/module.mk @@ -12,22 +12,14 @@ PORT_OBJS := \ arm9/source/gbampsave.o \ arm9/source/scummhelp.o \ arm9/source/osystem_ds.o \ - arm9/source/portdefs.o \ arm9/source/ramsave.o \ arm9/source/touchkeyboard.o \ arm9/source/zipreader.o \ arm9/source/dsoptions.o \ arm9/source/keys.o \ arm9/source/wordcompletion.o \ - arm9/source/interrupt.o - -ifdef USE_PROFILER - PORT_OBJS += arm9/source/profiler/cyg-profile.o -endif - -ifdef DYNAMIC_MODULES - PORT_OBJS += arm9/source/dsloader.o -endif + arm9/source/interrupt.o \ + arm9/source/dsloader.o DATA_OBJS := \ arm9/data/icons.o \ @@ -59,17 +51,71 @@ FAT_OBJS := arm9/source/fat/disc_io.o arm9/source/fat/gba_nds_fat.o\ # arm9/source/fat/io_sd_common.o arm9/source/fat/io_scsd_s.o \ # arm9/source/fat/io_sc_common.o arm9/source/fat/io_sd_common.o -LIBCARTRESET_OBJS := - #arm9/source/libcartreset/cartreset.o +LIBCARTRESET_OBJS := \ +# arm9/source/libcartreset/cartreset.o + + +#MODULE_OBJS := $(PORT_OBJS) $(DATA_OBJS) $(FAT_OBJS) +MODULE_OBJS := $(DATA_OBJS) $(LIBCARTRESET_OBJS) $(PORT_OBJS) $(COMPRESSOR_OBJS) $(FAT_OBJS) + + +#--------------------------------------------------------------------------------- +# canned command sequence for binary data +#--------------------------------------------------------------------------------- +define bin2o + $(MKDIR) $(*D) + bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@) +endef + +define bin2h + $(MKDIR) $(*D) + echo "extern const u8" `(echo $( $@ + echo "extern const u8" `(echo $(> $@ + echo "extern const u32" `(echo $(> $@ +endef + +vpath %.raw $(srcdir) +vpath %.pal $(srcdir) +vpath %.bin $(srcdir) + +%.o: %.raw + $(bin2o) + +%_raw.h: %.raw + $(bin2h) + +%.o: %.pal + $(bin2o) + +%_raw.h: %.pal + $(bin2h) + +%.o: %.bin + $(bin2o) + +%_raw.h: %.bin + $(bin2h) -MODULE_OBJS := +# Mark files which require the *_raw.h files manually (for now, at least) +$(MODULE)/arm9/source/dsmain.o: \ + $(MODULE)/arm9/data/icons_raw.h \ + $(MODULE)/arm9/data/keyboard_raw.h \ + $(MODULE)/arm9/data/keyboard_pal_raw.h +$(MODULE)/arm9/source/touchkeyboard.o: \ + $(MODULE)/arm9/data/keyboard_raw.h \ + $(MODULE)/arm9/data/keyboard_pal_raw.h \ + $(MODULE)/arm9/data/8x8font_tga_raw.h -# TODO: Should add more dirs to MODULE_DIRS so that "make distclean" can remove .deps dirs. MODULE_DIRS += \ - backends/platform/ds/ + backends/platform/ds/ \ + backends/platform/ds/arm7/source/ \ + backends/platform/ds/arm7/source/libcartreset/ \ + backends/platform/ds/arm9/source/ \ + backends/platform/ds/arm9/source/fat/ \ + backends/platform/ds/arm9/source/libcartreset/ # We don't use the rules.mk here on purpose OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS) diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp index c200e212cc..53987ff3fa 100644 --- a/backends/plugins/ds/ds-provider.cpp +++ b/backends/plugins/ds/ds-provider.cpp @@ -29,7 +29,7 @@ #include "backends/plugins/dynamic-plugin.h" #include "common/fs.h" -#include "backends/platform/ds/dsloader.h" +#include "backends/platform/ds/arm9/source/dsloader.h" class DSPlugin : public DynamicPlugin { -- cgit v1.2.3 From 6c8cae3c55c9734b847e30991bbd09dae1075bd1 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 7 Jul 2010 05:15:11 +0000 Subject: fixed some errors in makefile for plugin linking svn-id: r50733 --- backends/platform/ds/arm9/makefile | 41 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index ec1aa12dba..ecbd3fe9c3 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -18,7 +18,7 @@ ifeq ($(SCUMM_BUILD),k) DS_BUILD_K = 1 else ifeq ($(SCUMM_BUILD),j) - DS_BUILD_J = 1 + DS_BUILD_J = 1 else ifeq ($(SCUMM_BUILD),i) DS_BUILD_I = 1 @@ -72,7 +72,6 @@ else # TODO: Inherit the earth uses so much RAM that I have removed libmad in order to # claw some back. - else ifdef DS_BUILD_I @@ -116,7 +115,7 @@ USE_ARM_COSTUME_ASM = 1 #WRAP_MALLOC = 1 ifdef DS_BUILD_A - DEFINES = -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM + DEFINES += -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM LOGO = logoa.bmp ENABLE_SCUMM = $(ENABLED) DEFINES += -DENABLE_SCUMM=$(ENABLED) @@ -127,7 +126,7 @@ ifdef DS_BUILD_A endif ifdef DS_BUILD_B - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_B + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_B LOGO = logob.bmp ENABLE_SKY = $(ENABLED) ENABLE_QUEEN = $(ENABLED) @@ -135,14 +134,14 @@ ifdef DS_BUILD_B endif ifdef DS_BUILD_C - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_C + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_C LOGO = logoc.bmp ENABLE_AGOS = $(ENABLED) BUILD=scummvm-C endif ifdef DS_BUILD_D - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_D + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_D LOGO = logod.bmp ENABLE_GOB = $(ENABLED) ENABLE_CINE = $(ENABLED) @@ -151,42 +150,42 @@ ifdef DS_BUILD_D endif ifdef DS_BUILD_E - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_E + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_E LOGO = logoe.bmp ENABLE_SAGA = $(ENABLED) BUILD=scummvm-E endif ifdef DS_BUILD_F - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_F + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_F LOGO = logof.bmp ENABLE_KYRA = $(ENABLED) BUILD=scummvm-F endif ifdef DS_BUILD_G - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_G + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_G LOGO = logog.bmp ENABLE_LURE = $(ENABLED) BUILD=scummvm-G endif ifdef DS_BUILD_H - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_H + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_H LOGO = logoh.bmp ENABLE_PARALLACTION = $(ENABLED) BUILD=scummvm-H endif ifdef DS_BUILD_I - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_I + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_I LOGO = logoi.bmp ENABLE_MADE = $(ENABLED) BUILD=scummvm-I endif ifdef DS_BUILD_K - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_K + DEFINES += -DDS_NON_SCUMM_BUILD -DDS_BUILD_K LOGO = logok.bmp ENABLE_CRUISE = $(ENABLED) BUILD=scummvm-K @@ -275,12 +274,19 @@ ifdef USE_DEBUGGER LIBS += -ldsdebugger -ldswifi9 endif + +ifeq ($(DYNAMIC_MODULES),1) +DEFINES += -DDYNAMIC_MODULES +PRE_OBJS_FLAGS = -Wl,--whole-archive +POST_OBJS_FLAGS = -Wl,--no-whole-archive +endif + #-Lscumm -lscumm -Lbase -lbase -Lcommon -lcommon -Lgraphics -lgraphics -Lgui -lgui -Lsound -lsound -EXECUTABLE = scummvm.elf +EXECUTABLE = $(portdir)/$(BUILD)/scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = $(portdir)/plugin.ld $(portdir)/plugin.syms $(EXECUTABLE) -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-T$(portdir)/plugin.ld,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(portdir)/plugin.syms -lstdc++ -lc +PLUGIN_EXTRA_DEPS = $(portdir)/source/plugin.ld $(portdir)/source/plugin.syms $(EXECUTABLE) +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-T$(portdir)/source/plugin.ld,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf @@ -290,11 +296,6 @@ OBJCOPY = arm-eabi-objcopy AS = arm-eabi-as HAVE_GCC3 = true -ifeq ($(DYNAMIC_MODULES),1) -DEFINES += -DDYNAMIC_MODULES -PRE_OBJS_FLAGS = -Wl,--whole-archive -POST_OBJS_FLAGS = -Wl,--no-whole-archive -endif PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(portdir)/source/dsmain.o \ $(portdir)/../../../fs/ds/ds-fs.o $(portdir)/source/gbampsave.o $(portdir)/source/scummhelp.o\ -- cgit v1.2.3 From 7335e2fc6799478177e70e58645dea3a56883b5f Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 8 Jul 2010 21:40:26 +0000 Subject: fixed dependencies/paths/etc. in arm9/makefile to get engine plugins building; changed makefile to not clean before building further engines when building all engines; fixed syntax of plugin.ld svn-id: r50751 --- backends/platform/ds/arm9/makefile | 45 ++- backends/platform/ds/arm9/source/plugin.ld | 438 ++++++++++++++++------------- backends/platform/ds/makefile | 18 -- 3 files changed, 254 insertions(+), 247 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index ecbd3fe9c3..97094c8968 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -5,11 +5,7 @@ DYNAMIC_MODULES = 1 libndsdir = $(DEVKITPRO)/libnds #libndsdir = /home/neil/devkitpror21/libnds -ifeq ($(DYNAMIC_MODULES),1) - ENABLED = DYNAMIC_PLUGIN -else - ENABLED = STATIC_PLUGIN -endif +ENABLED = DYNAMIC_PLUGIN # Select the build by setting SCUMM_BUILD to a,b,c,d,e,f or g. # Anything else gets build a. @@ -70,8 +66,7 @@ ifdef DS_BUILD_F else ifdef DS_BUILD_E # TODO: Inherit the earth uses so much RAM that I have removed libmad in order to - # claw some back. - + # claw some back. else ifdef DS_BUILD_I @@ -118,8 +113,8 @@ ifdef DS_BUILD_A DEFINES += -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM LOGO = logoa.bmp ENABLE_SCUMM = $(ENABLED) - DEFINES += -DENABLE_SCUMM=$(ENABLED) - MODULES += engines/scumm + #DEFINES += -DENABLE_SCUMM=$(ENABLED) + #MODULES += engines/scumm USE_ARM_GFX_ASM = 1 BUILD=scummvm-A @@ -206,7 +201,7 @@ endif # BUILD=scummvm-K #endif -ARM7BIN := -7 $(CURDIR)/../../arm7/arm7.bin +ARM7BIN := -7 $(CURDIR)/../arm7/arm7.bin CC = arm-eabi-gcc CXX = arm-eabi-g++ @@ -259,13 +254,11 @@ ifdef WRAP_MALLOC DEFINES += -DWRAP_MALLOC endif -INCLUDES= -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/engines \ +INCLUDES= -I$(portdir) -I$(srcdir) -I$(srcdir)/engines \ -I$(portdir)/data -I$(portdir)/../commoninclude \ -I$(portdir)/source -I$(portdir)/source/mad -I$(portdir)/source/libcartreset \ -I$(libndsdir)/include -include $(srcdir)/common/scummsys.h -CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP - LIBS = -lm -L$(libndsdir)/lib -L$(portdir)/lib -lnds9 ifdef USE_MAD LIBS += -lmad @@ -274,7 +267,6 @@ ifdef USE_DEBUGGER LIBS += -ldsdebugger -ldswifi9 endif - ifeq ($(DYNAMIC_MODULES),1) DEFINES += -DDYNAMIC_MODULES PRE_OBJS_FLAGS = -Wl,--whole-archive @@ -282,11 +274,11 @@ POST_OBJS_FLAGS = -Wl,--no-whole-archive endif #-Lscumm -lscumm -Lbase -lbase -Lcommon -lcommon -Lgraphics -lgraphics -Lgui -lgui -Lsound -lsound -EXECUTABLE = $(portdir)/$(BUILD)/scummvm.elf +EXECUTABLE = scummvm.elf#$(portdir)/$(BUILD)/scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg PLUGIN_EXTRA_DEPS = $(portdir)/source/plugin.ld $(portdir)/source/plugin.syms $(EXECUTABLE) -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-T$(portdir)/source/plugin.ld,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu -Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf @@ -296,7 +288,6 @@ OBJCOPY = arm-eabi-objcopy AS = arm-eabi-as HAVE_GCC3 = true - PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(portdir)/source/dsmain.o \ $(portdir)/../../../fs/ds/ds-fs.o $(portdir)/source/gbampsave.o $(portdir)/source/scummhelp.o\ $(portdir)/source/osystem_ds.o $(portdir)/source/ramsave.o\ @@ -360,11 +351,10 @@ OPT_SIZE := -Os -mthumb OBJS := $(DATA_OBJS) $(LIBCARTRESET_OBJS) $(PORT_OBJS) $(COMPRESSOR_OBJS) $(FAT_OBJS) -MODULE_DIRS += ./ +MODULE_DIRS += . -ndsall: - @[ -d $(BUILD) ] || mkdir -p $(BUILD) - make -C ./$(BUILD) -f ../makefile scummvm.nds +ndsall: plugins + make -f makefile scummvm.nds include $(srcdir)/Makefile.common @@ -373,16 +363,15 @@ semiclean: clean: $(RM) $(OBJS) $(EXECUTABLE) - rm -fr $(BUILD) + rm -rf gui engines sound common plugins base backends graphics scummvm.nds scummvm.elf scummvm-stripped.elf scummvm.ds.gba *.h plugin_dist : - find . -name '*.plg' | while read p; do \ - sh-elf-strip -g -o "`basename \"$$p\" | tr '[:lower:]' '[:upper:]'`" "$$p"; \ + for p in $(PLUGINS); do \ + arm-elf-strip -g -o "`basename \"$$p\" | LC_CTYPE=C tr '[:lower:]' '[:upper:]'`" "$$p"; \ done dist : SCUMMVM.BIN plugins plugin_dist - #--------------------------------------------------------------------------------- # canned command sequence for binary data #--------------------------------------------------------------------------------- @@ -474,9 +463,9 @@ endef #--------------------------------------------------------------------------------- %.nds: %.bin - @echo ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../../$(LOGO) "$(shell basename $@);ScummVM $(VERSION);DS Port" - ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../../$(LOGO) "$(shell basename $@);ScummVM $(VERSION);DS Port" - dsbuild $@ -l ../ndsloader.bin + @echo ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../$(LOGO) "$(shell basename $@);ScummVM $(VERSION);DS Port" + ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../$(LOGO) "$(shell basename $@);ScummVM $(VERSION);DS Port" + dsbuild $@ -l ndsloader.bin padbin 16 $(basename $@).ds.gba diff --git a/backends/platform/ds/arm9/source/plugin.ld b/backends/platform/ds/arm9/source/plugin.ld index 65ba0496c7..0296dd571d 100644 --- a/backends/platform/ds/arm9/source/plugin.ld +++ b/backends/platform/ds/arm9/source/plugin.ld @@ -1,216 +1,252 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) + /* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ PHDRS { plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ } + +MEMORY { + rom : ORIGIN = 0x08000000, LENGTH = 32M + ewram : ORIGIN = 0x02000000, LENGTH = 4M - 4k + dtcm : ORIGIN = 0x0b000000, LENGTH = 16K + vectors : ORIGIN = 0x01000000, LENGTH = 256 + itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256 +} + +__vectors_start = ORIGIN(vectors); +__itcm_start = ORIGIN(itcm); +__ewram_end = ORIGIN(ewram) + LENGTH(ewram); +__eheap_end = ORIGIN(ewram) + LENGTH(ewram); +__dtcm_start = ORIGIN(dtcm); +__dtcm_top = ORIGIN(dtcm) + LENGTH(dtcm); +__irq_flags = __dtcm_top - 0x08; +__irq_vector = __dtcm_top - 0x04; + +__sp_svc = __dtcm_top - 0x100; +__sp_irq = __sp_svc - 0x100; +__sp_usr = __sp_irq - 0x100; + SECTIONS { - /* Read-only sections, merged into text segment: */ - . = 0; - .interp : { *(.interp) } : plugin /*The ": plugin" tells the linker to assign this and - the following sections to the "plugin" segment*/ - .note.gnu.build-id : { *(.note.gnu.build-id) } - .hash : { *(.hash) } - .gnu.hash : { *(.gnu.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.gnu.linkonce.d.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.*) - PROVIDE_HIDDEN (__rel_iplt_start = .); - *(.rel.iplt) - PROVIDE_HIDDEN (__rel_iplt_end = .); - PROVIDE_HIDDEN (__rela_iplt_start = .); - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .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.*) - PROVIDE_HIDDEN (__rel_iplt_start = .); - PROVIDE_HIDDEN (__rel_iplt_end = .); - PROVIDE_HIDDEN (__rela_iplt_start = .); - *(.rela.iplt) - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .rel.plt : - { - *(.rel.plt) - } - .rela.plt : - { - *(.rela.plt) - } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .iplt : { *(.iplt) } - .text : - { - *(.text.unlikely .text.*_unlikely) - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + .init : + { + __text_start = . ; + KEEP (*(.init)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >ewram :plugin = 0xff + + .plt : { *(.plt) } >ewram = 0xff + + .text : /* ALIGN (4): */ + { + *(EXCLUDE_FILE (*.itcm*) .text) + + *(.text.*) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >ewram = 0xff + + .fini : + { + KEEP (*(.fini)) + } >ewram =0xff + + __text_end = . ; + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + SORT(CONSTRUCTORS) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >ewram = 0xff + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram __exidx_start = .; - .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram __exidx_end = .; - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.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(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); - /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } - /* Thread Local Storage sections */ - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } + /* 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)) } >ewram = 0xff + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); .init_array : { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - } + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + } >ewram = 0xff + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); .fini_array : { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__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* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } - .dynamic : { *(.dynamic) } - .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } - .data : - { - __data_start = . ; - *(.data .data.* .gnu.linkonce.d.*) - 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. - FIXME: Why do we need it? When there is no .bss section, we don't - pad the .data section. */ - . = ALIGN(. != 0 ? 32 / 8 : 1); - } - _bss_end__ = . ; __bss_end__ = . ; - . = ALIGN(32 / 8); - . = ALIGN(32 / 8); - __end__ = . ; - _end = .; PROVIDE (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) } - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } - .debug_ranges 0 : { *(.debug_ranges) } - .stack 0x80000 : - { - _stack = .; - *(.stack) - } - .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } - .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } - /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + } >ewram = 0xff + PROVIDE (__fini_array_end = .); + + .ctors : + { + /* gcc uses crtbegin.o to find the start of the constructors, so + we make sure it is first. Because this is a wildcard, it + doesn't matter if the user does not actually link against + crtbegin.o; the linker won't look for a file to match a + wildcard. The wildcard also means that it doesn't matter which + directory crtbegin.o is in. */ + ___plugin_ctors = .; + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + ___plugin_ctors_end = .; + } >ewram = 0xff + + .dtors : + { + ___plugin_dtors = .; + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + ___plugin_dtors_end = .; + } >ewram = 0xff + + .eh_frame : + { + KEEP (*(.eh_frame)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >ewram = 0xff + + .gcc_except_table : + { + *(.gcc_except_table) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >ewram = 0xff + .jcr : { KEEP (*(.jcr)) } >ewram = 0 + .got : { *(.got.plt) *(.got) *(.rel.got) } >ewram = 0 + + .ewram ALIGN(4) : + { + __ewram_start = ABSOLUTE(.) ; + *(.ewram) + *ewram.*(.text) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >ewram = 0xff + + + .data ALIGN(4) : + { + __data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + CONSTRUCTORS + . = ALIGN(4); + __data_end = ABSOLUTE(.) ; + } >ewram = 0xff + + + __dtcm_lma = . ; + __bss_vma = . ; + + .dtcm __dtcm_start : AT (__dtcm_lma) + { + *(.dtcm) + *(.dtcm.*) + . = ALIGN(4); + __dtcm_end = ABSOLUTE(.); + } >dtcm = 0xff + + + __itcm_lma = __dtcm_lma + SIZEOF(.dtcm); + + .itcm __itcm_start : AT (__itcm_lma) + { + *(.itcm) + *itcm.*(.text) + . = ALIGN(4); + __itcm_end = ABSOLUTE(.); + } >itcm = 0xff + + __vectors_lma = __itcm_lma + SIZEOF(.itcm); + + .vectors __vectors_start : AT (__vectors_lma) + { + *(.vectors) + *vectors.*(.text) + . = ALIGN(4); + __vectors_end = ABSOLUTE(.); + } >vectors = 0xff + + .sbss __dtcm_end (NOLOAD): + { + __sbss_start = ABSOLUTE(.); + __sbss_start__ = ABSOLUTE(.); + *(.sbss) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + __sbss_end = ABSOLUTE(.); + } >dtcm + + .bss __bss_vma (NOLOAD): + { + __bss_start = ABSOLUTE(.); + __bss_start__ = ABSOLUTE(.); + *(.dynbss) + *(.gnu.linkonce.b*) + *(.bss*) + *(COMMON) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + __bss_end = ABSOLUTE(.) ; + __bss_end__ = __bss_end ; + } AT>ewram + + + _end = __bss_end__ ; + __end__ = __bss_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) } + .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) } + .stack 0x80000 : { _stack = .; *(.stack) } + /* These must appear regardless of . */ } diff --git a/backends/platform/ds/makefile b/backends/platform/ds/makefile index 7bfd419c14..f6f9033161 100644 --- a/backends/platform/ds/makefile +++ b/backends/platform/ds/makefile @@ -22,43 +22,25 @@ export: allbuilds: $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=a - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=b - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=c - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=d - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=e - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=f - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=g - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=h - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=i - $(MAKE) semiclean $(MAKE) all SCUMM_BUILD=k allbuildssafe: $(MAKE) clean SCUMM_BUILD=a $(MAKE) all SCUMM_BUILD=a - $(MAKE) clean SCUMM_BUILD=b $(MAKE) all SCUMM_BUILD=b - $(MAKE) clean SCUMM_BUILD=c $(MAKE) all SCUMM_BUILD=c - $(MAKE) clean SCUMM_BUILD=d $(MAKE) all SCUMM_BUILD=d - $(MAKE) clean SCUMM_BUILD=e $(MAKE) all SCUMM_BUILD=e - $(MAKE) clean SCUMM_BUILD=f $(MAKE) all SCUMM_BUILD=f - $(MAKE) clean SCUMM_BUILD=g $(MAKE) all SCUMM_BUILD=g - $(MAKE) clean SCUMM_BUILD=h $(MAKE) all SCUMM_BUILD=h - $(MAKE) clean SCUMM_BUILD=i $(MAKE) all SCUMM_BUILD=i - $(MAKE) clean SCUMM_BUILD=k $(MAKE) all SCUMM_BUILD=k -- cgit v1.2.3 From eced5b3c82c93d9febb14b5fe4eba34d5ce171b8 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 13 Jul 2010 03:22:42 +0000 Subject: removed --gc-sections linker flags so functions/data needed after run-time linking of plugins won't be mistakenly garbage-collected during building svn-id: r50838 --- backends/platform/ds/arm9/makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 97094c8968..706cf6549f 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -1,6 +1,7 @@ srcdir ?= . DEPDIR := .deps +VERBOSE_BUILD = 1 DYNAMIC_MODULES = 1 libndsdir = $(DEVKITPRO)/libnds #libndsdir = /home/neil/devkitpror21/libnds @@ -247,7 +248,7 @@ endif DEFINES += -DREDUCE_MEMORY_USAGE -LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections +LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt#-Wl,--gc-sections ifdef WRAP_MALLOC LDFLAGS += -Wl,--wrap,malloc @@ -274,11 +275,11 @@ POST_OBJS_FLAGS = -Wl,--no-whole-archive endif #-Lscumm -lscumm -Lbase -lbase -Lcommon -lcommon -Lgraphics -lgraphics -Lgui -lgui -Lsound -lsound -EXECUTABLE = scummvm.elf#$(portdir)/$(BUILD)/scummvm.elf +EXECUTABLE = scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg PLUGIN_EXTRA_DEPS = $(portdir)/source/plugin.ld $(portdir)/source/plugin.syms $(EXECUTABLE) -PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu -Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o +PLUGIN_LDFLAGS += -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf -- cgit v1.2.3 From 9d06726b6904f57ca62f3ff89e8c609acbe13ee2 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 13 Jul 2010 03:24:06 +0000 Subject: Started changing loader to use Common::SeekableReadStream svn-id: r50839 --- backends/platform/ds/arm9/source/dsloader.cpp | 28 ++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index 543d3648b5..ad5160a5b2 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -31,19 +31,26 @@ #include #include #include -#include +#include + +#include "common/str.h" +#include "common/util.h" +#include "backends/fs/stdiostream.h" +#include "backends/fs/ds/ds-fs.h" +#include "dsmain.h" +#include "fat/gba_nds_fat.h" #include "backends/platform/ds/arm9/source/dsloader.h" #define __DS_DEBUG_PLUGINS__ #ifdef __DS_DEBUG_PLUGINS__ -#define DBG(x,...) printf(x, ## __VA_ARGS__) +#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) #else #define DBG(x,...) #endif -#define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__) +#define seterror(x,...) consolePrintf(x, ## __VA_ARGS__) // Expel the symbol table from memory void DLObject::discard_symtab() { @@ -333,7 +340,7 @@ bool DLObject::load(int fd) { for (int i = 0; i < ehdr.e_phnum; i++) { // Load our 2 segments - fprintf(stderr, "Loading segment %d\n", i); + DBG("Loading segment %d\n", i); if (readProgramHeaders(fd, &ehdr, &phdr, i) == false) return false; @@ -365,16 +372,22 @@ bool DLObject::load(int fd) { bool DLObject::open(const char *path) { int fd; + + Common::SeekableReadStream* DLFile; //TODO: reimplement everything with SeekableReadStream instead of fd void *ctors_start, *ctors_end; - DBG(("open(\"%s\")\n", path)); + DBG("open(\"%s\")\n", path); - if ((fd = ::open(path, O_RDONLY)) < 0) { + Common::FSNode file(path); + + if (!(DLFile = file.createReadStream())) { seterror("%s not found.", path); return false; } - // Try to load and relocate + DBG("%s found!\n", path); + + /*Try to load and relocate*/ if (!load(fd)) { ::close(fd); unload(); @@ -403,6 +416,7 @@ bool DLObject::open(const char *path) { (**f)(); DBG(("%s opened ok.\n", path)); + return false; return true; } -- cgit v1.2.3 From 4d92cefb2fd146d4d56b23dd9d11fb5a30899b2d Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 13 Jul 2010 06:48:43 +0000 Subject: Changed loader to use Common::SeekableReadStream (compiles but doesn't run and needs polishing) svn-id: r50843 --- backends/platform/ds/arm9/source/dsloader.cpp | 77 +++++++++++++-------------- backends/platform/ds/arm9/source/dsloader.h | 18 +++---- 2 files changed, 45 insertions(+), 50 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index ad5160a5b2..595b4fbc54 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -33,12 +33,8 @@ #include #include -#include "common/str.h" -#include "common/util.h" -#include "backends/fs/stdiostream.h" +//#include "backends/fs/stdiostream.h" #include "backends/fs/ds/ds-fs.h" -#include "dsmain.h" -#include "fat/gba_nds_fat.h" #include "backends/platform/ds/arm9/source/dsloader.h" @@ -71,12 +67,12 @@ void DLObject::unload() { /** * Follow the instruction of a relocation section. * - * @param fd File Descriptor + * @param DLFile SeekableReadStream of File * @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) { +bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { Elf32_Rela *rela; //relocation entry // Allocate memory for relocation table @@ -86,8 +82,8 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * } // Read in our relocation table - if (lseek(fd, offset, SEEK_SET) < 0 || - read(fd, rela, size) != (ssize_t)size) { + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rela, size) != (ssize_t)size) { seterror("Relocation table load failed."); free(rela); return false; @@ -121,10 +117,10 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * return true; } -bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { +bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { // Start reading the elf header. Check for errors - if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || + if (DLFile->read(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 @@ -140,11 +136,11 @@ bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { return true; } -bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { +bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, 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)) { + if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || + DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { seterror("Program header load failed."); return false; } @@ -162,7 +158,7 @@ bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, in } -bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { +bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { char *baseAddress = 0; @@ -186,8 +182,8 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { 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) { + if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || + DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { seterror("Segment load failed."); return false; } @@ -195,7 +191,7 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { return true; } -Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { +Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { Elf32_Shdr *shdr = NULL; @@ -206,8 +202,8 @@ Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { } // Read from file into section headers - if (lseek(fd, ehdr->e_shoff, SEEK_SET) < 0 || - read(fd, shdr, ehdr->e_shnum * sizeof(*shdr)) != + if (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || + DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != (ssize_t)(ehdr->e_shnum * sizeof(*shdr))) { seterror("Section headers load failed."); return NULL; @@ -216,7 +212,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { return shdr; } -int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, 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++) { @@ -244,8 +240,8 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { } // Read symbol table into memory - if (lseek(fd, shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || - read(fd, _symtab, shdr[_symtab_sect].sh_size) != + if (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || + DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != (ssize_t)shdr[_symtab_sect].sh_size) { seterror("Symbol table load failed."); return -1; @@ -259,7 +255,7 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { } -bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { +bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr) { int string_sect = shdr[_symtab_sect].sh_link; @@ -270,8 +266,8 @@ bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { } // Read string table into memory - if (lseek(fd, shdr[string_sect].sh_offset, SEEK_SET) < 0 || - read(fd, _strtab, shdr[string_sect].sh_size) != + if (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || + DLFile->read(_strtab, shdr[string_sect].sh_size) != (ssize_t)shdr[string_sect].sh_size) { seterror("Symbol table strings load failed."); return false; @@ -302,7 +298,7 @@ void DLObject::relocateSymbols(Elf32_Addr offset) { DBG("Relocated %d symbols.\n",relocCount); } -bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +bool DLObject::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++) { @@ -316,7 +312,7 @@ bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { 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)) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { return false; } @@ -326,7 +322,7 @@ bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { return true; } -bool DLObject::load(int fd) { +bool DLObject::load(Common::SeekableReadStream* DLFile) { Elf32_Ehdr ehdr; Elf32_Phdr phdr; Elf32_Shdr *shdr; @@ -334,7 +330,7 @@ bool DLObject::load(int fd) { //int symtab_sect = -1; - if (readElfHeader(fd, &ehdr) == false) { + if (readElfHeader(DLFile, &ehdr) == false) { return false; } @@ -342,26 +338,26 @@ bool DLObject::load(int fd) { DBG("Loading segment %d\n", i); - if (readProgramHeaders(fd, &ehdr, &phdr, i) == false) + if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) return false; - if (!loadSegment(fd, &phdr)) + if (!loadSegment(DLFile, &phdr)) return false; } - if ((shdr = loadSectionHeaders(fd, &ehdr)) == NULL) + if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == NULL) ret = false; - if (ret && ((_symtab_sect = loadSymbolTable(fd, &ehdr, shdr)) < 0)) + if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) ret = false; - if (ret && (loadStringTable(fd, shdr) == false)) + if (ret && (loadStringTable(DLFile, shdr) == false)) ret = false; if (ret) relocateSymbols((Elf32_Addr)_segment); // Offset by our segment allocated address - if (ret && (relocateRels(fd, &ehdr, shdr) == false)) + if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) ret = false; free(shdr); @@ -371,9 +367,8 @@ bool DLObject::load(int fd) { } bool DLObject::open(const char *path) { - int fd; - Common::SeekableReadStream* DLFile; //TODO: reimplement everything with SeekableReadStream instead of fd + Common::SeekableReadStream* DLFile; void *ctors_start, *ctors_end; DBG("open(\"%s\")\n", path); @@ -388,13 +383,13 @@ bool DLObject::open(const char *path) { DBG("%s found!\n", path); /*Try to load and relocate*/ - if (!load(fd)) { - ::close(fd); + if (!load(DLFile)) { + //DLFile->finalize(); unload(); return false; } - ::close(fd); + //DLFile->finalize(); //TODO: flush data cache diff --git a/backends/platform/ds/arm9/source/dsloader.h b/backends/platform/ds/arm9/source/dsloader.h index f8a3cdefa4..ddb85900e8 100644 --- a/backends/platform/ds/arm9/source/dsloader.h +++ b/backends/platform/ds/arm9/source/dsloader.h @@ -44,17 +44,17 @@ class DLObject { void seterror(const char *fmt, ...); void unload(); - bool relocate(int fd, unsigned long offset, unsigned long size, void *relSegment); - bool load(int fd); + bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + bool load(Common::SeekableReadStream* DLFile); - 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); + bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); void relocateSymbols(Elf32_Addr offset); - bool relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: bool open(const char *path); -- cgit v1.2.3 From 6e5b0def209e6d98975ceabd429ea0117854e27e Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 13 Jul 2010 20:20:29 +0000 Subject: formatting fix for dsloader.h svn-id: r50852 --- backends/platform/ds/arm9/source/dsloader.h | 64 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.h b/backends/platform/ds/arm9/source/dsloader.h index ddb85900e8..1d824792bc 100644 --- a/backends/platform/ds/arm9/source/dsloader.h +++ b/backends/platform/ds/arm9/source/dsloader.h @@ -31,49 +31,49 @@ #define MAXDLERRLEN 80 class DLObject { - protected: - char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */ +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; + void *_segment, *_symtab; + char *_strtab; + int _symbol_cnt; + int _symtab_sect; + void *_dtors_start, *_dtors_end; - int _segmentSize; + int _segmentSize; - void seterror(const char *fmt, ...); - void unload(); - bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - bool load(Common::SeekableReadStream* DLFile); + void seterror(const char *fmt, ...); + void unload(); + bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + bool load(Common::SeekableReadStream* DLFile); - bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); - void relocateSymbols(Elf32_Addr offset); - bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); + void relocateSymbols(Elf32_Addr offset); + bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - public: - bool open(const char *path); - bool close(); - void *symbol(const char *name); - void discard_symtab(); +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) {} + 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); + 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 /* DS_LOADER_H */ -- cgit v1.2.3 From 264cb839dabb40081d6713dbc0b4c9606dd98234 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 14 Jul 2010 03:55:11 +0000 Subject: changed Elf32_Rela to Elf32_Rel svn-id: r50868 --- backends/platform/ds/arm9/source/elf32.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/elf32.h b/backends/platform/ds/arm9/source/elf32.h index 2b695c917d..c7971891fe 100644 --- a/backends/platform/ds/arm9/source/elf32.h +++ b/backends/platform/ds/arm9/source/elf32.h @@ -113,7 +113,7 @@ typedef struct { // sh_type values #define SHT_NULL 0 /* Inactive section */ -#define SHT_PROGBITS 1 /* Proprietary */ +#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 */ @@ -165,14 +165,13 @@ typedef struct { #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 +#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; +} Elf32_Rel; // Access macros for the relocation info #define REL_TYPE(x) ((unsigned char) (x)) /* Extract relocation type */ -- cgit v1.2.3 From 03b188468bf905ef0805f9863f6d5411828211dd Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 14 Jul 2010 03:57:36 +0000 Subject: various dsloader fixes, including initializing _symtab_sect to -1 in the header svn-id: r50869 --- backends/platform/ds/arm9/source/dsloader.cpp | 43 ++++++++++++++++----------- backends/platform/ds/arm9/source/dsloader.h | 4 ++- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index 595b4fbc54..a4fe0573d2 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -73,30 +73,30 @@ void DLObject::unload() { * */ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rela *rela; //relocation entry + Elf32_Rel *rel = NULL; //relocation entry // Allocate memory for relocation table - if (!(rela = (Elf32_Rela *)malloc(size))) { + if (!(rel = (Elf32_Rel *)malloc(size))) { seterror("Out of memory."); return false; } // Read in our relocation table if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rela, size) != (ssize_t)size) { + DLFile->read(rel, size) != (ssize_t)size) { seterror("Relocation table load failed."); - free(rela); + free(rel); return false; } // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rela); + int cnt = size / sizeof(*rel); + + DBG("# of relocation entries is %d.\n", cnt); // TODO: Loop over relocation entries for (int i = 0; i < cnt; i++) { - DBG("attempting to relocate!"); - //Elf32_Sym *sym = ???; //void *target = ???; @@ -107,13 +107,13 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset //break; // default: //seterror("Unknown relocation type %d.", ?? ?); - free(rela); + free(rel); return false; // } } - free(rela); + free(rel); return true; } @@ -170,17 +170,24 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) 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; + DBG("base address is %p\n", baseAddress); + DBG("_segmentSize is %p\n", _segmentSize); + // 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); } + + DBG("Reading the segment into memory\n"); + // Read the segment into memory if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { @@ -188,6 +195,8 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) return false; } + DBG("Segment has been read into memory\n"); + return true; } @@ -288,8 +297,8 @@ void DLObject::relocateSymbols(Elf32_Addr offset) { 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); + //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); } @@ -307,7 +316,7 @@ bool DLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr //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 + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 @@ -328,13 +337,11 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { Elf32_Shdr *shdr; bool ret = true; - //int symtab_sect = -1; - if (readElfHeader(DLFile, &ehdr) == false) { return false; } - for (int i = 0; i < ehdr.e_phnum; i++) { // Load our 2 segments + for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments DBG("Loading segment %d\n", i); @@ -389,9 +396,11 @@ bool DLObject::open(const char *path) { return false; } + DBG("loaded!/n"); + //DLFile->finalize(); - //TODO: flush data cache + //TODO?: flush data cache ctors_start = symbol("___plugin_ctors"); ctors_end = symbol("___plugin_ctors_end"); @@ -411,7 +420,7 @@ bool DLObject::open(const char *path) { (**f)(); DBG(("%s opened ok.\n", path)); - return false; + return true; } diff --git a/backends/platform/ds/arm9/source/dsloader.h b/backends/platform/ds/arm9/source/dsloader.h index 1d824792bc..ba8499d14d 100644 --- a/backends/platform/ds/arm9/source/dsloader.h +++ b/backends/platform/ds/arm9/source/dsloader.h @@ -27,6 +27,7 @@ #define DS_LOADER_H #include "elf32.h" +#include "common/list.h" #define MAXDLERRLEN 80 @@ -63,7 +64,8 @@ public: void discard_symtab(); DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _segment(NULL), _symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _dtors_start(NULL), _dtors_end(NULL) {} + _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), + _segmentSize(0) {} }; #define RTLD_LAZY 0 -- cgit v1.2.3 From 625230a8a9b9bb4411636a5e4c21d9157798efba Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 15 Jul 2010 02:45:49 +0000 Subject: restructured ps2loader to use Common::SeekableReadStream instead of a file descriptor svn-id: r50903 --- backends/platform/ps2/ps2loader.cpp | 80 ++++++++++++++++++------------------- backends/platform/ps2/ps2loader.h | 20 +++++----- 2 files changed, 48 insertions(+), 52 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp index 9ed4a373b3..f03fa1f282 100644 --- a/backends/platform/ps2/ps2loader.cpp +++ b/backends/platform/ps2/ps2loader.cpp @@ -76,13 +76,13 @@ void DLObject::unload() { /** * Follow the instruction of a relocation section. * - * @param fd File Descriptor + * @param DLFile SeekableReadStream of File * @param offset Offset into the File * @param size Size of relocation section * @param relSegment Base address of relocated segment in memory (memory offset) * */ -bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void *relSegment) { +bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { Elf32_Rel *rel = NULL; // relocation entry // Allocate memory for relocation table @@ -92,8 +92,8 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * } // Read in our relocation table - if (lseek(fd, offset, SEEK_SET) < 0 || - read(fd, rel, size) != (ssize_t)size) { + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != (ssize_t)size) { seterror("Relocation table load failed."); free(rel); return false; @@ -266,9 +266,9 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void * return true; } -bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { +bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { // Start reading the elf header. Check for errors - if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || + if (DLFile->read(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_MIPS || // Check for MIPS machine type @@ -284,10 +284,10 @@ bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) { return true; } -bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { +bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, 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)) { + if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || + DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { seterror("Program header load failed."); return false; } @@ -305,7 +305,7 @@ bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, in } -bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { +bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { char *baseAddress = 0; @@ -342,8 +342,8 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { 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) { + if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || + DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { seterror("Segment load failed."); return false; } @@ -352,7 +352,7 @@ bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { } -Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { +Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { Elf32_Shdr *shdr = NULL; @@ -363,8 +363,8 @@ Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { } // Read from file into section headers - if (lseek(fd, ehdr->e_shoff, SEEK_SET) < 0 || - read(fd, shdr, ehdr->e_shnum * sizeof(*shdr)) != + if (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || + DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != (ssize_t)(ehdr->e_shnum * sizeof(*shdr))) { seterror("Section headers load failed."); return NULL; @@ -373,7 +373,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { return shdr; } -int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, 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++) { @@ -404,8 +404,8 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { } // Read symbol table into memory - if (lseek(fd, shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || - read(fd, _symtab, shdr[_symtab_sect].sh_size) != + if (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || + DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != (ssize_t)shdr[_symtab_sect].sh_size) { seterror("Symbol table load failed."); return -1; @@ -419,7 +419,7 @@ int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { } -bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { +bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr) { int string_sect = shdr[_symtab_sect].sh_link; @@ -430,8 +430,8 @@ bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { } // Read string table into memory - if (lseek(fd, shdr[string_sect].sh_offset, SEEK_SET) < 0 || - read(fd, _strtab, shdr[string_sect].sh_size) != + if (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || + DLFile->read(_strtab, shdr[string_sect].sh_size) != (ssize_t)shdr[string_sect].sh_size) { seterror("Symbol table strings load failed."); return false; @@ -468,7 +468,7 @@ void DLObject::relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset) { DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); } -bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +bool DLObject::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++) { @@ -482,11 +482,11 @@ bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, _segment)) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { return false; } } else { // In Shorts segment - if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { return false; } } @@ -498,7 +498,7 @@ bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { } -bool DLObject::load(int fd) { +bool DLObject::load(Common::SeekableReadStream* DLFile) { fprintf(stderr, "In DLObject::load\n"); Elf32_Ehdr ehdr; // ELF header @@ -506,7 +506,7 @@ bool DLObject::load(int fd) { Elf32_Shdr *shdr; // Section header bool ret = true; - if (readElfHeader(fd, &ehdr) == false) { + if (readElfHeader(DLFile, &ehdr) == false) { return false; } @@ -514,26 +514,26 @@ bool DLObject::load(int fd) { fprintf(stderr, "Loading segment %d\n", i); - if (readProgramHeaders(fd, &ehdr, &phdr, i) == false) + if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) return false; - if (!loadSegment(fd, &phdr)) + if (!loadSegment(DLFile, &phdr)) return false; } - if ((shdr = loadSectionHeaders(fd, &ehdr)) == NULL) + if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == NULL) ret = false; - if (ret && ((_symtab_sect = loadSymbolTable(fd, &ehdr, shdr)) < 0)) + if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) ret = false; - if (ret && (loadStringTable(fd, shdr) == false)) + if (ret && (loadStringTable(DLFile, shdr) == false)) ret = false; if (ret) relocateSymbols((Elf32_Addr)_segment, _shortsSegment->getOffset()); // Offset by our segment allocated address - if (ret && (relocateRels(fd, &ehdr, shdr) == false)) + if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) ret = false; free(shdr); @@ -542,7 +542,7 @@ bool DLObject::load(int fd) { } bool DLObject::open(const char *path) { - int fd; + Common::SeekableReadStream* DLFile; void *ctors_start, *ctors_end; DBG("open(\"%s\")\n", path); @@ -551,25 +551,21 @@ bool DLObject::open(const char *path) { _gpVal = (unsigned int) & _gp; DBG("_gpVal is %x\n", _gpVal); - //PS2 has no "PowerMan" for suspending the system. - //PowerMan.beginCriticalSection(); + Common::FSNode file(path); - if ((fd = ::open(path, O_RDONLY)) < 0) { + if (!(DLFile = file.createReadStream())) { seterror("%s not found.", path); return false; } // Try to load and relocate - if (!load(fd)) { - ::close(fd); + if (!load(DLFile)) { + //::close(fd); unload(); return false; } - ::close(fd); - - //PS2 has no "PowerMan" for suspending the system. - //PowerMan.endCriticalSection(); + //::close(fd); // flush data cache DBG("Flushing data cache"); diff --git a/backends/platform/ps2/ps2loader.h b/backends/platform/ps2/ps2loader.h index 7c412e7b05..cb4e2416eb 100644 --- a/backends/platform/ps2/ps2loader.h +++ b/backends/platform/ps2/ps2loader.h @@ -99,17 +99,17 @@ protected: void seterror(const char *fmt, ...); void unload(); - bool relocate(int fd, unsigned long offset, unsigned long size, void *); - 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); + bool relocate(Common::SeekableReadStream, unsigned long offset, unsigned long size, void *); + bool load(Common::SeekableReadStream); + + bool readElfHeader(Common::SeekableReadStream, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool loadSegment(Common::SeekableReadStream, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream, Elf32_Shdr *shdr); void relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset); - bool relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool relocateRels(Common::SeekableReadStream, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: bool open(const char *path); -- cgit v1.2.3 From e6c9dc4d6c03df353943dc2f552e77a978b0eaa4 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 15 Jul 2010 05:07:59 +0000 Subject: Fixed function prototype typos svn-id: r50909 --- backends/platform/ps2/ps2loader.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/ps2loader.h b/backends/platform/ps2/ps2loader.h index cb4e2416eb..cfaf4e4f55 100644 --- a/backends/platform/ps2/ps2loader.h +++ b/backends/platform/ps2/ps2loader.h @@ -99,17 +99,17 @@ protected: void seterror(const char *fmt, ...); void unload(); - bool relocate(Common::SeekableReadStream, unsigned long offset, unsigned long size, void *); - bool load(Common::SeekableReadStream); - - bool readElfHeader(Common::SeekableReadStream, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - bool loadSegment(Common::SeekableReadStream, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream, Elf32_Shdr *shdr); + bool relocate(Common::SeekableReadStream*, unsigned long offset, unsigned long size, void *); + bool load(Common::SeekableReadStream*); + + bool readElfHeader(Common::SeekableReadStream*, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream*, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool loadSegment(Common::SeekableReadStream*, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream*, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream*, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream*, Elf32_Shdr *shdr); void relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset); - bool relocateRels(Common::SeekableReadStream, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool relocateRels(Common::SeekableReadStream*, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: bool open(const char *path); -- cgit v1.2.3 From 4da73f4a38d8abb2ab5a5d032cd47633a61d595d Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 15 Jul 2010 05:25:19 +0000 Subject: added necessary #includes to loader svn-id: r50910 --- backends/platform/ps2/ps2loader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp index f03fa1f282..0f46b2ad45 100644 --- a/backends/platform/ps2/ps2loader.cpp +++ b/backends/platform/ps2/ps2loader.cpp @@ -32,7 +32,8 @@ #include #include -//#include do these exist? +#include "savefilemgr.h" +#include "backends/fs/ps2/ps2-fs-factory.h" #include "backends/platform/ps2/ps2loader.h" -- cgit v1.2.3 From d5f442dc6bd63cfcdef2eae88b7e10f9671436ba Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 16 Jul 2010 20:44:11 +0000 Subject: put in initial relocations for R_ARM_ABS32, R_ARM_THM_CALL and R_ARM_V4BX svn-id: r50942 --- backends/platform/ds/arm9/source/dsloader.cpp | 83 +++++++++++++++++++++------ backends/platform/ds/arm9/source/elf32.h | 11 +--- 2 files changed, 70 insertions(+), 24 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index a4fe0573d2..2f953cc33b 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -35,6 +34,7 @@ //#include "backends/fs/stdiostream.h" #include "backends/fs/ds/ds-fs.h" +#include "dsmain.h" #include "backends/platform/ds/arm9/source/dsloader.h" @@ -92,24 +92,74 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset // Treat each relocation entry. Loop over all of them int cnt = size / sizeof(*rel); - DBG("# of relocation entries is %d.\n", cnt); + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + int a = 0; + unsigned int relocation = 0; - // TODO: Loop over relocation entries for (int i = 0; i < cnt; i++) { - //Elf32_Sym *sym = ???; + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; // Save for debugging + + //DBG("%d, ", REL_TYPE(rel[i].r_info)); + + switch (REL_TYPE(rel[i].r_info)) { + + case R_ARM_ABS32: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + /*TODO: + * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { + * relocation |= 1; + * } + */ + + *target = relocation; + + DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + case R_ARM_THM_CALL: + + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target & 0x00000fff; // Get the correct bits for addend: + a += ((*target & 0x0fff0000) >> 4); // Bits 0-11 of the first half-word encode the 12 most significant bits of the branch offset, + // bits 0-11 of the next half-word encode the 12 least significant bits. + a = (a << 8) >> 8; // sign-extend + a = a << 1; // branch offset is in units of half-bytes + + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + /*TODO: + * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { + * relocation |= 1; + * } + */ - //void *target = ???; + relocation -= rel[i].r_offset; - /*switch (REL_TYPE()) {*/ - //case ??? : - //TODO: Cases for each relocation type. - //break; - // default: - //seterror("Unknown relocation type %d.", ?? ?); + *target = relocation; + + DBG("R_ARM_THM_CALL: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + case R_ARM_V4BX: + DBG("R_ARM_V4BX: No relocation calculation necessary\n"); + break; + + default: + seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); free(rel); return false; - // } + } } @@ -400,7 +450,8 @@ bool DLObject::open(const char *path) { //DLFile->finalize(); - //TODO?: flush data cache + //flush data cache + DC_FlushAll(); ctors_start = symbol("___plugin_ctors"); ctors_end = symbol("___plugin_ctors_end"); @@ -444,9 +495,9 @@ void *DLObject::symbol(const char *name) { 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 can only import symbols that are global or weak in the plugin + if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && + !strcmp(name, _strtab + s->st_name)) { // We found the symbol DBG("=> %p\n", (void*)s->st_value); diff --git a/backends/platform/ds/arm9/source/elf32.h b/backends/platform/ds/arm9/source/elf32.h index c7971891fe..8167a40551 100644 --- a/backends/platform/ds/arm9/source/elf32.h +++ b/backends/platform/ds/arm9/source/elf32.h @@ -174,18 +174,13 @@ typedef struct { } Elf32_Rel; // Access macros for the relocation info -#define REL_TYPE(x) ((unsigned char) (x)) /* Extract relocation type */ +#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 +#define R_ARM_THM_CALL 10 +#define R_ARM_V4BX 40 #endif /* BACKENDS_ELF_H */ -- cgit v1.2.3 From 3d3e4e6c397a58d21dbc3be7fbe0c0173f193644 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 20 Jul 2010 04:04:13 +0000 Subject: coded for more relocations, added check for RELA type relocations, added comments svn-id: r51048 --- backends/platform/ds/arm9/source/dsloader.cpp | 55 +++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index 2f953cc33b..c0e8b63dbc 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -97,16 +97,18 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset int a = 0; unsigned int relocation = 0; + // Loop over relocation entries for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + // Get the target instruction in the code unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); unsigned int origTarget = *target; // Save for debugging - //DBG("%d, ", REL_TYPE(rel[i].r_info)); - + // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { case R_ARM_ABS32: @@ -151,6 +153,48 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset } break; + case R_ARM_CALL: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target & 0x00ffffff; + a = (a << 8) >> 6; // Calculate addend by sign-extending (insn[23:0] << 2) + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + /*TODO: + * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { + * relocation |= 1; + * } + */ + + relocation = relocation - rel[i].r_offset; + relocation = relocation >> 2; + *target &= 0xff000000; // Clean lower 26 target bits + *target |= (relocation & 0x00ffffff); + + DBG("R_ARM_CALL: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + case R_ARM_JUMP24: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target & 0x00ffffff; + a = (a << 8) >> 6; // Calculate addend by sign-extending (insn[23:0] << 2) + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + /*TODO: + * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { + * relocation |= 1; + * } + */ + + relocation = relocation - rel[i].r_offset; + relocation = relocation >> 2; + *target &= 0xff000000; // Clean lower 26 target bits + *target |= (relocation & 0x00ffffff); + + DBG("R_ARM_CALL: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + case R_ARM_V4BX: DBG("R_ARM_V4BX: No relocation calculation necessary\n"); break; @@ -365,12 +409,17 @@ bool DLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr Elf32_Shdr *curShdr = &(shdr[i]); //Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]); - if (curShdr->sh_type == SHT_REL && // Check for a relocation section + if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { + seterror("RELA entries not supported for ARM yet!\n"); + return false; + } + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { return false; } -- cgit v1.2.3 From da414e62b8b61bb661bbf62517c8d249574732e2 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 21 Jul 2010 08:50:30 +0000 Subject: switched out linker script for plugin linking on ds, added in check for RELA type relocations in ARM loader and coded for REL type relocations (DS now runs many games with Dynamic Plugins enabled) svn-id: r51083 --- backends/platform/ds/arm9/makefile | 2 +- backends/platform/ds/arm9/source/dsloader.cpp | 69 +--- backends/platform/ds/arm9/source/elf32.h | 9 + backends/platform/ds/arm9/source/plugin.ld | 438 ++++++++++++-------------- 4 files changed, 216 insertions(+), 302 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 706cf6549f..3d784f06aa 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -279,7 +279,7 @@ EXECUTABLE = scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg PLUGIN_EXTRA_DEPS = $(portdir)/source/plugin.ld $(portdir)/source/plugin.syms $(EXECUTABLE) -PLUGIN_LDFLAGS += -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index c0e8b63dbc..8ab64e226a 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -116,12 +116,6 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset a = *target; // Get full 32 bits of addend relocation = a + (Elf32_Addr)_segment; // Shift by main offset - /*TODO: - * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { - * relocation |= 1; - * } - */ - *target = relocation; DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); @@ -129,74 +123,19 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset break; case R_ARM_THM_CALL: - - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target & 0x00000fff; // Get the correct bits for addend: - a += ((*target & 0x0fff0000) >> 4); // Bits 0-11 of the first half-word encode the 12 most significant bits of the branch offset, - // bits 0-11 of the next half-word encode the 12 least significant bits. - a = (a << 8) >> 8; // sign-extend - a = a << 1; // branch offset is in units of half-bytes - - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - /*TODO: - * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { - * relocation |= 1; - * } - */ - - relocation -= rel[i].r_offset; - - *target = relocation; - - DBG("R_ARM_THM_CALL: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } + DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); break; case R_ARM_CALL: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target & 0x00ffffff; - a = (a << 8) >> 6; // Calculate addend by sign-extending (insn[23:0] << 2) - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - /*TODO: - * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { - * relocation |= 1; - * } - */ - - relocation = relocation - rel[i].r_offset; - relocation = relocation >> 2; - *target &= 0xff000000; // Clean lower 26 target bits - *target |= (relocation & 0x00ffffff); - - DBG("R_ARM_CALL: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } + DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); break; case R_ARM_JUMP24: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target & 0x00ffffff; - a = (a << 8) >> 6; // Calculate addend by sign-extending (insn[23:0] << 2) - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - /*TODO: - * if (SYM_TYPE(sym->st_info) == STT_FUNC && symbol addresses a thumb instruction) { - * relocation |= 1; - * } - */ - - relocation = relocation - rel[i].r_offset; - relocation = relocation >> 2; - *target &= 0xff000000; // Clean lower 26 target bits - *target |= (relocation & 0x00ffffff); - - DBG("R_ARM_CALL: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } + DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); break; case R_ARM_V4BX: - DBG("R_ARM_V4BX: No relocation calculation necessary\n"); + DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); break; default: diff --git a/backends/platform/ds/arm9/source/elf32.h b/backends/platform/ds/arm9/source/elf32.h index 8167a40551..c9253a6068 100644 --- a/backends/platform/ds/arm9/source/elf32.h +++ b/backends/platform/ds/arm9/source/elf32.h @@ -173,6 +173,13 @@ typedef struct { Elf32_Word r_info; /* Relocation type and symbol index */ } Elf32_Rel; +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 */ @@ -181,6 +188,8 @@ typedef struct { #define R_ARM_NONE 0 #define R_ARM_ABS32 2 #define R_ARM_THM_CALL 10 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 #define R_ARM_V4BX 40 #endif /* BACKENDS_ELF_H */ diff --git a/backends/platform/ds/arm9/source/plugin.ld b/backends/platform/ds/arm9/source/plugin.ld index 0296dd571d..2b2bca9745 100644 --- a/backends/platform/ds/arm9/source/plugin.ld +++ b/backends/platform/ds/arm9/source/plugin.ld @@ -1,4 +1,5 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") OUTPUT_ARCH(arm) /* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ @@ -6,247 +7,212 @@ PHDRS { plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ } -MEMORY { - rom : ORIGIN = 0x08000000, LENGTH = 32M - ewram : ORIGIN = 0x02000000, LENGTH = 4M - 4k - dtcm : ORIGIN = 0x0b000000, LENGTH = 16K - vectors : ORIGIN = 0x01000000, LENGTH = 256 - itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256 -} - -__vectors_start = ORIGIN(vectors); -__itcm_start = ORIGIN(itcm); -__ewram_end = ORIGIN(ewram) + LENGTH(ewram); -__eheap_end = ORIGIN(ewram) + LENGTH(ewram); -__dtcm_start = ORIGIN(dtcm); -__dtcm_top = ORIGIN(dtcm) + LENGTH(dtcm); -__irq_flags = __dtcm_top - 0x08; -__irq_vector = __dtcm_top - 0x04; - -__sp_svc = __dtcm_top - 0x100; -__sp_irq = __sp_svc - 0x100; -__sp_usr = __sp_irq - 0x100; - SECTIONS { - .init : - { - __text_start = . ; - KEEP (*(.init)) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram :plugin = 0xff - - .plt : { *(.plt) } >ewram = 0xff - - .text : /* ALIGN (4): */ - { - *(EXCLUDE_FILE (*.itcm*) .text) - - *(.text.*) - *(.stub) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.gnu.linkonce.t*) - *(.glue_7) - *(.glue_7t) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff - - .fini : - { - KEEP (*(.fini)) - } >ewram =0xff - - __text_end = . ; - - .rodata : - { - *(.rodata) - *all.rodata*(*) - *(.roda) - *(.rodata.*) - *(.gnu.linkonce.r*) - SORT(CONSTRUCTORS) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff - - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram + /* Read-only sections, merged into text segment: */ + . = 0; + .interp : { *(.interp) } : plugin + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.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.gnu.linkonce.d.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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rel.plt : + { + *(.rel.plt) + } + .rela.plt : + { + *(.rela.plt) + } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } __exidx_start = .; - .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } __exidx_end = .; - /* 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)) } >ewram = 0xff - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.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(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } .init_array : { - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - } >ewram = 0xff - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } .fini_array : { - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - } >ewram = 0xff - PROVIDE (__fini_array_end = .); - - .ctors : - { - /* gcc uses crtbegin.o to find the start of the constructors, so - we make sure it is first. Because this is a wildcard, it - doesn't matter if the user does not actually link against - crtbegin.o; the linker won't look for a file to match a - wildcard. The wildcard also means that it doesn't matter which - directory crtbegin.o is in. */ - ___plugin_ctors = .; - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - ___plugin_ctors_end = .; - } >ewram = 0xff - - .dtors : - { - ___plugin_dtors = .; - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - ___plugin_dtors_end = .; - } >ewram = 0xff - - .eh_frame : - { - KEEP (*(.eh_frame)) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff - - .gcc_except_table : - { - *(.gcc_except_table) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff - .jcr : { KEEP (*(.jcr)) } >ewram = 0 - .got : { *(.got.plt) *(.got) *(.rel.got) } >ewram = 0 - - .ewram ALIGN(4) : - { - __ewram_start = ABSOLUTE(.) ; - *(.ewram) - *ewram.*(.text) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - } >ewram = 0xff - - - .data ALIGN(4) : - { - __data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d*) - CONSTRUCTORS - . = ALIGN(4); - __data_end = ABSOLUTE(.) ; - } >ewram = 0xff - - - __dtcm_lma = . ; - __bss_vma = . ; - - .dtcm __dtcm_start : AT (__dtcm_lma) - { - *(.dtcm) - *(.dtcm.*) - . = ALIGN(4); - __dtcm_end = ABSOLUTE(.); - } >dtcm = 0xff - - - __itcm_lma = __dtcm_lma + SIZEOF(.dtcm); - - .itcm __itcm_start : AT (__itcm_lma) - { - *(.itcm) - *itcm.*(.text) - . = ALIGN(4); - __itcm_end = ABSOLUTE(.); - } >itcm = 0xff - - __vectors_lma = __itcm_lma + SIZEOF(.itcm); - - .vectors __vectors_start : AT (__vectors_lma) - { - *(.vectors) - *vectors.*(.text) - . = ALIGN(4); - __vectors_end = ABSOLUTE(.); - } >vectors = 0xff - - .sbss __dtcm_end (NOLOAD): - { - __sbss_start = ABSOLUTE(.); - __sbss_start__ = ABSOLUTE(.); - *(.sbss) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - __sbss_end = ABSOLUTE(.); - } >dtcm - - .bss __bss_vma (NOLOAD): - { - __bss_start = ABSOLUTE(.); - __bss_start__ = ABSOLUTE(.); - *(.dynbss) - *(.gnu.linkonce.b*) - *(.bss*) - *(COMMON) - . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ - __bss_end = ABSOLUTE(.) ; - __bss_end__ = __bss_end ; - } AT>ewram - - - _end = __bss_end__ ; - __end__ = __bss_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) } - .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) } - .stack 0x80000 : { _stack = .; *(.stack) } - /* These must appear regardless of . */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__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* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + 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. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + __end__ = . ; + _end = .; PROVIDE (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) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } } -- cgit v1.2.3 From 8d946ab847d03625bcc8938932f3ec393b312f20 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 22 Jul 2010 01:44:45 +0000 Subject: Added code for relocation R_ARM_TARGET1 (untested) svn-id: r51130 --- backends/platform/ds/arm9/source/dsloader.cpp | 14 +++++++++++++- backends/platform/ds/arm9/source/elf32.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index 8ab64e226a..21de4d77aa 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -106,7 +106,7 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset // Get the target instruction in the code unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - unsigned int origTarget = *target; // Save for debugging + unsigned int origTarget = *target; //Save for debugging // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { @@ -134,6 +134,18 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); break; + case R_ARM_TARGET1: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + seterror("WARNING: THIS RELOCATION CODE UNTESTED!\n"); //TODO: test cruise for corpse on ARM target! + } + break; + case R_ARM_V4BX: DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); break; diff --git a/backends/platform/ds/arm9/source/elf32.h b/backends/platform/ds/arm9/source/elf32.h index c9253a6068..d72b71664d 100644 --- a/backends/platform/ds/arm9/source/elf32.h +++ b/backends/platform/ds/arm9/source/elf32.h @@ -190,6 +190,7 @@ typedef struct #define R_ARM_THM_CALL 10 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 +#define R_ARM_TARGET1 38 #define R_ARM_V4BX 40 #endif /* BACKENDS_ELF_H */ -- cgit v1.2.3 From 155f45cec1d36730537dda4396ae5ade9bae90e2 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 23 Jul 2010 01:05:26 +0000 Subject: Added linker flags to ensure R_ARM_TARGET1 is treated as R_ARM_ABS32 svn-id: r51188 --- backends/platform/ds/arm9/makefile | 4 ++-- backends/platform/ds/arm9/source/dsloader.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 3d784f06aa..5b5a46f848 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -248,7 +248,7 @@ endif DEFINES += -DREDUCE_MEMORY_USAGE -LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt#-Wl,--gc-sections +LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,--target1-abs,-Map,map.txt#-Wl,--gc-sections ifdef WRAP_MALLOC LDFLAGS += -Wl,--wrap,malloc @@ -279,7 +279,7 @@ EXECUTABLE = scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg PLUGIN_EXTRA_DEPS = $(portdir)/source/plugin.ld $(portdir)/source/plugin.syms $(EXECUTABLE) -PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--target1-abs,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp index 21de4d77aa..00f52860a2 100644 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ b/backends/platform/ds/arm9/source/dsloader.cpp @@ -142,7 +142,7 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset *target = relocation; DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - seterror("WARNING: THIS RELOCATION CODE UNTESTED!\n"); //TODO: test cruise for corpse on ARM target! + DBG("Make sure --target1-abs is a flag to LD.\n"); } break; -- cgit v1.2.3 From 90e9282bf14180ae95f942678dc95849c210c03c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 23 Jul 2010 05:15:11 +0000 Subject: Added abstracted elf32 header file to plugins directory svn-id: r51192 --- backends/plugins/elf32.h | 229 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 backends/plugins/elf32.h (limited to 'backends') diff --git a/backends/plugins/elf32.h b/backends/plugins/elf32.h new file mode 100644 index 0000000000..5dec1d2e58 --- /dev/null +++ b/backends/plugins/elf32.h @@ -0,0 +1,229 @@ +/* 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_MIPS 8 +#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_MIPS_REGINFO 0x70000000 /* Register usage info for MIPS */ +#define PT_ARM_ARCHEXT 0x70000000 /* Platform architecture compatibility info for ARM */ +#define PT_ARM_EXIDX 0x70000001 /* Exception unwind tables for ARM */ + +// 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_MIPS_LIBLSIT 0x70000000 /* Info about dynamic shared object libs for MIPS*/ +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicts btw executables and shared objects for MIPS */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global pointer table for MIPS*/ +#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table for ARM*/ +#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map for ARM */ +#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes for ARM*/ + +// sh_flags values +#define SHF_WRITE 0 /* writable section */ +#define SHF_ALLOC 2 /* section occupies memory */ +#define SHF_EXECINSTR 4 /* machine instructions */ +#define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area for MIPS */ + +// 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 with implicit addend (info about how to relocate) +typedef struct { + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +// Relocation entry with explicit addend (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 */ + +//MIPS relocation types +#define R_MIPS_NONE 0 +#define R_MIPS_16 1 +#define R_MIPS_32 2 +#define R_MIPS_REL32 3 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_GPREL16 7 +#define R_MIPS_LITERAL 8 +#define R_MIPS_GOT16 9 +#define R_MIPS_PC16 10 +#define R_MIPS_CALL16 11 +#define R_MIPS_GPREL32 12 +#define R_MIPS_GOTHI16 13 +#define R_MIPS_GOTLO16 14 +#define R_MIPS_CALLHI16 15 +#define R_MIPS_CALLLO16 16 + +// ARM relocation types +#define R_ARM_NONE 0 +#define R_ARM_ABS32 2 +#define R_ARM_THM_CALL 10 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_TARGET1 38 +#define R_ARM_V4BX 40 + +// Mock function to get value of global pointer for MIPS +#define getGP() ({ \ + unsigned int __valgp; \ + __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ + __valgp; \ +}) + +#endif /* BACKENDS_ELF_H */ -- cgit v1.2.3 From 7694809b3de7dade9c9b950a046e89f194058248 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 23 Jul 2010 07:49:02 +0000 Subject: Began abstraction of generic ELF-loader svn-id: r51195 --- backends/plugins/MIPS-loader.h | 43 ++++++++++++++ backends/plugins/loader.h | 81 +++++++++++++++++++++++++ backends/plugins/shorts-segment-manager.cpp | 78 +++++++++++++++++++++++++ backends/plugins/shorts-segment-manager.h | 91 +++++++++++++++++++++++++++++ 4 files changed, 293 insertions(+) create mode 100644 backends/plugins/MIPS-loader.h create mode 100644 backends/plugins/loader.h create mode 100644 backends/plugins/shorts-segment-manager.cpp create mode 100644 backends/plugins/shorts-segment-manager.h (limited to 'backends') diff --git a/backends/plugins/MIPS-loader.h b/backends/plugins/MIPS-loader.h new file mode 100644 index 0000000000..3bc482e4f2 --- /dev/null +++ b/backends/plugins/MIPS-loader.h @@ -0,0 +1,43 @@ +/* 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 MIPS_LOADER_H +#define MIPS_LOADER_H + +#include "loader.h" +#include "shorts-segment-manager.h" + +class MIPS_DLObject : public DLObject { +protected: + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + unsigned int _gpVal; // Value of Global Pointer + +public: + MIPS_DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), + _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , + _segmentSize(0) {} +}; + +#endif /* MIPS_LOADER_H */ diff --git a/backends/plugins/loader.h b/backends/plugins/loader.h new file mode 100644 index 0000000000..60305f3493 --- /dev/null +++ b/backends/plugins/loader.h @@ -0,0 +1,81 @@ +/* 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 LOADER_H +#define LOADER_H + +#include "elf32.h" +#include "common/list.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(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + bool load(Common::SeekableReadStream* DLFile); + + bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); + void relocateSymbols(Elf32_Addr offset); + bool relocateRels(Common::SeekableReadStream* DLFile, 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), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), + _segmentSize(0) {} +}; + +#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 /* LOADER_H */ diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp new file mode 100644 index 0000000000..dd2b4e4a7e --- /dev/null +++ b/backends/plugins/shorts-segment-manager.cpp @@ -0,0 +1,78 @@ +/* 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) //TODO: && defined (MIPS target) + +#include "MIPS-loader.h" +#include "shorts-segment-manager.h" + +DECLARE_SINGLETON(ShortSegmentManager); // For singleton + +ShortSegmentManager::ShortSegmentManager() { + _shortsStart = &__plugin_hole_start ; + _shortsEnd = &__plugin_hole_end; +} + +ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { + char *lastAddress = origAddr; + Common::List::iterator i; + + // Find a block that fits, starting from the beginning + for (i = _list.begin(); i != _list.end(); ++i) { + char *currAddress = (*i)->getStart(); + + if ((int)(currAddress - lastAddress) >= size) break; + + lastAddress = (*i)->getEnd(); + } + + if ((Elf32_Addr)lastAddress & 3) + lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 + + if (lastAddress + size > _shortsEnd) { + seterror("Error. No space in shorts segment for %x bytes. Last address is %p, max address is %p.\n", + size, lastAddress, _shortsEnd); + return NULL; + } + + Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment + + if (lastAddress + size > _highestAddress) _highestAddress = lastAddress + size; // Keep track of maximum + + _list.insert(i, seg); + + DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", + size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); + + return seg; +} + +void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { + DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); + _list.remove(seg); + delete seg; +} + +#endif /* DYNAMIC_MODULES */ diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h new file mode 100644 index 0000000000..e6c38d45a8 --- /dev/null +++ b/backends/plugins/shorts-segment-manager.h @@ -0,0 +1,91 @@ +/* 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 SHORTS_SEGMENT_MANAGER_H +#define SHORTS_SEGMENT_MANAGER_H + +#include "loader.h" +#include "common/singleton.h" + +#define ShortsMan ShortSegmentManager::instance() + +class ShortSegmentManager : public Common::Singleton { +private: + char *_shortsStart; + char *_shortsEnd; + +public: + char *getShortsStart() { + return _shortsStart; + } + bool inGeneralSegment(char *addr) { + return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); + } + + class Segment { + private: + friend class ShortSegmentManager; + Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} + ~Segment() {} + char *_startAddress; // Start of shorts segment in memory + int _size; // Size of shorts segment + char *_origAddress; // Original address this segment was supposed to be at + public: + char *getStart() { + return _startAddress; + } + char *getEnd() { + return (_startAddress + _size); + } + Elf32_Addr getOffset() { + return (Elf32_Addr)(_startAddress - _origAddress); + } + bool inSegment(char *addr) { + return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); + } + }; + + Segment *newSegment(int size, char *origAddr); + void deleteSegment(Segment *); + +private: + ShortSegmentManager(); + friend class Common::Singleton; + Common::List _list; + char *_highestAddress; +}; + +class MIPS_DLObject : public DLObject { +protected: + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + unsigned int _gpVal; // Value of Global Pointer + +public: + MIPS_DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), + _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , + _segmentSize(0) {} +}; + +#endif /* SHORTS_SEGMENT_MANAGER_H */ -- cgit v1.2.3 From c39ca586839c8f6fd596fc743da52d2bc72b46ec Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 23 Jul 2010 20:01:54 +0000 Subject: renamed MIPS loader header to match file naming conventions svn-id: r51219 --- backends/plugins/MIPS-loader.h | 43 ------------------------------------------ backends/plugins/mips-loader.h | 43 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 43 deletions(-) delete mode 100644 backends/plugins/MIPS-loader.h create mode 100644 backends/plugins/mips-loader.h (limited to 'backends') diff --git a/backends/plugins/MIPS-loader.h b/backends/plugins/MIPS-loader.h deleted file mode 100644 index 3bc482e4f2..0000000000 --- a/backends/plugins/MIPS-loader.h +++ /dev/null @@ -1,43 +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 MIPS_LOADER_H -#define MIPS_LOADER_H - -#include "loader.h" -#include "shorts-segment-manager.h" - -class MIPS_DLObject : public DLObject { -protected: - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - unsigned int _gpVal; // Value of Global Pointer - -public: - MIPS_DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , - _segmentSize(0) {} -}; - -#endif /* MIPS_LOADER_H */ diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h new file mode 100644 index 0000000000..3bc482e4f2 --- /dev/null +++ b/backends/plugins/mips-loader.h @@ -0,0 +1,43 @@ +/* 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 MIPS_LOADER_H +#define MIPS_LOADER_H + +#include "loader.h" +#include "shorts-segment-manager.h" + +class MIPS_DLObject : public DLObject { +protected: + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + unsigned int _gpVal; // Value of Global Pointer + +public: + MIPS_DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), + _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , + _segmentSize(0) {} +}; + +#endif /* MIPS_LOADER_H */ -- cgit v1.2.3 From 5d8f4b5062db573d80bf3fe279cc112d75f75094 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 24 Jul 2010 02:07:35 +0000 Subject: Finished initial abstraction of ELF-loader (works for DS) svn-id: r51233 --- backends/plugins/ds/ds-loader.cpp | 143 +++++++++ backends/plugins/elf-loader.cpp | 464 ++++++++++++++++++++++++++++ backends/plugins/elf-loader.h | 85 +++++ backends/plugins/loader.h | 81 ----- backends/plugins/mips-loader.h | 4 +- backends/plugins/shorts-segment-manager.cpp | 2 +- backends/plugins/shorts-segment-manager.h | 11 - 7 files changed, 695 insertions(+), 95 deletions(-) create mode 100644 backends/plugins/ds/ds-loader.cpp create mode 100644 backends/plugins/elf-loader.cpp create mode 100644 backends/plugins/elf-loader.h delete mode 100644 backends/plugins/loader.h (limited to 'backends') diff --git a/backends/plugins/ds/ds-loader.cpp b/backends/plugins/ds/ds-loader.cpp new file mode 100644 index 0000000000..7dd27cfb4a --- /dev/null +++ b/backends/plugins/ds/ds-loader.cpp @@ -0,0 +1,143 @@ +/* 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$ + * + */ + +#include "backends/fs/ds/ds-fs.h" +#include "../elf-loader.h" +#include "dsmain.h" + +#define __DEBUG_PLUGINS__ + +#ifdef __DEBUG_PLUGINS__ +#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) consolePrintf(x, ## __VA_ARGS__) + +/** + * Flushes the data cache. + */ +void flushDataCache() { + DC_FlushAll(); +} + +/** + * Follow the instruction of a relocation section. + * + * @param DLFile SeekableReadStream of File + * @param offset Offset into the File + * @param size Size of relocation section + * + */ +bool dlRelocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = NULL; //relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + seterror("Out of memory."); + return false; + } + + // Read in our relocation table + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != (ssize_t)size) { + seterror("Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + int a = 0; + unsigned int relocation = 0; + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; //Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + + case R_ARM_ABS32: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + case R_ARM_THM_CALL: + DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + break; + + case R_ARM_CALL: + DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + break; + + case R_ARM_JUMP24: + DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); + break; + + case R_ARM_TARGET1: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + DBG("Make sure --target1-abs is a flag to LD.\n"); + } + break; + + case R_ARM_V4BX: + DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); + break; + + default: + seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); + free(rel); + return false; + } + + } + + free(rel); + return true; +} diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp new file mode 100644 index 0000000000..f675386df9 --- /dev/null +++ b/backends/plugins/elf-loader.cpp @@ -0,0 +1,464 @@ +/* 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) // TODO: && defined ELF loader target + +#include +#include +#include +#include +#include +#include + +//#include "backends/fs/stdiostream.h" +//#include "backends/fs/ds/ds-fs.h" +#include "dsmain.h" + +#include "elf-loader.h" + +#define __DEBUG_PLUGINS__ + +#ifdef __DEBUG_PLUGINS__ +#define DBG(x,...) printf(x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) printf(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 DLFile SeekableReadStream of File + * @param offset Offset into the File + * @param size Size of relocation section + * + */ +bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + dlRelocate(DLFile, offset, size, relSegment); +} + +bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { + + // Start reading the elf header. Check for errors + if (DLFile->read(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(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { + + // Read program header + if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || + DLFile->read(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(Common::SeekableReadStream* DLFile, 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; + + DBG("base address is %p\n", baseAddress); + DBG("_segmentSize is %p\n", _segmentSize); + + // 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); + } + + DBG("Reading the segment into memory\n"); + + // Read the segment into memory + if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || + DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { + seterror("Segment load failed."); + return false; + } + + DBG("Segment has been read into memory\n"); + + return true; +} + +Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || + DLFile->read(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(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || + DLFile->read(_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(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || + DLFile->read(_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(Common::SeekableReadStream* DLFile, 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 || curShdr->sh_type == SHT_RELA) && // Check for a relocation section + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { + seterror("RELA entries not supported yet!\n"); + return false; + } + + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { + return false; + } + + } + } + + return true; +} + +bool DLObject::load(Common::SeekableReadStream* DLFile) { + Elf32_Ehdr ehdr; + Elf32_Phdr phdr; + Elf32_Shdr *shdr; + bool ret = true; + + if (readElfHeader(DLFile, &ehdr) == false) { + return false; + } + + for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments + + DBG("Loading segment %d\n", i); + + if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) + return false; + + if (!loadSegment(DLFile, &phdr)) + return false; + } + + if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == NULL) + ret = false; + + if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) + ret = false; + + if (ret && (loadStringTable(DLFile, shdr) == false)) + ret = false; + + if (ret) + relocateSymbols((Elf32_Addr)_segment); // Offset by our segment allocated address + + if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) + ret = false; + + free(shdr); + + return ret; + +} + +bool DLObject::open(const char *path) { + + Common::SeekableReadStream* DLFile; + void *ctors_start, *ctors_end; + + DBG("open(\"%s\")\n", path); + + Common::FSNode file(path); + + if (!(DLFile = file.createReadStream())) { + seterror("%s not found.", path); + return false; + } + + DBG("%s found!\n", path); + + /*Try to load and relocate*/ + if (!load(DLFile)) { + unload(); + return false; + } + + DBG("loaded!/n"); + + flushDataCache(); + + 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++) + + // We can only import symbols that are global or weak in the plugin + if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && + !strcmp(name, _strtab + s->st_name)) { + + // 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 */ + diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h new file mode 100644 index 0000000000..e8c5701f6e --- /dev/null +++ b/backends/plugins/elf-loader.h @@ -0,0 +1,85 @@ +/* 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 LOADER_H +#define LOADER_H + +#include "backends/plugins/elf32.h" +#include "common/list.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(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + bool load(Common::SeekableReadStream* DLFile); + + bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); + void relocateSymbols(Elf32_Addr offset); + bool relocateRels(Common::SeekableReadStream* DLFile, 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), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), + _segmentSize(0) {} +}; + +#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); +} + +//The following need to be defined by specific ports. +extern void flushDataCache(); +extern bool dlRelocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + +#endif /* LOADER_H */ diff --git a/backends/plugins/loader.h b/backends/plugins/loader.h deleted file mode 100644 index 60305f3493..0000000000 --- a/backends/plugins/loader.h +++ /dev/null @@ -1,81 +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 LOADER_H -#define LOADER_H - -#include "elf32.h" -#include "common/list.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(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - bool load(Common::SeekableReadStream* DLFile); - - bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); - void relocateSymbols(Elf32_Addr offset); - bool relocateRels(Common::SeekableReadStream* DLFile, 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), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), - _segmentSize(0) {} -}; - -#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 /* LOADER_H */ diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h index 3bc482e4f2..fc8334ad17 100644 --- a/backends/plugins/mips-loader.h +++ b/backends/plugins/mips-loader.h @@ -29,13 +29,13 @@ #include "loader.h" #include "shorts-segment-manager.h" -class MIPS_DLObject : public DLObject { +class MipsDLObject : public DLObject { protected: ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges unsigned int _gpVal; // Value of Global Pointer public: - MIPS_DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), + MipsDLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , _segmentSize(0) {} }; diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index dd2b4e4a7e..cce93e7f86 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -25,7 +25,7 @@ #if defined(DYNAMIC_MODULES) //TODO: && defined (MIPS target) -#include "MIPS-loader.h" +//#include "MIPS-loader.h" #include "shorts-segment-manager.h" DECLARE_SINGLETON(ShortSegmentManager); // For singleton diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h index e6c38d45a8..40ceef60f0 100644 --- a/backends/plugins/shorts-segment-manager.h +++ b/backends/plugins/shorts-segment-manager.h @@ -77,15 +77,4 @@ private: char *_highestAddress; }; -class MIPS_DLObject : public DLObject { -protected: - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - unsigned int _gpVal; // Value of Global Pointer - -public: - MIPS_DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , - _segmentSize(0) {} -}; - #endif /* SHORTS_SEGMENT_MANAGER_H */ -- cgit v1.2.3 From 95f66e6fb280a65702fdb932827f89d2c63b0cda Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 24 Jul 2010 07:14:19 +0000 Subject: changed ds makefile to use abstracted ELF-loader with ds-specific additions added to backends/plugins/ds svn-id: r51236 --- backends/platform/ds/arm9/makefile | 3 +- backends/platform/ds/arm9/source/dsloader.cpp | 553 -------------------------- backends/platform/ds/arm9/source/dsloader.h | 81 ---- 3 files changed, 2 insertions(+), 635 deletions(-) delete mode 100644 backends/platform/ds/arm9/source/dsloader.cpp delete mode 100644 backends/platform/ds/arm9/source/dsloader.h (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 5b5a46f848..4831fab21a 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -295,7 +295,8 @@ PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(port $(portdir)/source/touchkeyboard.o $(portdir)/source/zipreader.o\ $(portdir)/source/dsoptions.o $(portdir)/source/keys.o $(portdir)/source/wordcompletion.o\ $(portdir)/source/interrupt.o\ - $(portdir)/source/dsloader.o + $(srcdir)/backends/plugins/elf-loader.o\ + $(srcdir)/backends/plugins/ds/ds-loader.o ifdef USE_PROFILER PORT_OBJS += $(portdir)/source/profiler/cyg-profile.o diff --git a/backends/platform/ds/arm9/source/dsloader.cpp b/backends/platform/ds/arm9/source/dsloader.cpp deleted file mode 100644 index 00f52860a2..0000000000 --- a/backends/platform/ds/arm9/source/dsloader.cpp +++ /dev/null @@ -1,553 +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(__DS__) - -#include -#include -#include -#include -#include -#include - -//#include "backends/fs/stdiostream.h" -#include "backends/fs/ds/ds-fs.h" -#include "dsmain.h" - -#include "backends/platform/ds/arm9/source/dsloader.h" - -#define __DS_DEBUG_PLUGINS__ - -#ifdef __DS_DEBUG_PLUGINS__ -#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) consolePrintf(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 DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * - */ -bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; //relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); - return false; - } - - // Read in our relocation table - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); - - int a = 0; - unsigned int relocation = 0; - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; //Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - - case R_ARM_ABS32: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } - break; - - case R_ARM_THM_CALL: - DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); - break; - - case R_ARM_CALL: - DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); - break; - - case R_ARM_JUMP24: - DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); - break; - - case R_ARM_TARGET1: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - DBG("Make sure --target1-abs is a flag to LD.\n"); - } - break; - - case R_ARM_V4BX: - DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); - break; - - default: - seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); - free(rel); - return false; - } - - } - - free(rel); - return true; -} - -bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - - // Start reading the elf header. Check for errors - if (DLFile->read(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(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { - - // Read program header - if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || - DLFile->read(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(Common::SeekableReadStream* DLFile, 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; - - DBG("base address is %p\n", baseAddress); - DBG("_segmentSize is %p\n", _segmentSize); - - // 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); - } - - DBG("Reading the segment into memory\n"); - - // Read the segment into memory - if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || - DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { - seterror("Segment load failed."); - return false; - } - - DBG("Segment has been read into memory\n"); - - return true; -} - -Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || - DLFile->read(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(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || - DLFile->read(_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(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || - DLFile->read(_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(Common::SeekableReadStream* DLFile, 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 || curShdr->sh_type == SHT_RELA) && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { - seterror("RELA entries not supported for ARM yet!\n"); - return false; - } - - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { - return false; - } - - } - } - - return true; -} - -bool DLObject::load(Common::SeekableReadStream* DLFile) { - Elf32_Ehdr ehdr; - Elf32_Phdr phdr; - Elf32_Shdr *shdr; - bool ret = true; - - if (readElfHeader(DLFile, &ehdr) == false) { - return false; - } - - for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments - - DBG("Loading segment %d\n", i); - - if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) - return false; - - if (!loadSegment(DLFile, &phdr)) - return false; - } - - if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == NULL) - ret = false; - - if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) - ret = false; - - if (ret && (loadStringTable(DLFile, shdr) == false)) - ret = false; - - if (ret) - relocateSymbols((Elf32_Addr)_segment); // Offset by our segment allocated address - - if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) - ret = false; - - free(shdr); - - return ret; - -} - -bool DLObject::open(const char *path) { - - Common::SeekableReadStream* DLFile; - void *ctors_start, *ctors_end; - - DBG("open(\"%s\")\n", path); - - Common::FSNode file(path); - - if (!(DLFile = file.createReadStream())) { - seterror("%s not found.", path); - return false; - } - - DBG("%s found!\n", path); - - /*Try to load and relocate*/ - if (!load(DLFile)) { - //DLFile->finalize(); - unload(); - return false; - } - - DBG("loaded!/n"); - - //DLFile->finalize(); - - //flush data cache - DC_FlushAll(); - - 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++) - - // We can only import symbols that are global or weak in the plugin - if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && - !strcmp(name, _strtab + s->st_name)) { - - // 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 && __DS__ */ diff --git a/backends/platform/ds/arm9/source/dsloader.h b/backends/platform/ds/arm9/source/dsloader.h deleted file mode 100644 index ba8499d14d..0000000000 --- a/backends/platform/ds/arm9/source/dsloader.h +++ /dev/null @@ -1,81 +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 DS_LOADER_H -#define DS_LOADER_H - -#include "elf32.h" -#include "common/list.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(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - bool load(Common::SeekableReadStream* DLFile); - - bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); - void relocateSymbols(Elf32_Addr offset); - bool relocateRels(Common::SeekableReadStream* DLFile, 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), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), - _segmentSize(0) {} -}; - -#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 /* DS_LOADER_H */ -- cgit v1.2.3 From 4e530debd2b2cb79078b705792fc599d328d6c7c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 26 Jul 2010 00:41:31 +0000 Subject: moved flushDataCache function from ds-loader.cpp to elf-loader.cpp and moved arm-relocations from ds-loader.cpp to arm-relocs.cpp; deleted ds-loader.cpp svn-id: r51289 --- backends/platform/ds/arm9/makefile | 2 +- backends/plugins/arm-relocs.cpp | 136 +++++++++++++++++++++++++++++++++++ backends/plugins/ds/ds-loader.cpp | 143 ------------------------------------- backends/plugins/elf-loader.cpp | 14 ++++ 4 files changed, 151 insertions(+), 144 deletions(-) create mode 100644 backends/plugins/arm-relocs.cpp delete mode 100644 backends/plugins/ds/ds-loader.cpp (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 4831fab21a..04f7ab9bf3 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -296,7 +296,7 @@ PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(port $(portdir)/source/dsoptions.o $(portdir)/source/keys.o $(portdir)/source/wordcompletion.o\ $(portdir)/source/interrupt.o\ $(srcdir)/backends/plugins/elf-loader.o\ - $(srcdir)/backends/plugins/ds/ds-loader.o + $(srcdir)/backends/plugins/arm-relocs.o ifdef USE_PROFILER PORT_OBJS += $(portdir)/source/profiler/cyg-profile.o diff --git a/backends/plugins/arm-relocs.cpp b/backends/plugins/arm-relocs.cpp new file mode 100644 index 0000000000..66e466a58a --- /dev/null +++ b/backends/plugins/arm-relocs.cpp @@ -0,0 +1,136 @@ +/* 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$ + * + */ + +#include "backends/fs/ds/ds-fs.h" +#include "elf-loader.h" +#include "dsmain.h" + +#define __DEBUG_PLUGINS__ + +#ifdef __DEBUG_PLUGINS__ +#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) consolePrintf(x, ## __VA_ARGS__) + +/** + * Follow the instruction of a relocation section. + * + * @param DLFile SeekableReadStream of File + * @param offset Offset into the File + * @param size Size of relocation section + * + */ +bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = NULL; //relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + seterror("Out of memory."); + return false; + } + + // Read in our relocation table + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != (ssize_t)size) { + seterror("Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + int a = 0; + unsigned int relocation = 0; + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; //Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + + case R_ARM_ABS32: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + case R_ARM_THM_CALL: + DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + break; + + case R_ARM_CALL: + DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + break; + + case R_ARM_JUMP24: + DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); + break; + + case R_ARM_TARGET1: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + DBG("Make sure --target1-abs is a flag to LD.\n"); + } + break; + + case R_ARM_V4BX: + DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); + break; + + default: + seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); + free(rel); + return false; + } + + } + + free(rel); + return true; +} diff --git a/backends/plugins/ds/ds-loader.cpp b/backends/plugins/ds/ds-loader.cpp deleted file mode 100644 index 7dd27cfb4a..0000000000 --- a/backends/plugins/ds/ds-loader.cpp +++ /dev/null @@ -1,143 +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$ - * - */ - -#include "backends/fs/ds/ds-fs.h" -#include "../elf-loader.h" -#include "dsmain.h" - -#define __DEBUG_PLUGINS__ - -#ifdef __DEBUG_PLUGINS__ -#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) consolePrintf(x, ## __VA_ARGS__) - -/** - * Flushes the data cache. - */ -void flushDataCache() { - DC_FlushAll(); -} - -/** - * Follow the instruction of a relocation section. - * - * @param DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * - */ -bool dlRelocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; //relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); - return false; - } - - // Read in our relocation table - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); - - int a = 0; - unsigned int relocation = 0; - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; //Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - - case R_ARM_ABS32: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } - break; - - case R_ARM_THM_CALL: - DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); - break; - - case R_ARM_CALL: - DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); - break; - - case R_ARM_JUMP24: - DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); - break; - - case R_ARM_TARGET1: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - DBG("Make sure --target1-abs is a flag to LD.\n"); - } - break; - - case R_ARM_V4BX: - DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); - break; - - default: - seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); - free(rel); - return false; - } - - } - - free(rel); - return true; -} diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index f675386df9..685d22e28a 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -48,6 +48,20 @@ #define seterror(x,...) printf(x, ## __VA_ARGS__) +/** + * Flushes the data cache. + */ +void flushDataCache() { +#ifdef __DS__ + DC_FlushAll(); +#endif +#ifdef __PLAYSTATION2__ + FlushCache(0); + FlushCache(2); +#endif +} + + // Expel the symbol table from memory void DLObject::discard_symtab() { free(_symtab); -- cgit v1.2.3 From 58f3e81f0073f55a892802b562081300345ca23d Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 27 Jul 2010 06:27:45 +0000 Subject: Continued abstraction of generic ELF-loader, splitting off MIPS-processor specific things into their own files and testing on the PS2 svn-id: r51345 --- backends/platform/ds/arm9/makefile | 4 +- backends/platform/ds/arm9/source/plugin.ld | 218 -------- backends/platform/ds/arm9/source/plugin.syms | 8 - backends/platform/ps2/Makefile.ps2 | 8 +- backends/platform/ps2/plugin.ld | 94 ---- backends/platform/ps2/plugin.syms | 8 - backends/platform/ps2/ps2loader.cpp | 721 --------------------------- backends/platform/ps2/ps2loader.h | 137 ----- backends/platform/psp/Makefile | 4 +- backends/platform/psp/plugin.ld | 239 --------- backends/platform/psp/plugin.syms | 8 - backends/plugins/arm-relocs.cpp | 28 ++ backends/plugins/ds/plugin.ld | 218 ++++++++ backends/plugins/elf-loader.cpp | 110 ++-- backends/plugins/elf-loader.h | 28 +- backends/plugins/mips-loader.h | 43 -- backends/plugins/mips-relocs.cpp | 259 ++++++++++ backends/plugins/plugin.syms | 8 + backends/plugins/ps2/plugin.ld | 94 ++++ backends/plugins/psp/plugin.ld | 239 +++++++++ backends/plugins/shorts-segment-manager.cpp | 13 +- backends/plugins/shorts-segment-manager.h | 3 +- 22 files changed, 948 insertions(+), 1544 deletions(-) delete mode 100644 backends/platform/ds/arm9/source/plugin.ld delete mode 100644 backends/platform/ds/arm9/source/plugin.syms delete mode 100644 backends/platform/ps2/plugin.ld delete mode 100644 backends/platform/ps2/plugin.syms delete mode 100644 backends/platform/ps2/ps2loader.cpp delete mode 100644 backends/platform/ps2/ps2loader.h delete mode 100644 backends/platform/psp/plugin.ld delete mode 100644 backends/platform/psp/plugin.syms create mode 100644 backends/plugins/ds/plugin.ld delete mode 100644 backends/plugins/mips-loader.h create mode 100644 backends/plugins/mips-relocs.cpp create mode 100644 backends/plugins/plugin.syms create mode 100644 backends/plugins/ps2/plugin.ld create mode 100644 backends/plugins/psp/plugin.ld (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 04f7ab9bf3..c5e4fe414c 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -278,8 +278,8 @@ endif EXECUTABLE = scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = $(portdir)/source/plugin.ld $(portdir)/source/plugin.syms $(EXECUTABLE) -PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--target1-abs,--just-symbols,$(EXECUTABLE),-T$(portdir)/source/plugin.ld,--retain-symbols-file,$(portdir)/source/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o +PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/ds/plugin.ld $(srcdir)/backends/plugins/plugin.syms $(EXECUTABLE) +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--target1-abs,--just-symbols,$(EXECUTABLE),-T$(srcdir)/backends/plugins/ds/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o MKDIR = mkdir -p RM = rm -f RM_REC = rm -rf diff --git a/backends/platform/ds/arm9/source/plugin.ld b/backends/platform/ds/arm9/source/plugin.ld deleted file mode 100644 index 2b2bca9745..0000000000 --- a/backends/platform/ds/arm9/source/plugin.ld +++ /dev/null @@ -1,218 +0,0 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", - "elf32-littlearm") -OUTPUT_ARCH(arm) - -/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ -PHDRS { - plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ -} - -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - .interp : { *(.interp) } : plugin - .note.gnu.build-id : { *(.note.gnu.build-id) } - .hash : { *(.hash) } - .gnu.hash : { *(.gnu.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.gnu.linkonce.d.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.*) - PROVIDE_HIDDEN (__rel_iplt_start = .); - *(.rel.iplt) - PROVIDE_HIDDEN (__rel_iplt_end = .); - PROVIDE_HIDDEN (__rela_iplt_start = .); - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .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.*) - PROVIDE_HIDDEN (__rel_iplt_start = .); - PROVIDE_HIDDEN (__rel_iplt_end = .); - PROVIDE_HIDDEN (__rela_iplt_start = .); - *(.rela.iplt) - PROVIDE_HIDDEN (__rela_iplt_end = .); - } - .rel.plt : - { - *(.rel.plt) - } - .rela.plt : - { - *(.rela.plt) - } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .iplt : { *(.iplt) } - .text : - { - *(.text.unlikely .text.*_unlikely) - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } - __exidx_start = .; - .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } - __exidx_end = .; - .eh_frame_hdr : { *(.eh_frame_hdr) } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RO { *(.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(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); - /* Exception handling */ - .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } - .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } - /* Thread Local Storage sections */ - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT(.init_array.*))) - KEEP (*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - } - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(.fini_array)) - KEEP (*(SORT(.fini_array.*))) - PROVIDE_HIDDEN (__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* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } - .dynamic : { *(.dynamic) } - .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } - .data : - { - __data_start = . ; - *(.data .data.* .gnu.linkonce.d.*) - 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. - FIXME: Why do we need it? When there is no .bss section, we don't - pad the .data section. */ - . = ALIGN(. != 0 ? 32 / 8 : 1); - } - _bss_end__ = . ; __bss_end__ = . ; - . = ALIGN(32 / 8); - . = ALIGN(32 / 8); - __end__ = . ; - _end = .; PROVIDE (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) } - /* DWARF 3 */ - .debug_pubtypes 0 : { *(.debug_pubtypes) } - .debug_ranges 0 : { *(.debug_ranges) } - .stack 0x80000 : - { - _stack = .; - *(.stack) - } - .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } - .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } - /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } -} diff --git a/backends/platform/ds/arm9/source/plugin.syms b/backends/platform/ds/arm9/source/plugin.syms deleted file mode 100644 index 24ee1a19dc..0000000000 --- a/backends/platform/ds/arm9/source/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/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index c2cf30ed23..5c60c4fca0 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -87,9 +87,9 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms elf/scummvm.elf +PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/plugin.syms elf/scummvm.elf PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-T$(srcdir)/backends/plugins/ps2/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/plugin.syms -lstdc++ -lc LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . @@ -111,7 +111,9 @@ OBJS := $(srcdir)/backends/platform/ps2/DmaPipe.o \ $(srcdir)/backends/platform/ps2/systemps2.o \ $(srcdir)/backends/platform/ps2/ps2mutex.o \ $(srcdir)/backends/platform/ps2/ps2time.o \ - $(srcdir)/backends/platform/ps2/ps2loader.o \ + $(srcdir)/backends/plugins/elf-loader.o \ + $(srcdir)/backends/plugins/mips-relocs.o \ + $(srcdir)/backends/plugins/shorts-segment-manager.o \ $(srcdir)/backends/platform/ps2/ps2debug.o include $(srcdir)/Makefile.common diff --git a/backends/platform/ps2/plugin.ld b/backends/platform/ps2/plugin.ld deleted file mode 100644 index 9879413b98..0000000000 --- a/backends/platform/ps2/plugin.ld +++ /dev/null @@ -1,94 +0,0 @@ -/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ -PHDRS { - plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ - shorts PT_LOAD ; /* Specifies that the shorts segment should be loaded from file */ -} -SECTIONS { - .text 0: { - _ftext = . ; - *(.text) - *(.text.*) - *(.gnu.linkonce.t*) - KEEP(*(.init)) - KEEP(*(.fini)) - QUAD(0) - } : plugin /*The ": plugin" tells the linker to assign this and - the following sections to the "plugin" segment*/ - PROVIDE(_etext = .); - PROVIDE(etext = .); - - .reginfo : { *(.reginfo) } - - /* Global/static constructors and deconstructors. */ - .ctors ALIGN(16): { - ___plugin_ctors = .; - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - ___plugin_ctors_end = .; - } - .dtors ALIGN(16): { - ___plugin_dtors = .; - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - ___plugin_dtors_end = .; - } - - /* Static data. */ - .rodata ALIGN(128): { - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r*) - } - - .data ALIGN(128): { - _fdata = . ; - *(.data) - *(.data.*) - *(.gnu.linkonce.d*) - SORT(CONSTRUCTORS) - } - - .rdata ALIGN(128): { *(.rdata) } - .gcc_except_table ALIGN(128): { *(.gcc_except_table) } - - .bss ALIGN(128) : { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b*) - *(COMMON) - } - _end_bss = .; - - _end = . ; - PROVIDE(end = .); - - /* Symbols needed by crt0.s. */ - PROVIDE(_heap_size = -1); - PROVIDE(_stack = -1); - PROVIDE(_stack_size = 128 * 1024); - - /*We assign the output location counter to the plugin hole made - in main_prog.ld, then assign the small data sections to the shorts segment*/ - . = __plugin_hole_start; - .lit4 ALIGN(128): { *(.lit4) } : shorts - .lit8 ALIGN(128): { *(.lit8) } - - .sdata ALIGN(128): { - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s*) - } - - _edata = .; - PROVIDE(edata = .); - - /* Uninitialized data. */ - .sbss ALIGN(128) : { - _fbss = . ; - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb*) - *(.scommon) - } - -} diff --git a/backends/platform/ps2/plugin.syms b/backends/platform/ps2/plugin.syms deleted file mode 100644 index 24ee1a19dc..0000000000 --- a/backends/platform/ps2/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/platform/ps2/ps2loader.cpp b/backends/platform/ps2/ps2loader.cpp deleted file mode 100644 index 0f46b2ad45..0000000000 --- a/backends/platform/ps2/ps2loader.cpp +++ /dev/null @@ -1,721 +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(__PLAYSTATION2__) - -#include -#include -#include -#include -#include -#include - -#include "savefilemgr.h" -#include "backends/fs/ps2/ps2-fs-factory.h" - -#include "backends/platform/ps2/ps2loader.h" - -//#define __PS2_DEBUG_PLUGINS__ - -#ifdef __PS2_DEBUG_PLUGINS__ -#define DBG(x,...) printf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) printf(x, ## __VA_ARGS__) - -extern char __plugin_hole_start; // Indicates start of hole in program file for shorts -extern char __plugin_hole_end; // Indicates end of hole in program file -extern char _gp[]; // Value of gp register - -DECLARE_SINGLETON(ShortSegmentManager); // For singleton - -// Get rid of symbol table in 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; - - if (_shortsSegment) { - ShortsMan.deleteSegment(_shortsSegment); - _shortsSegment = NULL; - } -} - -/** - * Follow the instruction of a relocation section. - * - * @param DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - * - */ -bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; // relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); - return false; - } - - // Read in our relocation table - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); - - bool seenHi16 = false; // For treating HI/LO16 commands - int firstHi16 = -1; // Mark the point of the first hi16 seen - Elf32_Addr ahl = 0; // Calculated addend - int a = 0; // Addend: taken from the target - - unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives - unsigned int relocation = 0; - int debugRelocs[10] = {0}; // For debugging - int extendedHi16 = 0; // Count extended hi16 treatments - Elf32_Addr lastHiSymVal = 0; - bool hi16InShorts = false; - -#define DEBUG_NUM 2 - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; // Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - - case R_MIPS_HI16: // Absolute addressing. - if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) - firstHi16 < 0) { // Only process first in block of HI16s - firstHi16 = i; // Keep the first Hi16 we saw - seenHi16 = true; - ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up - - lastHiSymVal = sym->st_value; - hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments - if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number - DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", - i, rel[i].r_offset, ahl, *target); - } - break; - - case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) - if (!seenHi16) { // We MUST have seen HI16 first - seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); - free(rel); - return false; - } - - // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) - // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section - // and will be screened out above - bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); - - // Correct the bug by getting the proper value in ahl (taken from the current symbol) - if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { - ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset - ahl += (sym->st_value & 0xffff0000); - } - - ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s - a = *target & 0xffff; // Take lower 16 bits of the target - a = (a << 16) >> 16; // Sign extend them - ahl += a; // Add lower 16 bits. AHL is now complete - - // Fix: we can have LO16 access to the short segment sometimes - if (lo16InShorts) { - relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset - } else // It's in the regular segment - relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment - - if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now - for (int j = firstHi16; j < i; j++) { - if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s - - lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target - *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target - *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation - if (relocation & 0x8000)(*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case - } - firstHi16 = -1; // Reset so we'll know we treated it - } else { - extendedHi16++; - } - - *target &= 0xffff0000; // Clear the lower 16 bits of current target - *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation - - if (debugRelocs[1]++ < DEBUG_NUM) - DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - } - break; - - case R_MIPS_26: // Absolute addressing (for jumps and branches only) - if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment - a = *target & 0x03ffffff; // Get 26 bits' worth of the addend - a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset - *target &= 0xfc000000; // Clean lower 26 target bits - *target |= (relocation & 0x03ffffff); - - if (debugRelocs[3]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } else { - if (debugRelocs[4]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } - break; - - case R_MIPS_GPREL16: // GP Relative addressing - if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section - ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole - a = *target & 0xffff; // Get 16 bits' worth of the addend - a = (a << 16) >> 16; // Sign extend it - - relocation = a + _shortsSegment->getOffset(); - - *target &= 0xffff0000; // Clear the lower 16 bits of the target - *target |= relocation & 0xffff; - - if (debugRelocs[5]++ < DEBUG_NUM) - DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", - i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); - } - - break; - - case R_MIPS_32: // Absolute addressing - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - - if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment - relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset - else // We're in the main section - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - *target = relocation; - - if (debugRelocs[6]++ < DEBUG_NUM) - DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } - break; - - default: - seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); - free(rel); - return false; - } - } - - DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); - - free(rel); - return true; -} - -bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - // Start reading the elf header. Check for errors - if (DLFile->read(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_MIPS || // Check for MIPS 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(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { - // Read program header - if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || - DLFile->read(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(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { - - char *baseAddress = 0; - - // We need to take account of non-allocated segment for shorts - if (phdr->p_flags & PF_X) { // This is a relocated segment - - // 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 (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - - 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; - } else { // This is a shorts section. - _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); - - baseAddress = _shortsSegment->getStart(); - DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", - _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); - - } - - // 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 (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || - DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { - seterror("Segment load failed."); - return false; - } - - return true; -} - - -Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || - DLFile->read(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(Common::SeekableReadStream* DLFile, 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++) { - DBG("Section %d: type = %x, size = %x, entsize = %x, link = %x\n", - i, shdr[i].sh_type, shdr[i].sh_size, shdr[i].sh_entsize, shdr[i].sh_link); - - 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 (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || - DLFile->read(_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(Common::SeekableReadStream* DLFile, 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 (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || - DLFile->read(_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, Elf32_Addr shortsOffset) { - - int shortsCount = 0, othersCount = 0; - DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); - - // 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) { - if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { - othersCount++; - 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); - } else { // shorts section - shortsCount++; - s->st_value += shortsOffset; - if (!_shortsSegment->inSegment((char *)s->st_value)) - seterror("Symbol out of bounds! st_value = %x\n", s->st_value); - } - - } - - } - - DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); -} - -bool DLObject::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++) { - - 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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { - return false; - } - } else { // In Shorts segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { - return false; - } - } - - } - } - - return true; -} - - -bool DLObject::load(Common::SeekableReadStream* DLFile) { - fprintf(stderr, "In DLObject::load\n"); - - Elf32_Ehdr ehdr; // ELF header - Elf32_Phdr phdr; // Program header - Elf32_Shdr *shdr; // Section header - bool ret = true; - - if (readElfHeader(DLFile, &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(DLFile, &ehdr, &phdr, i) == false) - return false; - - if (!loadSegment(DLFile, &phdr)) - return false; - } - - if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == NULL) - ret = false; - - if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) - ret = false; - - if (ret && (loadStringTable(DLFile, shdr) == false)) - ret = false; - - if (ret) - relocateSymbols((Elf32_Addr)_segment, _shortsSegment->getOffset()); // Offset by our segment allocated address - - if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) - ret = false; - - free(shdr); - - return ret; -} - -bool DLObject::open(const char *path) { - Common::SeekableReadStream* DLFile; - void *ctors_start, *ctors_end; - - DBG("open(\"%s\")\n", path); - - // Get the address of the global pointer - _gpVal = (unsigned int) & _gp; - DBG("_gpVal is %x\n", _gpVal); - - Common::FSNode file(path); - - if (!(DLFile = file.createReadStream())) { - seterror("%s not found.", path); - return false; - } - - // Try to load and relocate - if (!load(DLFile)) { - //::close(fd); - unload(); - return false; - } - - //::close(fd); - - // flush data cache - DBG("Flushing data cache"); - FlushCache(0); - FlushCache(2); - - // Get the symbols for the global constructors and destructors - 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++) { - - // We can only import symbols that are global or weak in the plugin - if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && - /*_strtab[s->st_name] == '_' && */ // Try to make this more efficient - !strcmp(name, _strtab + s->st_name)) { - - // We found the symbol - DBG("=> %p\n", (void*)s->st_value); - return (void*)s->st_value; - } - } - - seterror("Symbol \"%s\" not found.", name); - return NULL; -} - - - -ShortSegmentManager::ShortSegmentManager() { - _shortsStart = &__plugin_hole_start ; - _shortsEnd = &__plugin_hole_end; -} - -ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { - char *lastAddress = origAddr; - Common::List::iterator i; - - // Find a block that fits, starting from the beginning - for (i = _list.begin(); i != _list.end(); ++i) { - char *currAddress = (*i)->getStart(); - - if ((int)(currAddress - lastAddress) >= size) break; - - lastAddress = (*i)->getEnd(); - } - - if ((Elf32_Addr)lastAddress & 3) - lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 - - if (lastAddress + size > _shortsEnd) { - seterror("Error. No space in shorts segment for %x bytes. Last address is %p, max address is %p.\n", - size, lastAddress, _shortsEnd); - return NULL; - } - - Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment - - if (lastAddress + size > _highestAddress) _highestAddress = lastAddress + size; // Keep track of maximum - - _list.insert(i, seg); - - DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", - size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); - - return seg; -} - -void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { - DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); - _list.remove(seg); - delete seg; -} - -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 && __PLAYSTATION2__ */ diff --git a/backends/platform/ps2/ps2loader.h b/backends/platform/ps2/ps2loader.h deleted file mode 100644 index cfaf4e4f55..0000000000 --- a/backends/platform/ps2/ps2loader.h +++ /dev/null @@ -1,137 +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 PS2LOADER_H -#define PS2LOADER_H - -#include "elf32.h" -#include "common/list.h" -#include "common/singleton.h" - -#define MAXDLERRLEN 80 - -#define ShortsMan ShortSegmentManager::instance() - -class ShortSegmentManager : public Common::Singleton { -private: - char *_shortsStart; - char *_shortsEnd; - -public: - char *getShortsStart() { - return _shortsStart; - } - bool inGeneralSegment(char *addr) { - return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); - } - - class Segment { - private: - friend class ShortSegmentManager; - Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} - ~Segment() {} - char *_startAddress; // Start of shorts segment in memory - int _size; // Size of shorts segment - char *_origAddress; // Original address this segment was supposed to be at - public: - char *getStart() { - return _startAddress; - } - char *getEnd() { - return (_startAddress + _size); - } - Elf32_Addr getOffset() { - return (Elf32_Addr)(_startAddress - _origAddress); - } - bool inSegment(char *addr) { - return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); - } - }; - - Segment *newSegment(int size, char *origAddr); - void deleteSegment(Segment *); - -private: - ShortSegmentManager(); - friend class Common::Singleton; - Common::List _list; - char *_highestAddress; -}; - - - - -class DLObject { -protected: - char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */ - - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - void *_segment, *_symtab; - char *_strtab; - int _symbol_cnt; - int _symtab_sect; - void *_dtors_start, *_dtors_end; - - unsigned int _gpVal; // Value of Global Pointer - int _segmentSize; - - void seterror(const char *fmt, ...); - void unload(); - bool relocate(Common::SeekableReadStream*, unsigned long offset, unsigned long size, void *); - bool load(Common::SeekableReadStream*); - - bool readElfHeader(Common::SeekableReadStream*, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream*, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - bool loadSegment(Common::SeekableReadStream*, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream*, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream*, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream*, Elf32_Shdr *shdr); - void relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset); - bool relocateRels(Common::SeekableReadStream*, 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), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , - _segmentSize(0) {} -}; - - - -#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 /* PS2LOADER_H */ diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index 8e83563d10..c479244551 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -88,8 +88,8 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.syms scummvm-psp.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-psp.org.elf,-Tplugin.ld,--retain-symbols-file,plugin.syms -lstdc++ -lc +PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/plugin.syms scummvm-psp.elf +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-psp.org.elf,-T$(srcdir)/backends/plugins/psp/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/plugin.syms -lstdc++ -lc # PSP-specific variables STRIP = psp-strip diff --git a/backends/platform/psp/plugin.ld b/backends/platform/psp/plugin.ld deleted file mode 100644 index db4df45264..0000000000 --- a/backends/platform/psp/plugin.ld +++ /dev/null @@ -1,239 +0,0 @@ -OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", - "elf32-littlemips") -OUTPUT_ARCH(mips:allegrex) -PHDRS -{ - plugin PT_LOAD ; - shorts PT_LOAD ; -} -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = 0; - .interp : { *(.interp) } : plugin - .reginfo : { *(.reginfo) } : plugin - .dynamic : { *(.dynamic) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.init : { *(.rel.init) } - .rela.init : { *(.rela.init) } - .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } - .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } - .rel.fini : { *(.rel.fini) } - .rela.fini : { *(.rela.fini) } - /* PSP-specific relocations. */ - .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } - .rel.lib.ent.top : { *(.rel.lib.ent.top) } - .rel.lib.ent : { *(.rel.lib.ent) } - .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } - .rel.lib.stub.top : { *(.rel.lib.stub.top) } - .rel.lib.stub : { *(.rel.lib.stub) } - .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } - .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } - .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } - .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } - .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } - .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } - .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } - .rel.data.rel.ro : { *(.rel.data.rel.ro*) } - .rela.data.rel.ro : { *(.rel.data.rel.ro*) } - .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } - .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } - .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } - .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } - .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } - .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } - .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } - .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } - .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } - .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } - .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } - .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } - .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } - .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } - .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .text : - { - _ftext = . ; - *(.text .stub .text.* .gnu.linkonce.t.*) - KEEP (*(.text.*personality*)) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.mips16.fn.*) *(.mips16.call.*) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - /* PSP library stub functions. */ - .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - /* PSP library entry table and library stub table. */ - .lib.ent.top : { *(.lib.ent.top) } - .lib.ent : { *(.lib.ent) } - .lib.ent.btm : { *(.lib.ent.btm) } - .lib.stub.top : { *(.lib.stub.top) } - .lib.stub : { *(.lib.stub) } - .lib.stub.btm : { *(.lib.stub.btm) } - /* PSP read-only data for module info, NIDs, and Vstubs. The - .rodata.sceModuleInfo section must appear before the .rodata section - otherwise it would get absorbed into .rodata and the PSP bootloader - would be unable to locate the module info structure. */ - .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } - .rodata.sceResident : { *(.rodata.sceResident) } - .rodata.sceNid : { *(.rodata.sceNid) } - .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } - .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } - .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(256) + (. & (256 - 1)); - /* 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*) } - .data : - { - _fdata = . ; - *(.data .data.* .gnu.linkonce.d.*) - KEEP (*(.gnu.linkonce.d.*personality*)) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - . = .; - .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 = .; - PROVIDE (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) } - /DISCARD/ : { *(.comment) *(.pdr) } - /DISCARD/ : { *(.note.GNU-stack) } - - . = __plugin_hole_start; - .got : { *(.got.plt) *(.got) } : shorts - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : - { - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - _fbss = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - - -} diff --git a/backends/platform/psp/plugin.syms b/backends/platform/psp/plugin.syms deleted file mode 100644 index 24ee1a19dc..0000000000 --- a/backends/platform/psp/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-relocs.cpp b/backends/plugins/arm-relocs.cpp index 66e466a58a..b00fb42f4a 100644 --- a/backends/plugins/arm-relocs.cpp +++ b/backends/plugins/arm-relocs.cpp @@ -134,3 +134,31 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset free(rel); return true; } + +bool DLObject::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++) { + + Elf32_Shdr *curShdr = &(shdr[i]); + + if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { + seterror("RELA entries not supported yet!\n"); + return false; + } + + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { + return false; + } + + } + } + + return true; +} diff --git a/backends/plugins/ds/plugin.ld b/backends/plugins/ds/plugin.ld new file mode 100644 index 0000000000..2b2bca9745 --- /dev/null +++ b/backends/plugins/ds/plugin.ld @@ -0,0 +1,218 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", + "elf32-littlearm") +OUTPUT_ARCH(arm) + +/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ +PHDRS { + plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ +} + +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + .interp : { *(.interp) } : plugin + .note.gnu.build-id : { *(.note.gnu.build-id) } + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.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.gnu.linkonce.d.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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .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.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + PROVIDE_HIDDEN (__rel_iplt_end = .); + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rel.plt : + { + *(.rel.plt) + } + .rela.plt : + { + *(.rela.plt) + } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .iplt : { *(.iplt) } + .text : + { + *(.text.unlikely .text.*_unlikely) + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } + __exidx_start = .; + .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } + __exidx_end = .; + .eh_frame_hdr : { *(.eh_frame_hdr) } + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RO { *(.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(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); + /* Exception handling */ + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) } + /* Thread Local Storage sections */ + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + } + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + PROVIDE_HIDDEN (__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* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) } + .dynamic : { *(.dynamic) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + .data : + { + __data_start = . ; + *(.data .data.* .gnu.linkonce.d.*) + 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. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ + . = ALIGN(. != 0 ? 32 / 8 : 1); + } + _bss_end__ = . ; __bss_end__ = . ; + . = ALIGN(32 / 8); + . = ALIGN(32 / 8); + __end__ = . ; + _end = .; PROVIDE (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) } + /* DWARF 3 */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + .stack 0x80000 : + { + _stack = .; + *(.stack) + } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) } +} diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 685d22e28a..eae8bebcc7 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -30,12 +30,11 @@ #include #include #include +#include #include -//#include "backends/fs/stdiostream.h" -//#include "backends/fs/ds/ds-fs.h" -#include "dsmain.h" - +#include "common/file.h" +#include "common/fs.h" #include "elf-loader.h" #define __DEBUG_PLUGINS__ @@ -61,7 +60,6 @@ void flushDataCache() { #endif } - // Expel the symbol table from memory void DLObject::discard_symtab() { free(_symtab); @@ -76,18 +74,13 @@ void DLObject::unload() { discard_symtab(); free(_segment); _segment = NULL; -} -/** - * Follow the instruction of a relocation section. - * - * @param DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * - */ -bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - dlRelocate(DLFile, offset, size, relSegment); +#ifdef MIPS_TARGET + if (_shortsSegment) { + ShortsMan.deleteSegment(_shortsSegment); + _shortsSegment = NULL; + } +#endif } bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { @@ -135,6 +128,33 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) char *baseAddress = 0; +#ifdef MIPS_TARGET + // We need to take account of non-allocated segment for shorts + if (phdr->p_flags & PF_X) { // This is a relocated segment + + // 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 (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI + + 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; + } else { // This is a shorts section. + _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); + + baseAddress = _shortsSegment->getStart(); + DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", + _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + } +#else // 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); @@ -149,9 +169,7 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) // Get offset to load segment into baseAddress = (char *)_segment + phdr->p_vaddr; _segmentSize = phdr->p_memsz + extra; - - DBG("base address is %p\n", baseAddress); - DBG("_segmentSize is %p\n", _segmentSize); +#endif // Set bss segment to 0 if necessary (assumes bss is at the end) if (phdr->p_memsz > phdr->p_filesz) { @@ -260,53 +278,41 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s void DLObject::relocateSymbols(Elf32_Addr offset) { - int relocCount = 0; - DBG("Relocating symbols by %x\n", offset); + int mainCount = 0; + int shortsCount= 0; // Loop over symbols, add relocation offset Elf32_Sym *s = (Elf32_Sym *)_symtab; for (int c = _symbol_cnt; c--; s++) { + +#ifdef MIPS_TARGET // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { - relocCount++; + if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { + mainCount++; 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(Common::SeekableReadStream* DLFile, 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 || curShdr->sh_type == SHT_RELA) && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { - seterror("RELA entries not supported yet!\n"); - return false; + } else { // shorts section + shortsCount++; + s->st_value += _shortsSegment->getOffset(); + if (!_shortsSegment->inSegment((char *)s->st_value)) + seterror("Symbol out of bounds! st_value = %x\n", s->st_value); } - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { - return false; - } + } +#else + // 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); } - } +#endif - return true; + } } bool DLObject::load(Common::SeekableReadStream* DLFile) { diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index e8c5701f6e..1bbcbc4b78 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -23,11 +23,16 @@ * */ -#ifndef LOADER_H -#define LOADER_H +#ifndef ELF_LOADER_H +#define ELF_LOADER_H -#include "backends/plugins/elf32.h" -#include "common/list.h" +#include "elf32.h" +#include "common/stream.h" + +#if defined(__PLAYSTATION2__) || defined(__PSP__) +#define MIPS_TARGET +#include "shorts-segment-manager.h" +#endif #define MAXDLERRLEN 80 @@ -43,6 +48,11 @@ protected: int _segmentSize; +#ifdef MIPS_TARGET + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + unsigned int _gpVal; // Value of Global Pointer +#endif + void seterror(const char *fmt, ...); void unload(); bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); @@ -65,7 +75,13 @@ public: 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) {} + _segmentSize(0) { +#ifdef MIPS_TARGET + _shortsSegment = NULL; + _gpVal = 0; +#endif + } + }; #define RTLD_LAZY 0 @@ -78,8 +94,6 @@ extern "C" { void dlforgetsyms(void *handle); } -//The following need to be defined by specific ports. extern void flushDataCache(); -extern bool dlRelocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); #endif /* LOADER_H */ diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h deleted file mode 100644 index fc8334ad17..0000000000 --- a/backends/plugins/mips-loader.h +++ /dev/null @@ -1,43 +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 MIPS_LOADER_H -#define MIPS_LOADER_H - -#include "loader.h" -#include "shorts-segment-manager.h" - -class MipsDLObject : public DLObject { -protected: - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - unsigned int _gpVal; // Value of Global Pointer - -public: - MipsDLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , - _segmentSize(0) {} -}; - -#endif /* MIPS_LOADER_H */ diff --git a/backends/plugins/mips-relocs.cpp b/backends/plugins/mips-relocs.cpp new file mode 100644 index 0000000000..fe8fa7c1a0 --- /dev/null +++ b/backends/plugins/mips-relocs.cpp @@ -0,0 +1,259 @@ +/* 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$ + * + */ + +#include "elf-loader.h" + +#define __DEBUG_PLUGINS__ + +#ifdef __DEBUG_PLUGINS__ +#define DBG(x,...) printf(x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) printf(x, ## __VA_ARGS__) + +/** + * Follow the instruction of a relocation section. + * + * @param DLFile SeekableReadStream of File + * @param offset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) + * + */ +bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = NULL; // relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + seterror("Out of memory."); + return false; + } + + // Read in our relocation table + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != (ssize_t)size) { + seterror("Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + bool seenHi16 = false; // For treating HI/LO16 commands + int firstHi16 = -1; // Mark the point of the first hi16 seen + Elf32_Addr ahl = 0; // Calculated addend + int a = 0; // Addend: taken from the target + + unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives + unsigned int relocation = 0; + int debugRelocs[10] = {0}; // For debugging + int extendedHi16 = 0; // Count extended hi16 treatments + Elf32_Addr lastHiSymVal = 0; + bool hi16InShorts = false; + +#define DEBUG_NUM 2 + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; // Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + + case R_MIPS_HI16: // Absolute addressing. + if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) + firstHi16 < 0) { // Only process first in block of HI16s + firstHi16 = i; // Keep the first Hi16 we saw + seenHi16 = true; + ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up + + lastHiSymVal = sym->st_value; + hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments + if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number + DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", + i, rel[i].r_offset, ahl, *target); + } + break; + + case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) + if (!seenHi16) { // We MUST have seen HI16 first + seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); + free(rel); + return false; + } + + // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) + // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section + // and will be screened out above + bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); + + // Correct the bug by getting the proper value in ahl (taken from the current symbol) + if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { + ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset + ahl += (sym->st_value & 0xffff0000); + } + + ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s + a = *target & 0xffff; // Take lower 16 bits of the target + a = (a << 16) >> 16; // Sign extend them + ahl += a; // Add lower 16 bits. AHL is now complete + + // Fix: we can have LO16 access to the short segment sometimes + if (lo16InShorts) { + relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset + } else // It's in the regular segment + relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment + + if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now + for (int j = firstHi16; j < i; j++) { + if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s + + lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target + *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target + *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation + if (relocation & 0x8000)(*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case + } + firstHi16 = -1; // Reset so we'll know we treated it + } else { + extendedHi16++; + } + + *target &= 0xffff0000; // Clear the lower 16 bits of current target + *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation + + if (debugRelocs[1]++ < DEBUG_NUM) + DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) + DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + } + break; + + case R_MIPS_26: // Absolute addressing (for jumps and branches only) + if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment + a = *target & 0x03ffffff; // Get 26 bits' worth of the addend + a = (a << 6) >> 6; // Sign extend a + relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset + *target &= 0xfc000000; // Clean lower 26 target bits + *target |= (relocation & 0x03ffffff); + + if (debugRelocs[3]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } else { + if (debugRelocs[4]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } + break; + + case R_MIPS_GPREL16: // GP Relative addressing + if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section + ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole + a = *target & 0xffff; // Get 16 bits' worth of the addend + a = (a << 16) >> 16; // Sign extend it + + relocation = a + _shortsSegment->getOffset(); + + *target &= 0xffff0000; // Clear the lower 16 bits of the target + *target |= relocation & 0xffff; + + if (debugRelocs[5]++ < DEBUG_NUM) + DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", + i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); + } + + break; + + case R_MIPS_32: // Absolute addressing + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + + if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment + relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset + else // We're in the main section + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + *target = relocation; + + if (debugRelocs[6]++ < DEBUG_NUM) + DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + default: + seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); + free(rel); + return false; + } + } + + DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); + + free(rel); + return true; +} + +bool DLObject::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++) { + + 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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { + return false; + } + } else { // In Shorts segment + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { + return false; + } + } + + } + } + + return true; +} + diff --git a/backends/plugins/plugin.syms b/backends/plugins/plugin.syms new file mode 100644 index 0000000000..24ee1a19dc --- /dev/null +++ b/backends/plugins/plugin.syms @@ -0,0 +1,8 @@ +PLUGIN_getVersion +PLUGIN_getType +PLUGIN_getTypeVersion +PLUGIN_getObject +___plugin_ctors +___plugin_ctors_end +___plugin_dtors +___plugin_dtors_end diff --git a/backends/plugins/ps2/plugin.ld b/backends/plugins/ps2/plugin.ld new file mode 100644 index 0000000000..9879413b98 --- /dev/null +++ b/backends/plugins/ps2/plugin.ld @@ -0,0 +1,94 @@ +/* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ +PHDRS { + plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ + shorts PT_LOAD ; /* Specifies that the shorts segment should be loaded from file */ +} +SECTIONS { + .text 0: { + _ftext = . ; + *(.text) + *(.text.*) + *(.gnu.linkonce.t*) + KEEP(*(.init)) + KEEP(*(.fini)) + QUAD(0) + } : plugin /*The ": plugin" tells the linker to assign this and + the following sections to the "plugin" segment*/ + PROVIDE(_etext = .); + PROVIDE(etext = .); + + .reginfo : { *(.reginfo) } + + /* Global/static constructors and deconstructors. */ + .ctors ALIGN(16): { + ___plugin_ctors = .; + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + ___plugin_ctors_end = .; + } + .dtors ALIGN(16): { + ___plugin_dtors = .; + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + ___plugin_dtors_end = .; + } + + /* Static data. */ + .rodata ALIGN(128): { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + } + + .data ALIGN(128): { + _fdata = . ; + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + SORT(CONSTRUCTORS) + } + + .rdata ALIGN(128): { *(.rdata) } + .gcc_except_table ALIGN(128): { *(.gcc_except_table) } + + .bss ALIGN(128) : { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b*) + *(COMMON) + } + _end_bss = .; + + _end = . ; + PROVIDE(end = .); + + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); + + /*We assign the output location counter to the plugin hole made + in main_prog.ld, then assign the small data sections to the shorts segment*/ + . = __plugin_hole_start; + .lit4 ALIGN(128): { *(.lit4) } : shorts + .lit8 ALIGN(128): { *(.lit8) } + + .sdata ALIGN(128): { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s*) + } + + _edata = .; + PROVIDE(edata = .); + + /* Uninitialized data. */ + .sbss ALIGN(128) : { + _fbss = . ; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb*) + *(.scommon) + } + +} diff --git a/backends/plugins/psp/plugin.ld b/backends/plugins/psp/plugin.ld new file mode 100644 index 0000000000..db4df45264 --- /dev/null +++ b/backends/plugins/psp/plugin.ld @@ -0,0 +1,239 @@ +OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", + "elf32-littlemips") +OUTPUT_ARCH(mips:allegrex) +PHDRS +{ + plugin PT_LOAD ; + shorts PT_LOAD ; +} +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = 0; + .interp : { *(.interp) } : plugin + .reginfo : { *(.reginfo) } : plugin + .dynamic : { *(.dynamic) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + /* PSP-specific relocations. */ + .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } + .rel.lib.ent.top : { *(.rel.lib.ent.top) } + .rel.lib.ent : { *(.rel.lib.ent) } + .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } + .rel.lib.stub.top : { *(.rel.lib.stub.top) } + .rel.lib.stub : { *(.rel.lib.stub) } + .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } + .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } + .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } + .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } + .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data.rel.ro : { *(.rel.data.rel.ro*) } + .rela.data.rel.ro : { *(.rel.data.rel.ro*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } + .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } + .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } + .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + _ftext = . ; + *(.text .stub .text.* .gnu.linkonce.t.*) + KEEP (*(.text.*personality*)) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.mips16.fn.*) *(.mips16.call.*) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + /* PSP library stub functions. */ + .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + /* PSP library entry table and library stub table. */ + .lib.ent.top : { *(.lib.ent.top) } + .lib.ent : { *(.lib.ent) } + .lib.ent.btm : { *(.lib.ent.btm) } + .lib.stub.top : { *(.lib.stub.top) } + .lib.stub : { *(.lib.stub) } + .lib.stub.btm : { *(.lib.stub.btm) } + /* PSP read-only data for module info, NIDs, and Vstubs. The + .rodata.sceModuleInfo section must appear before the .rodata section + otherwise it would get absorbed into .rodata and the PSP bootloader + would be unable to locate the module info structure. */ + .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } + .rodata.sceResident : { *(.rodata.sceResident) } + .rodata.sceNid : { *(.rodata.sceNid) } + .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .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(256) + (. & (256 - 1)); + /* 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*) } + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + KEEP (*(.gnu.linkonce.d.*personality*)) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + . = .; + .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 = .; + PROVIDE (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) } + /DISCARD/ : { *(.comment) *(.pdr) } + /DISCARD/ : { *(.note.GNU-stack) } + + . = __plugin_hole_start; + .got : { *(.got.plt) *(.got) } : shorts + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + _fbss = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + + +} diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index cce93e7f86..eb2ab2d953 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -25,9 +25,20 @@ #if defined(DYNAMIC_MODULES) //TODO: && defined (MIPS target) -//#include "MIPS-loader.h" #include "shorts-segment-manager.h" +extern char __plugin_hole_start; // Indicates start of hole in program file for shorts +extern char __plugin_hole_end; // Indicates end of hole in program file +extern char _gp[]; // Value of gp register + +#ifdef DEBUG_PLUGINS +#define DBG(x,...) printf(x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) printf(x, ## __VA_ARGS__) + DECLARE_SINGLETON(ShortSegmentManager); // For singleton ShortSegmentManager::ShortSegmentManager() { diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h index 40ceef60f0..02f5221e8d 100644 --- a/backends/plugins/shorts-segment-manager.h +++ b/backends/plugins/shorts-segment-manager.h @@ -26,8 +26,9 @@ #ifndef SHORTS_SEGMENT_MANAGER_H #define SHORTS_SEGMENT_MANAGER_H -#include "loader.h" #include "common/singleton.h" +#include "common/list.h" +#include "elf32.h" #define ShortsMan ShortSegmentManager::instance() -- cgit v1.2.3 From e8fc5f207093e8a0518dca5d815233e912945e2d Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 28 Jul 2010 00:08:32 +0000 Subject: various manual tweaks to get ds port compiling from branch again after earlier merge from trunk svn-id: r51398 --- backends/platform/ds/arm7/source/main.cpp | 4 +- backends/platform/ds/arm9/makefile | 3 - backends/platform/ds/arm9/source/dsmain.cpp | 427 +++++++++------------ .../platform/ds/commoninclude/NDS/scummvm_ipc.h | 12 + backends/plugins/ds/ds-provider.cpp | 2 +- backends/plugins/elf-loader.cpp | 8 +- 6 files changed, 213 insertions(+), 243 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm7/source/main.cpp b/backends/platform/ds/arm7/source/main.cpp index 7029d96405..c2e949cd90 100644 --- a/backends/platform/ds/arm7/source/main.cpp +++ b/backends/platform/ds/arm7/source/main.cpp @@ -38,7 +38,7 @@ #include #include #include -//#include // not needed in current libnds +#include // Needed for SOUND_CR #include ////////////////////////////////////////////////////////////////////// #ifdef USE_DEBUGGER @@ -590,7 +590,7 @@ int main(int argc, char ** argv) { IPC->reset = false; - fifoInit(); + //fifoInit(); for (int r = 0; r < 8; r++) { IPC->adpcm.arm7Buffer[r] = (u8 *) malloc(512); diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index c5e4fe414c..d86a019452 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -114,9 +114,6 @@ ifdef DS_BUILD_A DEFINES += -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM LOGO = logoa.bmp ENABLE_SCUMM = $(ENABLED) - #DEFINES += -DENABLE_SCUMM=$(ENABLED) - #MODULES += engines/scumm - USE_ARM_GFX_ASM = 1 BUILD=scummvm-A endif diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index 8b1ed32c67..1f3a67d818 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -8,15 +8,18 @@ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ * */ @@ -80,8 +83,10 @@ //#include //basic print funcionality #include +#include + +#include "NDS/scummvm_ipc.h" #include "dsmain.h" -#include "string.h" #include "osystem_ds.h" #include "icons_raw.h" #include "fat/gba_nds_fat.h" @@ -97,17 +102,23 @@ #endif #include "ramsave.h" #include "blitters.h" -#include "cartreset_nolibfat.h" +#include "libcartreset/cartreset_nolibfat.h" #include "keys.h" #ifdef USE_PROFILER #include "profiler/cyg-profile.h" #endif -#include "backends/fs/ds/ds-fs.h" #include "base/version.h" #include "engine.h" + +#include "backends/plugins/ds/ds-provider.h" + +#include "backends/fs/ds/ds-fs.h" +#include "base/version.h" +#include "common/util.h" + extern "C" void OurIntrMain(void); -extern "C" u32 getExceptionAddress( u32 opcodeAddress, u32 thumbState); +extern "C" u32 getExceptionAddress(u32 opcodeAddress, u32 thumbState); extern const char __itcm_start[]; static const char *registerNames[] = @@ -116,22 +127,20 @@ static const char *registerNames[] = #ifdef WRAP_MALLOC -extern "C" void* __real_malloc(size_t size); +extern "C" void *__real_malloc(size_t size); -int total = 0; +static int s_total_malloc = 0; -void* operator new (size_t size) -{ +void *operator new (size_t size) { register unsigned int reg asm("lr"); volatile unsigned int poo = reg; - void* res = __real_malloc(size); - total += size; + void *res = __real_malloc(size); + s_total_malloc += size; - if (!res) - { + if (!res) { // *((u8 *) NULL) = 0; - consolePrintf("Failed alloc (new) %d (%d)\n", size, total); + consolePrintf("Failed alloc (new) %d (%d)\n", size, s_total_malloc); return NULL; } @@ -139,7 +148,7 @@ void* operator new (size_t size) } -extern "C" void* __wrap_malloc(size_t size) { +extern "C" void *__wrap_malloc(size_t size) { /* u32 addr; asm("mov %0, lr" @@ -151,23 +160,22 @@ extern "C" void* __wrap_malloc(size_t size) { volatile unsigned int poo = reg; - if (size == 0) - { + if (size == 0) { static int zeroSize = 0; consolePrintf("0 size malloc (%d)", zeroSize++); } - void* res = __real_malloc(size); + void *res = __real_malloc(size); if (res) { if (size > 50 * 1024) { consolePrintf("Allocated %d (%x)\n", size, poo); } - total += size; + s_total_malloc += size; return res; } else { // *((u8 *) NULL) = 0; - consolePrintf("Failed alloc %d (%d)\n", size, total); + consolePrintf("Failed alloc %d (%d)\n", size, s_total_malloc); return NULL; } } @@ -193,112 +201,109 @@ enum MouseMode { #define SCUMM_GAME_HEIGHT 142 #define SCUMM_GAME_WIDTH 227 -int textureID; -u16* texture; - -int frameCount; -int currentTimeMillis; +static int frameCount; +static int currentTimeMillis; // Timer Callback -int callbackInterval; -int callbackTimer; -OSystem_DS::TimerProc callback; +static int callbackInterval; +static int callbackTimer; +static OSystem_DS::TimerProc callback; // Scaled -bool scaledMode; -int scX; -int scY; +static bool scaledMode; +static int scX; +static int scY; -int subScX; -int subScY; -int subScTargetX; -int subScTargetY; -int subScreenWidth = SCUMM_GAME_WIDTH; -int subScreenHeight = SCUMM_GAME_HEIGHT; -int subScreenScale = 256; +static int subScX; +static int subScY; +static int subScTargetX; +static int subScTargetY; +static int subScreenWidth = SCUMM_GAME_WIDTH; +static int subScreenHeight = SCUMM_GAME_HEIGHT; +static int subScreenScale = 256; // Sound -int bufferSize; -s16* soundBuffer; -int bufferFrame; -int bufferRate; -int bufferSamples; -bool soundHiPart; -int soundFrequency; +static int bufferSize; +static s16 *soundBuffer; +static int bufferFrame; +static int bufferRate; +static int bufferSamples; +static bool soundHiPart; +static int soundFrequency; // Events -int lastEventFrame; -bool indyFightState; -bool indyFightRight; +static int lastEventFrame; +static bool indyFightState; +static bool indyFightRight; -OSystem_DS::SoundProc soundCallback; -void* soundParam; -int lastCallbackFrame; -bool bufferFirstHalf; -bool bufferSecondHalf; +static OSystem_DS::SoundProc soundCallback; +static int lastCallbackFrame; +static bool bufferFirstHalf; +static bool bufferSecondHalf; // Saved buffers -bool highBuffer; -bool displayModeIs8Bit = false; +static bool highBuffer; +static bool displayModeIs8Bit = false; // Game id -u8 gameID; +static u8 gameID; -bool snapToBorder = false; -bool consoleEnable = false; -bool gameScreenSwap = false; +static bool snapToBorder = false; +static bool consoleEnable = false; +static bool gameScreenSwap = false; bool isCpuScalerEnabled(); //#define HEAVY_LOGGING -MouseMode mouseMode = MOUSE_LEFT; +static MouseMode mouseMode = MOUSE_LEFT; -int storedMouseX = 0; -int storedMouseY = 0; +static int storedMouseX = 0; +static int storedMouseY = 0; // Sprites -SpriteEntry sprites[128]; -SpriteEntry spritesMain[128]; -int tweak; +static SpriteEntry sprites[128]; +static SpriteEntry spritesMain[128]; +static int tweak; // Shake -int shakePos = 0; +static int s_shakePos = 0; // Keyboard -bool keyboardEnable = false; -bool leftHandedMode = false; -bool keyboardIcon = false; +static bool keyboardEnable = false; +static bool leftHandedMode = false; +static bool keyboardIcon = false; // Touch -int touchScX, touchScY, touchX, touchY; -int mouseHotspotX, mouseHotspotY; -bool cursorEnable = false; -bool mouseCursorVisible = true; -bool rightButtonDown = false; -bool touchPadStyle = false; -int touchPadSensitivity = 8; -bool tapScreenClicks = true; - -int tapCount = 0; -int tapTimeout = 0; -int tapComplete = 0; +static int touchScX, touchScY, touchX, touchY; +static int mouseHotspotX, mouseHotspotY; +static bool cursorEnable = false; +static bool mouseCursorVisible = true; +static bool leftButtonDown = false; +static bool rightButtonDown = false; +static bool touchPadStyle = false; +static int touchPadSensitivity = 8; +static bool tapScreenClicks = true; + +static int tapCount = 0; +static int tapTimeout = 0; +static int tapComplete = 0; // Dragging -int dragStartX, dragStartY; -bool dragging = false; -int dragScX, dragScY; +static int dragStartX, dragStartY; +static bool dragging = false; +static int dragScX, dragScY; // Interface styles -char gameName[32]; +static char gameName[32]; // 8-bit surface size -int gameWidth = 320; -int gameHeight = 200; +static int gameWidth = 320; +static int gameHeight = 200; // Scale -bool twoHundredPercentFixedScale = false; -bool cpuScalerEnable = false; +static bool twoHundredPercentFixedScale = false; +static bool cpuScalerEnable = false; // 100 256 // 150 192 @@ -309,14 +314,14 @@ bool cpuScalerEnable = false; #ifdef USE_PROFILER -int hBlankCount = 0; +static int hBlankCount = 0; #endif -u8* scalerBackBuffer = NULL; +static u8 *scalerBackBuffer = NULL; #define NUM_SUPPORTED_GAMES 21 -gameListType gameList[NUM_SUPPORTED_GAMES] = { +static const gameListType gameList[NUM_SUPPORTED_GAMES] = { // Unknown game - use normal SCUMM controls {"unknown", CONT_SCUMM_ORIGINAL}, @@ -345,31 +350,29 @@ gameListType gameList[NUM_SUPPORTED_GAMES] = { {"parallaction", CONT_NIPPON}, }; -gameListType* currentGame = NULL; +static const gameListType *s_currentGame = NULL; // Stylus -#define ABS(x) ((x)>0?(x):-(x)) - -bool penDown = FALSE; -bool penHeld = FALSE; -bool penReleased = FALSE; -bool penDownLastFrame = FALSE; -s32 penX = 0, penY = 0; -s32 penDownX = 0, penDownY = 0; -int keysDownSaved = 0; -int keysReleasedSaved = 0; -int keysChangedSaved = 0; +static bool penDown = FALSE; +static bool penHeld = FALSE; +static bool penReleased = FALSE; +static bool penDownLastFrame = FALSE; +static s32 penX = 0, penY = 0; +static s32 penDownX = 0, penDownY = 0; +static int keysDownSaved = 0; +static int keysReleasedSaved = 0; +static int keysChangedSaved = 0; -bool penDownSaved = FALSE; -bool penReleasedSaved = FALSE; -int penDownFrames = 0; -int touchXOffset = 0; -int touchYOffset = 0; +static bool penDownSaved = FALSE; +static bool penReleasedSaved = FALSE; +static int penDownFrames = 0; +static int touchXOffset = 0; +static int touchYOffset = 0; -int triggeredIcon = 0; -int triggeredIconTimeout = 0; +static int triggeredIcon = 0; +static int triggeredIconTimeout = 0; -u16 savedPalEntry255 = RGB15(31, 31, 31); +static u16 savedPalEntry255 = RGB15(31, 31, 31); extern "C" int scummvm_main(int argc, char *argv[]); @@ -382,7 +385,7 @@ void setIcon(int num, int x, int y, int imageNum, int flags, bool enable); void setIconMain(int num, int x, int y, int imageNum, int flags, bool enable); void uploadSpriteGfx(); -TransferSound soundControl; +static TransferSound soundControl; bool isCpuScalerEnabled() { @@ -430,12 +433,12 @@ void setTopScreenZoom(int percentage) { // return (ConfMan.hasKey("cpu_scaler", "ds") && ConfMan.getBool("cpu_scaler", "ds")); controlType getControlType() { - return currentGame->control; + return s_currentGame->control; } //plays an 8 bit mono sample at 11025Hz -void playSound(const void* data, u32 length, bool loop, bool adpcm, int rate) { +void playSound(const void *data, u32 length, bool loop, bool adpcm, int rate) { if (!IPC->soundData) { soundControl.count = 0; @@ -551,21 +554,8 @@ int getSoundFrequency() { return soundFrequency; } -void setControls(char* gameName) { - - for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) { - if (!stricmp(gameName, gameList[r].gameId)) { - currentGame = &gameList[r]; - consolePrintf("Current game set to: %s\n", gameName); - return; - } - } - - consolePrintf("Failed to set current game to: %s\n", gameName); -} - void exitGame() { - currentGame = NULL; + s_currentGame = NULL; } void initGame() { @@ -580,17 +570,17 @@ void initGame() { setOptions(); //strcpy(gameName, ConfMan.getActiveDomain().c_str()); - if (currentGame == NULL) { + if (s_currentGame == NULL) { strcpy(gameName, ConfMan.get("gameid").c_str()); // consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]); - currentGame = &gameList[0]; // Default game + s_currentGame = &gameList[0]; // Default game for (int r = 0; r < NUM_SUPPORTED_GAMES; r++) { if (!stricmp(gameName, gameList[r].gameId)) { - currentGame = &gameList[r]; - // consolePrintf("Game list num: %d\n", currentGame); + s_currentGame = &gameList[r]; + // consolePrintf("Game list num: %d\n", s_currentGame); } } } @@ -785,7 +775,7 @@ void checkSleepMode() { } void setShowCursor(bool enable) { - if ((currentGame) && (currentGame->control == CONT_SCUMM_SAMNMAX)) { + if ((s_currentGame) && (s_currentGame->control == CONT_SCUMM_SAMNMAX)) { if (cursorEnable) { sprites[1].attribute[0] = ATTR0_BMP | 150; } else { @@ -801,7 +791,7 @@ void setMouseCursorVisible(bool enable) { mouseCursorVisible = enable; } -void setCursorIcon(const u8* icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY) { +void setCursorIcon(const u8 *icon, uint w, uint h, byte keycolor, int hotspotX, int hotspotY) { int off; @@ -833,7 +823,7 @@ void setCursorIcon(const u8* icon, uint w, uint h, byte keycolor, int hotspotX, } } - if (currentGame->control != CONT_SCUMM_SAMNMAX) + if (s_currentGame->control != CONT_SCUMM_SAMNMAX) return; uint16 border = RGB15(24,24,24) | 0x8000; @@ -982,7 +972,7 @@ void displayMode16BitFlipBuffer() { consolePrintf("Flip %s...", displayModeIs8Bit ? "8bpp" : "16bpp"); #endif if (!displayModeIs8Bit) { - u16* back = get16BitBackBuffer(); + u16 *back = get16BitBackBuffer(); // highBuffer = !highBuffer; // BG3_CR = BG_BMP16_512x256 | BG_BMP_RAM(highBuffer? 1: 0); @@ -1001,8 +991,8 @@ void displayMode16BitFlipBuffer() { TIMER1_CR = TIMER_ENABLE | TIMER_DIV_1024; u16 t0 = TIMER1_DATA; #endif - const u8* back = (const u8*)get8BitBackBuffer(); - u16* base = BG_GFX + 0x10000; + const u8 *back = (const u8*)get8BitBackBuffer(); + u16 *base = BG_GFX + 0x10000; Rescale_320x256xPAL8_To_256x256x1555( base, back, @@ -1031,17 +1021,18 @@ void displayMode16BitFlipBuffer() { } void setShakePos(int shakePos) { - shakePos = shakePos; + s_shakePos = shakePos; } -u16* get16BitBackBuffer() { +u16 *get16BitBackBuffer() { return BG_GFX + 0x20000; } s32 get8BitBackBufferStride() { - // When the CPU scaler is enabled, the back buffer is in system RAM and is 320 pixels wide - // When the CPU scaler is disabled, the back buffer is in video memory and therefore must have a 512 pixel stride + // When the CPU scaler is enabled, the back buffer is in system RAM and is + // 320 pixels wide. When the CPU scaler is disabled, the back buffer is in + // video memory and therefore must have a 512 pixel stride. if (isCpuScalerEnabled()){ return 320; @@ -1050,11 +1041,11 @@ s32 get8BitBackBufferStride() { } } -u16* getScalerBuffer() { +u16 *getScalerBuffer() { return (u16 *) scalerBackBuffer; } -u16* get8BitBackBuffer() { +u16 *get8BitBackBuffer() { if (isCpuScalerEnabled()) return (u16 *) scalerBackBuffer; else @@ -1124,7 +1115,7 @@ void soundUpdate() { void memoryReport() { int r = 0; - int* p; + int *p; do { p = (int *) malloc(r * 8192); free(p); @@ -1132,7 +1123,7 @@ void memoryReport() { } while ((p) && (r < 512)); int t = -1; - void* block[1024]; + void *block[1024]; do { t++; block[t] = (int *) malloc(4096); @@ -1147,7 +1138,7 @@ void memoryReport() { void addIndyFightingKeys() { - OSystem_DS* system = OSystem_DS::instance(); + OSystem_DS *system = OSystem_DS::instance(); Common::Event event; event.type = Common::EVENT_KEYDOWN; @@ -1247,7 +1238,7 @@ void addIndyFightingKeys() { void setKeyboardEnable(bool en) { if (en == keyboardEnable) return; keyboardEnable = en; - u16* backupBank = (u16 *) 0x6040000; + u16 *backupBank = (u16 *) 0x6040000; if (keyboardEnable) { @@ -1283,7 +1274,7 @@ void setKeyboardEnable(bool en) { if (displayModeIs8Bit) { // Copy the sub screen VRAM from the top screen - they should always be // the same. - u16* buffer = get8BitBackBuffer(); + u16 *buffer = get8BitBackBuffer(); s32 stride = get8BitBackBufferStride(); for (int y = 0; y < gameHeight; y++) { @@ -1319,8 +1310,7 @@ bool getIsDisplayMode8Bit() { return displayModeIs8Bit; } -void doScreenTapMode(OSystem_DS* system) -{ +void doScreenTapMode(OSystem_DS *system) { Common::Event event; static bool left = false, right = false; @@ -1386,8 +1376,7 @@ void doScreenTapMode(OSystem_DS* system) system->addEvent(event); } -void doButtonSelectMode(OSystem_DS* system) -{ +void doButtonSelectMode(OSystem_DS *system) { Common::Event event; @@ -1398,9 +1387,6 @@ void doButtonSelectMode(OSystem_DS* system) //consolePrintf("x=%d y=%d \n", getPenX(), getPenY()); } - static bool leftButtonDown = false; - static bool rightButtonDown = false; - if (getPenReleased() && (leftButtonDown || rightButtonDown)) { if (leftButtonDown) { event.type = Common::EVENT_LBUTTONUP; @@ -1467,7 +1453,6 @@ void doButtonSelectMode(OSystem_DS* system) } if (rightButtonDown) { - Common::Event event; event.mouse = Common::Point(getPenX(), getPenY()); event.type = Common::EVENT_RBUTTONUP; system->addEvent(event); @@ -1476,14 +1461,13 @@ void doButtonSelectMode(OSystem_DS* system) if (getKeysDown() & KEY_RIGHT) { - if ((currentGame->control != CONT_SCUMM_SAMNMAX) && (currentGame->control != CONT_FUTURE_WARS) && (currentGame->control != CONT_GOBLINS)) { + if ((s_currentGame->control != CONT_SCUMM_SAMNMAX) && (s_currentGame->control != CONT_FUTURE_WARS) && (s_currentGame->control != CONT_GOBLINS)) { mouseMode = MOUSE_RIGHT; } else { // If we're playing sam and max, click and release the right mouse // button to change verb - Common::Event event; - if (currentGame->control == CONT_FUTURE_WARS) { + if (s_currentGame->control == CONT_FUTURE_WARS) { event.mouse = Common::Point(320 - 128, 200 - 128); event.type = Common::EVENT_MOUSEMOVE; system->addEvent(event); @@ -1515,7 +1499,7 @@ void addEventsToQueue() { #ifdef HEAVY_LOGGING consolePrintf("addEventsToQueue\n"); #endif - OSystem_DS* system = OSystem_DS::instance(); + OSystem_DS *system = OSystem_DS::instance(); Common::Event event; #ifdef USE_PROFILER @@ -1558,7 +1542,7 @@ void addEventsToQueue() { if (!indyFightState) { if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) && (getKeysDown() & KEY_B)) { - if (currentGame->control == CONT_AGI) { + if (s_currentGame->control == CONT_AGI) { event.kbd.keycode = Common::KEYCODE_RETURN; event.kbd.ascii = 13; event.kbd.flags = 0; @@ -1596,8 +1580,7 @@ void addEventsToQueue() { bool release = getKeysReleased() & (KEY_LEFT | KEY_RIGHT | KEY_UP | KEY_DOWN); bool shoulders = getKeysHeld() & (KEY_L | KEY_R); - if ( (down && (!shoulders)) || release) - { + if ( (down && (!shoulders)) || release) { if (getKeysChanged() & KEY_LEFT) { event.kbd.keycode = Common::KEYCODE_LEFT; @@ -1675,8 +1658,6 @@ void addEventsToQueue() { updateStatus(); - Common::Event event; - if ((tapScreenClicks) && (getIsDisplayMode8Bit())) { if ((!keyboardEnable) || (!isInsideKeyboard(penDownX, penDownY))) { @@ -1693,13 +1674,10 @@ void addEventsToQueue() { if (!keyboardEnable) { - if (((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) || (indyFightState)) && (displayModeIs8Bit)) { // Controls specific to the control method - - - if (currentGame->control == CONT_SKY) { + if (s_currentGame->control == CONT_SKY) { // Extra controls for Beneath a Steel Sky if ((getKeysDown() & KEY_DOWN)) { penY = 0; @@ -1707,9 +1685,8 @@ void addEventsToQueue() { } } - if (currentGame->control == CONT_AGI) { + if (s_currentGame->control == CONT_AGI) { // Extra controls for Leisure Suit Larry and KQ4 - if ((getKeysHeld() & KEY_UP) && (getKeysHeld() & KEY_START) /*&& (!strcmp(gameName, "LLLLL"))*/) { consolePrintf("Cheat key!\n"); @@ -1722,16 +1699,11 @@ void addEventsToQueue() { event.type = Common::EVENT_KEYUP; system->addEvent(event); } - } - - - if (currentGame->control == CONT_SIMON) { + if (s_currentGame->control == CONT_SIMON) { // Extra controls for Simon the Sorcerer if ((getKeysDown() & KEY_DOWN)) { - Common::Event event; - event.type = Common::EVENT_KEYDOWN; event.kbd.keycode = Common::KEYCODE_F10; // F10 or # - show hotspots event.kbd.ascii = Common::ASCII_F10; @@ -1744,13 +1716,9 @@ void addEventsToQueue() { } } - - - if (currentGame->control == CONT_SCUMM_ORIGINAL) { + if (s_currentGame->control == CONT_SCUMM_ORIGINAL) { // Extra controls for Scumm v1-5 games if ((getKeysDown() & KEY_DOWN)) { - Common::Event event; - event.type = Common::EVENT_KEYDOWN; event.kbd.keycode = Common::KEYCODE_PERIOD; // Full stop - skips current dialogue line event.kbd.ascii = '.'; @@ -1806,14 +1774,14 @@ void addEventsToQueue() { if ((getKeysChanged() & KEY_START)) { event.kbd.flags = 0; event.type = getKeyEvent(KEY_START); - if (currentGame->control == CONT_FUTURE_WARS) { + if (s_currentGame->control == CONT_FUTURE_WARS) { event.kbd.keycode = Common::KEYCODE_F10; event.kbd.ascii = Common::ASCII_F10; - } else if (currentGame->control == CONT_GOBLINS) { + } else if (s_currentGame->control == CONT_GOBLINS) { event.kbd.keycode = Common::KEYCODE_F1; event.kbd.ascii = Common::ASCII_F1; // consolePrintf("!!!!!F1!!!!!"); - } else if (currentGame->control == CONT_AGI) { + } else if (s_currentGame->control == CONT_AGI) { event.kbd.keycode = Common::KEYCODE_ESCAPE; event.kbd.ascii = 27; } else { @@ -1830,9 +1798,7 @@ void addEventsToQueue() { } consumeKeys(); - consumePenEvents(); - } } @@ -1862,23 +1828,19 @@ void updateStatus() { if (displayModeIs8Bit) { if (!tapScreenClicks) { switch (mouseMode) { - case MOUSE_LEFT: { - offs = 1; - break; - } - case MOUSE_RIGHT: { - offs = 2; - break; - } - case MOUSE_HOVER: { - offs = 0; - break; - } - default: { - // Nothing! - offs = 0; - break; - } + case MOUSE_LEFT: + offs = 1; + break; + case MOUSE_RIGHT: + offs = 2; + break; + case MOUSE_HOVER: + offs = 0; + break; + default: + // Nothing! + offs = 0; + break; } setIcon(0, 208, 150, offs, 0, true); @@ -1962,15 +1924,12 @@ void setMainScreenScale(int x, int y) { SUB_BG3_YDX = 0; SUB_BG3_YDY = y; } else*/ { - if (isCpuScalerEnabled() && (x==320)) - { + if (isCpuScalerEnabled() && (x==320)) { BG3_XDX = 256; BG3_XDY = 0; BG3_YDX = 0; BG3_YDY = y; - } - else - { + } else { BG3_XDX = x; BG3_XDY = 0; BG3_YDX = 0; @@ -2057,11 +2016,9 @@ void VBlankHandler(void) { soundUpdate(); - - if ((!gameScreenSwap) && (!(getKeysHeld() & KEY_L) && !(getKeysHeld() & KEY_R))) { - if (currentGame) { - if (currentGame->control != CONT_SCUMM_SAMNMAX) { + if (s_currentGame) { + if (s_currentGame->control != CONT_SCUMM_SAMNMAX) { if (getPenHeld() && (getPenY() < SCUMM_GAME_HEIGHT)) { setTopScreenTarget(getPenX(), getPenY()); } @@ -2144,7 +2101,7 @@ void VBlankHandler(void) { SUB_BG3_CX = subScX + 64; } - SUB_BG3_CY = subScY + (shakePos << 8);*/ + SUB_BG3_CY = subScY + (s_shakePos << 8);*/ /*SUB_BG3_XDX = (int) (subScreenWidth / 256.0f * 256); SUB_BG3_XDY = 0; @@ -2284,7 +2241,7 @@ void VBlankHandler(void) { setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8); - setMainScreenScroll(scX << 8, (scY << 8) + (shakePos << 8)); + setMainScreenScroll(scX << 8, (scY << 8) + (s_shakePos << 8)); setMainScreenScale(256, 256); // 1:1 scale } else { @@ -2300,7 +2257,7 @@ void VBlankHandler(void) { setZoomedScreenScroll(subScX, subScY, (subScreenWidth != 256) && (subScreenWidth != 128)); setZoomedScreenScale(subScreenWidth, ((subScreenHeight * (256 << 8)) / 192) >> 8); - setMainScreenScroll(64, (scY << 8) + (shakePos << 8)); + setMainScreenScroll(64, (scY << 8) + (s_shakePos << 8)); setMainScreenScale(320, 256); // 1:1 scale } @@ -2388,7 +2345,7 @@ void uploadSpriteGfx() { vramSetBankE(VRAM_E_MAIN_SPRITE); // Convert texture from 24bit 888 to 16bit 1555, remembering to set top bit! - u8* srcTex = (u8 *) ::icons_raw; + const u8 *srcTex = (const u8 *) ::icons_raw; for (int r = 32 * 256 ; r >= 0; r--) { SPRITE_GFX_SUB[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10); SPRITE_GFX[r] = 0x8000 | (srcTex[r * 3] >> 3) | ((srcTex[r * 3 + 1] >> 3) << 5) | ((srcTex[r * 3 + 2] >> 3) << 10); @@ -2634,9 +2591,6 @@ void penUpdate() { } } - else - { - } } else { penDown = true; @@ -2856,20 +2810,18 @@ bool getIndyFightState() { return indyFightState; } -gameListType* getCurrentGame() { - return currentGame; -} - /////////////////// // Fast Ram /////////////////// #define FAST_RAM_SIZE (24000) -u8* fastRamPointer; +#define ITCM_DATA __attribute__((section(".itcm"))) + +u8 *fastRamPointer; u8 fastRamData[FAST_RAM_SIZE] ITCM_DATA; -void* fastRamAlloc(int size) { - void* result = (void *) fastRamPointer; +void *fastRamAlloc(int size) { + void *result = (void *) fastRamPointer; fastRamPointer += size; if(fastRamPointer > fastRamData + FAST_RAM_SIZE) { consolePrintf("FastRam (ITCM) allocation failed!\n"); @@ -2926,7 +2878,7 @@ void initDebugger() { // Ensure the function is processed with C linkage -extern "C" void debug_print_stub(char* string); +extern "C" void debug_print_stub(char *string); void debug_print_stub(char *string) { consolePrintf(string); @@ -3286,7 +3238,7 @@ int main(void) { */ // Create a file system node to force search for a zip file in GBA rom space - DSFileSystemNode* node = new DSFileSystemNode(); + DSFileSystemNode *node = new DSFileSystemNode(); if (!node->getZip() || (!node->getZip()->isReady())) { // If not found, init CF/SD driver initGBAMP(mode); @@ -3344,6 +3296,11 @@ int main(void) { const char *argv[] = {"/scummvmds", "--config=scummvmj.ini"}; #elif defined(DS_BUILD_K) const char *argv[] = {"/scummvmds", "--config=scummvmk.ini"}; +#else + // Use the default config file if no build was specified. This currently + // only happens with builds made using the regular ScummVM build system (as + // opposed to the nds specific build system). + const char *argv[] = {"/scummvmds"}; #endif #ifdef DYNAMIC_MODULES @@ -3359,7 +3316,8 @@ int main(void) { return 0; } -} +} // End of namespace DS + int main() { DS::main(); @@ -3380,7 +3338,6 @@ extern "C" void consolePrintf(char * format, ...) __attribute__ ((no_instrument_ extern "C" void consolePrintf(const char * format, ...) { - char buffer[256]; va_list args; va_start(args, format); viprintf(format, args); diff --git a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h b/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h index 9344be68f9..f41548f400 100644 --- a/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h +++ b/backends/platform/ds/commoninclude/NDS/scummvm_ipc.h @@ -33,6 +33,18 @@ ////////////////////////////////////////////////////////////////////// +typedef struct sTransferSoundData { +//--------------------------------------------------------------------------------- + const void *data; + u32 len; + u32 rate; + u8 vol; + u8 pan; + u8 format; + u8 PADDING; +} TransferSoundData, * pTransferSoundData; + + //--------------------------------------------------------------------------------- diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp index 53987ff3fa..ef3864003b 100644 --- a/backends/plugins/ds/ds-provider.cpp +++ b/backends/plugins/ds/ds-provider.cpp @@ -29,7 +29,7 @@ #include "backends/plugins/dynamic-plugin.h" #include "common/fs.h" -#include "backends/platform/ds/arm9/source/dsloader.h" +#include "backends/plugins/elf-loader.h" class DSPlugin : public DynamicPlugin { diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index eae8bebcc7..afb69714fa 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -37,6 +37,10 @@ #include "common/fs.h" #include "elf-loader.h" +#ifdef __DS__ +#include +#endif + #define __DEBUG_PLUGINS__ #ifdef __DEBUG_PLUGINS__ @@ -48,7 +52,7 @@ #define seterror(x,...) printf(x, ## __VA_ARGS__) /** - * Flushes the data cache. + * Flushes the data cache (Platform Specific). */ void flushDataCache() { #ifdef __DS__ @@ -304,7 +308,7 @@ void DLObject::relocateSymbols(Elf32_Addr offset) { #else // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { - relocCount++; + mainCount++; 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); -- cgit v1.2.3 From 749d47ba2668421806ef65f693f9a6bc97d6f902 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 28 Jul 2010 01:03:17 +0000 Subject: fixed incorrect header file include svn-id: r51399 --- backends/plugins/ps2/ps2-provider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp index 3e966bbd08..fa4d576306 100644 --- a/backends/plugins/ps2/ps2-provider.cpp +++ b/backends/plugins/ps2/ps2-provider.cpp @@ -29,7 +29,7 @@ #include "backends/plugins/dynamic-plugin.h" #include "common/fs.h" -#include "backends/platform/ps2/ps2loader.h" +#include "backends/plugins/elf-loader.h" class PS2Plugin : public DynamicPlugin { -- cgit v1.2.3 From ff78cf6771fbbb6a7fd26d00db36c4c72d7a71db Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 28 Jul 2010 02:05:17 +0000 Subject: abstracted an ELF plugin provider svn-id: r51400 --- backends/module.mk | 3 +- backends/platform/ds/arm9/source/dsmain.cpp | 4 +- backends/platform/ps2/systemps2.cpp | 4 +- backends/plugins/ds/ds-provider.cpp | 108 ---------------------------- backends/plugins/ds/ds-provider.h | 43 ----------- backends/plugins/elf-provider.cpp | 108 ++++++++++++++++++++++++++++ backends/plugins/elf-provider.h | 43 +++++++++++ backends/plugins/ps2/ps2-provider.cpp | 108 ---------------------------- backends/plugins/ps2/ps2-provider.h | 43 ----------- 9 files changed, 156 insertions(+), 308 deletions(-) delete mode 100644 backends/plugins/ds/ds-provider.cpp delete mode 100644 backends/plugins/ds/ds-provider.h create mode 100644 backends/plugins/elf-provider.cpp create mode 100644 backends/plugins/elf-provider.h delete mode 100644 backends/plugins/ps2/ps2-provider.cpp delete mode 100644 backends/plugins/ps2/ps2-provider.h (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index 2f39c548a0..748b786eb4 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -30,14 +30,13 @@ MODULE_OBJS := \ midi/timidity.o \ midi/dmedia.o \ midi/windows.o \ + plugins/elf-provider.o \ plugins/dc/dc-provider.o \ plugins/posix/posix-provider.o \ plugins/sdl/sdl-provider.o \ plugins/win32/win32-provider.o \ plugins/psp/psp-provider.o \ - plugins/ps2/ps2-provider.o \ plugins/gp2xwiz/gp2xwiz-provider.o \ - plugins/ds/ds-provider.o \ saves/savefile.o \ saves/default/default-saves.o \ saves/posix/posix-saves.o \ diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index 1f3a67d818..4e44e9f1dd 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -111,7 +111,7 @@ #include "engine.h" -#include "backends/plugins/ds/ds-provider.h" +#include "backends/plugins/elf-provider.h" #include "backends/fs/ds/ds-fs.h" #include "base/version.h" @@ -3304,7 +3304,7 @@ int main(void) { #endif #ifdef DYNAMIC_MODULES - PluginManager::instance().addPluginProvider(new DSPluginProvider()); + PluginManager::instance().addPluginProvider(new ELFPluginProvider()); #endif while (1) { diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index 357404c5c4..bd8179976b 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -59,7 +59,7 @@ #include "backends/platform/ps2/ps2debug.h" #include "backends/fs/ps2/ps2-fs-factory.h" -#include "backends/plugins/ps2/ps2-provider.h" +#include "backends/plugins/elf-provider.h" #include "backends/saves/default/default-saves.h" #include "common/config-manager.h" @@ -132,7 +132,7 @@ extern "C" int main(int argc, char *argv[]) { g_system = g_systemPs2 = new OSystem_PS2(argv[0]); #ifdef DYNAMIC_MODULES - PluginManager::instance().addPluginProvider(new PS2PluginProvider()); + PluginManager::instance().addPluginProvider(new ELFPluginProvider()); #endif g_systemPs2->init(); diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp deleted file mode 100644 index ef3864003b..0000000000 --- a/backends/plugins/ds/ds-provider.cpp +++ /dev/null @@ -1,108 +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(__DS__) - -#include "backends/plugins/ds/ds-provider.h" -#include "backends/plugins/dynamic-plugin.h" -#include "common/fs.h" - -#include "backends/plugins/elf-loader.h" - - -class DSPlugin : public DynamicPlugin { -protected: - void *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol) { - void *func = dlsym(_dlHandle, symbol); - if (!func) - warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); - - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp; - } - -public: - DSPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} - - ~DSPlugin() { - if (_dlHandle) unloadPlugin(); - } - - bool loadPlugin() { - assert(!_dlHandle); - _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); - - if (!_dlHandle) { - warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); - return false; - } - - bool ret = DynamicPlugin::loadPlugin(); - - if (ret) - dlforgetsyms(_dlHandle); - - return ret; - } - - void unloadPlugin() { - DynamicPlugin::unloadPlugin(); - if (_dlHandle) { - if (dlclose(_dlHandle) != 0) - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); - _dlHandle = 0; - } - } -}; - - -Plugin* DSPluginProvider::createPlugin(const Common::FSNode &node) const { - return new DSPlugin(node.getPath()); -} - -bool DSPluginProvider::isPluginFilename(const Common::FSNode &node) const { - // Check the plugin suffix - Common::String filename = node.getName(); - printf("Testing name %s", filename.c_str()); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { - printf(" fail.\n"); - return false; - } - - printf(" success!\n"); - return true; -} - -#endif // defined(DYNAMIC_MODULES) && defined(__DS__) diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h deleted file mode 100644 index 096c1b87a9..0000000000 --- a/backends/plugins/ds/ds-provider.h +++ /dev/null @@ -1,43 +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_PLUGINS_DS_DS_PROVIDER_H -#define BACKENDS_PLUGINS_DS_DS_PROVIDER_H - -#include "base/plugins.h" - -#if defined(DYNAMIC_MODULES) && defined(__DS__) - -class DSPluginProvider : public FilePluginProvider { -protected: - Plugin* createPlugin(const Common::FSNode &node) const; - - bool isPluginFilename(const Common::FSNode &node) const; - -}; - -#endif // defined(DYNAMIC_MODULES) && defined(__DS__) - -#endif /* BACKENDS_PLUGINS_DS_DS_PROVIDER_H */ diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp new file mode 100644 index 0000000000..b623f0d881 --- /dev/null +++ b/backends/plugins/elf-provider.cpp @@ -0,0 +1,108 @@ +/* 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) //TODO: && 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" + + +class ELFPlugin : public DynamicPlugin { +protected: + void *_dlHandle; + Common::String _filename; + + virtual VoidFunc findSymbol(const char *symbol) { + void *func = dlsym(_dlHandle, symbol); + if (!func) + warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. . + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp; + } + +public: + ELFPlugin(const Common::String &filename) + : _dlHandle(0), _filename(filename) {} + + ~ELFPlugin() { + if (_dlHandle) unloadPlugin(); + } + + bool loadPlugin() { + assert(!_dlHandle); + _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); + + if (!_dlHandle) { + warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); + return false; + } + + bool ret = DynamicPlugin::loadPlugin(); + + if (ret) + dlforgetsyms(_dlHandle); + + return ret; + } + + void unloadPlugin() { + DynamicPlugin::unloadPlugin(); + if (_dlHandle) { + if (dlclose(_dlHandle) != 0) + warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); + _dlHandle = 0; + } + } +}; + + +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(); + printf("Testing name %s", filename.c_str()); + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { + printf(" fail.\n"); + return false; + } + + printf(" success!\n"); + return true; +} + +#endif // defined(DYNAMIC_MODULES) diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h new file mode 100644 index 0000000000..10bd1c077f --- /dev/null +++ b/backends/plugins/elf-provider.h @@ -0,0 +1,43 @@ +/* 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_PLUGINS_ELF_PROVIDER_H +#define BACKENDS_PLUGINS_ELF_PROVIDER_H + +#include "base/plugins.h" + +#if defined(DYNAMIC_MODULES) // TODO: && defined(ELF-loader target) + +class ELFPluginProvider : public FilePluginProvider { +protected: + Plugin* createPlugin(const Common::FSNode &node) const; + + bool isPluginFilename(const Common::FSNode &node) const; + +}; + +#endif // defined(DYNAMIC_MODULES) + +#endif /* BACKENDS_PLUGINS_ELF_PROVIDER_H */ diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp deleted file mode 100644 index fa4d576306..0000000000 --- a/backends/plugins/ps2/ps2-provider.cpp +++ /dev/null @@ -1,108 +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(__PLAYSTATION2__) - -#include "backends/plugins/ps2/ps2-provider.h" -#include "backends/plugins/dynamic-plugin.h" -#include "common/fs.h" - -#include "backends/plugins/elf-loader.h" - - -class PS2Plugin : public DynamicPlugin { -protected: - void *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol) { - void *func = dlsym(_dlHandle, symbol); - if (!func) - warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); - - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp; - } - -public: - PS2Plugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} - - ~PS2Plugin() { - if (_dlHandle) unloadPlugin(); - } - - bool loadPlugin() { - assert(!_dlHandle); - _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); - - if (!_dlHandle) { - warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); - return false; - } - - bool ret = DynamicPlugin::loadPlugin(); - - if (ret) - dlforgetsyms(_dlHandle); - - return ret; - } - - void unloadPlugin() { - DynamicPlugin::unloadPlugin(); - if (_dlHandle) { - if (dlclose(_dlHandle) != 0) - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); - _dlHandle = 0; - } - } -}; - - -Plugin* PS2PluginProvider::createPlugin(const Common::FSNode &node) const { - return new PS2Plugin(node.getPath()); -} - -bool PS2PluginProvider::isPluginFilename(const Common::FSNode &node) const { - // Check the plugin suffix - Common::String filename = node.getName(); - fprintf(stderr, "Testing name %s", filename.c_str()); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg")) { - fprintf(stderr," fail.\n"); - return false; - } - - fprintf(stderr," success!\n"); - return true; -} - -#endif // defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h deleted file mode 100644 index 6a357db63d..0000000000 --- a/backends/plugins/ps2/ps2-provider.h +++ /dev/null @@ -1,43 +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_PLUGINS_PS2_PS2_PROVIDER_H -#define BACKENDS_PLUGINS_PS2_PS2_PROVIDER_H - -#include "base/plugins.h" - -#if defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) - -class PS2PluginProvider : public FilePluginProvider { -protected: - Plugin* createPlugin(const Common::FSNode &node) const; - - bool isPluginFilename(const Common::FSNode &node) const; - -}; - -#endif // defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) - -#endif /* BACKENDS_PLUGINS_PS2_PS2_PROVIDER_H */ -- cgit v1.2.3 From 9d236ac4d040cacdebd4e12e15a73279acfaf8f0 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 28 Jul 2010 05:18:46 +0000 Subject: added check for MIPS machine type in the 'readElfHeader' method svn-id: r51403 --- backends/plugins/elf-loader.cpp | 5 +++++ backends/plugins/elf-loader.h | 4 ++++ 2 files changed, 9 insertions(+) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index afb69714fa..33f97f5586 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -93,7 +93,12 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd if (DLFile->read(ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC ehdr->e_type != ET_EXEC || // Check for executable +#ifdef ARM_TARGET ehdr->e_machine != EM_ARM || // Check for ARM machine type +#endif +#ifdef MIPS_TARGET + ehdr->e_machine != EM_MIPS || +#endif 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."); diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 1bbcbc4b78..3f33b681bf 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -34,6 +34,10 @@ #include "shorts-segment-manager.h" #endif +#if defined(__DS__) +#define ARM_TARGET +#endif + #define MAXDLERRLEN 80 class DLObject { -- cgit v1.2.3 From 145d8899dfb3bd0b7af88c812a2696c9da094cbf Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Wed, 28 Jul 2010 23:17:39 +0000 Subject: added some comments to shorts-segment-manager, moved main engine linker script for ps2 into the plugins folder as it is only used when dynamic plugins are enabled svn-id: r51447 --- backends/platform/ps2/Makefile.ps2 | 2 +- backends/platform/ps2/main_prog.ld | 99 ----------------------------- backends/plugins/arm-relocs.cpp | 2 +- backends/plugins/ps2/main_prog.ld | 99 +++++++++++++++++++++++++++++ backends/plugins/shorts-segment-manager.cpp | 4 +- backends/plugins/shorts-segment-manager.h | 8 +++ 6 files changed, 111 insertions(+), 103 deletions(-) delete mode 100644 backends/platform/ps2/main_prog.ld create mode 100644 backends/plugins/ps2/main_prog.ld (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 5c60c4fca0..6d1a765456 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -91,7 +91,7 @@ PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/plugin.syms elf/scummvm.elf PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-T$(srcdir)/backends/plugins/ps2/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/plugin.syms -lstdc++ -lc -LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T main_prog.ld +LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(srcdir)/backends/plugins/ps2/main_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ diff --git a/backends/platform/ps2/main_prog.ld b/backends/platform/ps2/main_prog.ld deleted file mode 100644 index 9dba69c50e..0000000000 --- a/backends/platform/ps2/main_prog.ld +++ /dev/null @@ -1,99 +0,0 @@ -ENTRY(_start); - -SECTIONS { - .text 0x00100000: { - _ftext = . ; - *(.text) - *(.text.*) - *(.gnu.linkonce.t*) - KEEP(*(.init)) - KEEP(*(.fini)) - QUAD(0) - } - - PROVIDE(_etext = .); - PROVIDE(etext = .); - - .reginfo : { *(.reginfo) } - - /* Global/static constructors and deconstructors. */ - .ctors ALIGN(16): { - KEEP(*crtbegin*.o(.ctors)) - KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors)) - KEEP(*(SORT(.ctors.*))) - KEEP(*(.ctors)) - } - .dtors ALIGN(16): { - KEEP(*crtbegin*.o(.dtors)) - KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors)) - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - } - - /* Static data. */ - .rodata ALIGN(128): { - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r*) - } - - .data ALIGN(128): { - _fdata = . ; - *(.data) - *(.data.*) - *(.gnu.linkonce.d*) - SORT(CONSTRUCTORS) - } - - .rdata ALIGN(128): { *(.rdata) } - .gcc_except_table ALIGN(128): { *(.gcc_except_table) } - - _gp = ALIGN(128) + 0x7ff0; - .lit4 ALIGN(128): { *(.lit4) } - .lit8 ALIGN(128): { *(.lit8) } - - .sdata ALIGN(128): { - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s*) - } - - _edata = .; - PROVIDE(edata = .); - - /* Uninitialized data. */ - .sbss ALIGN(128) : { - _fbss = . ; - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb*) - *(.scommon) - } - - /*This "plugin hole" is so the plugins can all have global small data - in the same place.*/ - __plugin_hole_start = .; - . = _gp + 0x7ff0; - __plugin_hole_end = .; - - COMMON : - { - *(COMMON) - } - . = ALIGN(128); - - .bss ALIGN(128) : { - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b*) - } - _end_bss = .; - - _end = . ; - PROVIDE(end = .); - - /* Symbols needed by crt0.s. */ - PROVIDE(_heap_size = -1); - PROVIDE(_stack = -1); - PROVIDE(_stack_size = 128 * 1024); -} diff --git a/backends/plugins/arm-relocs.cpp b/backends/plugins/arm-relocs.cpp index b00fb42f4a..8ceccfb7e8 100644 --- a/backends/plugins/arm-relocs.cpp +++ b/backends/plugins/arm-relocs.cpp @@ -115,7 +115,7 @@ bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset *target = relocation; DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - DBG("Make sure --target1-abs is a flag to LD.\n"); + DBG("Make sure --target1-abs is a flag to LD!\n"); } break; diff --git a/backends/plugins/ps2/main_prog.ld b/backends/plugins/ps2/main_prog.ld new file mode 100644 index 0000000000..9dba69c50e --- /dev/null +++ b/backends/plugins/ps2/main_prog.ld @@ -0,0 +1,99 @@ +ENTRY(_start); + +SECTIONS { + .text 0x00100000: { + _ftext = . ; + *(.text) + *(.text.*) + *(.gnu.linkonce.t*) + KEEP(*(.init)) + KEEP(*(.fini)) + QUAD(0) + } + + PROVIDE(_etext = .); + PROVIDE(etext = .); + + .reginfo : { *(.reginfo) } + + /* Global/static constructors and deconstructors. */ + .ctors ALIGN(16): { + KEEP(*crtbegin*.o(.ctors)) + KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors)) + KEEP(*(SORT(.ctors.*))) + KEEP(*(.ctors)) + } + .dtors ALIGN(16): { + KEEP(*crtbegin*.o(.dtors)) + KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors)) + KEEP(*(SORT(.dtors.*))) + KEEP(*(.dtors)) + } + + /* Static data. */ + .rodata ALIGN(128): { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r*) + } + + .data ALIGN(128): { + _fdata = . ; + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + SORT(CONSTRUCTORS) + } + + .rdata ALIGN(128): { *(.rdata) } + .gcc_except_table ALIGN(128): { *(.gcc_except_table) } + + _gp = ALIGN(128) + 0x7ff0; + .lit4 ALIGN(128): { *(.lit4) } + .lit8 ALIGN(128): { *(.lit8) } + + .sdata ALIGN(128): { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s*) + } + + _edata = .; + PROVIDE(edata = .); + + /* Uninitialized data. */ + .sbss ALIGN(128) : { + _fbss = . ; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb*) + *(.scommon) + } + + /*This "plugin hole" is so the plugins can all have global small data + in the same place.*/ + __plugin_hole_start = .; + . = _gp + 0x7ff0; + __plugin_hole_end = .; + + COMMON : + { + *(COMMON) + } + . = ALIGN(128); + + .bss ALIGN(128) : { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b*) + } + _end_bss = .; + + _end = . ; + PROVIDE(end = .); + + /* Symbols needed by crt0.s. */ + PROVIDE(_heap_size = -1); + PROVIDE(_stack = -1); + PROVIDE(_stack_size = 128 * 1024); +} diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index eb2ab2d953..25962c504d 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -42,8 +42,8 @@ extern char _gp[]; // Value of gp register DECLARE_SINGLETON(ShortSegmentManager); // For singleton ShortSegmentManager::ShortSegmentManager() { - _shortsStart = &__plugin_hole_start ; - _shortsEnd = &__plugin_hole_end; + _shortsStart = &__plugin_hole_start ; //shorts segment begins at the plugin hole we made when linking + _shortsEnd = &__plugin_hole_end; //and ends at the end of that hole. } ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h index 02f5221e8d..54a13d88e1 100644 --- a/backends/plugins/shorts-segment-manager.h +++ b/backends/plugins/shorts-segment-manager.h @@ -32,6 +32,12 @@ #define ShortsMan ShortSegmentManager::instance() +/** + * Manages the segments of small data put in the gp-relative area for MIPS processors, + * and lets these segments be handled differently in the ELF loader. + * Since there's no true dynamic linker to change the GP register between plugins and the main engine, + * custom linker scripts ensure the GP-area is in the same place for both. + */ class ShortSegmentManager : public Common::Singleton { private: char *_shortsStart; @@ -41,6 +47,8 @@ public: char *getShortsStart() { return _shortsStart; } + + // Returns whether or not an absolute address is in the GP-relative section. bool inGeneralSegment(char *addr) { return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); } -- cgit v1.2.3 From 934c0b922c3927a203f2027f73a472fff5c48d4b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 3 Aug 2010 06:25:03 +0000 Subject: got rid of dlopen, dlclose, etc. wrappers svn-id: r51677 --- backends/plugins/elf-loader.cpp | 41 --------------------------------------- backends/plugins/elf-loader.h | 1 - backends/plugins/elf-provider.cpp | 38 ++++++++++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 50 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 33f97f5586..1b70ed5565 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -448,46 +448,5 @@ void *DLObject::symbol(const char *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 */ diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 3f33b681bf..d6273b7e71 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -93,7 +93,6 @@ public: 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); } diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index b623f0d881..4d4c66084d 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -31,6 +31,7 @@ #include "backends/plugins/elf-loader.h" +static char dlerr[MAXDLERRLEN]; class ELFPlugin : public DynamicPlugin { protected: @@ -38,9 +39,15 @@ protected: Common::String _filename; virtual VoidFunc findSymbol(const char *symbol) { - void *func = dlsym(_dlHandle, symbol); + void *func; + if (_dlHandle == NULL) { + strcpy(dlerr, "Handle is NULL."); + func = NULL; + } else { + func = ((DLObject *)_dlHandle)->symbol(symbol); + } if (!func) - warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); + warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerr); // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ // standard and POSIX: ISO C++ disallows casting between function pointers @@ -62,17 +69,25 @@ public: bool loadPlugin() { assert(!_dlHandle); - _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); + DLObject *obj = new DLObject(dlerr); + if (obj->open(_filename.c_str())) { + _dlHandle = (void *)obj; + } else { + delete obj; + _dlHandle = NULL; + } if (!_dlHandle) { - warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); + warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerr); return false; } bool ret = DynamicPlugin::loadPlugin(); - if (ret) - dlforgetsyms(_dlHandle); + if (ret) { + if (_dlHandle != NULL) + ((DLObject *)_dlHandle)->discard_symtab(); + } return ret; } @@ -80,8 +95,15 @@ public: void unloadPlugin() { DynamicPlugin::unloadPlugin(); if (_dlHandle) { - if (dlclose(_dlHandle) != 0) - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); + DLObject *obj = (DLObject *)_dlHandle; + if (obj == NULL) { + strcpy(dlerr, "Handle is NULL."); + warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerr); + } else if (obj->close()) { + delete obj; + } else { + warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerr); + } _dlHandle = 0; } } -- cgit v1.2.3 From 9be8f0a544510ae0843fce47c613af0de7f1df17 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 3 Aug 2010 07:52:10 +0000 Subject: got rid of dlerr[MAXDLERRLEN] svn-id: r51678 --- backends/plugins/elf-provider.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 4d4c66084d..cc592ca419 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -31,8 +31,6 @@ #include "backends/plugins/elf-loader.h" -static char dlerr[MAXDLERRLEN]; - class ELFPlugin : public DynamicPlugin { protected: void *_dlHandle; @@ -40,14 +38,20 @@ protected: virtual VoidFunc findSymbol(const char *symbol) { void *func; + bool handleNull; if (_dlHandle == NULL) { - strcpy(dlerr, "Handle is NULL."); func = NULL; + handleNull = true; } else { func = ((DLObject *)_dlHandle)->symbol(symbol); } - if (!func) - warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerr); + if (!func) { + if (handleNull) { + warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); + } else { + warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); + } + } // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ // standard and POSIX: ISO C++ disallows casting between function pointers @@ -69,7 +73,7 @@ public: bool loadPlugin() { assert(!_dlHandle); - DLObject *obj = new DLObject(dlerr); + DLObject *obj = new DLObject(NULL); if (obj->open(_filename.c_str())) { _dlHandle = (void *)obj; } else { @@ -78,7 +82,7 @@ public: } if (!_dlHandle) { - warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerr); + warning("Failed loading plugin '%s'", _filename.c_str()); return false; } @@ -97,12 +101,11 @@ public: if (_dlHandle) { DLObject *obj = (DLObject *)_dlHandle; if (obj == NULL) { - strcpy(dlerr, "Handle is NULL."); - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerr); + warning("Failed unloading plugin '%s' (Handle is NULL)", _filename.c_str()); } else if (obj->close()) { delete obj; } else { - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerr); + warning("Failed unloading plugin '%s'", _filename.c_str()); } _dlHandle = 0; } -- cgit v1.2.3 From 9f5bcadaea8bb51efb21d23b24a3ff4fafd9bb05 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 3 Aug 2010 12:45:12 +0000 Subject: Simplify code a bit, add several FIXMEs svn-id: r51688 --- backends/plugins/elf-loader.cpp | 4 ++-- backends/plugins/elf-provider.cpp | 25 ++++++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 1b70ed5565..24532740b4 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -28,10 +28,10 @@ #include #include #include -#include +#include // for memalign() (Linux specific) #include #include -#include +#include // FIXME: Why do we need this DevKitPro specific header? #include "common/file.h" #include "common/fs.h" diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index cc592ca419..ae728495fa 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -33,7 +33,7 @@ class ELFPlugin : public DynamicPlugin { protected: - void *_dlHandle; + DLObject *_dlHandle; Common::String _filename; virtual VoidFunc findSymbol(const char *symbol) { @@ -43,7 +43,7 @@ protected: func = NULL; handleNull = true; } else { - func = ((DLObject *)_dlHandle)->symbol(symbol); + func = _dlHandle->symbol(symbol); } if (!func) { if (handleNull) { @@ -68,14 +68,15 @@ public: : _dlHandle(0), _filename(filename) {} ~ELFPlugin() { - if (_dlHandle) unloadPlugin(); + if (_dlHandle) + unloadPlugin(); } bool loadPlugin() { assert(!_dlHandle); DLObject *obj = new DLObject(NULL); if (obj->open(_filename.c_str())) { - _dlHandle = (void *)obj; + _dlHandle = obj; } else { delete obj; _dlHandle = NULL; @@ -88,9 +89,8 @@ public: bool ret = DynamicPlugin::loadPlugin(); - if (ret) { - if (_dlHandle != NULL) - ((DLObject *)_dlHandle)->discard_symtab(); + if (ret && _dlHandle) { + _dlHandle->discard_symtab(); } return ret; @@ -99,13 +99,15 @@ public: void unloadPlugin() { DynamicPlugin::unloadPlugin(); if (_dlHandle) { - DLObject *obj = (DLObject *)_dlHandle; - if (obj == NULL) { + if (_dlHandle == NULL) { + // FIXME: This check makes no sense, _dlHandle cannot be NULL at this point warning("Failed unloading plugin '%s' (Handle is NULL)", _filename.c_str()); - } else if (obj->close()) { - delete obj; + } else if (_dlHandle->close()) { + delete _dlHandle; } else { warning("Failed unloading plugin '%s'", _filename.c_str()); + // FIXME: We are leaking _dlHandle here! + // Any particular reasons why we would want to do that??? } _dlHandle = 0; } @@ -119,6 +121,7 @@ Plugin* ELFPluginProvider::createPlugin(const Common::FSNode &node) const { bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { // Check the plugin suffix + // FIXME: Do we need these printfs? Should get rid of them eventually. Common::String filename = node.getName(); printf("Testing name %s", filename.c_str()); if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { -- cgit v1.2.3 From 520c0a40098a9687f4d85343267cda9c5b5c971b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Tue, 3 Aug 2010 22:08:32 +0000 Subject: added checks for ELF_LOADER_TARGET before including the elf plugin provider svn-id: r51716 --- backends/platform/ds/arm9/makefile | 2 +- backends/platform/ps2/Makefile.ps2 | 2 +- backends/platform/psp/Makefile | 2 +- backends/plugins/elf-loader.cpp | 4 ++-- backends/plugins/elf-provider.cpp | 4 ++-- backends/plugins/elf-provider.h | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index d86a019452..adcf24f5ff 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -238,7 +238,7 @@ CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \ ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DARM +DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT -DARM ifdef USE_MAD DEFINES += -DUSE_MAD endif diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 6d1a765456..0d6df8ae69 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -77,7 +77,7 @@ DEPDIR = .deps TARGET = elf/scummvm.elf -DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR +DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -DELF_LOADER_TARGET -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index c479244551..010f6e635a 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -68,7 +68,7 @@ endif # Variables for common Scummvm makefile CXX = psp-g++ CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti -DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR +DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR -DELF_LOADER_TARGET LDFLAGS := INCDIR := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 24532740b4..a3b453ed0f 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) // TODO: && defined ELF loader target +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) #include #include @@ -448,5 +448,5 @@ void *DLObject::symbol(const char *name) { return NULL; } -#endif /* DYNAMIC_MODULES */ +#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index ae728495fa..76fa3cd6df 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) //TODO: && defined(ELF loader target) +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) #include "backends/plugins/elf-provider.h" #include "backends/plugins/dynamic-plugin.h" @@ -133,4 +133,4 @@ bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { return true; } -#endif // defined(DYNAMIC_MODULES) +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index 10bd1c077f..a6b55d97f3 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -28,7 +28,7 @@ #include "base/plugins.h" -#if defined(DYNAMIC_MODULES) // TODO: && defined(ELF-loader target) +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) class ELFPluginProvider : public FilePluginProvider { protected: @@ -38,6 +38,6 @@ protected: }; -#endif // defined(DYNAMIC_MODULES) +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) #endif /* BACKENDS_PLUGINS_ELF_PROVIDER_H */ -- cgit v1.2.3 From cade67be4f2d297b855628ff7ca0f2cd1c1efcc2 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 5 Aug 2010 02:21:11 +0000 Subject: added plugin design first refinement define to ps2 makefile svn-id: r51749 --- backends/platform/ps2/Makefile.ps2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 0d6df8ae69..e5617f40bd 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -77,7 +77,7 @@ DEPDIR = .deps TARGET = elf/scummvm.elf -DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -DELF_LOADER_TARGET -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR +DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -DELF_LOADER_TARGET -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR -DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines -- cgit v1.2.3 From d1deaedc1a1e66ea34ca9544bc0e178dd24f48f9 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 5 Aug 2010 20:54:48 +0000 Subject: dealt with FIXME comments: removing superfluous checks, printfs, etc. svn-id: r51765 --- backends/plugins/elf-provider.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 76fa3cd6df..226ac06469 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -99,15 +99,9 @@ public: void unloadPlugin() { DynamicPlugin::unloadPlugin(); if (_dlHandle) { - if (_dlHandle == NULL) { - // FIXME: This check makes no sense, _dlHandle cannot be NULL at this point - warning("Failed unloading plugin '%s' (Handle is NULL)", _filename.c_str()); - } else if (_dlHandle->close()) { - delete _dlHandle; - } else { + delete _dlHandle; + if (!_dlHandle->close()) { warning("Failed unloading plugin '%s'", _filename.c_str()); - // FIXME: We are leaking _dlHandle here! - // Any particular reasons why we would want to do that??? } _dlHandle = 0; } @@ -121,15 +115,10 @@ Plugin* ELFPluginProvider::createPlugin(const Common::FSNode &node) const { bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { // Check the plugin suffix - // FIXME: Do we need these printfs? Should get rid of them eventually. Common::String filename = node.getName(); - printf("Testing name %s", filename.c_str()); if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { - printf(" fail.\n"); return false; } - - printf(" success!\n"); return true; } -- cgit v1.2.3 From 09a41c94be1da2ab13db99045840f20aec2be89b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 5 Aug 2010 21:48:15 +0000 Subject: Moved ELFPlugin class definition into elf-provider.h svn-id: r51767 --- backends/plugins/elf-provider.cpp | 94 +++++++++++---------------------------- backends/plugins/elf-provider.h | 52 ++++++++++++++++++++++ 2 files changed, 78 insertions(+), 68 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 226ac06469..4e1f277fb8 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -23,90 +23,48 @@ * */ -#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" -class ELFPlugin : public DynamicPlugin { -protected: - DLObject *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol) { - void *func; - bool handleNull; - if (_dlHandle == NULL) { - func = NULL; - handleNull = true; - } else { - func = _dlHandle->symbol(symbol); - } - if (!func) { - if (handleNull) { - warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); - } else { - warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); - } - } +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - 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; } -public: - ELFPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} - - ~ELFPlugin() { - if (_dlHandle) - unloadPlugin(); + if (!_dlHandle) { + warning("Failed loading plugin '%s'", _filename.c_str()); + return false; } - bool loadPlugin() { - assert(!_dlHandle); - DLObject *obj = new DLObject(NULL); - if (obj->open(_filename.c_str())) { - _dlHandle = obj; - } else { - delete obj; - _dlHandle = NULL; - } + bool ret = DynamicPlugin::loadPlugin(); - if (!_dlHandle) { - warning("Failed loading plugin '%s'", _filename.c_str()); - return false; - } - - bool ret = DynamicPlugin::loadPlugin(); - - if (ret && _dlHandle) { - _dlHandle->discard_symtab(); - } - - return ret; + if (ret && _dlHandle) { + _dlHandle->discard_symtab(); } - void unloadPlugin() { - DynamicPlugin::unloadPlugin(); - if (_dlHandle) { - delete _dlHandle; - if (!_dlHandle->close()) { - warning("Failed unloading plugin '%s'", _filename.c_str()); - } - _dlHandle = 0; + return ret; +} + +void ELFPlugin::unloadPlugin() { + DynamicPlugin::unloadPlugin(); + if (_dlHandle) { + delete _dlHandle; + if (!_dlHandle->close()) { + warning("Failed unloading plugin '%s'", _filename.c_str()); } + _dlHandle = 0; } -}; +} Plugin* ELFPluginProvider::createPlugin(const Common::FSNode &node) const { diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index a6b55d97f3..981d0d0638 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -27,9 +27,61 @@ #define BACKENDS_PLUGINS_ELF_PROVIDER_H #include "base/plugins.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) +class ELFPlugin : public DynamicPlugin { +protected: + DLObject *_dlHandle; + Common::String _filename; + + //FIXME: The code for this method should be in elf-provider.cpp, + // but VoidFunc isn't recognized if we do that as is. + virtual VoidFunc findSymbol(const char *symbol) { + void *func; + bool handleNull; + if (_dlHandle == NULL) { + func = NULL; + handleNull = true; + } else { + func = _dlHandle->symbol(symbol); + } + if (!func) { + if (handleNull) { + warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); + } else { + warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); + } + } + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. . + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp;; + } + +public: + ELFPlugin(const Common::String &filename) + : _dlHandle(0), _filename(filename) {} + + ~ELFPlugin() { + if (_dlHandle) + unloadPlugin(); + } + + bool loadPlugin(); + void unloadPlugin(); + +}; + class ELFPluginProvider : public FilePluginProvider { protected: Plugin* createPlugin(const Common::FSNode &node) const; -- cgit v1.2.3 From 9369c769fe3c9741f5b1aa8ae7552c108e5ed94d Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 5 Aug 2010 23:59:34 +0000 Subject: Fix for mixed-up ordering of '_dlHandle->close()' and 'delete _dlHandle' svn-id: r51773 --- backends/plugins/elf-provider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 4e1f277fb8..08ef7899d2 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -58,10 +58,10 @@ bool ELFPlugin::loadPlugin() { void ELFPlugin::unloadPlugin() { DynamicPlugin::unloadPlugin(); if (_dlHandle) { - delete _dlHandle; if (!_dlHandle->close()) { warning("Failed unloading plugin '%s'", _filename.c_str()); } + delete _dlHandle; _dlHandle = 0; } } -- cgit v1.2.3 From 415a5aaa363634d76c3b75bf76a51172166e2306 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 6 Aug 2010 01:36:47 +0000 Subject: hacky way to put ELFPlugin::findSymbol in elf-provider.cpp without compiler errors svn-id: r51775 --- backends/plugins/elf-provider.cpp | 27 +++++++++++++++++++++++++++ backends/plugins/elf-provider.h | 29 +---------------------------- 2 files changed, 28 insertions(+), 28 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 08ef7899d2..43f999b461 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -31,6 +31,33 @@ #if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +void (* ELFPlugin::findSymbol(const char *symbol))() { + void *func; + bool handleNull; + if (_dlHandle == NULL) { + func = NULL; + handleNull = true; + } else { + func = _dlHandle->symbol(symbol); + } + if (!func) { + if (handleNull) { + warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); + } else { + warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); + } + } + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. . + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp; +} + bool ELFPlugin::loadPlugin() { assert(!_dlHandle); DLObject *obj = new DLObject(NULL); diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index 981d0d0638..3ed4816c19 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -39,34 +39,7 @@ protected: DLObject *_dlHandle; Common::String _filename; - //FIXME: The code for this method should be in elf-provider.cpp, - // but VoidFunc isn't recognized if we do that as is. - virtual VoidFunc findSymbol(const char *symbol) { - void *func; - bool handleNull; - if (_dlHandle == NULL) { - func = NULL; - handleNull = true; - } else { - func = _dlHandle->symbol(symbol); - } - if (!func) { - if (handleNull) { - warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); - } else { - warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); - } - } - - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp;; - } + virtual VoidFunc findSymbol(const char *symbol); public: ELFPlugin(const Common::String &filename) -- cgit v1.2.3 From d4a4176123f1a39916d1b407ab531bf3adb04697 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 6 Aug 2010 06:03:34 +0000 Subject: added DSPlugin and DS Plugin Provider (steps towards using subtypes of DLObject) svn-id: r51777 --- backends/module.mk | 1 + backends/platform/ds/arm9/makefile | 2 +- backends/platform/ds/arm9/source/dsmain.cpp | 3 +- backends/plugins/ds/ds-provider.cpp | 59 +++++++++++++++++++++++++++++ backends/plugins/ds/ds-provider.h | 35 +++++++++++++++++ backends/plugins/elf-provider.h | 7 +++- 6 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 backends/plugins/ds/ds-provider.cpp create mode 100644 backends/plugins/ds/ds-provider.h (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index 748b786eb4..bcfcb53a3e 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -32,6 +32,7 @@ MODULE_OBJS := \ midi/windows.o \ plugins/elf-provider.o \ plugins/dc/dc-provider.o \ + plugins/ds/ds-provider.o \ plugins/posix/posix-provider.o \ plugins/sdl/sdl-provider.o \ plugins/win32/win32-provider.o \ diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index adcf24f5ff..e68624679f 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -238,7 +238,7 @@ CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \ ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT -DARM +DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT ifdef USE_MAD DEFINES += -DUSE_MAD endif diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index 4e44e9f1dd..ee9e4d7622 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -112,6 +112,7 @@ #include "backends/plugins/elf-provider.h" +#include "backends/plugins/ds/ds-provider.h" #include "backends/fs/ds/ds-fs.h" #include "base/version.h" @@ -3304,7 +3305,7 @@ int main(void) { #endif #ifdef DYNAMIC_MODULES - PluginManager::instance().addPluginProvider(new ELFPluginProvider()); + PluginManager::instance().addPluginProvider(new DSPluginProvider()); #endif while (1) { diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp new file mode 100644 index 0000000000..e4ffb7bd43 --- /dev/null +++ b/backends/plugins/ds/ds-provider.cpp @@ -0,0 +1,59 @@ +/* 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$ + * + */ + +/*#include "base/plugins.h" +#include "backends/plugins/dynamic-plugin.h" +#include "common/fs.h" + +#include "backends/plugins/elf-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: + DSPlugin(const Common::String &filename) { + _dlHandle = 0; + _filename = filename; + } + + ~DSPlugin() { + if (_dlHandle) + unloadPlugin(); + } + +}; + +/*bool DSPlugin::loadPlugin() { + +};*/ + +Plugin* DSPluginProvider::createPlugin(const Common::FSNode &node) const { + return new DSPlugin(node.getPath()); +} + +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) + diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h new file mode 100644 index 0000000000..d9b1ee9cf4 --- /dev/null +++ b/backends/plugins/ds/ds-provider.h @@ -0,0 +1,35 @@ +/* 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$ + * + */ + +#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-provider.h b/backends/plugins/elf-provider.h index 3ed4816c19..2e659df80c 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -42,6 +42,9 @@ protected: virtual VoidFunc findSymbol(const char *symbol); public: + ELFPlugin() { + } + ELFPlugin(const Common::String &filename) : _dlHandle(0), _filename(filename) {} @@ -51,13 +54,13 @@ public: } bool loadPlugin(); - void unloadPlugin(); + virtual void unloadPlugin(); }; class ELFPluginProvider : public FilePluginProvider { protected: - Plugin* createPlugin(const Common::FSNode &node) const; + virtual Plugin* createPlugin(const Common::FSNode &node) const; bool isPluginFilename(const Common::FSNode &node) const; -- cgit v1.2.3 From 4bed67767cc4b8555a3d7169fcbb589ce0145303 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 6 Aug 2010 06:54:44 +0000 Subject: added loadPlugin function into DSPlugin (doesn't use a DSDLObject yet) svn-id: r51778 --- backends/plugins/ds/ds-provider.cpp | 25 +++++++++++++++++++++++-- backends/plugins/elf-provider.h | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp index e4ffb7bd43..999781754b 100644 --- a/backends/plugins/ds/ds-provider.cpp +++ b/backends/plugins/ds/ds-provider.cpp @@ -45,11 +45,32 @@ public: unloadPlugin(); } + bool loadPlugin(); }; -/*bool DSPlugin::loadPlugin() { +bool DSPlugin::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; +}; Plugin* DSPluginProvider::createPlugin(const Common::FSNode &node) const { return new DSPlugin(node.getPath()); diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index 2e659df80c..eb0ea5d51d 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -53,7 +53,7 @@ public: unloadPlugin(); } - bool loadPlugin(); + virtual bool loadPlugin(); virtual void unloadPlugin(); }; -- cgit v1.2.3 From 026c9ba6562a3fb88edcef60b7bd16f2a7f32773 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 6 Aug 2010 17:33:44 +0000 Subject: got rid of unneccessary 'extern C' section in elf-loader header and refactored arm-relocs.cpp to arm-loader.cpp svn-id: r51793 --- backends/platform/ds/arm9/makefile | 2 +- backends/plugins/arm-loader.cpp | 164 +++++++++++++++++++++++++++++++++++++ backends/plugins/arm-relocs.cpp | 164 ------------------------------------- backends/plugins/elf-loader.h | 9 -- 4 files changed, 165 insertions(+), 174 deletions(-) create mode 100644 backends/plugins/arm-loader.cpp delete mode 100644 backends/plugins/arm-relocs.cpp (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index e68624679f..86b7bd3628 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -293,7 +293,7 @@ PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(port $(portdir)/source/dsoptions.o $(portdir)/source/keys.o $(portdir)/source/wordcompletion.o\ $(portdir)/source/interrupt.o\ $(srcdir)/backends/plugins/elf-loader.o\ - $(srcdir)/backends/plugins/arm-relocs.o + $(srcdir)/backends/plugins/arm-loader.o ifdef USE_PROFILER PORT_OBJS += $(portdir)/source/profiler/cyg-profile.o diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp new file mode 100644 index 0000000000..8ceccfb7e8 --- /dev/null +++ b/backends/plugins/arm-loader.cpp @@ -0,0 +1,164 @@ +/* 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$ + * + */ + +#include "backends/fs/ds/ds-fs.h" +#include "elf-loader.h" +#include "dsmain.h" + +#define __DEBUG_PLUGINS__ + +#ifdef __DEBUG_PLUGINS__ +#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) consolePrintf(x, ## __VA_ARGS__) + +/** + * Follow the instruction of a relocation section. + * + * @param DLFile SeekableReadStream of File + * @param offset Offset into the File + * @param size Size of relocation section + * + */ +bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = NULL; //relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + seterror("Out of memory."); + return false; + } + + // Read in our relocation table + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != (ssize_t)size) { + seterror("Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + int a = 0; + unsigned int relocation = 0; + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; //Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + + case R_ARM_ABS32: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + case R_ARM_THM_CALL: + DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + break; + + case R_ARM_CALL: + DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + break; + + case R_ARM_JUMP24: + DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); + break; + + case R_ARM_TARGET1: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + DBG("Make sure --target1-abs is a flag to LD!\n"); + } + break; + + case R_ARM_V4BX: + DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); + break; + + default: + seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); + free(rel); + return false; + } + + } + + free(rel); + return true; +} + +bool DLObject::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++) { + + Elf32_Shdr *curShdr = &(shdr[i]); + + if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { + seterror("RELA entries not supported yet!\n"); + return false; + } + + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { + return false; + } + + } + } + + return true; +} diff --git a/backends/plugins/arm-relocs.cpp b/backends/plugins/arm-relocs.cpp deleted file mode 100644 index 8ceccfb7e8..0000000000 --- a/backends/plugins/arm-relocs.cpp +++ /dev/null @@ -1,164 +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$ - * - */ - -#include "backends/fs/ds/ds-fs.h" -#include "elf-loader.h" -#include "dsmain.h" - -#define __DEBUG_PLUGINS__ - -#ifdef __DEBUG_PLUGINS__ -#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) consolePrintf(x, ## __VA_ARGS__) - -/** - * Follow the instruction of a relocation section. - * - * @param DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * - */ -bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; //relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); - return false; - } - - // Read in our relocation table - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); - - int a = 0; - unsigned int relocation = 0; - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; //Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - - case R_ARM_ABS32: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } - break; - - case R_ARM_THM_CALL: - DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); - break; - - case R_ARM_CALL: - DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); - break; - - case R_ARM_JUMP24: - DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); - break; - - case R_ARM_TARGET1: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - DBG("Make sure --target1-abs is a flag to LD!\n"); - } - break; - - case R_ARM_V4BX: - DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); - break; - - default: - seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); - free(rel); - return false; - } - - } - - free(rel); - return true; -} - -bool DLObject::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++) { - - Elf32_Shdr *curShdr = &(shdr[i]); - - if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { - seterror("RELA entries not supported yet!\n"); - return false; - } - - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { - return false; - } - - } - } - - return true; -} diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index d6273b7e71..355b5557a2 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -88,15 +88,6 @@ public: }; -#define RTLD_LAZY 0 - -extern "C" { - void *dlopen(const char *filename, int flags); - int dlclose(void *handle); - const char *dlerror(); - void dlforgetsyms(void *handle); -} - extern void flushDataCache(); #endif /* LOADER_H */ -- cgit v1.2.3 From 5696fde1395d61f09bfc5cf0403477a7359e506d Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 6 Aug 2010 18:10:53 +0000 Subject: removed unnecessary declaration of flushDataCache() in elf-loader header svn-id: r51794 --- backends/plugins/elf-loader.cpp | 2 +- backends/plugins/elf-loader.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index a3b453ed0f..3c66c765f6 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -54,7 +54,7 @@ /** * Flushes the data cache (Platform Specific). */ -void flushDataCache() { +static void flushDataCache() { #ifdef __DS__ DC_FlushAll(); #endif diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 355b5557a2..80ef9b3fe3 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -88,6 +88,4 @@ public: }; -extern void flushDataCache(); - #endif /* LOADER_H */ -- cgit v1.2.3 From 66225374b2f75f8c5b4406564c35ca476242aa81 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 6 Aug 2010 20:09:16 +0000 Subject: made a couple of functions in DLObject virtual, other minor fixes/changes svn-id: r51797 --- backends/plugins/elf-loader.h | 6 +++--- backends/plugins/elf-provider.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 80ef9b3fe3..0a84d9c0b9 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -59,7 +59,7 @@ protected: void seterror(const char *fmt, ...); void unload(); - 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); bool load(Common::SeekableReadStream* DLFile); bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); @@ -69,7 +69,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); - bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: bool open(const char *path); @@ -77,7 +77,7 @@ public: void *symbol(const char *name); void discard_symtab(); - DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _segment(NULL), _symtab(NULL), + 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 diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 43f999b461..22e365130b 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -31,7 +31,7 @@ #if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) -void (* ELFPlugin::findSymbol(const char *symbol))() { +DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { void *func; bool handleNull; if (_dlHandle == NULL) { -- cgit v1.2.3 From 646587f79a4249e25e47af74d36c72602f00dd0f Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 6 Aug 2010 23:30:27 +0000 Subject: 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 --- backends/platform/gp2xwiz/elf32.h | 192 ----------- backends/platform/gp2xwiz/gp2xwiz-loader.cpp | 485 --------------------------- backends/platform/gp2xwiz/gp2xwiz-loader.h | 79 ----- backends/platform/gp2xwiz/plugin.ld | 182 ---------- backends/platform/gp2xwiz/plugin.syms | 8 - backends/plugins/arm-loader.cpp | 9 +- backends/plugins/ds/ds-provider.cpp | 7 +- backends/plugins/ds/ds-provider.h | 3 - backends/plugins/elf-loader.h | 22 +- backends/plugins/elf-provider.cpp | 33 +- backends/plugins/elf-provider.h | 6 +- 11 files changed, 22 insertions(+), 1004 deletions(-) delete mode 100644 backends/platform/gp2xwiz/elf32.h delete mode 100644 backends/platform/gp2xwiz/gp2xwiz-loader.cpp delete mode 100644 backends/platform/gp2xwiz/gp2xwiz-loader.h delete mode 100644 backends/platform/gp2xwiz/plugin.ld delete mode 100644 backends/platform/gp2xwiz/plugin.syms (limited to 'backends') 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 -#include -#include -#include -#include -#include -#include - - -#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; -- cgit v1.2.3 From 6982aed8a43be6a33802be95c9fde557885b7a5b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 00:40:15 +0000 Subject: made MIPSDLObject and PS2 plugin provider that uses it svn-id: r51818 --- backends/module.mk | 1 + backends/platform/ps2/Makefile.ps2 | 4 +- backends/platform/ps2/systemps2.cpp | 4 +- backends/plugins/arm-loader.cpp | 6 +- backends/plugins/ds/ds-provider.cpp | 6 - backends/plugins/mips-loader.cpp | 262 ++++++++++++++++++++++++++++++++++++ backends/plugins/mips-relocs.cpp | 259 ----------------------------------- 7 files changed, 270 insertions(+), 272 deletions(-) create mode 100644 backends/plugins/mips-loader.cpp delete mode 100644 backends/plugins/mips-relocs.cpp (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index bcfcb53a3e..d164cd3782 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -37,6 +37,7 @@ MODULE_OBJS := \ plugins/sdl/sdl-provider.o \ plugins/win32/win32-provider.o \ plugins/psp/psp-provider.o \ + plugins/ps2/ps2-provider.o \ plugins/gp2xwiz/gp2xwiz-provider.o \ saves/savefile.o \ saves/default/default-saves.o \ diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index e5617f40bd..8c59ee8c17 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -77,7 +77,7 @@ DEPDIR = .deps TARGET = elf/scummvm.elf -DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -DELF_LOADER_TARGET -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR -DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT +DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -DELF_LOADER_TARGET -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines @@ -112,7 +112,7 @@ OBJS := $(srcdir)/backends/platform/ps2/DmaPipe.o \ $(srcdir)/backends/platform/ps2/ps2mutex.o \ $(srcdir)/backends/platform/ps2/ps2time.o \ $(srcdir)/backends/plugins/elf-loader.o \ - $(srcdir)/backends/plugins/mips-relocs.o \ + $(srcdir)/backends/plugins/mips-loader.o \ $(srcdir)/backends/plugins/shorts-segment-manager.o \ $(srcdir)/backends/platform/ps2/ps2debug.o diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index bd8179976b..357404c5c4 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -59,7 +59,7 @@ #include "backends/platform/ps2/ps2debug.h" #include "backends/fs/ps2/ps2-fs-factory.h" -#include "backends/plugins/elf-provider.h" +#include "backends/plugins/ps2/ps2-provider.h" #include "backends/saves/default/default-saves.h" #include "common/config-manager.h" @@ -132,7 +132,7 @@ extern "C" int main(int argc, char *argv[]) { g_system = g_systemPs2 = new OSystem_PS2(argv[0]); #ifdef DYNAMIC_MODULES - PluginManager::instance().addPluginProvider(new ELFPluginProvider()); + PluginManager::instance().addPluginProvider(new PS2PluginProvider()); #endif g_systemPs2->init(); diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index 61d7c73236..cb19af78b6 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ARM) +#if defined(DYNAMIC_MODULES) #include "backends/fs/ds/ds-fs.h" #include "elf-loader.h" @@ -146,7 +146,7 @@ bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e Elf32_Shdr *curShdr = &(shdr[i]); if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 @@ -166,4 +166,4 @@ bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e return true; } -#endif /* defined(DYNAMIC_MODULES) && defined(ARM) */ +#endif /* defined(DYNAMIC_MODULES) */ diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp index c83f198b5e..66e063f151 100644 --- a/backends/plugins/ds/ds-provider.cpp +++ b/backends/plugins/ds/ds-provider.cpp @@ -25,17 +25,11 @@ #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" - class DSPlugin : public ELFPlugin { public: DSPlugin(const Common::String &filename) { diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp new file mode 100644 index 0000000000..708456d475 --- /dev/null +++ b/backends/plugins/mips-loader.cpp @@ -0,0 +1,262 @@ +/* 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) + +#include "mips-loader.h" + +#define __DEBUG_PLUGINS__ + +#ifdef __DEBUG_PLUGINS__ +#define DBG(x,...) printf(x, ## __VA_ARGS__) +#else +#define DBG(x,...) +#endif + +#define seterror(x,...) printf(x, ## __VA_ARGS__) + +/** + * Follow the instruction of a relocation section. + * + * @param DLFile SeekableReadStream of File + * @param offset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) + * + */ +bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = NULL; // relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + seterror("Out of memory."); + return false; + } + + // Read in our relocation table + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != (ssize_t)size) { + seterror("Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + bool seenHi16 = false; // For treating HI/LO16 commands + int firstHi16 = -1; // Mark the point of the first hi16 seen + Elf32_Addr ahl = 0; // Calculated addend + int a = 0; // Addend: taken from the target + + unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives + unsigned int relocation = 0; + int debugRelocs[10] = {0}; // For debugging + int extendedHi16 = 0; // Count extended hi16 treatments + Elf32_Addr lastHiSymVal = 0; + bool hi16InShorts = false; + +#define DEBUG_NUM 2 + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; // Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + + case R_MIPS_HI16: // Absolute addressing. + if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) + firstHi16 < 0) { // Only process first in block of HI16s + firstHi16 = i; // Keep the first Hi16 we saw + seenHi16 = true; + ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up + + lastHiSymVal = sym->st_value; + hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments + if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number + DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", + i, rel[i].r_offset, ahl, *target); + } + break; + + case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) + if (!seenHi16) { // We MUST have seen HI16 first + seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); + free(rel); + return false; + } + + // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) + // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section + // and will be screened out above + bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); + + // Correct the bug by getting the proper value in ahl (taken from the current symbol) + if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { + ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset + ahl += (sym->st_value & 0xffff0000); + } + + ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s + a = *target & 0xffff; // Take lower 16 bits of the target + a = (a << 16) >> 16; // Sign extend them + ahl += a; // Add lower 16 bits. AHL is now complete + + // Fix: we can have LO16 access to the short segment sometimes + if (lo16InShorts) { + relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset + } else // It's in the regular segment + relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment + + if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now + for (int j = firstHi16; j < i; j++) { + if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s + + lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target + *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target + *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation + if (relocation & 0x8000)(*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case + } + firstHi16 = -1; // Reset so we'll know we treated it + } else { + extendedHi16++; + } + + *target &= 0xffff0000; // Clear the lower 16 bits of current target + *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation + + if (debugRelocs[1]++ < DEBUG_NUM) + DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) + DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + } + break; + + case R_MIPS_26: // Absolute addressing (for jumps and branches only) + if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment + a = *target & 0x03ffffff; // Get 26 bits' worth of the addend + a = (a << 6) >> 6; // Sign extend a + relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset + *target &= 0xfc000000; // Clean lower 26 target bits + *target |= (relocation & 0x03ffffff); + + if (debugRelocs[3]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } else { + if (debugRelocs[4]++ < DEBUG_NUM) + DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } + break; + + case R_MIPS_GPREL16: // GP Relative addressing + if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section + ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole + a = *target & 0xffff; // Get 16 bits' worth of the addend + a = (a << 16) >> 16; // Sign extend it + + relocation = a + _shortsSegment->getOffset(); + + *target &= 0xffff0000; // Clear the lower 16 bits of the target + *target |= relocation & 0xffff; + + if (debugRelocs[5]++ < DEBUG_NUM) + DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", + i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); + } + + break; + + case R_MIPS_32: // Absolute addressing + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + + if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment + relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset + else // We're in the main section + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + *target = relocation; + + if (debugRelocs[6]++ < DEBUG_NUM) + DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + } + break; + + default: + seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); + free(rel); + return false; + } + } + + DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); + + free(rel); + return true; +} + +bool MIPSDLObject::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++) { + + 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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { + return false; + } + } else { // In Shorts segment + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { + return false; + } + } + + } + } + + return true; +} + +#endif /* defined(DYNAMIC_MODULES) */ diff --git a/backends/plugins/mips-relocs.cpp b/backends/plugins/mips-relocs.cpp deleted file mode 100644 index fe8fa7c1a0..0000000000 --- a/backends/plugins/mips-relocs.cpp +++ /dev/null @@ -1,259 +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$ - * - */ - -#include "elf-loader.h" - -#define __DEBUG_PLUGINS__ - -#ifdef __DEBUG_PLUGINS__ -#define DBG(x,...) printf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) printf(x, ## __VA_ARGS__) - -/** - * Follow the instruction of a relocation section. - * - * @param DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - * - */ -bool DLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; // relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); - return false; - } - - // Read in our relocation table - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); - - bool seenHi16 = false; // For treating HI/LO16 commands - int firstHi16 = -1; // Mark the point of the first hi16 seen - Elf32_Addr ahl = 0; // Calculated addend - int a = 0; // Addend: taken from the target - - unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives - unsigned int relocation = 0; - int debugRelocs[10] = {0}; // For debugging - int extendedHi16 = 0; // Count extended hi16 treatments - Elf32_Addr lastHiSymVal = 0; - bool hi16InShorts = false; - -#define DEBUG_NUM 2 - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; // Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - - case R_MIPS_HI16: // Absolute addressing. - if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) - firstHi16 < 0) { // Only process first in block of HI16s - firstHi16 = i; // Keep the first Hi16 we saw - seenHi16 = true; - ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up - - lastHiSymVal = sym->st_value; - hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments - if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number - DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", - i, rel[i].r_offset, ahl, *target); - } - break; - - case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) - if (!seenHi16) { // We MUST have seen HI16 first - seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); - free(rel); - return false; - } - - // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) - // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section - // and will be screened out above - bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); - - // Correct the bug by getting the proper value in ahl (taken from the current symbol) - if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { - ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset - ahl += (sym->st_value & 0xffff0000); - } - - ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s - a = *target & 0xffff; // Take lower 16 bits of the target - a = (a << 16) >> 16; // Sign extend them - ahl += a; // Add lower 16 bits. AHL is now complete - - // Fix: we can have LO16 access to the short segment sometimes - if (lo16InShorts) { - relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset - } else // It's in the regular segment - relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment - - if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now - for (int j = firstHi16; j < i; j++) { - if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s - - lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target - *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target - *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation - if (relocation & 0x8000)(*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case - } - firstHi16 = -1; // Reset so we'll know we treated it - } else { - extendedHi16++; - } - - *target &= 0xffff0000; // Clear the lower 16 bits of current target - *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation - - if (debugRelocs[1]++ < DEBUG_NUM) - DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - } - break; - - case R_MIPS_26: // Absolute addressing (for jumps and branches only) - if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment - a = *target & 0x03ffffff; // Get 26 bits' worth of the addend - a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset - *target &= 0xfc000000; // Clean lower 26 target bits - *target |= (relocation & 0x03ffffff); - - if (debugRelocs[3]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } else { - if (debugRelocs[4]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } - break; - - case R_MIPS_GPREL16: // GP Relative addressing - if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section - ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole - a = *target & 0xffff; // Get 16 bits' worth of the addend - a = (a << 16) >> 16; // Sign extend it - - relocation = a + _shortsSegment->getOffset(); - - *target &= 0xffff0000; // Clear the lower 16 bits of the target - *target |= relocation & 0xffff; - - if (debugRelocs[5]++ < DEBUG_NUM) - DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", - i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); - } - - break; - - case R_MIPS_32: // Absolute addressing - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - - if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment - relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset - else // We're in the main section - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - *target = relocation; - - if (debugRelocs[6]++ < DEBUG_NUM) - DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } - break; - - default: - seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); - free(rel); - return false; - } - } - - DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); - - free(rel); - return true; -} - -bool DLObject::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++) { - - 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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { - return false; - } - } else { // In Shorts segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { - return false; - } - } - - } - } - - return true; -} - -- cgit v1.2.3 From 0712d418708540c2c6dbba4c4912eb94302c9125 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 05:01:43 +0000 Subject: modified psp to use mips-loader.cpp (and added things to backends/module.mk) svn-id: r51826 --- backends/module.mk | 4 ++ backends/platform/ds/arm9/makefile | 6 +-- backends/platform/ps2/Makefile.ps2 | 6 +-- backends/platform/psp/Makefile | 2 +- backends/plugins/arm-loader.cpp | 4 +- backends/plugins/elf-loader.h | 7 +-- backends/plugins/mips-loader.cpp | 4 +- backends/plugins/psp/psp-provider.cpp | 80 +++++++++-------------------- backends/plugins/psp/psp-provider.h | 8 +-- backends/plugins/shorts-segment-manager.cpp | 4 +- 10 files changed, 42 insertions(+), 83 deletions(-) (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index d164cd3782..0a1cadd366 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -30,6 +30,10 @@ MODULE_OBJS := \ midi/timidity.o \ midi/dmedia.o \ midi/windows.o \ + plugins/elf-loader.o \ + plugins/mips-loader.o \ + plugins/shorts-segment-manager.o \ + plugins/arm-loader.o \ plugins/elf-provider.o \ plugins/dc/dc-provider.o \ plugins/ds/ds-provider.o \ diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 86b7bd3628..c43c28c223 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -238,7 +238,7 @@ CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \ ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT +DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT ifdef USE_MAD DEFINES += -DUSE_MAD endif @@ -291,9 +291,7 @@ PORT_OBJS := $(portdir)/source/blitters_arm.o $(portdir)/source/cdaudio.o $(port $(portdir)/source/osystem_ds.o $(portdir)/source/ramsave.o\ $(portdir)/source/touchkeyboard.o $(portdir)/source/zipreader.o\ $(portdir)/source/dsoptions.o $(portdir)/source/keys.o $(portdir)/source/wordcompletion.o\ - $(portdir)/source/interrupt.o\ - $(srcdir)/backends/plugins/elf-loader.o\ - $(srcdir)/backends/plugins/arm-loader.o + $(portdir)/source/interrupt.o ifdef USE_PROFILER PORT_OBJS += $(portdir)/source/profiler/cyg-profile.o diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 8c59ee8c17..717bc94379 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -77,7 +77,8 @@ DEPDIR = .deps TARGET = elf/scummvm.elf -DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -DELF_LOADER_TARGET -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT +DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR +DEFINES += -DELF_LOADER_TARGET -DMIPS_TARGET#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines @@ -111,9 +112,6 @@ OBJS := $(srcdir)/backends/platform/ps2/DmaPipe.o \ $(srcdir)/backends/platform/ps2/systemps2.o \ $(srcdir)/backends/platform/ps2/ps2mutex.o \ $(srcdir)/backends/platform/ps2/ps2time.o \ - $(srcdir)/backends/plugins/elf-loader.o \ - $(srcdir)/backends/plugins/mips-loader.o \ - $(srcdir)/backends/plugins/shorts-segment-manager.o \ $(srcdir)/backends/platform/ps2/ps2debug.o include $(srcdir)/Makefile.common diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index 010f6e635a..754bc775f0 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -68,7 +68,7 @@ endif # Variables for common Scummvm makefile CXX = psp-g++ CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti -DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR -DELF_LOADER_TARGET +DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR -DELF_LOADER_TARGET -DMIPS_TARGET LDFLAGS := INCDIR := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index cb19af78b6..7e8269220b 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) +#if defined(DYNAMIC_MODULES) && defined(ARM_TARGET) #include "backends/fs/ds/ds-fs.h" #include "elf-loader.h" @@ -166,4 +166,4 @@ bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e return true; } -#endif /* defined(DYNAMIC_MODULES) */ +#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 423a97bc42..7abe012003 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -30,15 +30,10 @@ #include "common/stream.h" #include "backends/plugins/dynamic-plugin.h" -#if defined(__PLAYSTATION2__) || defined(__PSP__) -#define MIPS_TARGET +#if defined(MIPS_TARGET) #include "shorts-segment-manager.h" #endif -#if defined(__DS__) -#define ARM_TARGET -#endif - class DLObject { protected: void *_segment, *_symtab; diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp index 708456d475..f537729197 100644 --- a/backends/plugins/mips-loader.cpp +++ b/backends/plugins/mips-loader.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) +#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) #include "mips-loader.h" @@ -259,4 +259,4 @@ bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr * return true; } -#endif /* defined(DYNAMIC_MODULES) */ +#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/psp/psp-provider.cpp b/backends/plugins/psp/psp-provider.cpp index f394916538..f542373b87 100644 --- a/backends/plugins/psp/psp-provider.cpp +++ b/backends/plugins/psp/psp-provider.cpp @@ -25,84 +25,52 @@ #if defined(DYNAMIC_MODULES) && defined(__PSP__) +#include "backends/plugins/mips-loader.h" +#include "backends/plugins/elf-provider.h" #include "backends/plugins/psp/psp-provider.h" -#include "backends/plugins/dynamic-plugin.h" -#include "common/fs.h" -#include "backends/platform/psp/psploader.h" - - -class PSPPlugin : public DynamicPlugin { -protected: - void *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol) { - void *func = dlsym(_dlHandle, symbol); - if (!func) - warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); - - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp; - } +class PSPPlugin : public ELFPlugin { public: - PSPPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} + PSPPlugin(const Common::String &filename) { + _dlHandle = 0; + _filename = filename; + } ~PSPPlugin() { - if (_dlHandle) unloadPlugin(); + if (_dlHandle) + unloadPlugin(); } - bool loadPlugin() { + bool loadPlugin(); +}; + +bool PSPPlugin::loadPlugin() { assert(!_dlHandle); - _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); + DLObject *obj = new MIPSDLObject(); + if (obj->open(_filename.c_str())) { + _dlHandle = obj; + } else { + delete obj; + _dlHandle = NULL; + } if (!_dlHandle) { - warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); + warning("Failed loading plugin '%s'", _filename.c_str()); return false; } bool ret = DynamicPlugin::loadPlugin(); - if (ret) - dlforgetsyms(_dlHandle); + if (ret && _dlHandle) { + _dlHandle->discard_symtab(); + } return ret; - } - - void unloadPlugin() { - DynamicPlugin::unloadPlugin(); - if (_dlHandle) { - if (dlclose(_dlHandle) != 0) - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); - _dlHandle = 0; - } - } }; - Plugin* PSPPluginProvider::createPlugin(const Common::FSNode &node) const { return new PSPPlugin(node.getPath()); } -bool PSPPluginProvider::isPluginFilename(const Common::FSNode &node) const { - // Check the plugin suffix - Common::String filename = node.getName(); - fprintf(stderr, "Testing name %s", filename.c_str()); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg")) { - fprintf(stderr," fail.\n"); - return false; - } - - fprintf(stderr," success!\n"); - return true; -} - #endif // defined(DYNAMIC_MODULES) && defined(__PSP__) diff --git a/backends/plugins/psp/psp-provider.h b/backends/plugins/psp/psp-provider.h index d6c44c5a85..c4debc7997 100644 --- a/backends/plugins/psp/psp-provider.h +++ b/backends/plugins/psp/psp-provider.h @@ -26,16 +26,12 @@ #ifndef BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H #define BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H -#include "base/plugins.h" +#include "backends/plugins/elf-provider.h" #if defined(DYNAMIC_MODULES) && defined(__PSP__) -class PSPPluginProvider : public FilePluginProvider { -protected: +class PSPPluginProvider : public ELFPluginProvider { Plugin* createPlugin(const Common::FSNode &node) const; - - bool isPluginFilename(const Common::FSNode &node) const; - }; #endif // defined(DYNAMIC_MODULES) && defined(__PSP__) diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index 25962c504d..2376759919 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -23,7 +23,7 @@ * */ -#if defined(DYNAMIC_MODULES) //TODO: && defined (MIPS target) +#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) #include "shorts-segment-manager.h" @@ -86,4 +86,4 @@ void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { delete seg; } -#endif /* DYNAMIC_MODULES */ +#endif /* DYNAMIC_MODULES && MIPS_TARGET */ -- cgit v1.2.3 From d6adeb9ccf3e361d206dbf09b5279cea43459ff2 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 06:15:57 +0000 Subject: took out hacky 'ifdef MIPS_TARGET' statements in DLObject's methods and instead overrode those methods in MIPSDLObject svn-id: r51827 --- backends/plugins/elf-loader.cpp | 73 ++++++++------------------------ backends/plugins/elf-loader.h | 15 ++----- backends/plugins/mips-loader.cpp | 89 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 68 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 3c66c765f6..9787c880ae 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -37,6 +37,11 @@ #include "common/fs.h" #include "elf-loader.h" +#ifdef __PSP__ +#include "backends/platform/psp/powerman.h" +#include "psputils.h" +#endif + #ifdef __DS__ #include #endif @@ -62,6 +67,9 @@ static void flushDataCache() { FlushCache(0); FlushCache(2); #endif +#ifdef __PSP__ + sceKernelDcacheWritebackAll(); +#endif } // Expel the symbol table from memory @@ -78,13 +86,6 @@ void DLObject::unload() { discard_symtab(); free(_segment); _segment = NULL; - -#ifdef MIPS_TARGET - if (_shortsSegment) { - ShortsMan.deleteSegment(_shortsSegment); - _shortsSegment = NULL; - } -#endif } bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { @@ -97,7 +98,7 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd ehdr->e_machine != EM_ARM || // Check for ARM machine type #endif #ifdef MIPS_TARGET - ehdr->e_machine != EM_MIPS || + ehdr->e_machine != EM_MIPS || // Check for MIPS machine type #endif ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header @@ -137,33 +138,6 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) char *baseAddress = 0; -#ifdef MIPS_TARGET - // We need to take account of non-allocated segment for shorts - if (phdr->p_flags & PF_X) { // This is a relocated segment - - // 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 (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - - 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; - } else { // This is a shorts section. - _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); - - baseAddress = _shortsSegment->getStart(); - DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", - _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); - } -#else // 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); @@ -178,7 +152,6 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) // Get offset to load segment into baseAddress = (char *)_segment + phdr->p_vaddr; _segmentSize = phdr->p_memsz + extra; -#endif // Set bss segment to 0 if necessary (assumes bss is at the end) if (phdr->p_memsz > phdr->p_filesz) { @@ -294,33 +267,13 @@ void DLObject::relocateSymbols(Elf32_Addr offset) { Elf32_Sym *s = (Elf32_Sym *)_symtab; for (int c = _symbol_cnt; c--; s++) { -#ifdef MIPS_TARGET - // Make sure we don't relocate special valued symbols - if (s->st_shndx < SHN_LOPROC) { - if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { - mainCount++; - 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); - } else { // shorts section - shortsCount++; - s->st_value += _shortsSegment->getOffset(); - if (!_shortsSegment->inSegment((char *)s->st_value)) - seterror("Symbol out of bounds! st_value = %x\n", s->st_value); - } - - } -#else // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { mainCount++; 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); - } -#endif - } } @@ -371,6 +324,10 @@ bool DLObject::open(const char *path) { Common::SeekableReadStream* DLFile; void *ctors_start, *ctors_end; +#ifdef __PSP__ + PowerMan.beginCriticalSection(); +#endif + DBG("open(\"%s\")\n", path); Common::FSNode file(path); @@ -390,6 +347,10 @@ bool DLObject::open(const char *path) { DBG("loaded!/n"); +#ifdef __PSP__ + PowerMan.endCriticalSection(); +#endif + flushDataCache(); ctors_start = symbol("___plugin_ctors"); diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 7abe012003..56a9fa3767 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -30,10 +30,6 @@ #include "common/stream.h" #include "backends/plugins/dynamic-plugin.h" -#if defined(MIPS_TARGET) -#include "shorts-segment-manager.h" -#endif - class DLObject { protected: void *_segment, *_symtab; @@ -44,23 +40,18 @@ protected: int _segmentSize; -#ifdef MIPS_TARGET - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - unsigned int _gpVal; // Value of Global Pointer -#endif - //void seterror(const char *fmt, ...); - void unload(); + virtual void unload(); 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); bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); 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 void relocateSymbols(Elf32_Addr offset); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; public: diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp index f537729197..7b59a2cffa 100644 --- a/backends/plugins/mips-loader.cpp +++ b/backends/plugins/mips-loader.cpp @@ -259,4 +259,93 @@ bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr * return true; } +void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { + + int mainCount = 0; + int shortsCount= 0; + + // 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) { + if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { + mainCount++; + 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); + } else { // shorts section + shortsCount++; + s->st_value += _shortsSegment->getOffset(); + if (!_shortsSegment->inSegment((char *)s->st_value)) + seterror("Symbol out of bounds! st_value = %x\n", s->st_value); + } + + } + } +} + +bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { + + char *baseAddress = 0; + + // We need to take account of non-allocated segment for shorts + if (phdr->p_flags & PF_X) { // This is a relocated segment + + // 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 (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI + + 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; + } else { // This is a shorts section. + _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); + + baseAddress = _shortsSegment->getStart(); + DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", + _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + } + + // 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); + } + + DBG("Reading the segment into memory\n"); + + // Read the segment into memory + if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || + DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { + seterror("Segment load failed."); + return false; + } + + DBG("Segment has been read into memory\n"); + + return true; +} + +// Unload all objects from memory +void MIPSDLObject::unload() { + discard_symtab(); + free(_segment); + _segment = NULL; + + if (_shortsSegment) { + ShortsMan.deleteSegment(_shortsSegment); + _shortsSegment = NULL; + } +} + #endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ -- cgit v1.2.3 From 59b2b46fe8eaf292602ea6e1011ce35ed598e742 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 06:21:22 +0000 Subject: removed psploader code, as it is covered by the mipsloader and elfloader in backends/plugins svn-id: r51828 --- backends/platform/psp/psploader.cpp | 721 ------------------------------------ backends/platform/psp/psploader.h | 137 ------- 2 files changed, 858 deletions(-) delete mode 100644 backends/platform/psp/psploader.cpp delete mode 100644 backends/platform/psp/psploader.h (limited to 'backends') diff --git a/backends/platform/psp/psploader.cpp b/backends/platform/psp/psploader.cpp deleted file mode 100644 index 68e51c1a50..0000000000 --- a/backends/platform/psp/psploader.cpp +++ /dev/null @@ -1,721 +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(__PSP__) - -#include -#include -#include -#include -#include -#include - -#include - -#include "backends/platform/psp/psploader.h" -#include "backends/platform/psp/powerman.h" - -//#define __PSP_DEBUG_PLUGINS__ - -#ifdef __PSP_DEBUG_PLUGINS__ -#define DBG(x,...) fprintf(stderr,x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__) - -extern char __plugin_hole_start; // Indicates start of hole in program file for shorts -extern char __plugin_hole_end; // Indicates end of hole in program file -extern char _gp[]; // Value of gp register - -DECLARE_SINGLETON(ShortSegmentManager) // For singleton - -// Get rid of symbol table in 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; - - if (_shortsSegment) { - ShortsMan.deleteSegment(_shortsSegment); - _shortsSegment = NULL; - } -} - -/** - * Follow the instruction of a relocation section. - * - * @param fd File Descriptor - * @param offset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - * - */ -bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; // relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); - return false; - } - - // Read in our relocation table - if (lseek(fd, offset, SEEK_SET) < 0 || - read(fd, rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); - - bool seenHi16 = false; // For treating HI/LO16 commands - int firstHi16 = -1; // Mark the point of the first hi16 seen - Elf32_Addr ahl = 0; // Calculated addend - int a = 0; // Addend: taken from the target - - unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives - unsigned int relocation = 0; - int debugRelocs[10] = {0}; // For debugging - int extendedHi16 = 0; // Count extended hi16 treatments - Elf32_Addr lastHiSymVal = 0; - bool hi16InShorts = false; - -#define DEBUG_NUM 2 - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; // Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - - case R_MIPS_HI16: // Absolute addressing. - if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) - firstHi16 < 0) { // Only process first in block of HI16s - firstHi16 = i; // Keep the first Hi16 we saw - seenHi16 = true; - ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up - - lastHiSymVal = sym->st_value; - hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments - if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number - DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", - i, rel[i].r_offset, ahl, *target); - } - break; - - case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) - if (!seenHi16) { // We MUST have seen HI16 first - seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); - free(rel); - return false; - } - - // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) - // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section - // and will be screened out above - bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); - - // Correct the bug by getting the proper value in ahl (taken from the current symbol) - if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { - ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset - ahl += (sym->st_value & 0xffff0000); - } - - ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s - a = *target & 0xffff; // Take lower 16 bits of the target - a = (a << 16) >> 16; // Sign extend them - ahl += a; // Add lower 16 bits. AHL is now complete - - // Fix: we can have LO16 access to the short segment sometimes - if (lo16InShorts) { - relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset - } else // It's in the regular segment - relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment - - if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now - for (int j = firstHi16; j < i; j++) { - if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s - - lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target - *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target - *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation - if (relocation & 0x8000)(*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case - } - firstHi16 = -1; // Reset so we'll know we treated it - } else { - extendedHi16++; - } - - *target &= 0xffff0000; // Clear the lower 16 bits of current target - *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation - - if (debugRelocs[1]++ < DEBUG_NUM) - DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - } - break; - - case R_MIPS_26: // Absolute addressing (for jumps and branches only) - if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment - a = *target & 0x03ffffff; // Get 26 bits' worth of the addend - a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset - *target &= 0xfc000000; // Clean lower 26 target bits - *target |= (relocation & 0x03ffffff); - - if (debugRelocs[3]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } else { - if (debugRelocs[4]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } - break; - - case R_MIPS_GPREL16: // GP Relative addressing - if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section - ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole - a = *target & 0xffff; // Get 16 bits' worth of the addend - a = (a << 16) >> 16; // Sign extend it - - relocation = a + _shortsSegment->getOffset(); - - *target &= 0xffff0000; // Clear the lower 16 bits of the target - *target |= relocation & 0xffff; - - if (debugRelocs[5]++ < DEBUG_NUM) - DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", - i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); - } - - break; - - case R_MIPS_32: // Absolute addressing - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - - if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment - relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset - else // We're in the main section - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - *target = relocation; - - if (debugRelocs[6]++ < DEBUG_NUM) - DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - } - break; - - default: - seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); - free(rel); - return false; - } - } - - DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); - - free(rel); - 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_MIPS || // Check for MIPS 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; - - // We need to take account of non-allocated segment for shorts - if (phdr->p_flags & PF_X) { // This is a relocated segment - - // 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 (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - - 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; - } else { // This is a shorts section. - _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); - - baseAddress = _shortsSegment->getStart(); - DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", - _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); - - } - - // 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++) { - //DBG("Section %d: type = %x, size = %x, entsize = %x, link = %x\n", - // i, shdr[i].sh_type, shdr[i].sh_size, shdr[i].sh_entsize, shdr[i].sh_link); - - 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, Elf32_Addr shortsOffset) { - - int shortsCount = 0, othersCount = 0; - DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); - - // 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) { - if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { - othersCount++; - 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); - } else { // shorts section - shortsCount++; - s->st_value += shortsOffset; - if (!_shortsSegment->inSegment((char *)s->st_value)) - seterror("Symbol out of bounds! st_value = %x\n", s->st_value); - } - - } - - } - - DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); -} - -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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, _segment)) { - return false; - } - } else { // In Shorts segment - if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { - return false; - } - } - - } - } - - return true; -} - - -bool DLObject::load(int fd) { - fprintf(stderr, "In DLObject::load\n"); - - Elf32_Ehdr ehdr; // ELF header - Elf32_Phdr phdr; // Program header - Elf32_Shdr *shdr; // Section header - bool ret = true; - - 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, _shortsSegment->getOffset()); // 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); - - // Get the address of the global pointer - _gpVal = (unsigned int) & _gp; - DBG("_gpVal is %x\n", _gpVal); - - PowerMan.beginCriticalSection(); - - 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); - - PowerMan.endCriticalSection(); - - // flush data cache - sceKernelDcacheWritebackAll(); - - // Get the symbols for the global constructors and destructors - 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++) { - - // We can only import symbols that are global or weak in the plugin - if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && - /*_strtab[s->st_name] == '_' && */ // Try to make this more efficient - !strcmp(name, _strtab + s->st_name)) { - - // We found the symbol - DBG("=> %p\n", (void*)s->st_value); - return (void*)s->st_value; - } - } - - seterror("Symbol \"%s\" not found.", name); - return NULL; -} - - - -ShortSegmentManager::ShortSegmentManager() { - _shortsStart = &__plugin_hole_start ; - _shortsEnd = &__plugin_hole_end; -} - -ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { - char *lastAddress = origAddr; - Common::List::iterator i; - - // Find a block that fits, starting from the beginning - for (i = _list.begin(); i != _list.end(); ++i) { - char *currAddress = (*i)->getStart(); - - if ((int)(currAddress - lastAddress) >= size) break; - - lastAddress = (*i)->getEnd(); - } - - if ((Elf32_Addr)lastAddress & 3) - lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 - - if (lastAddress + size > _shortsEnd) { - seterror("Error. No space in shorts segment for %x bytes. Last address is %p, max address is %p.\n", - size, lastAddress, _shortsEnd); - return NULL; - } - - Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment - - if (lastAddress + size > _highestAddress) _highestAddress = lastAddress + size; // Keep track of maximum - - _list.insert(i, seg); - - DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", - size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); - - return seg; -} - -void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { - DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); - _list.remove(seg); - delete seg; -} - -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 && __PSP__ */ diff --git a/backends/platform/psp/psploader.h b/backends/platform/psp/psploader.h deleted file mode 100644 index 13dcf6ef98..0000000000 --- a/backends/platform/psp/psploader.h +++ /dev/null @@ -1,137 +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 PSPLOADER_H -#define PSPLOADER_H - -#include "elf32.h" -#include "common/list.h" -#include "common/singleton.h" - -#define MAXDLERRLEN 80 - -#define ShortsMan ShortSegmentManager::instance() - -class ShortSegmentManager : public Common::Singleton { -private: - char *_shortsStart; - char *_shortsEnd; - -public: - char *getShortsStart() { - return _shortsStart; - } - bool inGeneralSegment(char *addr) { - return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); - } - - class Segment { - private: - friend class ShortSegmentManager; - Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} - ~Segment() {} - char *_startAddress; // Start of shorts segment in memory - int _size; // Size of shorts segment - char *_origAddress; // Original address this segment was supposed to be at - public: - char *getStart() { - return _startAddress; - } - char *getEnd() { - return (_startAddress + _size); - } - Elf32_Addr getOffset() { - return (Elf32_Addr)(_startAddress - _origAddress); - } - bool inSegment(char *addr) { - return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); - } - }; - - Segment *newSegment(int size, char *origAddr); - void deleteSegment(Segment *); - -private: - ShortSegmentManager(); - friend class Common::Singleton; - Common::List _list; - char *_highestAddress; -}; - - - - -class DLObject { -protected: - char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */ - - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - void *_segment, *_symtab; - char *_strtab; - int _symbol_cnt; - int _symtab_sect; - void *_dtors_start, *_dtors_end; - - unsigned int _gpVal; // Value of Global Pointer - int _segmentSize; - - void seterror(const char *fmt, ...); - void unload(); - bool relocate(int fd, unsigned long offset, unsigned long size, void *); - 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, Elf32_Addr shortsOffset); - 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), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), - _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , - _segmentSize(0) {} -}; - - - -#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 /* PSPLOADER_H */ -- cgit v1.2.3 From 68b986545a7ce24e3c0d2a8635d538941b67729f Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 21:47:50 +0000 Subject: added necessary files I forgot to commit yesterday (whoops...) for mips and arm loaders svn-id: r51843 --- backends/plugins/arm-loader.h | 46 +++++++++++++++++++++ backends/plugins/mips-loader.h | 54 +++++++++++++++++++++++++ backends/plugins/ps2/ps2-provider.cpp | 76 +++++++++++++++++++++++++++++++++++ backends/plugins/ps2/ps2-provider.h | 31 ++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 backends/plugins/arm-loader.h create mode 100644 backends/plugins/mips-loader.h create mode 100644 backends/plugins/ps2/ps2-provider.cpp create mode 100644 backends/plugins/ps2/ps2-provider.h (limited to 'backends') diff --git a/backends/plugins/arm-loader.h b/backends/plugins/arm-loader.h new file mode 100644 index 0000000000..babbe69739 --- /dev/null +++ b/backends/plugins/arm-loader.h @@ -0,0 +1,46 @@ +/* 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$ + * + */ + +#include "backends/fs/ds/ds-fs.h" +#include "elf-loader.h" +#include "dsmain.h" + +class ARMDLObject : public DLObject { +protected: + bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + +public: + ARMDLObject() { + _segment = NULL; + _symtab = NULL; + _strtab = NULL; + _symbol_cnt = 0; + _symtab_sect = -1; + _dtors_start = NULL; + _dtors_end = NULL; + _segmentSize = 0; + } +}; diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h new file mode 100644 index 0000000000..9d13feccbb --- /dev/null +++ b/backends/plugins/mips-loader.h @@ -0,0 +1,54 @@ + +/* 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$ + * + */ + +#include "elf-loader.h" +#include "shorts-segment-manager.h" + +class MIPSDLObject : public DLObject { +protected: + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + unsigned int _gpVal; // Value of Global Pointer + + bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + void relocateSymbols(Elf32_Addr offset); + bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + void unload(); + +public: + MIPSDLObject() { + _segment = NULL; + _symtab = NULL; + _strtab = NULL; + _symbol_cnt = 0; + _symtab_sect = -1; + _dtors_start = NULL; + _dtors_end = NULL; + _segmentSize = 0; + _shortsSegment = NULL; + _gpVal = 0; + } +}; diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp new file mode 100644 index 0000000000..7305c27c74 --- /dev/null +++ b/backends/plugins/ps2/ps2-provider.cpp @@ -0,0 +1,76 @@ +/* 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(__PLAYSTATION2__) + +#include "backends/plugins/mips-loader.h" +#include "backends/plugins/elf-provider.h" +#include "backends/plugins/ps2/ps2-provider.h" + + +class PS2Plugin : public ELFPlugin { +public: + PS2Plugin(const Common::String &filename) { + _dlHandle = 0; + _filename = filename; + } + + ~PS2Plugin() { + if (_dlHandle) + unloadPlugin(); + } + + bool loadPlugin(); +}; + +bool PS2Plugin::loadPlugin() { + assert(!_dlHandle); + DLObject *obj = new MIPSDLObject(); + 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; +}; + +Plugin* PS2PluginProvider::createPlugin(const Common::FSNode &node) const { + return new PS2Plugin(node.getPath()); +} + +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h new file mode 100644 index 0000000000..28a2321c29 --- /dev/null +++ b/backends/plugins/ps2/ps2-provider.h @@ -0,0 +1,31 @@ +/* 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$ + * + */ + +#include "backends/plugins/elf-provider.h" + +class PS2PluginProvider : public ELFPluginProvider { + Plugin* createPlugin(const Common::FSNode &node) const; +}; + -- cgit v1.2.3 From de1e941370b7e2fad704e072eccfb79b3db1399b Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 22:27:23 +0000 Subject: refined constructors, removed destructors, got rid of unneccessary method duplication in DLObject and its subtypes svn-id: r51845 --- backends/plugins/arm-loader.h | 11 +---------- backends/plugins/ds/ds-provider.cpp | 36 ++--------------------------------- backends/plugins/elf-loader.h | 2 ++ backends/plugins/elf-provider.cpp | 24 +++++++++++++++++++++++ backends/plugins/elf-provider.h | 7 +++---- backends/plugins/mips-loader.h | 10 +--------- backends/plugins/ps2/ps2-provider.cpp | 36 ++--------------------------------- backends/plugins/psp/psp-provider.cpp | 36 ++--------------------------------- 8 files changed, 37 insertions(+), 125 deletions(-) (limited to 'backends') diff --git a/backends/plugins/arm-loader.h b/backends/plugins/arm-loader.h index babbe69739..7f7a1f7f4b 100644 --- a/backends/plugins/arm-loader.h +++ b/backends/plugins/arm-loader.h @@ -33,14 +33,5 @@ protected: bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: - ARMDLObject() { - _segment = NULL; - _symtab = NULL; - _strtab = NULL; - _symbol_cnt = 0; - _symtab_sect = -1; - _dtors_start = NULL; - _dtors_end = NULL; - _segmentSize = 0; - } + ARMDLObject() : DLObject() {} }; diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp index 66e063f151..7365a2e6e9 100644 --- a/backends/plugins/ds/ds-provider.cpp +++ b/backends/plugins/ds/ds-provider.cpp @@ -32,41 +32,9 @@ class DSPlugin : public ELFPlugin { public: - DSPlugin(const Common::String &filename) { - _dlHandle = 0; - _filename = filename; - } + DSPlugin(const Common::String &filename) : ELFPlugin(filename) {} - ~DSPlugin() { - if (_dlHandle) - unloadPlugin(); - } - - bool loadPlugin(); -}; - -bool DSPlugin::loadPlugin() { - assert(!_dlHandle); - DLObject *obj = new ARMDLObject(); - 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; + DLObject *makeDLObject() { return new ARMDLObject(); } }; Plugin* DSPluginProvider::createPlugin(const Common::FSNode &node) const { diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 56a9fa3767..1d30aa0c3b 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -60,6 +60,8 @@ public: void *symbol(const char *name); void discard_symtab(); + DLObject() : _segment(NULL), _symtab(NULL), _strtab(NULL), _symbol_cnt(0), + _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _segmentSize(0) {} }; #endif /* ELF_LOADER_H */ diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 03218130fb..e6edd4c578 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -58,6 +58,30 @@ DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { return tmp; } +bool ELFPlugin::loadPlugin() { + assert(!_dlHandle); + DLObject *obj = makeDLObject(); + 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) { diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index fd047fd0d3..e0382c3e45 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -42,9 +42,6 @@ protected: virtual VoidFunc findSymbol(const char *symbol); public: - ELFPlugin() { - } - ELFPlugin(const Common::String &filename) : _dlHandle(0), _filename(filename) {} @@ -53,7 +50,9 @@ public: unloadPlugin(); } - virtual bool loadPlugin() = 0; + virtual DLObject *makeDLObject() = 0; + + bool loadPlugin(); void unloadPlugin(); }; diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h index 9d13feccbb..eb22e368f4 100644 --- a/backends/plugins/mips-loader.h +++ b/backends/plugins/mips-loader.h @@ -39,15 +39,7 @@ protected: void unload(); public: - MIPSDLObject() { - _segment = NULL; - _symtab = NULL; - _strtab = NULL; - _symbol_cnt = 0; - _symtab_sect = -1; - _dtors_start = NULL; - _dtors_end = NULL; - _segmentSize = 0; + MIPSDLObject() : DLObject() { _shortsSegment = NULL; _gpVal = 0; } diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp index 7305c27c74..096c6d4050 100644 --- a/backends/plugins/ps2/ps2-provider.cpp +++ b/backends/plugins/ps2/ps2-provider.cpp @@ -32,41 +32,9 @@ class PS2Plugin : public ELFPlugin { public: - PS2Plugin(const Common::String &filename) { - _dlHandle = 0; - _filename = filename; - } + PS2Plugin(const Common::String &filename) : ELFPlugin(filename) {} - ~PS2Plugin() { - if (_dlHandle) - unloadPlugin(); - } - - bool loadPlugin(); -}; - -bool PS2Plugin::loadPlugin() { - assert(!_dlHandle); - DLObject *obj = new MIPSDLObject(); - 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; + DLObject *makeDLObject() { return new MIPSDLObject(); } }; Plugin* PS2PluginProvider::createPlugin(const Common::FSNode &node) const { diff --git a/backends/plugins/psp/psp-provider.cpp b/backends/plugins/psp/psp-provider.cpp index f542373b87..99aa33c123 100644 --- a/backends/plugins/psp/psp-provider.cpp +++ b/backends/plugins/psp/psp-provider.cpp @@ -32,41 +32,9 @@ class PSPPlugin : public ELFPlugin { public: - PSPPlugin(const Common::String &filename) { - _dlHandle = 0; - _filename = filename; - } + PSPPlugin(const Common::String &filename) : ELFPlugin(filename) {} - ~PSPPlugin() { - if (_dlHandle) - unloadPlugin(); - } - - bool loadPlugin(); -}; - -bool PSPPlugin::loadPlugin() { - assert(!_dlHandle); - DLObject *obj = new MIPSDLObject(); - 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; + DLObject *makeDLObject() { return new MIPSDLObject(); } }; Plugin* PSPPluginProvider::createPlugin(const Common::FSNode &node) const { -- cgit v1.2.3 From 9cf5dedca53b04403977baa95848ddab231d1c17 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 22:30:18 +0000 Subject: got rid of rest of leftover stuff from GP2X-WIZ elf-loader attempt svn-id: r51846 --- backends/platform/gp2xwiz/gp2xwiz-main.cpp | 10 --- backends/plugins/gp2xwiz/gp2xwiz-provider.cpp | 108 -------------------------- backends/plugins/gp2xwiz/gp2xwiz-provider.h | 43 ---------- 3 files changed, 161 deletions(-) delete mode 100644 backends/plugins/gp2xwiz/gp2xwiz-provider.cpp delete mode 100644 backends/plugins/gp2xwiz/gp2xwiz-provider.h (limited to 'backends') diff --git a/backends/platform/gp2xwiz/gp2xwiz-main.cpp b/backends/platform/gp2xwiz/gp2xwiz-main.cpp index fa08cff9f7..8c95a94639 100644 --- a/backends/platform/gp2xwiz/gp2xwiz-main.cpp +++ b/backends/platform/gp2xwiz/gp2xwiz-main.cpp @@ -41,7 +41,6 @@ #include "common/file.h" #include "base/main.h" -#include "backends/plugins/gp2xwiz/gp2xwiz-provider.h" #include "backends/saves/default/default-saves.h" #include "backends/timer/default/default-timer.h" #include "sound/mixer_intern.h" @@ -54,9 +53,6 @@ #include #include // for getTimeAndDate() -//comment this out to use POSIX plugins -#define ELF_LOADER - /* Dump console info to files. */ // #define DUMP_STDOUT @@ -66,13 +62,7 @@ int main(int argc, char *argv[]) { assert(g_system); #ifdef DYNAMIC_MODULES - -#ifdef ELF_LOADER - PluginManager::instance().addPluginProvider(new GP2XWIZPluginProvider()); -#else PluginManager::instance().addPluginProvider(new POSIXPluginProvider()); -#endif /* ELF_LOADER */ - #endif /* DYNAMIC_MODULES */ // Invoke the actual ScummVM main entry point: diff --git a/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp b/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp deleted file mode 100644 index 859ac8fbc8..0000000000 --- a/backends/plugins/gp2xwiz/gp2xwiz-provider.cpp +++ /dev/null @@ -1,108 +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 "backends/plugins/gp2xwiz/gp2xwiz-provider.h" -#include "backends/plugins/dynamic-plugin.h" -#include "common/fs.h" - -#include "backends/platform/gp2xwiz/gp2xwiz-loader.h" - - -class GP2XWIZPlugin : public DynamicPlugin { -protected: - void *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol) { - void *func = dlsym(_dlHandle, symbol); - if (!func) - warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); - - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp; - } - -public: - GP2XWIZPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} - - ~GP2XWIZPlugin() { - if (_dlHandle) unloadPlugin(); - } - - bool loadPlugin() { - assert(!_dlHandle); - _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); - - if (!_dlHandle) { - warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); - return false; - } - - bool ret = DynamicPlugin::loadPlugin(); - - if (ret) - dlforgetsyms(_dlHandle); - - return ret; - } - - void unloadPlugin() { - DynamicPlugin::unloadPlugin(); - if (_dlHandle) { - if (dlclose(_dlHandle) != 0) - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); - _dlHandle = 0; - } - } -}; - - -Plugin* GP2XWIZPluginProvider::createPlugin(const Common::FSNode &node) const { - return new GP2XWIZPlugin(node.getPath()); -} - -bool GP2XWIZPluginProvider::isPluginFilename(const Common::FSNode &node) const { - // Check the plugin suffix - Common::String filename = node.getName(); - printf("Testing name %s", filename.c_str()); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { - printf(" fail.\n"); - return false; - } - - printf(" success!\n"); - return true; -} - -#endif // defined(DYNAMIC_MODULES) && defined(GP2XWIZ) diff --git a/backends/plugins/gp2xwiz/gp2xwiz-provider.h b/backends/plugins/gp2xwiz/gp2xwiz-provider.h deleted file mode 100644 index 929a9af1f6..0000000000 --- a/backends/plugins/gp2xwiz/gp2xwiz-provider.h +++ /dev/null @@ -1,43 +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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ps2/ps2-provider.h $ - * $Id: ps2-provider.h 49435 2010-06-05 01:05:19Z toneman1138 $ - * - */ - -#ifndef BACKENDS_PLUGINS_GP2XWIZ_GP2XWIZ_PROVIDER_H -#define BACKENDS_PLUGINS_GP2XWIZ_GP2XWIZ_PROVIDER_H - -#include "base/plugins.h" - -#if defined(DYNAMIC_MODULES) && defined(GP2XWIZ) - -class GP2XWIZPluginProvider : public FilePluginProvider { -protected: - Plugin* createPlugin(const Common::FSNode &node) const; - - bool isPluginFilename(const Common::FSNode &node) const; - -}; - -#endif // defined(DYNAMIC_MODULES) && defined(GP2XWIZ) - -#endif /* BACKENDS_PLUGINS_GP2XWIZ_GP2XWIZ_PROVIDER_H */ -- cgit v1.2.3 From 924c4e0c06eb90677847d04b185468ad3d2efb22 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 7 Aug 2010 22:42:12 +0000 Subject: removed gp2x-wiz plugin provider from backends/module.mk svn-id: r51847 --- backends/module.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index 0a1cadd366..50ef1596ae 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -42,7 +42,6 @@ MODULE_OBJS := \ plugins/win32/win32-provider.o \ plugins/psp/psp-provider.o \ plugins/ps2/ps2-provider.o \ - plugins/gp2xwiz/gp2xwiz-provider.o \ saves/savefile.o \ saves/default/default-saves.o \ saves/posix/posix-saves.o \ -- cgit v1.2.3 From 139a96182d2a52e25b42ec35f834f7a10f30675c Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Thu, 12 Aug 2010 23:55:12 +0000 Subject: modified DS makefile to use new plugin design where only one plugin is loaded at a time and tested successfully on the DS. Added code to prevent a crash in the case where there are no engine plugins present. Removed code for R_ARM_TARGET1 in arm-loader, as it is no longer used and was never used successfully svn-id: r52052 --- backends/platform/ds/arm9/makefile | 6 +++--- backends/plugins/arm-loader.cpp | 12 ------------ 2 files changed, 3 insertions(+), 15 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 407df8243c..75a2e68ec5 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -1,7 +1,7 @@ srcdir ?= . DEPDIR := .deps -VERBOSE_BUILD = 1 +VERBOSE_BUILD = 0 DYNAMIC_MODULES = 1 libndsdir = $(DEVKITPRO)/libnds #libndsdir = /home/neil/devkitpror21/libnds @@ -237,7 +237,7 @@ CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \ ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT +DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET -DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT ifdef USE_MAD DEFINES += -DUSE_MAD endif @@ -364,7 +364,7 @@ semiclean: clean: $(RM) $(OBJS) $(EXECUTABLE) - rm -rf *.h engines plugins scummvm.nds scummvm.ds.gba + rm -rf *.h engines plugins graphics gui common sound backends base map.txt scummvm.nds scummvm.ds.gba dist : SCUMMVM.BIN plugins plugin_dist diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index 7e8269220b..d8ed083962 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -110,18 +110,6 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); break; - case R_ARM_TARGET1: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - DBG("R_ARM_TARGET1: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); - DBG("Make sure --target1-abs is a flag to LD!\n"); - } - break; - case R_ARM_V4BX: DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); break; -- cgit v1.2.3 From 62d8126df0ec90a9b1f3b660fce769631c57208e Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 13 Aug 2010 02:58:52 +0000 Subject: added appropriate ifdefs throughout the plugins directory svn-id: r52053 --- backends/plugins/arm-loader.h | 4 ++++ backends/plugins/ds/ds-provider.h | 4 +++- backends/plugins/elf-loader.h | 4 ++++ backends/plugins/elf-provider.h | 8 ++++---- backends/plugins/mips-loader.h | 4 ++++ backends/plugins/ps2/ps2-provider.h | 4 ++++ backends/plugins/psp/psp-provider.h | 8 ++++---- backends/plugins/shorts-segment-manager.h | 4 ++++ 8 files changed, 31 insertions(+), 9 deletions(-) (limited to 'backends') diff --git a/backends/plugins/arm-loader.h b/backends/plugins/arm-loader.h index 7f7a1f7f4b..d377912bbe 100644 --- a/backends/plugins/arm-loader.h +++ b/backends/plugins/arm-loader.h @@ -23,6 +23,8 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(ARM_TARGET) + #include "backends/fs/ds/ds-fs.h" #include "elf-loader.h" #include "dsmain.h" @@ -35,3 +37,5 @@ protected: public: ARMDLObject() : DLObject() {} }; + +#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h index 462c3e3b63..2a3e731d1c 100644 --- a/backends/plugins/ds/ds-provider.h +++ b/backends/plugins/ds/ds-provider.h @@ -23,10 +23,12 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(__DS__) + #include "backends/plugins/elf-provider.h" 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 1d30aa0c3b..4b5ec99b57 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -23,6 +23,8 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) + #ifndef ELF_LOADER_H #define ELF_LOADER_H @@ -65,3 +67,5 @@ public: }; #endif /* ELF_LOADER_H */ + +#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index e0382c3e45..61112e5b4e 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -23,6 +23,8 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) + #ifndef BACKENDS_PLUGINS_ELF_PROVIDER_H #define BACKENDS_PLUGINS_ELF_PROVIDER_H @@ -32,8 +34,6 @@ #include "backends/plugins/elf-loader.h" -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - class ELFPlugin : public DynamicPlugin { protected: DLObject *_dlHandle; @@ -65,6 +65,6 @@ protected: }; -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - #endif /* BACKENDS_PLUGINS_ELF_PROVIDER_H */ + +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h index eb22e368f4..0b66412485 100644 --- a/backends/plugins/mips-loader.h +++ b/backends/plugins/mips-loader.h @@ -24,6 +24,8 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) + #include "elf-loader.h" #include "shorts-segment-manager.h" @@ -44,3 +46,5 @@ public: _gpVal = 0; } }; + +#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index 28a2321c29..4833b9a281 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -23,9 +23,13 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) + #include "backends/plugins/elf-provider.h" class PS2PluginProvider : public ELFPluginProvider { Plugin* createPlugin(const Common::FSNode &node) const; }; +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) + diff --git a/backends/plugins/psp/psp-provider.h b/backends/plugins/psp/psp-provider.h index c4debc7997..4662f875b7 100644 --- a/backends/plugins/psp/psp-provider.h +++ b/backends/plugins/psp/psp-provider.h @@ -23,17 +23,17 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(__PSP__) + #ifndef BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H #define BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H #include "backends/plugins/elf-provider.h" -#if defined(DYNAMIC_MODULES) && defined(__PSP__) - class PSPPluginProvider : public ELFPluginProvider { Plugin* createPlugin(const Common::FSNode &node) const; }; -#endif // defined(DYNAMIC_MODULES) && defined(__PSP__) - #endif /* BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H */ + +#endif // defined(DYNAMIC_MODULES) && defined(__PSP__) diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h index 54a13d88e1..caefc7da8c 100644 --- a/backends/plugins/shorts-segment-manager.h +++ b/backends/plugins/shorts-segment-manager.h @@ -23,6 +23,8 @@ * */ +#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) + #ifndef SHORTS_SEGMENT_MANAGER_H #define SHORTS_SEGMENT_MANAGER_H @@ -87,3 +89,5 @@ private: }; #endif /* SHORTS_SEGMENT_MANAGER_H */ + +#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ -- cgit v1.2.3 From 2cd99b449f9a42f8d9cc45ae4902e326f8925bd8 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Fri, 13 Aug 2010 05:58:11 +0000 Subject: refactored NEW_PLUGIN_DESIGN_FIRST_REFINEMENT define into ONE_PLUGIN_AT_A_TIME svn-id: r52058 --- backends/platform/ds/arm9/makefile | 4 ++-- backends/platform/ps2/Makefile.ps2 | 2 +- backends/plugins/arm-loader.cpp | 2 +- backends/plugins/mips-loader.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 75a2e68ec5..3f3c46b452 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -237,7 +237,7 @@ CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \ ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET -DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT +DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET -DONE_PLUGIN_AT_A_TIME ifdef USE_MAD DEFINES += -DUSE_MAD endif @@ -362,7 +362,7 @@ include $(srcdir)/Makefile.common semiclean: $(RM) $(portdir)/source/dsoptions.o $(portdir)/source/dsmain.o $(FAT_OBJS) $(DATA_OBJS) $(portdir)/source/wordcompletion.o $(portdir)/source/dsoptions.o -clean: +clean: #TODO: Manual removal of engine, plugins, etc. isn't very elegant! $(RM) $(OBJS) $(EXECUTABLE) rm -rf *.h engines plugins graphics gui common sound backends base map.txt scummvm.nds scummvm.ds.gba diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index f836bd3eaa..53f9b51360 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -78,7 +78,7 @@ DEPDIR = .deps TARGET = elf/scummvm.elf DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR -DEFINES += -DELF_LOADER_TARGET -DMIPS_TARGET#-DNEW_PLUGIN_DESIGN_FIRST_REFINEMENT +DEFINES += -DELF_LOADER_TARGET -DMIPS_TARGET#-DONE_PLUGIN_AT_A_TIME INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index d8ed083962..916516aed9 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -30,7 +30,7 @@ #include "dsmain.h" #include "arm-loader.h" -#define __DEBUG_PLUGINS__ +//#define __DEBUG_PLUGINS__ #ifdef __DEBUG_PLUGINS__ #define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp index 7b59a2cffa..dfa2765cfa 100644 --- a/backends/plugins/mips-loader.cpp +++ b/backends/plugins/mips-loader.cpp @@ -27,7 +27,7 @@ #include "mips-loader.h" -#define __DEBUG_PLUGINS__ +//#define __DEBUG_PLUGINS__ #ifdef __DEBUG_PLUGINS__ #define DBG(x,...) printf(x, ## __VA_ARGS__) -- cgit v1.2.3 From af81ed98c5aa0020ebbac21bc54df4acd917ccf7 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 14 Aug 2010 09:03:35 +0000 Subject: added dynamic plugins stuff for PS2 into Makefile (and added couple of defines for abstracted ELF-LOADER for psp svn-id: r52083 --- backends/platform/ps2/Makefile.ps2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 53f9b51360..f0e57fab0f 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -6,7 +6,7 @@ PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /tremor/tremor # Set to 1 to enable, 0 to disable dynamic modules -DYNAMIC_MODULES = 1 +DYNAMIC_MODULES = 0 # Set to 1 to enable, 0 to disable more detailed printing of gcc commands VERBOSE_BUILD=0 -- cgit v1.2.3 From 14061c94f7f15e887ad2d93748755b1fde7726a9 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Sat, 14 Aug 2010 09:06:50 +0000 Subject: removed psploader.o from objects in psp makefile (psp should be using abstracted MIPS loader now) svn-id: r52085 --- backends/platform/psp/Makefile | 1 - 1 file changed, 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index 01bcf7006f..49455f6b97 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -143,7 +143,6 @@ OBJS := powerman.o \ input.o \ cursor.o \ trace.o \ - psploader.o \ pspkeyboard.o \ audio.o \ thread.o \ -- cgit v1.2.3 From 34b5eb3ba3fa68093f13f9be493c1e25ad9c5123 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 16 Aug 2010 08:41:04 +0000 Subject: added a todo to plugins.cpp and a comment to elf32.h; Collapsed plugin providers for a few ports into their .h files, removing the corresponding .cpp files svn-id: r52112 --- backends/module.mk | 7 ++---- backends/plugins/ds/ds-provider.cpp | 45 ----------------------------------- backends/plugins/ds/ds-provider.h | 15 ++++++++++-- backends/plugins/elf32.h | 6 ++++- backends/plugins/ps2/ps2-provider.cpp | 44 ---------------------------------- backends/plugins/ps2/ps2-provider.h | 15 ++++++++++-- backends/plugins/psp/psp-provider.cpp | 44 ---------------------------------- backends/plugins/psp/psp-provider.h | 14 ++++++++++- 8 files changed, 46 insertions(+), 144 deletions(-) delete mode 100644 backends/plugins/ds/ds-provider.cpp delete mode 100644 backends/plugins/ps2/ps2-provider.cpp delete mode 100644 backends/plugins/psp/psp-provider.cpp (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index c0457d8062..922abc2afd 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -49,8 +49,7 @@ endif ifeq ($(BACKEND),ds) MODULE_OBJS += \ fs/ds/ds-fs-factory.o \ - fs/ds/ds-fs.o \ - plugins/ds/ds-provider.o + fs/ds/ds-fs.o endif ifeq ($(BACKEND),n64) @@ -61,15 +60,13 @@ endif ifeq ($(BACKEND),ps2) MODULE_OBJS += \ - fs/ps2/ps2-fs-factory.o \ - plugins/ps2/ps2-provider.o + fs/ps2/ps2-fs-factory.o endif ifeq ($(BACKEND),psp) MODULE_OBJS += \ fs/psp/psp-fs-factory.o \ fs/psp/psp-stream.o \ - plugins/psp/psp-provider.o \ saves/psp/psp-saves.o \ timer/psp/timer.o endif diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp deleted file mode 100644 index 7365a2e6e9..0000000000 --- a/backends/plugins/ds/ds-provider.cpp +++ /dev/null @@ -1,45 +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(__DS__) - -#include "backends/plugins/arm-loader.h" -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/ds/ds-provider.h" - - -class DSPlugin : public ELFPlugin { -public: - DSPlugin(const Common::String &filename) : ELFPlugin(filename) {} - - DLObject *makeDLObject() { return new ARMDLObject(); } -}; - -Plugin* DSPluginProvider::createPlugin(const Common::FSNode &node) const { - return new DSPlugin(node.getPath()); -} - -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h index 2a3e731d1c..0013145358 100644 --- a/backends/plugins/ds/ds-provider.h +++ b/backends/plugins/ds/ds-provider.h @@ -26,9 +26,20 @@ #if defined(DYNAMIC_MODULES) && defined(__DS__) #include "backends/plugins/elf-provider.h" +#include "backends/plugins/arm-loader.h" class DSPluginProvider : public ELFPluginProvider { - Plugin* createPlugin(const Common::FSNode &node) const; + class DSPlugin : public ELFPlugin { + public: + DSPlugin(const Common::String &filename) : ELFPlugin(filename) {} + + DLObject *makeDLObject() { return new ARMDLObject(); } + }; + +public: + Plugin* createPlugin(const Common::FSNode &node) const { + return new DSPlugin(node.getPath()); + } }; -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +#endif // defined(DYNAMIC_MODULES) && defined(__DS__) diff --git a/backends/plugins/elf32.h b/backends/plugins/elf32.h index 5dec1d2e58..ef6b714a5e 100644 --- a/backends/plugins/elf32.h +++ b/backends/plugins/elf32.h @@ -26,7 +26,11 @@ #ifndef BACKENDS_ELF_H #define BACKENDS_ELF_H -/* ELF stuff */ +/** + * ELF stuff: + * The contents of this file were gathered mainly from the SYSTEM V APPLICATION BINARY INTERFACE. + * Processor-specific things were garnered from processor-specific supplements to the abi. + */ typedef unsigned short Elf32_Half, Elf32_Section; typedef unsigned int Elf32_Word, Elf32_Addr, Elf32_Off; diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp deleted file mode 100644 index 096c6d4050..0000000000 --- a/backends/plugins/ps2/ps2-provider.cpp +++ /dev/null @@ -1,44 +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(__PLAYSTATION2__) - -#include "backends/plugins/mips-loader.h" -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/ps2/ps2-provider.h" - - -class PS2Plugin : public ELFPlugin { -public: - PS2Plugin(const Common::String &filename) : ELFPlugin(filename) {} - - DLObject *makeDLObject() { return new MIPSDLObject(); } -}; - -Plugin* PS2PluginProvider::createPlugin(const Common::FSNode &node) const { - return new PS2Plugin(node.getPath()); -} - -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index 4833b9a281..dfadfffc29 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -26,10 +26,21 @@ #if defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) #include "backends/plugins/elf-provider.h" +#include "backends/plugins/mips-loader.h" class PS2PluginProvider : public ELFPluginProvider { - Plugin* createPlugin(const Common::FSNode &node) const; + class PS2Plugin : public ELFPlugin { + public: + PS2Plugin(const Common::String &filename) : ELFPlugin(filename) {} + + DLObject *makeDLObject() { return new MIPSDLObject(); } + }; + +public: + Plugin* PS2PluginProvider::createPlugin(const Common::FSNode &node) const { + return new PS2Plugin(node.getPath()); + } }; -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +#endif // defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) diff --git a/backends/plugins/psp/psp-provider.cpp b/backends/plugins/psp/psp-provider.cpp deleted file mode 100644 index 99aa33c123..0000000000 --- a/backends/plugins/psp/psp-provider.cpp +++ /dev/null @@ -1,44 +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(__PSP__) - -#include "backends/plugins/mips-loader.h" -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/psp/psp-provider.h" - - -class PSPPlugin : public ELFPlugin { -public: - PSPPlugin(const Common::String &filename) : ELFPlugin(filename) {} - - DLObject *makeDLObject() { return new MIPSDLObject(); } -}; - -Plugin* PSPPluginProvider::createPlugin(const Common::FSNode &node) const { - return new PSPPlugin(node.getPath()); -} - -#endif // defined(DYNAMIC_MODULES) && defined(__PSP__) diff --git a/backends/plugins/psp/psp-provider.h b/backends/plugins/psp/psp-provider.h index 4662f875b7..efe62ecf2c 100644 --- a/backends/plugins/psp/psp-provider.h +++ b/backends/plugins/psp/psp-provider.h @@ -29,9 +29,21 @@ #define BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H #include "backends/plugins/elf-provider.h" +#include "backends/plugins/mips-loader.h" class PSPPluginProvider : public ELFPluginProvider { - Plugin* createPlugin(const Common::FSNode &node) const; + class PSPPlugin : public ELFPlugin { + public: + PSPPlugin(const Common::String &filename) : ELFPlugin(filename) {} + + DLObject *makeDLObject() { return new MIPSDLObject(); } + }; + +public: + Plugin* PSPPluginProvider::createPlugin(const Common::FSNode &node) const { + return new PSPPlugin(node.getPath()); + } +} }; #endif /* BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H */ -- cgit v1.2.3 From 80012ad865d618955ee3154627a43d226cb10b83 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 16 Aug 2010 09:47:00 +0000 Subject: Added define to PS2 so it uses ONE_PLUGIN_AT_A_TIME svn-id: r52114 --- backends/platform/ps2/Makefile.ps2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index f0e57fab0f..00f09e0ac9 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -6,7 +6,7 @@ PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /tremor/tremor # Set to 1 to enable, 0 to disable dynamic modules -DYNAMIC_MODULES = 0 +DYNAMIC_MODULES = 1 # Set to 1 to enable, 0 to disable more detailed printing of gcc commands VERBOSE_BUILD=0 @@ -78,7 +78,7 @@ DEPDIR = .deps TARGET = elf/scummvm.elf DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR -DEFINES += -DELF_LOADER_TARGET -DMIPS_TARGET#-DONE_PLUGIN_AT_A_TIME +DEFINES += -DELF_LOADER_TARGET -DMIPS_TARGET -DONE_PLUGIN_AT_A_TIME INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines -- cgit v1.2.3 From b5d705554de8596550035d9f3bdbf7acbc926148 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 16 Aug 2010 10:09:44 +0000 Subject: removed redundant include of Makefile.common in PS2 Makefile svn-id: r52115 --- backends/platform/ps2/Makefile.ps2 | 2 -- 1 file changed, 2 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 00f09e0ac9..e278b0bf7d 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -119,8 +119,6 @@ OBJS := $(srcdir)/backends/platform/ps2/DmaPipe.o \ $(srcdir)/backends/platform/ps2/ps2time.o \ $(srcdir)/backends/platform/ps2/ps2debug.o -include $(srcdir)/Makefile.common - all: $(TARGET) $(TARGET): $(OBJS) -- cgit v1.2.3 From 8e199cf434e5e82725957b2cb28e9fc59565b869 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 16 Aug 2010 11:04:34 +0000 Subject: moved include of Makefile.common in PS2 Makefile svn-id: r52117 --- backends/platform/ps2/Makefile.ps2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index e278b0bf7d..d5b0ae3e2a 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -95,8 +95,6 @@ PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-T$(srcdir BACKEND := ps2 -include $(srcdir)/Makefile.common - LDFLAGS = -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(srcdir)/backends/plugins/ps2/main_prog.ld LDFLAGS += -L $(PS2SDK)/ee/lib -L . LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) @@ -119,6 +117,8 @@ OBJS := $(srcdir)/backends/platform/ps2/DmaPipe.o \ $(srcdir)/backends/platform/ps2/ps2time.o \ $(srcdir)/backends/platform/ps2/ps2debug.o +include $(srcdir)/Makefile.common + all: $(TARGET) $(TARGET): $(OBJS) -- cgit v1.2.3 From 8f7de9974f859ffa4841be015340af667e604168 Mon Sep 17 00:00:00 2001 From: Tony Puccinelli Date: Mon, 16 Aug 2010 16:32:06 +0000 Subject: Added doxygen comments for a few different plugin-related classes svn-id: r52124 --- backends/plugins/elf-loader.h | 7 +++++++ backends/plugins/elf-provider.h | 9 +++++++++ backends/plugins/shorts-segment-manager.h | 15 ++++++++++++--- 3 files changed, 28 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 4b5ec99b57..df0427e429 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -32,6 +32,13 @@ #include "common/stream.h" #include "backends/plugins/dynamic-plugin.h" +/** + * DLObject + * + * Class that most directly handles operations on a plugin file + * (opening it for reading, loading/unloading it in memory, finding a specific symbol in the file, etc.) + * Subclasses have the same functionality, but implementations specific to different processors/platforms. + */ class DLObject { protected: void *_segment, *_symtab; diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index 61112e5b4e..200d4faf40 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -34,6 +34,15 @@ #include "backends/plugins/elf-loader.h" +/** + * ELFPlugin + * + * Objects of this class are returned when the PluginManager calls + * getPlugins() on an ELFPluginProvider. An intermediary class for + * dealing with plugin files, ELFPlugin is responsible for creating/destroying + * a DLObject that handles the opening/loading/unloading of the plugin file whose + * path in the target backend's file system is "_filename". + */ class ELFPlugin : public DynamicPlugin { protected: DLObject *_dlHandle; diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h index caefc7da8c..2710a7b9ff 100644 --- a/backends/plugins/shorts-segment-manager.h +++ b/backends/plugins/shorts-segment-manager.h @@ -35,10 +35,19 @@ #define ShortsMan ShortSegmentManager::instance() /** - * Manages the segments of small data put in the gp-relative area for MIPS processors, - * and lets these segments be handled differently in the ELF loader. + * ShortSegmentManager + * + * Since MIPS is limited to 32 bits per instruction, loading data that's further away than 16 bits + * takes several instructions. Thus, small global data (which is likely to be accessed a lot from + * multiple locations) is often put into a GP-relative area (GP standing for the global pointer register) + * in MIPS processors. This class manages these segments of small global data, and is used by the + * member functions of MIPSDLObject, which query in information from this manager in order to deal with + * this segment during the loading/unloading of plugins. + * * Since there's no true dynamic linker to change the GP register between plugins and the main engine, - * custom linker scripts ensure the GP-area is in the same place for both. + * custom ld linker scripts for both the main executable and the plugins ensure the GP-area is in the + * same place for both. The ShortSegmentManager accesses this place via the symbols __plugin_hole_start + * and __plugin_hole_end, which are defined in those custom ld linker scripts. */ class ShortSegmentManager : public Common::Singleton { private: -- cgit v1.2.3 From 3ece67d1b8cbb6e5bfc493297726b8cb2afc8ee7 Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Thu, 19 Aug 2010 11:17:17 +0000 Subject: PLUGINS: added virtual destructor to DLObject This could be really important. Maybe. svn-id: r52205 --- backends/plugins/elf-loader.h | 1 + 1 file changed, 1 insertion(+) (limited to 'backends') diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index df0427e429..7150141567 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -71,6 +71,7 @@ public: DLObject() : _segment(NULL), _symtab(NULL), _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _segmentSize(0) {} + virtual ~DLObject() { unload(); } }; #endif /* ELF_LOADER_H */ -- cgit v1.2.3 From 8fb92b9e2a95ec8ef137eba930287f3c29772e8d Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Thu, 19 Aug 2010 11:18:01 +0000 Subject: PSP: made PSP compile with plugins. Also removed criticalSection calls from elf-loader.cpp, since now streams are used so the criticalSections are automatic. svn-id: r52206 --- backends/platform/psp/module.mk | 1 - backends/plugins/elf-loader.cpp | 8 -------- backends/plugins/psp/psp-provider.h | 3 +-- 3 files changed, 1 insertion(+), 11 deletions(-) (limited to 'backends') diff --git a/backends/platform/psp/module.mk b/backends/platform/psp/module.mk index 4652189ab4..a854ec1252 100644 --- a/backends/platform/psp/module.mk +++ b/backends/platform/psp/module.mk @@ -11,7 +11,6 @@ MODULE_OBJS := powerman.o \ input.o \ cursor.o \ trace.o \ - psploader.o \ pspkeyboard.o \ audio.o \ thread.o \ diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 9787c880ae..2cf61aa246 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -324,10 +324,6 @@ bool DLObject::open(const char *path) { Common::SeekableReadStream* DLFile; void *ctors_start, *ctors_end; -#ifdef __PSP__ - PowerMan.beginCriticalSection(); -#endif - DBG("open(\"%s\")\n", path); Common::FSNode file(path); @@ -347,10 +343,6 @@ bool DLObject::open(const char *path) { DBG("loaded!/n"); -#ifdef __PSP__ - PowerMan.endCriticalSection(); -#endif - flushDataCache(); ctors_start = symbol("___plugin_ctors"); diff --git a/backends/plugins/psp/psp-provider.h b/backends/plugins/psp/psp-provider.h index efe62ecf2c..b7934179bf 100644 --- a/backends/plugins/psp/psp-provider.h +++ b/backends/plugins/psp/psp-provider.h @@ -40,10 +40,9 @@ class PSPPluginProvider : public ELFPluginProvider { }; public: - Plugin* PSPPluginProvider::createPlugin(const Common::FSNode &node) const { + Plugin* createPlugin(const Common::FSNode &node) const { return new PSPPlugin(node.getPath()); } -} }; #endif /* BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H */ -- cgit v1.2.3 From c45b3e4e0e66ae56d06dcf1215477cf77eecc375 Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Sun, 22 Aug 2010 14:05:57 +0000 Subject: PSP: switched from stdio to psp functions in plugin branch Allows us to work with PSP plugins in this branch. Otherwise it's just too slow. svn-id: r52273 --- backends/fs/psp/psp-stream.cpp | 69 ++++++++++++++---------------------------- backends/fs/psp/psp-stream.h | 12 +++++--- 2 files changed, 31 insertions(+), 50 deletions(-) (limited to 'backends') diff --git a/backends/fs/psp/psp-stream.cpp b/backends/fs/psp/psp-stream.cpp index 67c73beeaa..8843bfd2fb 100644 --- a/backends/fs/psp/psp-stream.cpp +++ b/backends/fs/psp/psp-stream.cpp @@ -24,16 +24,11 @@ */ #ifdef __PSP__ -#include #include -#include -#include #include "backends/platform/psp/powerman.h" #include "backends/fs/psp/psp-stream.h" -#include - #define MIN2(a,b) ((a < b) ? a : b) #define MIN3(a,b,c) ( (a < b) ? (a < c ? a : c) : (b < c ? b : c) ) @@ -65,7 +60,7 @@ void printBuffer(byte *ptr, uint32 len) { PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode) - : StdioStream((void *)1), _path(path), _writeMode(writeMode), + : _handle(0), _path(path), _writeMode(writeMode), _ferror(false), _pos(0), _physicalPos(0), _fileSize(0), _inCache(false), _eos(false), _cacheStartOffset(-1), _cache(0), @@ -74,8 +69,6 @@ PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode) DEBUG_ENTER_FUNC(); // assert(!path.empty()); // do we need this? - - _handle = (void *)0; // Need to do this since base class asserts not 0. } PSPIoStream::~PSPIoStream() { @@ -87,7 +80,7 @@ PSPIoStream::~PSPIoStream() { PowerMan.unregisterForSuspend(this); // Unregister with powermanager to be suspended // Must do this before fclose() or resume() will reopen. - fclose((FILE *)_handle); // We don't need a critical section. Worst case, the handle gets closed on its own + sceIoClose(_handle); // We don't need a critical section. Worst case, the handle gets closed on its own if (_cache) free(_cache); @@ -105,7 +98,7 @@ void *PSPIoStream::open() { PSP_DEBUG_PRINT_FUNC("Suspended\n"); } - _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); // open + _handle = sceIoOpen(_path.c_str(), _writeMode ? PSP_O_RDWR | PSP_O_CREAT : PSP_O_RDONLY, 0777); // open if (_handle) { // Get the file size. This way is much faster than going to the end of the file and back @@ -122,7 +115,7 @@ void *PSPIoStream::open() { PowerMan.endCriticalSection(); - return _handle; + return (void *)_handle; } bool PSPIoStream::err() const { @@ -188,7 +181,7 @@ bool PSPIoStream::seek(int32 offs, int whence) { } else { // not in cache _inCache = false; } - _pos = posToSearchFor; + _pos = posToSearchFor; return true; } @@ -245,11 +238,10 @@ uint32 PSPIoStream::read(void *ptr, uint32 len) { PSP_DEBUG_PRINT("filling cache with 0x%x bytes from physicalPos[0x%x]. cacheStart[0x%x], pos[0x%x], fileSize[0x%x]\n", lenToCopyToCache, _physicalPos, _cacheStartOffset, _pos, _fileSize); - size_t ret = fread(_cache, 1, lenToCopyToCache, (FILE *)_handle); - if (ret != lenToCopyToCache) { + int ret = sceIoRead(_handle, _cache, lenToCopyToCache); + if (ret != (int)lenToCopyToCache) { PSP_ERROR("in filling cache, failed to get 0x%x bytes. Only got 0x%x\n", lenToCopyToCache, ret); _ferror = true; - clearerr((FILE *)_handle); } _cacheStartOffset = _physicalPos; _inCache = true; @@ -264,15 +256,14 @@ uint32 PSPIoStream::read(void *ptr, uint32 len) { } else { // Too big for cache. No caching PSP_DEBUG_PRINT("reading 0x%x bytes from file to %p. Pos[0x%x], physPos[0x%x]\n", lenFromFile, destPtr, _pos, _physicalPos); - size_t ret = fread(destPtr, 1, lenFromFile, (FILE *)_handle); + int ret = sceIoRead(_handle, destPtr, lenFromFile); _physicalPos += ret; // Update pos _pos = _physicalPos; - if (ret != lenFromFile) { // error + if (ret != (int)lenFromFile) { // error PSP_ERROR("fread returned [0x%x] instead of len[0x%x]\n", ret, lenFromFile); _ferror = true; - clearerr((FILE *)_handle); _errorSource = 4; } _inCache = false; @@ -290,8 +281,10 @@ uint32 PSPIoStream::read(void *ptr, uint32 len) { // TODO: Test if seeking backwards/forwards has any effect on performance inline bool PSPIoStream::synchronizePhysicalPos() { if (_pos != _physicalPos) { - if (fseek((FILE *)_handle, _pos - _physicalPos, SEEK_CUR) != 0) + if (sceIoLseek32(_handle, _pos - _physicalPos, PSP_SEEK_CUR) < 0) { + _ferror = true; return false; + } _physicalPos = _pos; } @@ -314,26 +307,25 @@ uint32 PSPIoStream::write(const void *ptr, uint32 len) { PSP_DEBUG_PRINT_FUNC("filename[%s], len[0x%x]\n", _path.c_str(), len); - if (_ferror) + if (!len || _ferror) // we actually get calls with len=0 return 0; _eos = false; // we can't have eos with write synchronizePhysicalPos(); - size_t ret = fwrite(ptr, 1, len, (FILE *)_handle); + int ret = sceIoWrite(_handle, ptr, len); // If we're making the file bigger, adjust the size - if (_physicalPos + (int)ret > _fileSize) + if (_physicalPos + ret > _fileSize) _fileSize = _physicalPos + ret; + _physicalPos += ret; _pos = _physicalPos; _inCache = false; _cacheStartOffset = -1; // invalidate cache - if (ret != len) { // Set error + if (ret != (int)len) { // Set error _ferror = true; - clearerr((FILE *)_handle); - _pos = ftell((FILE *)_handle); // Update pos _errorSource = 5; PSP_ERROR("fwrite returned[0x%x] instead of len[0x%x]\n", ret, len); } @@ -344,23 +336,8 @@ uint32 PSPIoStream::write(const void *ptr, uint32 len) { } bool PSPIoStream::flush() { - DEBUG_ENTER_FUNC(); - // Enter critical section - if (PowerMan.beginCriticalSection()) - PSP_DEBUG_PRINT_FUNC("Suspended\n"); - int ret = fflush((FILE *)_handle); - - if (ret != 0) { - _ferror = true; - clearerr((FILE *)_handle); - _errorSource = 6; - PSP_ERROR("fflush returned ret[%d]\n", ret); - } - - PowerMan.endCriticalSection(); - - return (ret == 0); + return true; } // For the PSP, since we're building in suspend support, we moved opening @@ -393,8 +370,8 @@ int PSPIoStream::suspend() { } if (_handle > 0) { - fclose((FILE *)_handle); // close our file descriptor - _handle = (void *)0xFFFFFFFF; // Set handle to non-null invalid value so makeFromPath doesn't return error + sceIoClose(_handle); // close our file descriptor + _handle = 0xFFFFFFFF; // Set handle to non-null invalid value so makeFromPath doesn't return error } return 0; @@ -409,19 +386,19 @@ int PSPIoStream::resume() { _suspendCount--; // We reopen our file descriptor - _handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); + _handle = sceIoOpen(_path.c_str(), _writeMode ? PSP_O_RDWR | PSP_O_CREAT : PSP_O_RDONLY, 0777); // open if (_handle <= 0) { PSP_ERROR("Couldn't reopen file %s\n", _path.c_str()); } // Resume our previous position if (_handle > 0 && _pos > 0) { - ret = fseek((FILE *)_handle, _pos, SEEK_SET); + ret = sceIoLseek32(_handle, _pos, PSP_SEEK_SET); _physicalPos = _pos; _inCache = false; - if (ret != 0) { // Check for problem + if (ret < 0) { // Check for problem _errorSuspend = ResumeError; _errorPos = _pos; _errorHandle = _handle; diff --git a/backends/fs/psp/psp-stream.h b/backends/fs/psp/psp-stream.h index 9fd1ad0470..ca9d40c720 100644 --- a/backends/fs/psp/psp-stream.h +++ b/backends/fs/psp/psp-stream.h @@ -26,15 +26,19 @@ #ifndef PSPSTREAM_H_ #define PSPSTREAM_H_ -#include "backends/fs/stdiostream.h" +#include #include "backends/platform/psp/powerman.h" -#include "common/list.h" +//#include "common/list.h" +#include "common/noncopyable.h" +#include "common/stream.h" +#include "common/str.h" /* * Class to handle special suspend/resume needs of PSP IO Streams */ -class PSPIoStream : public StdioStream, public Suspendable { +class PSPIoStream : public Common::SeekableReadStream, public Common::WriteStream, public Common::NonCopyable, public Suspendable { protected: + SceUID _handle; // file handle Common::String _path; int _fileSize; bool _writeMode; // for resuming in the right mode @@ -61,7 +65,7 @@ protected: int _errorSuspend; // for debugging mutable int _errorSource; int _errorPos; - void * _errorHandle; + SceUID _errorHandle; int _suspendCount; bool synchronizePhysicalPos(); // synchronize the physical and virtual positions -- cgit v1.2.3 From 80b9e8371b3cb8ef07df3495f8569271f8088211 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sat, 28 Aug 2010 12:51:12 +0000 Subject: WII: svn merge Wii port commits from trunk svn-id: r52425 --- backends/fs/wii/wii-fs-factory.cpp | 22 +++------------ backends/platform/wii/main.cpp | 12 +++++--- backends/platform/wii/options.cpp | 6 +--- backends/platform/wii/osystem.h | 2 +- backends/platform/wii/osystem_gfx.cpp | 3 +- backends/platform/wii/osystem_sfx.cpp | 52 ++++++++++++++++++----------------- 6 files changed, 42 insertions(+), 55 deletions(-) (limited to 'backends') diff --git a/backends/fs/wii/wii-fs-factory.cpp b/backends/fs/wii/wii-fs-factory.cpp index 5bc8ba56f5..2e8051029d 100644 --- a/backends/fs/wii/wii-fs-factory.cpp +++ b/backends/fs/wii/wii-fs-factory.cpp @@ -29,6 +29,7 @@ #ifdef USE_WII_DI #include +#include #endif #ifdef USE_WII_SMB @@ -71,8 +72,10 @@ void WiiFilesystemFactory::asyncInit() { void WiiFilesystemFactory::asyncDeinit() { #ifdef USE_WII_DI umount(kDVD); +#ifndef GAMECUBE DI_Close(); #endif +#endif #ifdef USE_WII_SMB umount(kSMB); net_deinit(); @@ -125,24 +128,11 @@ void WiiFilesystemFactory::mount(FileSystemType type) { break; printf("mount dvd\n"); - DI_Mount(); - - while (DI_GetStatus() & DVD_INIT) - usleep(20 * 1000); - - if (!(DI_GetStatus() & DVD_READY)) { - DI_StopMotor(); - printf("error mounting dvd\n"); - break; - } - - printf("mount ISO9660\n"); if (ISO9660_Mount()) { _dvdMounted = true; _dvdError = false; printf("ISO9660 mounted\n"); } else { - DI_StopMotor(); _dvdError = true; printf("ISO9660 mount failed\n"); } @@ -185,7 +175,6 @@ void WiiFilesystemFactory::umount(FileSystemType type) { printf("umount dvd\n"); ISO9660_Unmount(); - DI_StopMotor(); _dvdMounted = false; _dvdError = false; @@ -199,10 +188,7 @@ void WiiFilesystemFactory::umount(FileSystemType type) { printf("umount smb\n"); - if (smbClose("smb:")) - printf("smb umounted\n"); - else - printf("error umounting smb\n"); + smbClose("smb:"); _smbMounted = false; _smbError = false; diff --git a/backends/platform/wii/main.cpp b/backends/platform/wii/main.cpp index 627cc7d1db..7f141f2339 100644 --- a/backends/platform/wii/main.cpp +++ b/backends/platform/wii/main.cpp @@ -37,8 +37,7 @@ #ifdef DEBUG_WII_GDB #include #endif -#include -#include +#include #ifdef __cplusplus extern "C" { @@ -51,7 +50,6 @@ void reset_cb(void) { #ifdef DEBUG_WII_GDB printf("attach gdb now\n"); _break(); - SYS_SetResetCallback(reset_cb); #else reset_btn_pressed = true; #endif @@ -78,6 +76,11 @@ static void show_console(int code) { for (i = 0; i < 60 * 3; ++i) VIDEO_WaitVSync(); +#ifdef DEBUG_WII_GDB + printf("attach gdb now\n"); + _break(); +#endif + printf("Press any key to continue.\n"); if (!gfx_frame_start()) @@ -157,12 +160,13 @@ void wii_memstats(void) { int main(int argc, char *argv[]) { s32 res; -#ifdef USE_WII_DI +#if defined(USE_WII_DI) && !defined(GAMECUBE) DI_Init(); #endif VIDEO_Init(); PAD_Init(); + DSP_Init(); AUDIO_Init(NULL); gfx_video_init(NULL); diff --git a/backends/platform/wii/options.cpp b/backends/platform/wii/options.cpp index 295856d564..0a21b45561 100644 --- a/backends/platform/wii/options.cpp +++ b/backends/platform/wii/options.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include "common/config-manager.h" #include "gui/dialog.h" @@ -133,11 +133,9 @@ WiiOptionsDialog::~WiiOptionsDialog() { } void WiiOptionsDialog::handleTickle() { -#ifndef GAMECUBE WiiFilesystemFactory &fsf = WiiFilesystemFactory::instance(); int tab = _tab->getActiveTab(); -#endif #ifdef USE_WII_DI if (tab == _tabDVD) { @@ -198,9 +196,7 @@ void WiiOptionsDialog::handleTickle() { void WiiOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { -#ifndef GAMECUBE WiiFilesystemFactory &fsf = WiiFilesystemFactory::instance(); -#endif switch (cmd) { case 'x': diff --git a/backends/platform/wii/osystem.h b/backends/platform/wii/osystem.h index 8180d5727f..eaaf616538 100644 --- a/backends/platform/wii/osystem.h +++ b/backends/platform/wii/osystem.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include "base/main.h" #include "common/fs.h" diff --git a/backends/platform/wii/osystem_gfx.cpp b/backends/platform/wii/osystem_gfx.cpp index 19190048a0..3ce6343800 100644 --- a/backends/platform/wii/osystem_gfx.cpp +++ b/backends/platform/wii/osystem_gfx.cpp @@ -21,8 +21,7 @@ #include -#include -#include +#include #include "common/config-manager.h" #include "graphics/conversion.h" diff --git a/backends/platform/wii/osystem_sfx.cpp b/backends/platform/wii/osystem_sfx.cpp index d2e884aa22..33397f0a93 100644 --- a/backends/platform/wii/osystem_sfx.cpp +++ b/backends/platform/wii/osystem_sfx.cpp @@ -25,7 +25,8 @@ #define SFX_THREAD_STACKSIZE (1024 * 128) #define SFX_THREAD_PRIO 80 -#define SFX_THREAD_FRAG_SIZE 4096 +#define SFX_THREAD_FRAG_SIZE (1024 * 8) +#define SFX_BUFFERS 3 static lwpq_t sfx_queue; static lwp_t sfx_thread; @@ -33,20 +34,18 @@ static u8 *sfx_stack; static bool sfx_thread_running = false; static bool sfx_thread_quit = false; -static u8 sb = 0; -static u8 *sound_buffer[2]; +static u32 sb_hw; +static u8 *sound_buffer[SFX_BUFFERS]; static void audio_switch_buffers() { - AUDIO_StopDMA(); - AUDIO_InitDMA((u32) sound_buffer[sb], SFX_THREAD_FRAG_SIZE); - AUDIO_StartDMA(); - + sb_hw = (sb_hw + 1) % SFX_BUFFERS; + AUDIO_InitDMA((u32) sound_buffer[sb_hw], SFX_THREAD_FRAG_SIZE); LWP_ThreadSignal(sfx_queue); } static void * sfx_thread_func(void *arg) { Audio::MixerImpl *mixer = (Audio::MixerImpl *) arg; - u8 next_sb; + u8 sb_sw; while (true) { LWP_ThreadSleep(sfx_queue); @@ -54,11 +53,15 @@ static void * sfx_thread_func(void *arg) { if (sfx_thread_quit) break; - next_sb = sb ^ 1; - mixer->mixCallback(sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE); - DCFlushRange(sound_buffer[next_sb], SFX_THREAD_FRAG_SIZE); - - sb = next_sb; + // the hardware uses two buffers: a front and a back buffer + // we use 3 buffers here: two are beeing pushed to the DSP, + // and the free one is where our mixer writes to + // thus the latency of our stream is: + // 8192 [frag size] / 48000 / 2 [16bit] / 2 [stereo] * 2 [hw buffers] + // -> 85.3ms + sb_sw = (sb_hw + 1) % SFX_BUFFERS; + mixer->mixCallback(sound_buffer[sb_sw], SFX_THREAD_FRAG_SIZE); + DCFlushRange(sound_buffer[sb_sw], SFX_THREAD_FRAG_SIZE); } return NULL; @@ -89,21 +92,20 @@ void OSystem_Wii::initSfx() { sfx_thread_running = true; } - sound_buffer[0] = (u8 *) memalign(32, SFX_THREAD_FRAG_SIZE); - sound_buffer[1] = (u8 *) memalign(32, SFX_THREAD_FRAG_SIZE); - - memset(sound_buffer[0], 0, SFX_THREAD_FRAG_SIZE); - memset(sound_buffer[1], 0, SFX_THREAD_FRAG_SIZE); - - DCFlushRange(sound_buffer[0], SFX_THREAD_FRAG_SIZE); - DCFlushRange(sound_buffer[1], SFX_THREAD_FRAG_SIZE); + for (u32 i = 0; i < SFX_BUFFERS; ++i) { + sound_buffer[i] = (u8 *) memalign(32, SFX_THREAD_FRAG_SIZE); + memset(sound_buffer[i], 0, SFX_THREAD_FRAG_SIZE); + DCFlushRange(sound_buffer[i], SFX_THREAD_FRAG_SIZE); + } _mixer->setReady(true); + sb_hw = 0; + AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); AUDIO_RegisterDMACallback(audio_switch_buffers); - - audio_switch_buffers(); + AUDIO_InitDMA((u32) sound_buffer[sb_hw], SFX_THREAD_FRAG_SIZE); + AUDIO_StartDMA(); } void OSystem_Wii::deinitSfx() { @@ -123,8 +125,8 @@ void OSystem_Wii::deinitSfx() { free(sfx_stack); sfx_thread_running = false; - free(sound_buffer[0]); - free(sound_buffer[1]); + for (u32 i = 0; i < SFX_BUFFERS; ++i) + free(sound_buffer[i]); } } -- cgit v1.2.3 From ff1b64937aa7663dd02ef7582d8655a1c31f5abb Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 29 Aug 2010 11:14:14 +0000 Subject: PLUGINS: Fix warnings and unnecessary casts. svn-id: r52439 --- backends/plugins/elf-loader.cpp | 32 +++++++------------------------- 1 file changed, 7 insertions(+), 25 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 2cf61aa246..eb4891e641 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -89,7 +89,6 @@ void DLObject::unload() { } bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - // Start reading the elf header. Check for errors if (DLFile->read(ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC @@ -113,7 +112,6 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd } bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { - // Read program header if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { @@ -131,11 +129,9 @@ bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); return true; - } bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { - char *baseAddress = 0; // Attempt to allocate memory for segment @@ -163,7 +159,7 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) // Read the segment into memory if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || - DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { + DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { seterror("Segment load failed."); return false; } @@ -174,7 +170,6 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) } Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - Elf32_Shdr *shdr = NULL; // Allocate memory for section headers @@ -186,7 +181,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El // Read from file into section headers if (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != - (ssize_t)(ehdr->e_shnum * sizeof(*shdr))) { + ehdr->e_shnum * sizeof(*shdr)) { seterror("Section headers load failed."); return NULL; } @@ -195,7 +190,6 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El } int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, 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 && @@ -224,7 +218,7 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh // Read symbol table into memory if (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != - (ssize_t)shdr[_symtab_sect].sh_size) { + shdr[_symtab_sect].sh_size) { seterror("Symbol table load failed."); return -1; } @@ -234,11 +228,9 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh DBG("Loaded %d symbols.\n", _symbol_cnt); return _symtab_sect; - } bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr) { - int string_sect = shdr[_symtab_sect].sh_link; // Allocate memory for string table @@ -250,7 +242,7 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s // Read string table into memory if (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || DLFile->read(_strtab, shdr[string_sect].sh_size) != - (ssize_t)shdr[string_sect].sh_size) { + shdr[string_sect].sh_size) { seterror("Symbol table strings load failed."); return false; } @@ -259,17 +251,11 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s } void DLObject::relocateSymbols(Elf32_Addr offset) { - - int mainCount = 0; - int shortsCount= 0; - // 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) { - mainCount++; 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); @@ -288,7 +274,6 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { } for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments - DBG("Loading segment %d\n", i); if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) @@ -316,11 +301,9 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { free(shdr); return ret; - } bool DLObject::open(const char *path) { - Common::SeekableReadStream* DLFile; void *ctors_start, *ctors_end; @@ -358,11 +341,11 @@ bool DLObject::open(const char *path) { return false; } - DBG(("Calling constructors.\n")); + DBG("Calling constructors.\n"); for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) (**f)(); - DBG(("%s opened ok.\n", path)); + DBG("%s opened ok.\n", path); return true; } @@ -377,7 +360,7 @@ bool DLObject::close() { } void *DLObject::symbol(const char *name) { - DBG(("symbol(\"%s\")\n", name)); + DBG("symbol(\"%s\")\n", name); if (_symtab == NULL || _strtab == NULL || _symbol_cnt < 1) { seterror("No symbol table loaded."); @@ -386,7 +369,6 @@ void *DLObject::symbol(const char *name) { Elf32_Sym *s = (Elf32_Sym *)_symtab; for (int c = _symbol_cnt; c--; s++) - // We can only import symbols that are global or weak in the plugin if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && !strcmp(name, _strtab + s->st_name)) { -- cgit v1.2.3 From 9c495a23b26dce79e0a95ed06d3a98956f68ca64 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sat, 4 Sep 2010 22:26:12 +0000 Subject: DS: Merge r52533 from trunk. svn-id: r52534 --- backends/fs/ds/ds-fs.cpp | 3 +++ backends/platform/ds/arm9/makefile | 2 +- backends/platform/ds/arm9/source/dsmain.cpp | 4 ++++ backends/platform/ds/arm9/source/portdefs.h | 4 ---- 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'backends') diff --git a/backends/fs/ds/ds-fs.cpp b/backends/fs/ds/ds-fs.cpp index 675084ff56..cbc1c054fe 100644 --- a/backends/fs/ds/ds-fs.cpp +++ b/backends/fs/ds/ds-fs.cpp @@ -631,7 +631,10 @@ size_t std_fwrite(const void *ptr, size_t size, size_t numItems, FILE *handle) { return 0; if ((handle == stderr) || (handle == stdout)) { +#ifndef DISABLE_TEXT_CONSOLE + nocashMessage((char *) ptr); // consolePrintf((char *) ptr); +#endif return size; } diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 3f3c46b452..288ca206fc 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -237,7 +237,7 @@ CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \ ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET -DONE_PLUGIN_AT_A_TIME +DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET -DONE_PLUGIN_AT_A_TIME ifdef USE_MAD DEFINES += -DUSE_MAD endif diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index 4c7d6b89ae..0d0b88778b 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -3232,6 +3232,10 @@ int main(void) { int main() { +#ifndef DISABLE_TEXT_CONSOLE + consoleDebugInit(DebugDevice_NOCASH); + nocashMessage("startup\n"); +#endif DS::main(); } diff --git a/backends/platform/ds/arm9/source/portdefs.h b/backends/platform/ds/arm9/source/portdefs.h index cc38d66a73..ad36503e83 100644 --- a/backends/platform/ds/arm9/source/portdefs.h +++ b/backends/platform/ds/arm9/source/portdefs.h @@ -40,10 +40,6 @@ #define double float -#ifndef DISABLE_TEXT_CONSOLE -#define DISABLE_TEXT_CONSOLE -#endif - #ifndef DISABLE_COMMAND_LINE #define DISABLE_COMMAND_LINE #endif -- cgit v1.2.3 From 61cc69baf089ee2b5efffdb470dfe3e0a0777054 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 00:41:59 +0000 Subject: WII: Merge r52536 from trunk. svn-id: r52537 --- backends/platform/wii/wii.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/platform/wii/wii.mk b/backends/platform/wii/wii.mk index c92b9017b6..c1512551d7 100644 --- a/backends/platform/wii/wii.mk +++ b/backends/platform/wii/wii.mk @@ -40,6 +40,9 @@ ifneq ($(DIST_FILES_ENGINEDATA),) endif $(CP) $(srcdir)/backends/vkeybd/packs/vkeybd_default.zip wiidist/scummvm/ +wiiloaddist: wiidist + cd wiidist && zip -9r scummvm.zip scummvm/ + $(DEVKITPPC)/bin/wiiload wiidist/scummvm.zip -.PHONY: wiiclean wiiload geckoupload wiigdb wiidebug wiidist +.PHONY: wiiclean wiiload geckoupload wiigdb wiidebug wiidist wiiloaddist -- cgit v1.2.3 From 4ac6c6a1ddfd5d4b99b8cc4937ca730683758010 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:36:46 +0000 Subject: DS: Enable debug level 2 when DISABLE_TEXT_CONSOLE is not set. svn-id: r52545 --- backends/platform/ds/arm9/source/dsmain.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'backends') diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index 0d0b88778b..dc0b59e777 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -3230,11 +3230,15 @@ int main(void) { } // End of namespace DS +#ifndef DISABLE_TEXT_CONSOLE +extern int gDebugLevel; +#endif int main() { #ifndef DISABLE_TEXT_CONSOLE consoleDebugInit(DebugDevice_NOCASH); nocashMessage("startup\n"); + gDebugLevel = 2; #endif DS::main(); } -- cgit v1.2.3 From 2c746709aac3bbd1e228cc9e2e675011d895bbc4 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:37:07 +0000 Subject: PLUGINS: Flush only memory ranges, not everything svn-id: r52546 --- backends/plugins/elf-loader.cpp | 19 ++++++++++++------- backends/plugins/elf-loader.h | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index eb4891e641..231c2ffa22 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -39,7 +39,8 @@ #ifdef __PSP__ #include "backends/platform/psp/powerman.h" -#include "psputils.h" +#include +#include #endif #ifdef __DS__ @@ -59,16 +60,20 @@ /** * Flushes the data cache (Platform Specific). */ -static void flushDataCache() { +static void flushDataCache(void *ptr, uint32 len) { #ifdef __DS__ - DC_FlushAll(); + DC_FlushRange(ptr, len); + IC_InvalidateRange(ptr, len); #endif #ifdef __PLAYSTATION2__ - FlushCache(0); - FlushCache(2); + (void) ptr; + (void) len; + FlushCache(0); + FlushCache(2); #endif #ifdef __PSP__ - sceKernelDcacheWritebackAll(); + sceKernelDcacheWritebackRange(ptr, len); + sceKernelIcacheInvalidateRange(ptr, len); #endif } @@ -326,7 +331,7 @@ bool DLObject::open(const char *path) { DBG("loaded!/n"); - flushDataCache(); + flushDataCache(_segment, _segmentSize); ctors_start = symbol("___plugin_ctors"); ctors_end = symbol("___plugin_ctors_end"); diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 7150141567..fc6a022d34 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -47,7 +47,7 @@ protected: int _symtab_sect; void *_dtors_start, *_dtors_end; - int _segmentSize; + uint32 _segmentSize; //void seterror(const char *fmt, ...); virtual void unload(); -- cgit v1.2.3 From 07e3a422245e0fb118323ef95f354b81669231d3 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:37:36 +0000 Subject: PLUGINS: Cleanup includes and debug output. Use the common debug functions instead of spamming #defines. svn-id: r52547 --- backends/plugins/arm-loader.cpp | 36 ++++------- backends/plugins/arm-loader.h | 4 +- backends/plugins/elf-loader.cpp | 94 ++++++++++++----------------- backends/plugins/elf-loader.h | 6 +- backends/plugins/elf-provider.cpp | 13 ++-- backends/plugins/elf-provider.h | 6 +- backends/plugins/mips-loader.cpp | 58 ++++++++---------- backends/plugins/mips-loader.h | 4 +- backends/plugins/shorts-segment-manager.cpp | 18 ++---- backends/plugins/shorts-segment-manager.h | 3 +- 10 files changed, 100 insertions(+), 142 deletions(-) (limited to 'backends') diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index 916516aed9..7fd4c12e65 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -25,20 +25,10 @@ #if defined(DYNAMIC_MODULES) && defined(ARM_TARGET) -#include "backends/fs/ds/ds-fs.h" -#include "elf-loader.h" -#include "dsmain.h" -#include "arm-loader.h" +#include "backends/plugins/elf-loader.h" +#include "backends/plugins/arm-loader.h" -//#define __DEBUG_PLUGINS__ - -#ifdef __DEBUG_PLUGINS__ -#define DBG(x,...) consolePrintf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) consolePrintf(x, ## __VA_ARGS__) +#include "common/debug.h" /** * Follow the instruction of a relocation section. @@ -53,14 +43,14 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off // Allocate memory for relocation table if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); + warning("elfloader: Out of memory."); return false; } // Read in our relocation table if (DLFile->seek(offset, SEEK_SET) < 0 || DLFile->read(rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); + warning("elfloader: Relocation table load failed."); free(rel); return false; } @@ -68,7 +58,7 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off // Treat each relocation entry. Loop over all of them int cnt = size / sizeof(*rel); - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); int a = 0; unsigned int relocation = 0; @@ -94,28 +84,28 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off *target = relocation; - DBG("R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + debug(8, "elfloader: R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x", i, a, origTarget, *target); } break; case R_ARM_THM_CALL: - DBG("R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + debug(8, "elfloader: R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us."); break; case R_ARM_CALL: - DBG("R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us.\n"); + debug(8, "elfloader: R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us."); break; case R_ARM_JUMP24: - DBG("R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us.\n"); + debug(8, "elfloader: R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us."); break; case R_ARM_V4BX: - DBG("R_ARM_V4BX: No relocation calculation necessary.\n"); + debug(8, "elfloader: R_ARM_V4BX: No relocation calculation necessary."); break; default: - seterror("Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); + warning("elfloader: Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); free(rel); return false; } @@ -140,7 +130,7 @@ bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory if (curShdr->sh_type == SHT_RELA) { - seterror("RELA entries not supported yet!\n"); + warning("elfloader: RELA entries not supported yet!"); return false; } diff --git a/backends/plugins/arm-loader.h b/backends/plugins/arm-loader.h index d377912bbe..c0ad94ef43 100644 --- a/backends/plugins/arm-loader.h +++ b/backends/plugins/arm-loader.h @@ -25,9 +25,7 @@ #if defined(DYNAMIC_MODULES) && defined(ARM_TARGET) -#include "backends/fs/ds/ds-fs.h" -#include "elf-loader.h" -#include "dsmain.h" +#include "backends/plugins/elf-loader.h" class ARMDLObject : public DLObject { protected: diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 231c2ffa22..ac65bcb8e8 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -27,18 +27,8 @@ #include #include -#include -#include // for memalign() (Linux specific) -#include -#include -#include // FIXME: Why do we need this DevKitPro specific header? - -#include "common/file.h" -#include "common/fs.h" -#include "elf-loader.h" #ifdef __PSP__ -#include "backends/platform/psp/powerman.h" #include #include #endif @@ -47,15 +37,11 @@ #include #endif -#define __DEBUG_PLUGINS__ +#include "backends/plugins/elf-loader.h" -#ifdef __DEBUG_PLUGINS__ -#define DBG(x,...) printf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) printf(x, ## __VA_ARGS__) +#include "common/debug.h" +#include "common/file.h" +#include "common/fs.h" /** * Flushes the data cache (Platform Specific). @@ -106,12 +92,12 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd #endif 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."); + warning("elfloader: Invalid file type."); return false; } - DBG("phoff = %d, phentsz = %d, phnum = %d\n", - ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); + debug(2, "elfloader: phoff = %d, phentsz = %d, phnum = %d", + ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); return true; } @@ -120,18 +106,18 @@ bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr // Read program header if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { - seterror("Program header load failed."); + warning("elfloader: 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."); + warning("elfloader: 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); + debug(2, "elfloader: offs = %x, filesz = %x, memsz = %x, align = %x", + phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); return true; } @@ -141,14 +127,14 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) // 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); + debug(2, "elfloader: Extra mem is %x", extra); if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { - seterror("Out of memory.\n"); + warning("elfloader: Out of memory."); return false; } - DBG("allocated segment @ %p\n", _segment); + debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into baseAddress = (char *)_segment + phdr->p_vaddr; @@ -156,20 +142,20 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) // 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); + debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } - DBG("Reading the segment into memory\n"); + debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { - seterror("Segment load failed."); + warning("elfloader: Segment load failed."); return false; } - DBG("Segment has been read into memory\n"); + debug(2, "elfloader: Segment has been read into memory"); return true; } @@ -179,7 +165,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El // Allocate memory for section headers if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { - seterror("Out of memory."); + warning("elfloader: Out of memory."); return NULL; } @@ -187,7 +173,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El if (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != ehdr->e_shnum * sizeof(*shdr)) { - seterror("Section headers load failed."); + warning("elfloader: Section headers load failed."); return NULL; } @@ -208,15 +194,15 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh // Check for no symbol table if (_symtab_sect < 0) { - seterror("No symbol table."); + warning("elfloader: No symbol table."); return -1; } - DBG("Symbol section at section %d, size %x\n", _symtab_sect, shdr[_symtab_sect].sh_size); + debug(2, "elfloader: Symbol section at section %d, size %x", _symtab_sect, shdr[_symtab_sect].sh_size); // Allocate memory for symbol table if (!(_symtab = malloc(shdr[_symtab_sect].sh_size))) { - seterror("Out of memory."); + warning("elfloader: Out of memory."); return -1; } @@ -224,13 +210,13 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh if (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != shdr[_symtab_sect].sh_size) { - seterror("Symbol table load failed."); + warning("elfloader: 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); + debug(2, "elfloader: Loaded %d symbols.", _symbol_cnt); return _symtab_sect; } @@ -240,7 +226,7 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s // Allocate memory for string table if (!(_strtab = (char *)malloc(shdr[string_sect].sh_size))) { - seterror("Out of memory."); + warning("elfloader: Out of memory."); return false; } @@ -248,7 +234,7 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s if (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || DLFile->read(_strtab, shdr[string_sect].sh_size) != shdr[string_sect].sh_size) { - seterror("Symbol table strings load failed."); + warning("elfloader: Symbol table strings load failed."); return false; } @@ -263,7 +249,7 @@ void DLObject::relocateSymbols(Elf32_Addr offset) { if (s->st_shndx < SHN_LOPROC) { 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); + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } } @@ -279,7 +265,7 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { } for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments - DBG("Loading segment %d\n", i); + debug(2, "elfloader: Loading segment %d", i); if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) return false; @@ -312,16 +298,16 @@ bool DLObject::open(const char *path) { Common::SeekableReadStream* DLFile; void *ctors_start, *ctors_end; - DBG("open(\"%s\")\n", path); + debug(2, "elfloader: open(\"%s\")", path); Common::FSNode file(path); if (!(DLFile = file.createReadStream())) { - seterror("%s not found.", path); + warning("elfloader: %s not found.", path); return false; } - DBG("%s found!\n", path); + debug(2, "elfloader: %s found!", path); /*Try to load and relocate*/ if (!load(DLFile)) { @@ -329,7 +315,7 @@ bool DLObject::open(const char *path) { return false; } - DBG("loaded!/n"); + debug(2, "elfloader: Loaded!"); flushDataCache(_segment, _segmentSize); @@ -340,17 +326,17 @@ bool DLObject::open(const char *path) { if (ctors_start == NULL || ctors_end == NULL || _dtors_start == NULL || _dtors_end == NULL) { - seterror("Missing ctors/dtors."); + warning("elfloader: Missing ctors/dtors."); _dtors_start = _dtors_end = NULL; unload(); return false; } - DBG("Calling constructors.\n"); + debug(2, "elfloader: Calling constructors."); for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) (**f)(); - DBG("%s opened ok.\n", path); + debug(2, "elfloader: %s opened ok.", path); return true; } @@ -365,10 +351,10 @@ bool DLObject::close() { } void *DLObject::symbol(const char *name) { - DBG("symbol(\"%s\")\n", name); + debug(2, "elfloader: Symbol(\"%s\")", name); if (_symtab == NULL || _strtab == NULL || _symbol_cnt < 1) { - seterror("No symbol table loaded."); + warning("elfloader: No symbol table loaded."); return NULL; } @@ -379,12 +365,12 @@ void *DLObject::symbol(const char *name) { !strcmp(name, _strtab + s->st_name)) { // We found the symbol - DBG("=> %p\n", (void*)s->st_value); + debug(2, "elfloader: => %p", (void*)s->st_value); return (void*)s->st_value; } // We didn't find the symbol - seterror("Symbol \"%s\" not found.", name); + warning("elfloader: Symbol \"%s\" not found.", name); return NULL; } diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index fc6a022d34..93a6a15309 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -28,9 +28,10 @@ #ifndef ELF_LOADER_H #define ELF_LOADER_H -#include "elf32.h" -#include "common/stream.h" #include "backends/plugins/dynamic-plugin.h" +#include "backends/plugins/elf32.h" + +#include "common/stream.h" /** * DLObject @@ -49,7 +50,6 @@ protected: uint32 _segmentSize; - //void seterror(const char *fmt, ...); virtual void unload(); virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; bool load(Common::SeekableReadStream* DLFile); diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index e6edd4c578..47f0436ab9 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -27,9 +27,8 @@ #include "backends/plugins/elf-provider.h" #include "backends/plugins/dynamic-plugin.h" -#include "common/fs.h" -#include "backends/plugins/elf-loader.h" +#include "common/fs.h" DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { void *func; @@ -42,9 +41,9 @@ DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { } if (!func) { if (handleNull) { - warning("Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); + warning("elfloader: Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); } else { - warning("Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); + warning("elfloader: Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); } } @@ -69,7 +68,7 @@ bool ELFPlugin::loadPlugin() { } if (!_dlHandle) { - warning("Failed loading plugin '%s'", _filename.c_str()); + warning("elfloader: Failed loading plugin '%s'", _filename.c_str()); return false; } @@ -80,13 +79,13 @@ bool ELFPlugin::loadPlugin() { } return ret; -}; +} void ELFPlugin::unloadPlugin() { DynamicPlugin::unloadPlugin(); if (_dlHandle) { if (!_dlHandle->close()) { - warning("Failed unloading plugin '%s'", _filename.c_str()); + warning("elfloader: Failed unloading plugin '%s'", _filename.c_str()); } delete _dlHandle; _dlHandle = 0; diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index 200d4faf40..f6cede0219 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -28,12 +28,10 @@ #ifndef BACKENDS_PLUGINS_ELF_PROVIDER_H #define BACKENDS_PLUGINS_ELF_PROVIDER_H -#include "base/plugins.h" -#include "backends/plugins/dynamic-plugin.h" -#include "common/fs.h" - #include "backends/plugins/elf-loader.h" +#include "common/fs.h" + /** * ELFPlugin * diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp index dfa2765cfa..67e12949d8 100644 --- a/backends/plugins/mips-loader.cpp +++ b/backends/plugins/mips-loader.cpp @@ -25,17 +25,9 @@ #if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) -#include "mips-loader.h" +#include "backends/plugins/mips-loader.h" -//#define __DEBUG_PLUGINS__ - -#ifdef __DEBUG_PLUGINS__ -#define DBG(x,...) printf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) printf(x, ## __VA_ARGS__) +#include "common/debug.h" /** * Follow the instruction of a relocation section. @@ -51,14 +43,14 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of // Allocate memory for relocation table if (!(rel = (Elf32_Rel *)malloc(size))) { - seterror("Out of memory."); + warning("elfloader: Out of memory."); return false; } // Read in our relocation table if (DLFile->seek(offset, SEEK_SET) < 0 || DLFile->read(rel, size) != (ssize_t)size) { - seterror("Relocation table load failed."); + warning("elfloader: Relocation table load failed."); free(rel); return false; } @@ -66,7 +58,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of // Treat each relocation entry. Loop over all of them int cnt = size / sizeof(*rel); - DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); bool seenHi16 = false; // For treating HI/LO16 commands int firstHi16 = -1; // Mark the point of the first hi16 seen @@ -105,7 +97,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of lastHiSymVal = sym->st_value; hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number - DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", + debug(8, "elfloader: R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x", i, rel[i].r_offset, ahl, *target); } break; @@ -113,7 +105,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) if (!seenHi16) { // We MUST have seen HI16 first - seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); + debug(8, "elfloader: R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!", i); free(rel); return false; } @@ -158,10 +150,10 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation if (debugRelocs[1]++ < DEBUG_NUM) - DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + debug(8, "elfloader: R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - DBG("R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", + debug(8, "elfloader: R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); } break; @@ -175,11 +167,11 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of *target |= (relocation & 0x03ffffff); if (debugRelocs[3]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } else { if (debugRelocs[4]++ < DEBUG_NUM) - DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", + debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } break; @@ -196,7 +188,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of *target |= relocation & 0xffff; if (debugRelocs[5]++ < DEBUG_NUM) - DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", + debug(8, "elfloader: R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x", i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); } @@ -213,18 +205,18 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of *target = relocation; if (debugRelocs[6]++ < DEBUG_NUM) - DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); + debug("8, elfloader: R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x", i, a, origTarget, *target); } break; default: - seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); + warning("elfloader: Unknown relocation type %x at relocation %d.", REL_TYPE(rel[i].r_info), i); free(rel); return false; } } - DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); + debug(2, "elfloader: Done with relocation. extendedHi16=%d", extendedHi16); free(rel); return true; @@ -274,12 +266,12 @@ void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { mainCount++; 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); + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } else { // shorts section shortsCount++; s->st_value += _shortsSegment->getOffset(); if (!_shortsSegment->inSegment((char *)s->st_value)) - seterror("Symbol out of bounds! st_value = %x\n", s->st_value); + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } @@ -295,15 +287,15 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p // 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); + debug(2, "elfloader: Extra mem is %x", extra); if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { - seterror("Out of memory.\n"); + warning("elfloader: Out of memory."); return false; } - DBG("allocated segment @ %p\n", _segment); + debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into baseAddress = (char *)_segment + phdr->p_vaddr; @@ -312,26 +304,26 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); baseAddress = _shortsSegment->getStart(); - DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", + debug(2, "elfloader: Shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x", _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); } // 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); + debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } - DBG("Reading the segment into memory\n"); + debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { - seterror("Segment load failed."); + warning("elfloader: Segment load failed."); return false; } - DBG("Segment has been read into memory\n"); + debug(2, "elfloader: Segment has been read into memory"); return true; } diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h index 0b66412485..90e0bf92b2 100644 --- a/backends/plugins/mips-loader.h +++ b/backends/plugins/mips-loader.h @@ -26,8 +26,8 @@ #if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) -#include "elf-loader.h" -#include "shorts-segment-manager.h" +#include "backends/plugins/elf-loader.h" +#include "backends/plugins/shorts-segment-manager.h" class MIPSDLObject : public DLObject { protected: diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index 2376759919..788d7807ce 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -25,20 +25,14 @@ #if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) -#include "shorts-segment-manager.h" +#include "backends/plugins/shorts-segment-manager.h" + +#include "common/debug.h" extern char __plugin_hole_start; // Indicates start of hole in program file for shorts extern char __plugin_hole_end; // Indicates end of hole in program file extern char _gp[]; // Value of gp register -#ifdef DEBUG_PLUGINS -#define DBG(x,...) printf(x, ## __VA_ARGS__) -#else -#define DBG(x,...) -#endif - -#define seterror(x,...) printf(x, ## __VA_ARGS__) - DECLARE_SINGLETON(ShortSegmentManager); // For singleton ShortSegmentManager::ShortSegmentManager() { @@ -63,7 +57,7 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 if (lastAddress + size > _shortsEnd) { - seterror("Error. No space in shorts segment for %x bytes. Last address is %p, max address is %p.\n", + warning("elfloader: No space in shorts segment for %x bytes. Last address is %p, max address is %p.", size, lastAddress, _shortsEnd); return NULL; } @@ -74,14 +68,14 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or _list.insert(i, seg); - DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", + debug(2, "elfloader: Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.", size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); return seg; } void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { - DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); + debug(2, "elfloader: Deleting shorts segment from %p to %p.", seg->getStart(), seg->getEnd()); _list.remove(seg); delete seg; } diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h index 2710a7b9ff..bf583c021a 100644 --- a/backends/plugins/shorts-segment-manager.h +++ b/backends/plugins/shorts-segment-manager.h @@ -28,9 +28,10 @@ #ifndef SHORTS_SEGMENT_MANAGER_H #define SHORTS_SEGMENT_MANAGER_H +#include "backends/plugins/elf32.h" + #include "common/singleton.h" #include "common/list.h" -#include "elf32.h" #define ShortsMan ShortSegmentManager::instance() -- cgit v1.2.3 From 253a0aa7f9756a16d4c6490cebba623b9352b945 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:37:59 +0000 Subject: PLUGINS: Fix warnings. svn-id: r52548 --- backends/plugins/arm-loader.cpp | 4 +-- backends/plugins/elf-loader.cpp | 39 ++++++++++++++--------------- backends/plugins/elf-provider.cpp | 18 ++++++------- backends/plugins/mips-loader.cpp | 14 +++++------ backends/plugins/shorts-segment-manager.cpp | 2 +- 5 files changed, 36 insertions(+), 41 deletions(-) (limited to 'backends') diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index 7fd4c12e65..e2aa8e9fe1 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -39,7 +39,7 @@ * */ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; //relocation entry + Elf32_Rel *rel = 0; //relocation entry // Allocate memory for relocation table if (!(rel = (Elf32_Rel *)malloc(size))) { @@ -49,7 +49,7 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off // Read in our relocation table if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != (ssize_t)size) { + DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index ac65bcb8e8..1f6dcd7d7a 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -67,8 +67,8 @@ static void flushDataCache(void *ptr, uint32 len) { void DLObject::discard_symtab() { free(_symtab); free(_strtab); - _symtab = NULL; - _strtab = NULL; + _symtab = 0; + _strtab = 0; _symbol_cnt = 0; } @@ -76,7 +76,7 @@ void DLObject::discard_symtab() { void DLObject::unload() { discard_symtab(); free(_segment); - _segment = NULL; + _segment = 0; } bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { @@ -104,7 +104,7 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { // Read program header - if (DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) < 0 || + if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) || DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { warning("elfloader: Program header load failed."); return false; @@ -149,7 +149,7 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory - if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || + if (!DLFile->seek(phdr->p_offset, SEEK_SET) || DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; @@ -161,20 +161,20 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) } Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - Elf32_Shdr *shdr = NULL; + Elf32_Shdr *shdr = 0; // Allocate memory for section headers if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { warning("elfloader: Out of memory."); - return NULL; + return 0; } // Read from file into section headers - if (DLFile->seek(ehdr->e_shoff, SEEK_SET) < 0 || + if (!DLFile->seek(ehdr->e_shoff, SEEK_SET) || DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != ehdr->e_shnum * sizeof(*shdr)) { warning("elfloader: Section headers load failed."); - return NULL; + return 0; } return shdr; @@ -207,7 +207,7 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh } // Read symbol table into memory - if (DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) < 0 || + if (!DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) || DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != shdr[_symtab_sect].sh_size) { warning("elfloader: Symbol table load failed."); @@ -231,7 +231,7 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s } // Read string table into memory - if (DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) < 0 || + if (!DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) || DLFile->read(_strtab, shdr[string_sect].sh_size) != shdr[string_sect].sh_size) { warning("elfloader: Symbol table strings load failed."); @@ -274,7 +274,7 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { return false; } - if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == NULL) + if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == 0) ret = false; if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) @@ -324,10 +324,9 @@ bool DLObject::open(const char *path) { _dtors_start = symbol("___plugin_dtors"); _dtors_end = symbol("___plugin_dtors_end"); - if (ctors_start == NULL || ctors_end == NULL || _dtors_start == NULL || - _dtors_end == NULL) { + if (!ctors_start || !ctors_end || !_dtors_start || !_dtors_end) { warning("elfloader: Missing ctors/dtors."); - _dtors_start = _dtors_end = NULL; + _dtors_start = _dtors_end = 0; unload(); return false; } @@ -342,10 +341,10 @@ bool DLObject::open(const char *path) { } bool DLObject::close() { - if (_dtors_start != NULL && _dtors_end != NULL) + if (_dtors_start && _dtors_end) for (void (**f)(void) = (void (**)(void))_dtors_start; f != _dtors_end; f++) (**f)(); - _dtors_start = _dtors_end = NULL; + _dtors_start = _dtors_end = 0; unload(); return true; } @@ -353,9 +352,9 @@ bool DLObject::close() { void *DLObject::symbol(const char *name) { debug(2, "elfloader: Symbol(\"%s\")", name); - if (_symtab == NULL || _strtab == NULL || _symbol_cnt < 1) { + if (!_symtab || !_strtab || _symbol_cnt < 1) { warning("elfloader: No symbol table loaded."); - return NULL; + return 0; } Elf32_Sym *s = (Elf32_Sym *)_symtab; @@ -371,7 +370,7 @@ void *DLObject::symbol(const char *name) { // We didn't find the symbol warning("elfloader: Symbol \"%s\" not found.", name); - return NULL; + return 0; } #endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 47f0436ab9..00d93fcd34 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -31,20 +31,16 @@ #include "common/fs.h" DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { - void *func; - bool handleNull; - if (_dlHandle == NULL) { - func = NULL; - handleNull = true; - } else { + void *func = 0; + + if (_dlHandle) func = _dlHandle->symbol(symbol); - } + if (!func) { - if (handleNull) { + if (!_dlHandle) warning("elfloader: Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); - } else { + else warning("elfloader: Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); - } } // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ @@ -64,7 +60,7 @@ bool ELFPlugin::loadPlugin() { _dlHandle = obj; } else { delete obj; - _dlHandle = NULL; + _dlHandle = 0; } if (!_dlHandle) { diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp index 67e12949d8..5a0db74041 100644 --- a/backends/plugins/mips-loader.cpp +++ b/backends/plugins/mips-loader.cpp @@ -39,7 +39,7 @@ * */ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = NULL; // relocation entry + Elf32_Rel *rel = 0; // relocation entry // Allocate memory for relocation table if (!(rel = (Elf32_Rel *)malloc(size))) { @@ -48,8 +48,8 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of } // Read in our relocation table - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != (ssize_t)size) { + if (!DLFile->seek(offset, SEEK_SET) || + DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; @@ -317,8 +317,8 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory - if (DLFile->seek(phdr->p_offset, SEEK_SET) < 0 || - DLFile->read(baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { + if (!DLFile->seek(phdr->p_offset, SEEK_SET) || + DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; } @@ -332,11 +332,11 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p void MIPSDLObject::unload() { discard_symtab(); free(_segment); - _segment = NULL; + _segment = 0; if (_shortsSegment) { ShortsMan.deleteSegment(_shortsSegment); - _shortsSegment = NULL; + _shortsSegment = 0; } } diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index 788d7807ce..dfb3f9093a 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -59,7 +59,7 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or if (lastAddress + size > _shortsEnd) { warning("elfloader: No space in shorts segment for %x bytes. Last address is %p, max address is %p.", size, lastAddress, _shortsEnd); - return NULL; + return 0; } Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment -- cgit v1.2.3 From 628842d4575e2fac1b1b6bee8245756d2f8a7e36 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:38:18 +0000 Subject: PLUGINS: The VMA doesn't get added to any PHDR. svn-id: r52549 --- backends/plugins/elf-loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 1f6dcd7d7a..053b8120ad 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -137,7 +137,7 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into - baseAddress = (char *)_segment + phdr->p_vaddr; + baseAddress = (char *)_segment; _segmentSize = phdr->p_memsz + extra; // Set bss segment to 0 if necessary (assumes bss is at the end) -- cgit v1.2.3 From ee2f4ef18963c4f3339a3cbdd5424fc0f36661c0 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:38:38 +0000 Subject: PLUGINS: Properly check the ELF header. The ELFMAG is only 4 bytes, not 6. Properly check for endianess. svn-id: r52550 --- backends/plugins/elf-loader.cpp | 51 ++++++++++++++++++++++++++++++++++------- backends/plugins/elf32.h | 14 +++++++++-- 2 files changed, 55 insertions(+), 10 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 053b8120ad..b058f06e86 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -80,19 +80,54 @@ void DLObject::unload() { } bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - // Start reading the elf header. Check for errors + // Start reading the elf header. Check for errors and magic if (DLFile->read(ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || - memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC - ehdr->e_type != ET_EXEC || // Check for executable + memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { + warning("elfloader: No ELF file."); + return false; + } + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) { + warning("elfloader: Wrong ELF file class."); + return false; + } + + if (ehdr->e_ident[EI_DATA] != +#ifdef SCUMM_BIG_ENDIAN + ELFDATA2MSB +#else + ELFDATA2LSB +#endif + ) { + warning("elfloader: Wrong ELF file endianess."); + return false; + } + + if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) { + warning("elfloader: Wrong ELF file version."); + return false; + } + + if (ehdr->e_type != ET_EXEC) { + warning("elfloader: No executable ELF file."); + return false; + } + + if (ehdr->e_machine != #ifdef ARM_TARGET - ehdr->e_machine != EM_ARM || // Check for ARM machine type + EM_ARM #endif #ifdef MIPS_TARGET - ehdr->e_machine != EM_MIPS || // Check for MIPS machine type + EM_MIPS #endif - ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header - ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header - warning("elfloader: Invalid file type."); + ) { + warning("elfloader: Wrong ELF file architecture."); + return false; + } + + if (ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header + ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header + warning("elfloader: Invalid ELF structure sizes."); return false; } diff --git a/backends/plugins/elf32.h b/backends/plugins/elf32.h index ef6b714a5e..f18f4090a2 100644 --- a/backends/plugins/elf32.h +++ b/backends/plugins/elf32.h @@ -38,7 +38,7 @@ typedef signed int Elf32_Sword; typedef Elf32_Half Elf32_Versym; #define EI_NIDENT (16) -#define SELFMAG 6 +#define SELFMAG 4 /* ELF File format structures. Look up ELF structure for more details */ @@ -61,7 +61,17 @@ typedef struct { } Elf32_Ehdr; // Should be in e_ident -#define ELFMAG "\177ELF\1\1" /* ELF Magic number */ +#define ELFMAG "\177ELF" /* ELF Magic number */ + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASS32 1 /* 32-bit objects */ + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ + +#define EI_VERSION 6 +#define EV_CURRENT 1 /* Current version */ // e_type values #define ET_NONE 0 /* no file type */ -- cgit v1.2.3 From c5a189f4d5f5a9f94b7e063077ba0ee5aaf1a788 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:38:58 +0000 Subject: PLUGINS: Respect the VMA when relocating. Plugins do not have to be linked at 0x0. Some platforms have limited relocation jump offsets, which makes 0x0 unusable. svn-id: r52551 --- backends/plugins/elf-loader.cpp | 25 ++++++++++++++++++++++--- backends/plugins/elf-loader.h | 10 ++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index b058f06e86..406f99913e 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -63,6 +63,22 @@ static void flushDataCache(void *ptr, uint32 len) { #endif } +DLObject::DLObject() : + _segment(0), + _symtab(0), + _strtab(0), + _symbol_cnt(0), + _symtab_sect(-1), + _dtors_start(0), + _dtors_end(0), + _segmentSize(0), + _segmentOffset(0) { +} + +DLObject::~DLObject() { + unload(); +} + // Expel the symbol table from memory void DLObject::discard_symtab() { free(_symtab); @@ -276,7 +292,7 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s return true; } -void DLObject::relocateSymbols(Elf32_Addr offset) { +void DLObject::relocateSymbols(ptrdiff_t offset) { // Loop over symbols, add relocation offset Elf32_Sym *s = (Elf32_Sym *)_symtab; for (int c = _symbol_cnt; c--; s++) { @@ -318,8 +334,11 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { if (ret && (loadStringTable(DLFile, shdr) == false)) ret = false; - if (ret) - relocateSymbols((Elf32_Addr)_segment); // Offset by our segment allocated address + if (ret) { + // Offset by our segment allocated address + _segmentOffset = ptrdiff_t(_segment) - phdr.p_vaddr; + relocateSymbols(_segmentOffset); + } if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) ret = false; diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 93a6a15309..8d974eccb7 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -28,6 +28,8 @@ #ifndef ELF_LOADER_H #define ELF_LOADER_H +#include + #include "backends/plugins/dynamic-plugin.h" #include "backends/plugins/elf32.h" @@ -49,6 +51,7 @@ protected: void *_dtors_start, *_dtors_end; uint32 _segmentSize; + ptrdiff_t _segmentOffset; virtual void unload(); virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; @@ -60,7 +63,7 @@ protected: Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); - virtual void relocateSymbols(Elf32_Addr offset); + virtual void relocateSymbols(ptrdiff_t offset); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; public: @@ -69,9 +72,8 @@ public: void *symbol(const char *name); void discard_symtab(); - DLObject() : _segment(NULL), _symtab(NULL), _strtab(NULL), _symbol_cnt(0), - _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _segmentSize(0) {} - virtual ~DLObject() { unload(); } + DLObject(); + virtual ~DLObject(); }; #endif /* ELF_LOADER_H */ -- cgit v1.2.3 From 5986aa96f2d8f06c1a54be614f483712e7d4d8f0 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:39:28 +0000 Subject: PLUGINS: Formatting. svn-id: r52552 --- backends/plugins/arm-loader.cpp | 29 +++++-------- backends/plugins/arm-loader.h | 6 +-- backends/plugins/dynamic-plugin.h | 1 - backends/plugins/elf-loader.cpp | 30 +++++++------- backends/plugins/elf-loader.h | 45 +++++++++++---------- backends/plugins/elf-provider.cpp | 37 +++++++++-------- backends/plugins/elf-provider.h | 2 - backends/plugins/elf32.h | 28 ++++++------- backends/plugins/mips-loader.cpp | 63 +++++++++++++---------------- backends/plugins/mips-loader.h | 10 ++--- backends/plugins/ps2/ps2-provider.h | 2 +- backends/plugins/shorts-segment-manager.cpp | 5 ++- 12 files changed, 120 insertions(+), 138 deletions(-) (limited to 'backends') diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp index e2aa8e9fe1..5c71c7e433 100644 --- a/backends/plugins/arm-loader.cpp +++ b/backends/plugins/arm-loader.cpp @@ -33,10 +33,10 @@ /** * Follow the instruction of a relocation section. * - * @param DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * + * @param DLFile SeekableReadStream of File + * @param fileOffset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) */ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { Elf32_Rel *rel = 0; //relocation entry @@ -48,8 +48,8 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off } // Read in our relocation table - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != size) { + if (!DLFile->seek(offset, SEEK_SET) || + DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; @@ -65,7 +65,6 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off // Loop over relocation entries for (int i = 0; i < cnt; i++) { - // Get the symbol this relocation entry is referring to Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); @@ -76,7 +75,6 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { - case R_ARM_ABS32: if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. a = *target; // Get full 32 bits of addend @@ -109,7 +107,6 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off free(rel); return false; } - } free(rel); @@ -117,27 +114,23 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off } 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++) { - Elf32_Shdr *curShdr = &(shdr[i]); if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { warning("elfloader: RELA entries not supported yet!"); return false; } - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) return false; - } - } } diff --git a/backends/plugins/arm-loader.h b/backends/plugins/arm-loader.h index c0ad94ef43..24290d5c6d 100644 --- a/backends/plugins/arm-loader.h +++ b/backends/plugins/arm-loader.h @@ -29,11 +29,11 @@ class ARMDLObject : public DLObject { protected: - bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: - ARMDLObject() : DLObject() {} + ARMDLObject() : DLObject() {} }; #endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/dynamic-plugin.h b/backends/plugins/dynamic-plugin.h index ec051c4ed7..970ac3531d 100644 --- a/backends/plugins/dynamic-plugin.h +++ b/backends/plugins/dynamic-plugin.h @@ -28,7 +28,6 @@ #include "base/plugins.h" - class DynamicPlugin : public Plugin { protected: typedef int32 (*IntFunc)(); diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 406f99913e..478ec564bf 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -156,7 +156,7 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { // Read program header if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) || - DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { + DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { warning("elfloader: Program header load failed."); return false; } @@ -201,7 +201,7 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) // Read the segment into memory if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { + DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; } @@ -222,8 +222,8 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El // Read from file into section headers if (!DLFile->seek(ehdr->e_shoff, SEEK_SET) || - DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != - ehdr->e_shnum * sizeof(*shdr)) { + DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != + ehdr->e_shnum * sizeof(*shdr)) { warning("elfloader: Section headers load failed."); return 0; } @@ -235,10 +235,10 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh // 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) { + 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; } } @@ -259,8 +259,8 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh // Read symbol table into memory if (!DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) || - DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != - shdr[_symtab_sect].sh_size) { + DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != + shdr[_symtab_sect].sh_size) { warning("elfloader: Symbol table load failed."); return -1; } @@ -283,8 +283,8 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s // Read string table into memory if (!DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) || - DLFile->read(_strtab, shdr[string_sect].sh_size) != - shdr[string_sect].sh_size) { + DLFile->read(_strtab, shdr[string_sect].sh_size) != + shdr[string_sect].sh_size) { warning("elfloader: Symbol table strings load failed."); return false; } @@ -414,9 +414,9 @@ void *DLObject::symbol(const char *name) { Elf32_Sym *s = (Elf32_Sym *)_symtab; for (int c = _symbol_cnt; c--; s++) // We can only import symbols that are global or weak in the plugin - if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && - !strcmp(name, _strtab + s->st_name)) { - + if ((SYM_BIND(s->st_info) == STB_GLOBAL || + SYM_BIND(s->st_info) == STB_WEAK) && + !strcmp(name, _strtab + s->st_name)) { // We found the symbol debug(2, "elfloader: => %p", (void*)s->st_value); return (void*)s->st_value; diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index 8d974eccb7..c1dd39a52e 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -44,36 +44,37 @@ */ class DLObject { protected: - void *_segment, *_symtab; - char *_strtab; - int _symbol_cnt; - int _symtab_sect; - void *_dtors_start, *_dtors_end; + void *_segment, *_symtab; + char *_strtab; + int _symbol_cnt; + int _symtab_sect; + void *_dtors_start, *_dtors_end; - uint32 _segmentSize; + uint32 _segmentSize; ptrdiff_t _segmentOffset; - virtual void unload(); - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; - bool load(Common::SeekableReadStream* DLFile); + virtual void unload(); + bool load(Common::SeekableReadStream* DLFile); - bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); - virtual void relocateSymbols(ptrdiff_t offset); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; + bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); + virtual void relocateSymbols(ptrdiff_t offset); -public: - bool open(const char *path); - bool close(); - void *symbol(const char *name); - void discard_symtab(); + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; +public: DLObject(); virtual ~DLObject(); + + bool open(const char *path); + bool close(); + void *symbol(const char *name); + void discard_symtab(); }; #endif /* ELF_LOADER_H */ diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp index 00d93fcd34..997a43b653 100644 --- a/backends/plugins/elf-provider.cpp +++ b/backends/plugins/elf-provider.cpp @@ -54,27 +54,26 @@ DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { } bool ELFPlugin::loadPlugin() { - assert(!_dlHandle); - DLObject *obj = makeDLObject(); - if (obj->open(_filename.c_str())) { - _dlHandle = obj; - } else { - delete obj; - _dlHandle = 0; - } + assert(!_dlHandle); + DLObject *obj = makeDLObject(); + if (obj->open(_filename.c_str())) { + _dlHandle = obj; + } else { + delete obj; + _dlHandle = 0; + } - if (!_dlHandle) { - warning("elfloader: Failed loading plugin '%s'", _filename.c_str()); - return false; - } + if (!_dlHandle) { + warning("elfloader: Failed loading plugin '%s'", _filename.c_str()); + return false; + } - bool ret = DynamicPlugin::loadPlugin(); + bool ret = DynamicPlugin::loadPlugin(); - if (ret && _dlHandle) { - _dlHandle->discard_symtab(); - } + if (ret && _dlHandle) + _dlHandle->discard_symtab(); - return ret; + return ret; } void ELFPlugin::unloadPlugin() { @@ -91,9 +90,9 @@ void ELFPlugin::unloadPlugin() { bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { // Check the plugin suffix Common::String filename = node.getName(); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) { + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) return false; - } + return true; } diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h index f6cede0219..df9c503674 100644 --- a/backends/plugins/elf-provider.h +++ b/backends/plugins/elf-provider.h @@ -61,7 +61,6 @@ public: bool loadPlugin(); void unloadPlugin(); - }; class ELFPluginProvider : public FilePluginProvider { @@ -69,7 +68,6 @@ protected: virtual Plugin* createPlugin(const Common::FSNode &node) const = 0; bool isPluginFilename(const Common::FSNode &node) const; - }; #endif /* BACKENDS_PLUGINS_ELF_PROVIDER_H */ diff --git a/backends/plugins/elf32.h b/backends/plugins/elf32.h index f18f4090a2..9d69a7128e 100644 --- a/backends/plugins/elf32.h +++ b/backends/plugins/elf32.h @@ -61,7 +61,7 @@ typedef struct { } Elf32_Ehdr; // Should be in e_ident -#define ELFMAG "\177ELF" /* ELF Magic number */ +#define ELFMAG "\177ELF" /* ELF Magic number */ #define EI_CLASS 4 /* File class byte index */ #define ELFCLASS32 1 /* 32-bit objects */ @@ -129,7 +129,7 @@ typedef struct { // sh_type values #define SHT_NULL 0 /* Inactive section */ -#define SHT_PROGBITS 1 /* Proprietary */ +#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 */ @@ -143,9 +143,9 @@ typedef struct { #define SHT_MIPS_LIBLSIT 0x70000000 /* Info about dynamic shared object libs for MIPS*/ #define SHT_MIPS_CONFLICT 0x70000002 /* Conflicts btw executables and shared objects for MIPS */ #define SHT_MIPS_GPTAB 0x70000003 /* Global pointer table for MIPS*/ -#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table for ARM*/ -#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map for ARM */ -#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes for ARM*/ +#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table for ARM*/ +#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map for ARM */ +#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes for ARM*/ // sh_flags values #define SHF_WRITE 0 /* writable section */ @@ -168,8 +168,8 @@ typedef struct { #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_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 @@ -180,12 +180,12 @@ typedef struct { #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 +#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 with implicit addend (info about how to relocate) typedef struct { @@ -227,7 +227,7 @@ typedef struct // ARM relocation types #define R_ARM_NONE 0 #define R_ARM_ABS32 2 -#define R_ARM_THM_CALL 10 +#define R_ARM_THM_CALL 10 #define R_ARM_CALL 28 #define R_ARM_JUMP24 29 #define R_ARM_TARGET1 38 diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp index 5a0db74041..729c8f4224 100644 --- a/backends/plugins/mips-loader.cpp +++ b/backends/plugins/mips-loader.cpp @@ -32,11 +32,10 @@ /** * Follow the instruction of a relocation section. * - * @param DLFile SeekableReadStream of File - * @param offset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - * + * @param DLFile SeekableReadStream of File + * @param fileOffset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) */ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { Elf32_Rel *rel = 0; // relocation entry @@ -49,7 +48,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of // Read in our relocation table if (!DLFile->seek(offset, SEEK_SET) || - DLFile->read(rel, size) != size) { + DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; @@ -86,10 +85,9 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { - case R_MIPS_HI16: // Absolute addressing. if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) - firstHi16 < 0) { // Only process first in block of HI16s + firstHi16 < 0) { // Only process first in block of HI16s firstHi16 = i; // Keep the first Hi16 we saw seenHi16 = true; ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up @@ -98,7 +96,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number debug(8, "elfloader: R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x", - i, rel[i].r_offset, ahl, *target); + i, rel[i].r_offset, ahl, *target); } break; @@ -127,9 +125,9 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of ahl += a; // Add lower 16 bits. AHL is now complete // Fix: we can have LO16 access to the short segment sometimes - if (lo16InShorts) { + if (lo16InShorts) relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset - } else // It's in the regular segment + else // It's in the regular segment relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now @@ -139,7 +137,8 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation - if (relocation & 0x8000)(*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case + if (relocation & 0x8000) + (*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case } firstHi16 = -1; // Reset so we'll know we treated it } else { @@ -151,10 +150,10 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (debugRelocs[1]++ < DEBUG_NUM) debug(8, "elfloader: R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) debug(8, "elfloader: R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); } break; @@ -168,17 +167,17 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (debugRelocs[3]++ < DEBUG_NUM) debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } else { if (debugRelocs[4]++ < DEBUG_NUM) debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } break; case R_MIPS_GPREL16: // GP Relative addressing if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section - ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole + ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole a = *target & 0xffff; // Get 16 bits' worth of the addend a = (a << 16) >> 16; // Sign extend it @@ -189,7 +188,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (debugRelocs[5]++ < DEBUG_NUM) debug(8, "elfloader: R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x", - i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); + i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); } break; @@ -223,7 +222,6 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of } bool MIPSDLObject::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++) { @@ -231,20 +229,17 @@ bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr * //Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]); if (curShdr->sh_type == SHT_REL && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) return false; - } } else { // In Shorts segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) return false; - } } - } } @@ -252,14 +247,12 @@ bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr * } void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { - int mainCount = 0; int shortsCount= 0; // 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) { if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { @@ -273,23 +266,21 @@ void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { if (!_shortsSegment->inSegment((char *)s->st_value)) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } - } } } bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { - char *baseAddress = 0; // We need to take account of non-allocated segment for shorts if (phdr->p_flags & PF_X) { // This is a relocated segment - // Attempt to allocate memory for segment int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); - if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI + if (phdr->p_align < 0x10000) + phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { warning("elfloader: Out of memory."); @@ -305,7 +296,7 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p baseAddress = _shortsSegment->getStart(); debug(2, "elfloader: Shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x", - _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); } // Set bss segment to 0 if necessary (assumes bss is at the end) @@ -318,7 +309,7 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p // Read the segment into memory if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { + DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; } diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h index 90e0bf92b2..98bda5263f 100644 --- a/backends/plugins/mips-loader.h +++ b/backends/plugins/mips-loader.h @@ -34,11 +34,11 @@ protected: ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges unsigned int _gpVal; // Value of Global Pointer - bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - void relocateSymbols(Elf32_Addr offset); - bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - void unload(); + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual void relocateSymbols(Elf32_Addr offset); + virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + virtual void unload(); public: MIPSDLObject() : DLObject() { diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index dfadfffc29..809b88920a 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -37,7 +37,7 @@ class PS2PluginProvider : public ELFPluginProvider { }; public: - Plugin* PS2PluginProvider::createPlugin(const Common::FSNode &node) const { + Plugin* createPlugin(const Common::FSNode &node) const { return new PS2Plugin(node.getPath()); } }; diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp index dfb3f9093a..17af17aa45 100644 --- a/backends/plugins/shorts-segment-manager.cpp +++ b/backends/plugins/shorts-segment-manager.cpp @@ -64,12 +64,13 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment - if (lastAddress + size > _highestAddress) _highestAddress = lastAddress + size; // Keep track of maximum + if (lastAddress + size > _highestAddress) + _highestAddress = lastAddress + size; // Keep track of maximum _list.insert(i, seg); debug(2, "elfloader: Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.", - size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); + size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); return seg; } -- cgit v1.2.3 From 13770ce9cd61ba2c50218db786366971a64ad82f Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:49:29 +0000 Subject: PLUGINS: Plugin support for the GameCube/Wii backend. svn-id: r52553 --- backends/module.mk | 1 + backends/platform/wii/main.cpp | 5 + backends/plugins/elf-loader.cpp | 16 ++- backends/plugins/elf-loader.h | 1 + backends/plugins/elf32.h | 9 ++ backends/plugins/ppc-loader.cpp | 128 ++++++++++++++++++ backends/plugins/ppc-loader.h | 40 ++++++ backends/plugins/wii/plugin.ld | 263 ++++++++++++++++++++++++++++++++++++ backends/plugins/wii/wii-provider.h | 45 ++++++ 9 files changed, 507 insertions(+), 1 deletion(-) create mode 100644 backends/plugins/ppc-loader.cpp create mode 100644 backends/plugins/ppc-loader.h create mode 100644 backends/plugins/wii/plugin.ld create mode 100644 backends/plugins/wii/wii-provider.h (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index 922abc2afd..ab3d1efa47 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -26,6 +26,7 @@ MODULE_OBJS := \ plugins/mips-loader.o \ plugins/shorts-segment-manager.o \ plugins/arm-loader.o \ + plugins/ppc-loader.o \ plugins/elf-provider.o \ plugins/dc/dc-provider.o \ plugins/posix/posix-provider.o \ diff --git a/backends/platform/wii/main.cpp b/backends/platform/wii/main.cpp index 7f141f2339..aa688534fc 100644 --- a/backends/platform/wii/main.cpp +++ b/backends/platform/wii/main.cpp @@ -25,6 +25,7 @@ #include #include "osystem.h" +#include "backends/plugins/wii/wii-provider.h" #include #include @@ -210,6 +211,10 @@ int main(int argc, char *argv[]) { g_system = new OSystem_Wii(); assert(g_system); +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new WiiPluginProvider()); +#endif + res = scummvm_main(argc, argv); g_system->quit(); diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp index 478ec564bf..e1a1b8cef6 100644 --- a/backends/plugins/elf-loader.cpp +++ b/backends/plugins/elf-loader.cpp @@ -37,6 +37,11 @@ #include #endif +#ifdef __WII__ +#include +#include +#endif + #include "backends/plugins/elf-loader.h" #include "common/debug.h" @@ -61,6 +66,10 @@ static void flushDataCache(void *ptr, uint32 len) { sceKernelDcacheWritebackRange(ptr, len); sceKernelIcacheInvalidateRange(ptr, len); #endif +#ifdef __WII__ + DCFlushRange(ptr, len); + ICInvalidateRange(ptr, len); +#endif } DLObject::DLObject() : @@ -72,7 +81,8 @@ DLObject::DLObject() : _dtors_start(0), _dtors_end(0), _segmentSize(0), - _segmentOffset(0) { + _segmentOffset(0), + _segmentVMA(0) { } DLObject::~DLObject() { @@ -135,6 +145,9 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd #endif #ifdef MIPS_TARGET EM_MIPS +#endif +#ifdef PPC_TARGET + EM_PPC #endif ) { warning("elfloader: Wrong ELF file architecture."); @@ -190,6 +203,7 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) // Get offset to load segment into baseAddress = (char *)_segment; _segmentSize = phdr->p_memsz + extra; + _segmentVMA = phdr->p_vaddr; // Set bss segment to 0 if necessary (assumes bss is at the end) if (phdr->p_memsz > phdr->p_filesz) { diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h index c1dd39a52e..b5c0e1355d 100644 --- a/backends/plugins/elf-loader.h +++ b/backends/plugins/elf-loader.h @@ -52,6 +52,7 @@ protected: uint32 _segmentSize; ptrdiff_t _segmentOffset; + uint32 _segmentVMA; virtual void unload(); bool load(Common::SeekableReadStream* DLFile); diff --git a/backends/plugins/elf32.h b/backends/plugins/elf32.h index 9d69a7128e..c83093fed7 100644 --- a/backends/plugins/elf32.h +++ b/backends/plugins/elf32.h @@ -82,6 +82,7 @@ typedef struct { // e_machine values #define EM_MIPS 8 +#define EM_PPC 20 #define EM_ARM 40 // Program header (contains info about segment) @@ -233,6 +234,14 @@ typedef struct #define R_ARM_TARGET1 38 #define R_ARM_V4BX 40 +// PPC relocation types +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_REL24 10 +#define R_PPC_REL32 26 + // Mock function to get value of global pointer for MIPS #define getGP() ({ \ unsigned int __valgp; \ diff --git a/backends/plugins/ppc-loader.cpp b/backends/plugins/ppc-loader.cpp new file mode 100644 index 0000000000..dcd5fceff1 --- /dev/null +++ b/backends/plugins/ppc-loader.cpp @@ -0,0 +1,128 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.cpp $ + * $Id: arm-loader.cpp 52058 2010-08-13 05:58:11Z toneman1138 $ + * + */ + +#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) + +#include "backends/plugins/elf-loader.h" +#include "backends/plugins/ppc-loader.h" + +#include "common/debug.h" + +bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rela *rel = NULL; + + if (!(rel = (Elf32_Rela *)malloc(size))) { + warning("elfloader: Out of memory."); + return false; + } + + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != size) { + warning("elfloader: Relocation table load failed."); + free(rel); + return false; + } + + int cnt = size / sizeof(*rel); + + debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + uint32 *src; + uint32 value; + + for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + src = (uint32 *)((char *)relSegment + rel[i].r_offset - _segmentVMA); + value = sym->st_value + rel[i].r_addend; + + //debug(8, "elfloader: i=%05d %p +0x%04x: (0x%08x) 0x%08x ", i, src, rel[i].r_addend, sym->st_value, *src); + + switch (REL_TYPE(rel[i].r_info)) { + case R_PPC_ADDR32: + *src = value; + debug(8, "elfloader: R_PPC_ADDR32 -> 0x%08x\n", *src); + break; + case R_PPC_ADDR16_LO: + *((uint16 *) src) = value; + debug(8, "elfloader: R_PPC_ADDR16_LO -> 0x%08x\n", *src); + break; + case R_PPC_ADDR16_HI: + *(uint16 *) src = value >> 16; + debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); + break; + case R_PPC_ADDR16_HA: + *(uint16 *) src = (value + 0x8000) >> 16; + debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); + break; + case R_PPC_REL24: + *src = (*src & ~0x03fffffc) | ((value - (uint32) src) & 0x03fffffc); + debug(8, "elfloader: R_PPC_REL24 -> 0x%08x\n", *src); + break; + case R_PPC_REL32: + *src = value - (uint32) src; + debug(8, "elfloader: R_PPC_REL32 -> 0x%08x\n", *src); + break; + default: + warning("elfloader: Unknown relocation type %d\n", REL_TYPE(rel[i].r_info)); + free(rel); + return false; + } + } + + free(rel); + return true; +} + +bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { + for (int i = 0; i < ehdr->e_shnum; i++) { + Elf32_Shdr *curShdr = &(shdr[i]); + + if ((curShdr->sh_type == SHT_REL) && + curShdr->sh_entsize == sizeof(Elf32_Rel) && + (int)curShdr->sh_link == _symtab_sect && + curShdr->sh_info < ehdr->e_shnum && + (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { + warning("elfloader: REL entries not supported!\n"); + return false; + } + + if ((curShdr->sh_type == SHT_RELA) && + curShdr->sh_entsize == sizeof(Elf32_Rela) && + (int)curShdr->sh_link == _symtab_sect && + curShdr->sh_info < ehdr->e_shnum && + (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) + return false; + } + } + + return true; +} + +#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ + diff --git a/backends/plugins/ppc-loader.h b/backends/plugins/ppc-loader.h new file mode 100644 index 0000000000..14d1f16720 --- /dev/null +++ b/backends/plugins/ppc-loader.h @@ -0,0 +1,40 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.h $ + * $Id: arm-loader.h 52053 2010-08-13 02:58:52Z toneman1138 $ + * + */ + +#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) + +#include "backends/plugins/elf-loader.h" + +class PPCDLObject : public DLObject { +protected: + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + +public: + PPCDLObject() : DLObject() {} +}; + +#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ + diff --git a/backends/plugins/wii/plugin.ld b/backends/plugins/wii/plugin.ld new file mode 100644 index 0000000000..61b90d3394 --- /dev/null +++ b/backends/plugins/wii/plugin.ld @@ -0,0 +1,263 @@ +/* + * Linkscript for Wii + */ + +OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc"); +OUTPUT_ARCH(powerpc:common); + +PHDRS +{ + plugin PT_LOAD FLAGS(7); +} + +SECTIONS +{ + . = 0x81000000; + + /* Program */ + .init : + { + KEEP (*crt0.o(*.init)) + KEEP (*(.init)) + } :plugin = 0 + .plt : { *(.plt) } + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.init : { *(.rel.init) } + .rela.init : { *(.rela.init) } + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rel.fini : { *(.rel.fini) } + .rela.fini : { *(.rela.fini) } + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rela.got1 : { *(.rela.got1) } + .rela.got2 : { *(.rela.got2) } + .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } + .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } + .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } + .rela.sbss : { *(.rela.sbss .rela.sbss.* .rel.gnu.linkonce.sb.*) } + .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } + .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } + .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } + .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + + .text : + { + *(.text) + *(.text.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t.*) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } = 0 + + .fini : + { + KEEP (*(.fini)) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } = 0 + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2) *(.sdata2.*) *(.gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2) *(.sbss2.*) *(.gnu.linkonce.sb2.*) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + /* 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 : { *(.preinit_array) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE (__fini_array_end = .); + .data : + { + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .fixup : { *(.fixup) } + .got1 : { *(.got1) } + .got2 : { *(.got2) } + .dynamic : { *(.dynamic) } + + .ctors : + { + ___plugin_ctors = .; + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + ___plugin_ctors_end = .; + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + .dtors : + { + ___plugin_dtors = .; + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + ___plugin_dtors_end = .; + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + .jcr : { KEEP (*(.jcr)) } + .got : { *(.got.plt) *(.got) } + + + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + + .sdata : + { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + } + + _edata = .; + PROVIDE (edata = .); + + .sbss : + { + __sbss_start = .; + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + . = ALIGN(32); /* REQUIRED. LD is flaky without it. */ + __sbss_end = .; + } + + .bss : + { + __bss_start = .; + PROVIDE (__bss_start = .); + *(.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); + + PROVIDE (__bss_end = .); + __bss_end = .; + } + + _end = .; + PROVIDE(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) } + .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) } + /* These must appear regardless of . */ +} + +__isIPL = 0; +__stack_addr = (__bss_start + SIZEOF(.bss) + 0x20000 + 7) & (-8); +__stack_end = (__bss_start + SIZEOF(.bss)); +__intrstack_addr = (__stack_addr + 0x4000); +__intrstack_end = (__stack_addr); +__Arena1Lo = (__intrstack_addr + 31) & (-32); +__Arena1Hi = (0x816ffff0); +__Arena2Lo = (0x90002000); +__Arena2Hi = (0x933E0000); + +__gxregs = (__Arena1Hi + 31) & (-32); +__ipcbufferLo = (0x933e0000); +__ipcbufferHi = (0x93400000); + +/* for backward compatibility with old crt0 */ +PROVIDE (__stack = (0x816ffff0)); + +PROVIDE(__isIPL = __isIPL); +PROVIDE(__stack_addr = __stack_addr); +PROVIDE(__stack_end = __stack_end); +PROVIDE(__intrstack_addr = __intrstack_addr); +PROVIDE(__intrstack_end = __intrstack_end); +PROVIDE(__Arena1Lo = __Arena1Lo); +PROVIDE(__Arena1Hi = __Arena1Hi); +PROVIDE(__Arena2Lo = __Arena2Lo); +PROVIDE(__Arena2Hi = __Arena2Hi); +PROVIDE(__ipcbufferLo = __ipcbufferLo); +PROVIDE(__ipcbufferHi = __ipcbufferHi); +PROVIDE(__gxregs = __gxregs); diff --git a/backends/plugins/wii/wii-provider.h b/backends/plugins/wii/wii-provider.h new file mode 100644 index 0000000000..a299ff4add --- /dev/null +++ b/backends/plugins/wii/wii-provider.h @@ -0,0 +1,45 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ds/ds-provider.h $ + * $Id: ds-provider.h 52112 2010-08-16 08:41:04Z toneman1138 $ + * + */ + +#if defined(DYNAMIC_MODULES) && defined(__WII__) + +#include "backends/plugins/elf-provider.h" +#include "backends/plugins/ppc-loader.h" + +class WiiPluginProvider : public ELFPluginProvider { + class WiiPlugin : public ELFPlugin { + public: + WiiPlugin(const Common::String &filename) : ELFPlugin(filename) {} + + DLObject *makeDLObject() { return new PPCDLObject(); } + }; + +public: + Plugin* createPlugin(const Common::FSNode &node) const { + return new WiiPlugin(node.getPath()); + } +}; + +#endif // defined(DYNAMIC_MODULES) && defined(__WII__) -- cgit v1.2.3 From a9a615a867ba4b24bb17314558ffbdf64d3d9091 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:49:50 +0000 Subject: WII: Add plugins to the distribution. svn-id: r52554 --- backends/platform/wii/wii.mk | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'backends') diff --git a/backends/platform/wii/wii.mk b/backends/platform/wii/wii.mk index c1512551d7..28066df8d4 100644 --- a/backends/platform/wii/wii.mk +++ b/backends/platform/wii/wii.mk @@ -31,6 +31,10 @@ else $(STRIP) $(EXECUTABLE) -o wiidist/scummvm/boot.elf $(CP) $(srcdir)/dists/wii/icon.png wiidist/scummvm/ sed "s/@REVISION@/$(VER_SVNREV)/;s/@TIMESTAMP@/`date +%Y%m%d%H%M%S`/" < $(srcdir)/dists/wii/meta.xml > wiidist/scummvm/meta.xml +endif +ifeq ($(DYNAMIC_MODULES),1) + $(MKDIR) wiidist/scummvm/plugins + for i in $(PLUGINS); do $(STRIP) --strip-debug $$i -o wiidist/scummvm/plugins/`basename $$i`; done endif sed 's/$$/\r/' < $(srcdir)/dists/wii/READMII > wiidist/scummvm/READMII.txt for i in $(DIST_FILES_DOCS); do sed 's/$$/\r/' < $$i > wiidist/scummvm/`basename $$i`.txt; done -- cgit v1.2.3 From 86f4dbd956fa2b6622ceb8748427700373a1aceb Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:51:25 +0000 Subject: PLUGINS: Move all ELF loader related files to its own directory. svn-id: r52555 --- backends/module.mk | 12 +- backends/platform/ds/arm9/makefile | 4 +- backends/platform/ds/arm9/source/dsmain.cpp | 1 - backends/platform/ps2/Makefile.ps2 | 4 +- backends/platform/psp/Makefile | 4 +- backends/platform/psp/psp_main.cpp | 1 - backends/plugins/arm-loader.cpp | 140 -------- backends/plugins/arm-loader.h | 39 --- backends/plugins/ds/ds-provider.h | 4 +- backends/plugins/elf-loader.cpp | 445 ------------------------ backends/plugins/elf-loader.h | 83 ----- backends/plugins/elf-provider.cpp | 99 ------ backends/plugins/elf-provider.h | 75 ---- backends/plugins/elf/arm-loader.cpp | 140 ++++++++ backends/plugins/elf/arm-loader.h | 39 +++ backends/plugins/elf/elf-loader.cpp | 445 ++++++++++++++++++++++++ backends/plugins/elf/elf-loader.h | 83 +++++ backends/plugins/elf/elf-provider.cpp | 99 ++++++ backends/plugins/elf/elf-provider.h | 75 ++++ backends/plugins/elf/elf32.h | 252 ++++++++++++++ backends/plugins/elf/mips-loader.cpp | 334 ++++++++++++++++++ backends/plugins/elf/mips-loader.h | 50 +++ backends/plugins/elf/plugin.syms | 8 + backends/plugins/elf/ppc-loader.cpp | 128 +++++++ backends/plugins/elf/ppc-loader.h | 40 +++ backends/plugins/elf/shorts-segment-manager.cpp | 84 +++++ backends/plugins/elf/shorts-segment-manager.h | 103 ++++++ backends/plugins/elf32.h | 252 -------------- backends/plugins/mips-loader.cpp | 334 ------------------ backends/plugins/mips-loader.h | 50 --- backends/plugins/plugin.syms | 8 - backends/plugins/ppc-loader.cpp | 128 ------- backends/plugins/ppc-loader.h | 40 --- backends/plugins/ps2/ps2-provider.h | 4 +- backends/plugins/psp/psp-provider.h | 4 +- backends/plugins/shorts-segment-manager.cpp | 84 ----- backends/plugins/shorts-segment-manager.h | 103 ------ backends/plugins/wii/wii-provider.h | 4 +- 38 files changed, 1900 insertions(+), 1902 deletions(-) delete mode 100644 backends/plugins/arm-loader.cpp delete mode 100644 backends/plugins/arm-loader.h delete mode 100644 backends/plugins/elf-loader.cpp delete mode 100644 backends/plugins/elf-loader.h delete mode 100644 backends/plugins/elf-provider.cpp delete mode 100644 backends/plugins/elf-provider.h create mode 100644 backends/plugins/elf/arm-loader.cpp create mode 100644 backends/plugins/elf/arm-loader.h create mode 100644 backends/plugins/elf/elf-loader.cpp create mode 100644 backends/plugins/elf/elf-loader.h create mode 100644 backends/plugins/elf/elf-provider.cpp create mode 100644 backends/plugins/elf/elf-provider.h create mode 100644 backends/plugins/elf/elf32.h create mode 100644 backends/plugins/elf/mips-loader.cpp create mode 100644 backends/plugins/elf/mips-loader.h create mode 100644 backends/plugins/elf/plugin.syms create mode 100644 backends/plugins/elf/ppc-loader.cpp create mode 100644 backends/plugins/elf/ppc-loader.h create mode 100644 backends/plugins/elf/shorts-segment-manager.cpp create mode 100644 backends/plugins/elf/shorts-segment-manager.h delete mode 100644 backends/plugins/elf32.h delete mode 100644 backends/plugins/mips-loader.cpp delete mode 100644 backends/plugins/mips-loader.h delete mode 100644 backends/plugins/plugin.syms delete mode 100644 backends/plugins/ppc-loader.cpp delete mode 100644 backends/plugins/ppc-loader.h delete mode 100644 backends/plugins/shorts-segment-manager.cpp delete mode 100644 backends/plugins/shorts-segment-manager.h (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index ab3d1efa47..eea7ec98d2 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -22,12 +22,12 @@ MODULE_OBJS := \ midi/timidity.o \ midi/dmedia.o \ midi/windows.o \ - plugins/elf-loader.o \ - plugins/mips-loader.o \ - plugins/shorts-segment-manager.o \ - plugins/arm-loader.o \ - plugins/ppc-loader.o \ - plugins/elf-provider.o \ + plugins/elf/elf-loader.o \ + plugins/elf/mips-loader.o \ + plugins/elf/shorts-segment-manager.o \ + plugins/elf/ppc-loader.o \ + plugins/elf/arm-loader.o \ + plugins/elf/elf-provider.o \ plugins/dc/dc-provider.o \ plugins/posix/posix-provider.o \ plugins/sdl/sdl-provider.o \ diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index 288ca206fc..b2512d788e 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -276,8 +276,8 @@ EXECUTABLE = scummvm.elf PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/ds/plugin.ld $(srcdir)/backends/plugins/plugin.syms $(EXECUTABLE) -PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--target1-abs,--just-symbols,$(EXECUTABLE),-T$(srcdir)/backends/plugins/ds/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o +PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/ds/plugin.ld $(srcdir)/backends/plugins/elf/plugin.syms $(EXECUTABLE) +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--target1-abs,--just-symbols,$(EXECUTABLE),-T$(srcdir)/backends/plugins/ds/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/elf/plugin.syms -lstdc++ -lc -mthumb-interwork -mno-fpu#-Wl,--gc-sections -mno-crt0 $(DEVKITPRO)/devkitARM/arm-eabi/lib/ds_arm9_crt0.o MKDIR = mkdir -p RM = rm -f diff --git a/backends/platform/ds/arm9/source/dsmain.cpp b/backends/platform/ds/arm9/source/dsmain.cpp index dc0b59e777..3e33b168ee 100644 --- a/backends/platform/ds/arm9/source/dsmain.cpp +++ b/backends/platform/ds/arm9/source/dsmain.cpp @@ -106,7 +106,6 @@ #include "engine.h" #include "backends/plugins/ds/ds-provider.h" -#include "backends/plugins/elf-provider.h" #include "backends/fs/ds/ds-fs.h" #include "base/version.h" #include "common/util.h" diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index d5b0ae3e2a..7319fcb21d 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -88,9 +88,9 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/plugin.syms elf/scummvm.elf +PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/elf/plugin.syms elf/scummvm.elf PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-T$(srcdir)/backends/plugins/ps2/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/plugin.syms -lstdc++ -lc +PLUGIN_LDFLAGS += -nostartfiles -Wl,-q,--just-symbols,elf/scummvm.elf,-T$(srcdir)/backends/plugins/ps2/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/elf/plugin.syms -lstdc++ -lc BACKEND := ps2 diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index 49455f6b97..96816348fd 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -87,8 +87,8 @@ CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP # Variables for dynamic plugin building PLUGIN_PREFIX = PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/plugin.syms scummvm-psp.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-psp.org.elf,-T$(srcdir)/backends/plugins/psp/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/plugin.syms -lstdc++ -lc +PLUGIN_EXTRA_DEPS = $(srcdir)/backends/plugins/elf/plugin.syms scummvm-psp.elf +PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-psp.org.elf,-T$(srcdir)/backends/plugins/psp/plugin.ld,--retain-symbols-file,$(srcdir)/backends/plugins/elf/plugin.syms -lstdc++ -lc # PSP-specific variables STRIP = psp-strip diff --git a/backends/platform/psp/psp_main.cpp b/backends/platform/psp/psp_main.cpp index dba9a8fc2b..41cf451323 100644 --- a/backends/platform/psp/psp_main.cpp +++ b/backends/platform/psp/psp_main.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include "backends/platform/psp/powerman.h" #include "backends/platform/psp/thread.h" diff --git a/backends/plugins/arm-loader.cpp b/backends/plugins/arm-loader.cpp deleted file mode 100644 index 5c71c7e433..0000000000 --- a/backends/plugins/arm-loader.cpp +++ /dev/null @@ -1,140 +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(ARM_TARGET) - -#include "backends/plugins/elf-loader.h" -#include "backends/plugins/arm-loader.h" - -#include "common/debug.h" - -/** - * Follow the instruction of a relocation section. - * - * @param DLFile SeekableReadStream of File - * @param fileOffset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - */ -bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = 0; //relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - warning("elfloader: Out of memory."); - return false; - } - - // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || - DLFile->read(rel, size) != size) { - warning("elfloader: Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); - - int a = 0; - unsigned int relocation = 0; - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; //Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - case R_ARM_ABS32: - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - - *target = relocation; - - debug(8, "elfloader: R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x", i, a, origTarget, *target); - } - break; - - case R_ARM_THM_CALL: - debug(8, "elfloader: R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us."); - break; - - case R_ARM_CALL: - debug(8, "elfloader: R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us."); - break; - - case R_ARM_JUMP24: - debug(8, "elfloader: R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us."); - break; - - case R_ARM_V4BX: - debug(8, "elfloader: R_ARM_V4BX: No relocation calculation necessary."); - break; - - default: - warning("elfloader: Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); - free(rel); - return false; - } - } - - free(rel); - return true; -} - -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++) { - Elf32_Shdr *curShdr = &(shdr[i]); - - if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section - curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { - warning("elfloader: RELA entries not supported yet!"); - return false; - } - - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) - return false; - } - } - - return true; -} - -#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/arm-loader.h b/backends/plugins/arm-loader.h deleted file mode 100644 index 24290d5c6d..0000000000 --- a/backends/plugins/arm-loader.h +++ /dev/null @@ -1,39 +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(ARM_TARGET) - -#include "backends/plugins/elf-loader.h" - -class ARMDLObject : public DLObject { -protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - -public: - ARMDLObject() : DLObject() {} -}; - -#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h index 0013145358..c856937172 100644 --- a/backends/plugins/ds/ds-provider.h +++ b/backends/plugins/ds/ds-provider.h @@ -25,8 +25,8 @@ #if defined(DYNAMIC_MODULES) && defined(__DS__) -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/arm-loader.h" +#include "backends/plugins/elf/elf-provider.h" +#include "backends/plugins/elf/arm-loader.h" class DSPluginProvider : public ELFPluginProvider { class DSPlugin : public ELFPlugin { diff --git a/backends/plugins/elf-loader.cpp b/backends/plugins/elf-loader.cpp deleted file mode 100644 index e1a1b8cef6..0000000000 --- a/backends/plugins/elf-loader.cpp +++ /dev/null @@ -1,445 +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(ELF_LOADER_TARGET) - -#include -#include - -#ifdef __PSP__ -#include -#include -#endif - -#ifdef __DS__ -#include -#endif - -#ifdef __WII__ -#include -#include -#endif - -#include "backends/plugins/elf-loader.h" - -#include "common/debug.h" -#include "common/file.h" -#include "common/fs.h" - -/** - * Flushes the data cache (Platform Specific). - */ -static void flushDataCache(void *ptr, uint32 len) { -#ifdef __DS__ - DC_FlushRange(ptr, len); - IC_InvalidateRange(ptr, len); -#endif -#ifdef __PLAYSTATION2__ - (void) ptr; - (void) len; - FlushCache(0); - FlushCache(2); -#endif -#ifdef __PSP__ - sceKernelDcacheWritebackRange(ptr, len); - sceKernelIcacheInvalidateRange(ptr, len); -#endif -#ifdef __WII__ - DCFlushRange(ptr, len); - ICInvalidateRange(ptr, len); -#endif -} - -DLObject::DLObject() : - _segment(0), - _symtab(0), - _strtab(0), - _symbol_cnt(0), - _symtab_sect(-1), - _dtors_start(0), - _dtors_end(0), - _segmentSize(0), - _segmentOffset(0), - _segmentVMA(0) { -} - -DLObject::~DLObject() { - unload(); -} - -// Expel the symbol table from memory -void DLObject::discard_symtab() { - free(_symtab); - free(_strtab); - _symtab = 0; - _strtab = 0; - _symbol_cnt = 0; -} - -// Unload all objects from memory -void DLObject::unload() { - discard_symtab(); - free(_segment); - _segment = 0; -} - -bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - // Start reading the elf header. Check for errors and magic - if (DLFile->read(ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || - memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { - warning("elfloader: No ELF file."); - return false; - } - - if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) { - warning("elfloader: Wrong ELF file class."); - return false; - } - - if (ehdr->e_ident[EI_DATA] != -#ifdef SCUMM_BIG_ENDIAN - ELFDATA2MSB -#else - ELFDATA2LSB -#endif - ) { - warning("elfloader: Wrong ELF file endianess."); - return false; - } - - if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) { - warning("elfloader: Wrong ELF file version."); - return false; - } - - if (ehdr->e_type != ET_EXEC) { - warning("elfloader: No executable ELF file."); - return false; - } - - if (ehdr->e_machine != -#ifdef ARM_TARGET - EM_ARM -#endif -#ifdef MIPS_TARGET - EM_MIPS -#endif -#ifdef PPC_TARGET - EM_PPC -#endif - ) { - warning("elfloader: Wrong ELF file architecture."); - return false; - } - - if (ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header - ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header - warning("elfloader: Invalid ELF structure sizes."); - return false; - } - - debug(2, "elfloader: phoff = %d, phentsz = %d, phnum = %d", - ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); - - return true; -} - -bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { - // Read program header - if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) || - DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { - warning("elfloader: Program header load failed."); - return false; - } - - // Check program header values - if (phdr->p_type != PT_LOAD || phdr->p_filesz > phdr->p_memsz) { - warning("elfloader: Invalid program header."); - return false; - } - - debug(2, "elfloader: offs = %x, filesz = %x, memsz = %x, align = %x", - phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); - - return true; -} - -bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, 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 - debug(2, "elfloader: Extra mem is %x", extra); - - if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { - warning("elfloader: Out of memory."); - return false; - } - - debug(2, "elfloader: Allocated segment @ %p", _segment); - - // Get offset to load segment into - baseAddress = (char *)_segment; - _segmentSize = phdr->p_memsz + extra; - _segmentVMA = phdr->p_vaddr; - - // Set bss segment to 0 if necessary (assumes bss is at the end) - if (phdr->p_memsz > phdr->p_filesz) { - debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); - memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); - } - - debug(2, "elfloader: Reading the segment into memory"); - - // Read the segment into memory - if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { - warning("elfloader: Segment load failed."); - return false; - } - - debug(2, "elfloader: Segment has been read into memory"); - - return true; -} - -Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { - Elf32_Shdr *shdr = 0; - - // Allocate memory for section headers - if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { - warning("elfloader: Out of memory."); - return 0; - } - - // Read from file into section headers - if (!DLFile->seek(ehdr->e_shoff, SEEK_SET) || - DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != - ehdr->e_shnum * sizeof(*shdr)) { - warning("elfloader: Section headers load failed."); - return 0; - } - - return shdr; -} - -int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, 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) { - warning("elfloader: No symbol table."); - return -1; - } - - debug(2, "elfloader: Symbol section at section %d, size %x", _symtab_sect, shdr[_symtab_sect].sh_size); - - // Allocate memory for symbol table - if (!(_symtab = malloc(shdr[_symtab_sect].sh_size))) { - warning("elfloader: Out of memory."); - return -1; - } - - // Read symbol table into memory - if (!DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) || - DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != - shdr[_symtab_sect].sh_size) { - warning("elfloader: Symbol table load failed."); - return -1; - } - - // Set number of symbols - _symbol_cnt = shdr[_symtab_sect].sh_size / sizeof(Elf32_Sym); - debug(2, "elfloader: Loaded %d symbols.", _symbol_cnt); - - return _symtab_sect; -} - -bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, 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))) { - warning("elfloader: Out of memory."); - return false; - } - - // Read string table into memory - if (!DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) || - DLFile->read(_strtab, shdr[string_sect].sh_size) != - shdr[string_sect].sh_size) { - warning("elfloader: Symbol table strings load failed."); - return false; - } - - return true; -} - -void DLObject::relocateSymbols(ptrdiff_t 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) { - s->st_value += offset; - if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) - warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); - } - } -} - -bool DLObject::load(Common::SeekableReadStream* DLFile) { - Elf32_Ehdr ehdr; - Elf32_Phdr phdr; - Elf32_Shdr *shdr; - bool ret = true; - - if (readElfHeader(DLFile, &ehdr) == false) { - return false; - } - - for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments - debug(2, "elfloader: Loading segment %d", i); - - if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) - return false; - - if (!loadSegment(DLFile, &phdr)) - return false; - } - - if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == 0) - ret = false; - - if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) - ret = false; - - if (ret && (loadStringTable(DLFile, shdr) == false)) - ret = false; - - if (ret) { - // Offset by our segment allocated address - _segmentOffset = ptrdiff_t(_segment) - phdr.p_vaddr; - relocateSymbols(_segmentOffset); - } - - if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) - ret = false; - - free(shdr); - - return ret; -} - -bool DLObject::open(const char *path) { - Common::SeekableReadStream* DLFile; - void *ctors_start, *ctors_end; - - debug(2, "elfloader: open(\"%s\")", path); - - Common::FSNode file(path); - - if (!(DLFile = file.createReadStream())) { - warning("elfloader: %s not found.", path); - return false; - } - - debug(2, "elfloader: %s found!", path); - - /*Try to load and relocate*/ - if (!load(DLFile)) { - unload(); - return false; - } - - debug(2, "elfloader: Loaded!"); - - flushDataCache(_segment, _segmentSize); - - 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 || !ctors_end || !_dtors_start || !_dtors_end) { - warning("elfloader: Missing ctors/dtors."); - _dtors_start = _dtors_end = 0; - unload(); - return false; - } - - debug(2, "elfloader: Calling constructors."); - for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) - (**f)(); - - debug(2, "elfloader: %s opened ok.", path); - - return true; -} - -bool DLObject::close() { - if (_dtors_start && _dtors_end) - for (void (**f)(void) = (void (**)(void))_dtors_start; f != _dtors_end; f++) - (**f)(); - _dtors_start = _dtors_end = 0; - unload(); - return true; -} - -void *DLObject::symbol(const char *name) { - debug(2, "elfloader: Symbol(\"%s\")", name); - - if (!_symtab || !_strtab || _symbol_cnt < 1) { - warning("elfloader: No symbol table loaded."); - return 0; - } - - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) - // We can only import symbols that are global or weak in the plugin - if ((SYM_BIND(s->st_info) == STB_GLOBAL || - SYM_BIND(s->st_info) == STB_WEAK) && - !strcmp(name, _strtab + s->st_name)) { - // We found the symbol - debug(2, "elfloader: => %p", (void*)s->st_value); - return (void*)s->st_value; - } - - // We didn't find the symbol - warning("elfloader: Symbol \"%s\" not found.", name); - return 0; -} - -#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ - diff --git a/backends/plugins/elf-loader.h b/backends/plugins/elf-loader.h deleted file mode 100644 index b5c0e1355d..0000000000 --- a/backends/plugins/elf-loader.h +++ /dev/null @@ -1,83 +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(ELF_LOADER_TARGET) - -#ifndef ELF_LOADER_H -#define ELF_LOADER_H - -#include - -#include "backends/plugins/dynamic-plugin.h" -#include "backends/plugins/elf32.h" - -#include "common/stream.h" - -/** - * DLObject - * - * Class that most directly handles operations on a plugin file - * (opening it for reading, loading/unloading it in memory, finding a specific symbol in the file, etc.) - * Subclasses have the same functionality, but implementations specific to different processors/platforms. - */ -class DLObject { -protected: - void *_segment, *_symtab; - char *_strtab; - int _symbol_cnt; - int _symtab_sect; - void *_dtors_start, *_dtors_end; - - uint32 _segmentSize; - ptrdiff_t _segmentOffset; - uint32 _segmentVMA; - - virtual void unload(); - bool load(Common::SeekableReadStream* DLFile); - - bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); - virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); - virtual void relocateSymbols(ptrdiff_t offset); - - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; - -public: - DLObject(); - virtual ~DLObject(); - - bool open(const char *path); - bool close(); - void *symbol(const char *name); - void discard_symtab(); -}; - -#endif /* ELF_LOADER_H */ - -#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ diff --git a/backends/plugins/elf-provider.cpp b/backends/plugins/elf-provider.cpp deleted file mode 100644 index 997a43b653..0000000000 --- a/backends/plugins/elf-provider.cpp +++ /dev/null @@ -1,99 +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(ELF_LOADER_TARGET) - -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/dynamic-plugin.h" - -#include "common/fs.h" - -DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { - void *func = 0; - - if (_dlHandle) - func = _dlHandle->symbol(symbol); - - if (!func) { - if (!_dlHandle) - warning("elfloader: Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); - else - warning("elfloader: Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); - } - - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp; -} - -bool ELFPlugin::loadPlugin() { - assert(!_dlHandle); - DLObject *obj = makeDLObject(); - if (obj->open(_filename.c_str())) { - _dlHandle = obj; - } else { - delete obj; - _dlHandle = 0; - } - - if (!_dlHandle) { - warning("elfloader: 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) { - if (!_dlHandle->close()) { - warning("elfloader: Failed unloading plugin '%s'", _filename.c_str()); - } - delete _dlHandle; - _dlHandle = 0; - } -} - -bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { - // Check the plugin suffix - Common::String filename = node.getName(); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) - return false; - - return true; -} - -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/elf-provider.h b/backends/plugins/elf-provider.h deleted file mode 100644 index df9c503674..0000000000 --- a/backends/plugins/elf-provider.h +++ /dev/null @@ -1,75 +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(ELF_LOADER_TARGET) - -#ifndef BACKENDS_PLUGINS_ELF_PROVIDER_H -#define BACKENDS_PLUGINS_ELF_PROVIDER_H - -#include "backends/plugins/elf-loader.h" - -#include "common/fs.h" - -/** - * ELFPlugin - * - * Objects of this class are returned when the PluginManager calls - * getPlugins() on an ELFPluginProvider. An intermediary class for - * dealing with plugin files, ELFPlugin is responsible for creating/destroying - * a DLObject that handles the opening/loading/unloading of the plugin file whose - * path in the target backend's file system is "_filename". - */ -class ELFPlugin : public DynamicPlugin { -protected: - DLObject *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol); - -public: - ELFPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} - - ~ELFPlugin() { - if (_dlHandle) - unloadPlugin(); - } - - virtual DLObject *makeDLObject() = 0; - - bool loadPlugin(); - void unloadPlugin(); -}; - -class ELFPluginProvider : public FilePluginProvider { -protected: - virtual Plugin* createPlugin(const Common::FSNode &node) const = 0; - - bool isPluginFilename(const Common::FSNode &node) const; -}; - -#endif /* BACKENDS_PLUGINS_ELF_PROVIDER_H */ - -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp new file mode 100644 index 0000000000..ab1129d34c --- /dev/null +++ b/backends/plugins/elf/arm-loader.cpp @@ -0,0 +1,140 @@ +/* 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(ARM_TARGET) + +#include "backends/plugins/elf/elf-loader.h" +#include "backends/plugins/elf/arm-loader.h" + +#include "common/debug.h" + +/** + * Follow the instruction of a relocation section. + * + * @param DLFile SeekableReadStream of File + * @param fileOffset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) + */ +bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = 0; //relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + warning("elfloader: Out of memory."); + return false; + } + + // Read in our relocation table + if (!DLFile->seek(offset, SEEK_SET) || + DLFile->read(rel, size) != size) { + warning("elfloader: Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); + + int a = 0; + unsigned int relocation = 0; + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; //Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + case R_ARM_ABS32: + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + + *target = relocation; + + debug(8, "elfloader: R_ARM_ABS32: i=%d, a=%x, origTarget=%x, target=%x", i, a, origTarget, *target); + } + break; + + case R_ARM_THM_CALL: + debug(8, "elfloader: R_ARM_THM_CALL: PC-relative jump, ld takes care of necessary relocation work for us."); + break; + + case R_ARM_CALL: + debug(8, "elfloader: R_ARM_CALL: PC-relative jump, ld takes care of necessary relocation work for us."); + break; + + case R_ARM_JUMP24: + debug(8, "elfloader: R_ARM_JUMP24: PC-relative jump, ld takes care of all relocation work for us."); + break; + + case R_ARM_V4BX: + debug(8, "elfloader: R_ARM_V4BX: No relocation calculation necessary."); + break; + + default: + warning("elfloader: Unknown relocation type %d.", REL_TYPE(rel[i].r_info)); + free(rel); + return false; + } + } + + free(rel); + return true; +} + +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++) { + Elf32_Shdr *curShdr = &(shdr[i]); + + if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section + curShdr->sh_entsize == sizeof(Elf32_Rel) && // 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 (curShdr->sh_type == SHT_RELA) { + warning("elfloader: RELA entries not supported yet!"); + return false; + } + + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) + return false; + } + } + + return true; +} + +#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/elf/arm-loader.h b/backends/plugins/elf/arm-loader.h new file mode 100644 index 0000000000..52a3be5447 --- /dev/null +++ b/backends/plugins/elf/arm-loader.h @@ -0,0 +1,39 @@ +/* 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(ARM_TARGET) + +#include "backends/plugins/elf/elf-loader.h" + +class ARMDLObject : public DLObject { +protected: + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + +public: + ARMDLObject() : DLObject() {} +}; + +#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp new file mode 100644 index 0000000000..5ce8af6295 --- /dev/null +++ b/backends/plugins/elf/elf-loader.cpp @@ -0,0 +1,445 @@ +/* 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(ELF_LOADER_TARGET) + +#include +#include + +#ifdef __PSP__ +#include +#include +#endif + +#ifdef __DS__ +#include +#endif + +#ifdef __WII__ +#include +#include +#endif + +#include "backends/plugins/elf/elf-loader.h" + +#include "common/debug.h" +#include "common/file.h" +#include "common/fs.h" + +/** + * Flushes the data cache (Platform Specific). + */ +static void flushDataCache(void *ptr, uint32 len) { +#ifdef __DS__ + DC_FlushRange(ptr, len); + IC_InvalidateRange(ptr, len); +#endif +#ifdef __PLAYSTATION2__ + (void) ptr; + (void) len; + FlushCache(0); + FlushCache(2); +#endif +#ifdef __PSP__ + sceKernelDcacheWritebackRange(ptr, len); + sceKernelIcacheInvalidateRange(ptr, len); +#endif +#ifdef __WII__ + DCFlushRange(ptr, len); + ICInvalidateRange(ptr, len); +#endif +} + +DLObject::DLObject() : + _segment(0), + _symtab(0), + _strtab(0), + _symbol_cnt(0), + _symtab_sect(-1), + _dtors_start(0), + _dtors_end(0), + _segmentSize(0), + _segmentOffset(0), + _segmentVMA(0) { +} + +DLObject::~DLObject() { + unload(); +} + +// Expel the symbol table from memory +void DLObject::discard_symtab() { + free(_symtab); + free(_strtab); + _symtab = 0; + _strtab = 0; + _symbol_cnt = 0; +} + +// Unload all objects from memory +void DLObject::unload() { + discard_symtab(); + free(_segment); + _segment = 0; +} + +bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { + // Start reading the elf header. Check for errors and magic + if (DLFile->read(ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || + memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { + warning("elfloader: No ELF file."); + return false; + } + + if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) { + warning("elfloader: Wrong ELF file class."); + return false; + } + + if (ehdr->e_ident[EI_DATA] != +#ifdef SCUMM_BIG_ENDIAN + ELFDATA2MSB +#else + ELFDATA2LSB +#endif + ) { + warning("elfloader: Wrong ELF file endianess."); + return false; + } + + if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) { + warning("elfloader: Wrong ELF file version."); + return false; + } + + if (ehdr->e_type != ET_EXEC) { + warning("elfloader: No executable ELF file."); + return false; + } + + if (ehdr->e_machine != +#ifdef ARM_TARGET + EM_ARM +#endif +#ifdef MIPS_TARGET + EM_MIPS +#endif +#ifdef PPC_TARGET + EM_PPC +#endif + ) { + warning("elfloader: Wrong ELF file architecture."); + return false; + } + + if (ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header + ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header + warning("elfloader: Invalid ELF structure sizes."); + return false; + } + + debug(2, "elfloader: phoff = %d, phentsz = %d, phnum = %d", + ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); + + return true; +} + +bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { + // Read program header + if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) || + DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { + warning("elfloader: Program header load failed."); + return false; + } + + // Check program header values + if (phdr->p_type != PT_LOAD || phdr->p_filesz > phdr->p_memsz) { + warning("elfloader: Invalid program header."); + return false; + } + + debug(2, "elfloader: offs = %x, filesz = %x, memsz = %x, align = %x", + phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); + + return true; +} + +bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, 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 + debug(2, "elfloader: Extra mem is %x", extra); + + if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { + warning("elfloader: Out of memory."); + return false; + } + + debug(2, "elfloader: Allocated segment @ %p", _segment); + + // Get offset to load segment into + baseAddress = (char *)_segment; + _segmentSize = phdr->p_memsz + extra; + _segmentVMA = phdr->p_vaddr; + + // Set bss segment to 0 if necessary (assumes bss is at the end) + if (phdr->p_memsz > phdr->p_filesz) { + debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); + memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + } + + debug(2, "elfloader: Reading the segment into memory"); + + // Read the segment into memory + if (!DLFile->seek(phdr->p_offset, SEEK_SET) || + DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { + warning("elfloader: Segment load failed."); + return false; + } + + debug(2, "elfloader: Segment has been read into memory"); + + return true; +} + +Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { + Elf32_Shdr *shdr = 0; + + // Allocate memory for section headers + if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { + warning("elfloader: Out of memory."); + return 0; + } + + // Read from file into section headers + if (!DLFile->seek(ehdr->e_shoff, SEEK_SET) || + DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != + ehdr->e_shnum * sizeof(*shdr)) { + warning("elfloader: Section headers load failed."); + return 0; + } + + return shdr; +} + +int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, 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) { + warning("elfloader: No symbol table."); + return -1; + } + + debug(2, "elfloader: Symbol section at section %d, size %x", _symtab_sect, shdr[_symtab_sect].sh_size); + + // Allocate memory for symbol table + if (!(_symtab = malloc(shdr[_symtab_sect].sh_size))) { + warning("elfloader: Out of memory."); + return -1; + } + + // Read symbol table into memory + if (!DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) || + DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != + shdr[_symtab_sect].sh_size) { + warning("elfloader: Symbol table load failed."); + return -1; + } + + // Set number of symbols + _symbol_cnt = shdr[_symtab_sect].sh_size / sizeof(Elf32_Sym); + debug(2, "elfloader: Loaded %d symbols.", _symbol_cnt); + + return _symtab_sect; +} + +bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, 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))) { + warning("elfloader: Out of memory."); + return false; + } + + // Read string table into memory + if (!DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) || + DLFile->read(_strtab, shdr[string_sect].sh_size) != + shdr[string_sect].sh_size) { + warning("elfloader: Symbol table strings load failed."); + return false; + } + + return true; +} + +void DLObject::relocateSymbols(ptrdiff_t 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) { + s->st_value += offset; + if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); + } + } +} + +bool DLObject::load(Common::SeekableReadStream* DLFile) { + Elf32_Ehdr ehdr; + Elf32_Phdr phdr; + Elf32_Shdr *shdr; + bool ret = true; + + if (readElfHeader(DLFile, &ehdr) == false) { + return false; + } + + for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments + debug(2, "elfloader: Loading segment %d", i); + + if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) + return false; + + if (!loadSegment(DLFile, &phdr)) + return false; + } + + if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == 0) + ret = false; + + if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) + ret = false; + + if (ret && (loadStringTable(DLFile, shdr) == false)) + ret = false; + + if (ret) { + // Offset by our segment allocated address + _segmentOffset = ptrdiff_t(_segment) - phdr.p_vaddr; + relocateSymbols(_segmentOffset); + } + + if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) + ret = false; + + free(shdr); + + return ret; +} + +bool DLObject::open(const char *path) { + Common::SeekableReadStream* DLFile; + void *ctors_start, *ctors_end; + + debug(2, "elfloader: open(\"%s\")", path); + + Common::FSNode file(path); + + if (!(DLFile = file.createReadStream())) { + warning("elfloader: %s not found.", path); + return false; + } + + debug(2, "elfloader: %s found!", path); + + /*Try to load and relocate*/ + if (!load(DLFile)) { + unload(); + return false; + } + + debug(2, "elfloader: Loaded!"); + + flushDataCache(_segment, _segmentSize); + + 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 || !ctors_end || !_dtors_start || !_dtors_end) { + warning("elfloader: Missing ctors/dtors."); + _dtors_start = _dtors_end = 0; + unload(); + return false; + } + + debug(2, "elfloader: Calling constructors."); + for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) + (**f)(); + + debug(2, "elfloader: %s opened ok.", path); + + return true; +} + +bool DLObject::close() { + if (_dtors_start && _dtors_end) + for (void (**f)(void) = (void (**)(void))_dtors_start; f != _dtors_end; f++) + (**f)(); + _dtors_start = _dtors_end = 0; + unload(); + return true; +} + +void *DLObject::symbol(const char *name) { + debug(2, "elfloader: Symbol(\"%s\")", name); + + if (!_symtab || !_strtab || _symbol_cnt < 1) { + warning("elfloader: No symbol table loaded."); + return 0; + } + + Elf32_Sym *s = (Elf32_Sym *)_symtab; + for (int c = _symbol_cnt; c--; s++) + // We can only import symbols that are global or weak in the plugin + if ((SYM_BIND(s->st_info) == STB_GLOBAL || + SYM_BIND(s->st_info) == STB_WEAK) && + !strcmp(name, _strtab + s->st_name)) { + // We found the symbol + debug(2, "elfloader: => %p", (void*)s->st_value); + return (void*)s->st_value; + } + + // We didn't find the symbol + warning("elfloader: Symbol \"%s\" not found.", name); + return 0; +} + +#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ + diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h new file mode 100644 index 0000000000..6413c46cea --- /dev/null +++ b/backends/plugins/elf/elf-loader.h @@ -0,0 +1,83 @@ +/* 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(ELF_LOADER_TARGET) + +#ifndef ELF_LOADER_H +#define ELF_LOADER_H + +#include + +#include "backends/plugins/elf/elf32.h" +#include "backends/plugins/dynamic-plugin.h" + +#include "common/stream.h" + +/** + * DLObject + * + * Class that most directly handles operations on a plugin file + * (opening it for reading, loading/unloading it in memory, finding a specific symbol in the file, etc.) + * Subclasses have the same functionality, but implementations specific to different processors/platforms. + */ +class DLObject { +protected: + void *_segment, *_symtab; + char *_strtab; + int _symbol_cnt; + int _symtab_sect; + void *_dtors_start, *_dtors_end; + + uint32 _segmentSize; + ptrdiff_t _segmentOffset; + uint32 _segmentVMA; + + virtual void unload(); + bool load(Common::SeekableReadStream* DLFile); + + bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); + int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); + virtual void relocateSymbols(ptrdiff_t offset); + + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; + +public: + DLObject(); + virtual ~DLObject(); + + bool open(const char *path); + bool close(); + void *symbol(const char *name); + void discard_symtab(); +}; + +#endif /* ELF_LOADER_H */ + +#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp new file mode 100644 index 0000000000..9b42d4edd3 --- /dev/null +++ b/backends/plugins/elf/elf-provider.cpp @@ -0,0 +1,99 @@ +/* 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(ELF_LOADER_TARGET) + +#include "backends/plugins/elf/elf-provider.h" +#include "backends/plugins/dynamic-plugin.h" + +#include "common/fs.h" + +DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { + void *func = 0; + + if (_dlHandle) + func = _dlHandle->symbol(symbol); + + if (!func) { + if (!_dlHandle) + warning("elfloader: Failed loading symbol '%s' from plugin '%s' (Handle is NULL)", symbol, _filename.c_str()); + else + warning("elfloader: Failed loading symbol '%s' from plugin '%s'", symbol, _filename.c_str()); + } + + // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ + // standard and POSIX: ISO C++ disallows casting between function pointers + // and data pointers, but dlsym always returns a void pointer. For details, + // see e.g. . + assert(sizeof(VoidFunc) == sizeof(func)); + VoidFunc tmp; + memcpy(&tmp, &func, sizeof(VoidFunc)); + return tmp; +} + +bool ELFPlugin::loadPlugin() { + assert(!_dlHandle); + DLObject *obj = makeDLObject(); + if (obj->open(_filename.c_str())) { + _dlHandle = obj; + } else { + delete obj; + _dlHandle = 0; + } + + if (!_dlHandle) { + warning("elfloader: 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) { + if (!_dlHandle->close()) { + warning("elfloader: Failed unloading plugin '%s'", _filename.c_str()); + } + delete _dlHandle; + _dlHandle = 0; + } +} + +bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { + // Check the plugin suffix + Common::String filename = node.getName(); + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) + return false; + + return true; +} + +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/elf/elf-provider.h b/backends/plugins/elf/elf-provider.h new file mode 100644 index 0000000000..f06621f5b7 --- /dev/null +++ b/backends/plugins/elf/elf-provider.h @@ -0,0 +1,75 @@ +/* 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(ELF_LOADER_TARGET) + +#ifndef BACKENDS_PLUGINS_ELF_PROVIDER_H +#define BACKENDS_PLUGINS_ELF_PROVIDER_H + +#include "backends/plugins/elf/elf-loader.h" + +#include "common/fs.h" + +/** + * ELFPlugin + * + * Objects of this class are returned when the PluginManager calls + * getPlugins() on an ELFPluginProvider. An intermediary class for + * dealing with plugin files, ELFPlugin is responsible for creating/destroying + * a DLObject that handles the opening/loading/unloading of the plugin file whose + * path in the target backend's file system is "_filename". + */ +class ELFPlugin : public DynamicPlugin { +protected: + DLObject *_dlHandle; + Common::String _filename; + + virtual VoidFunc findSymbol(const char *symbol); + +public: + ELFPlugin(const Common::String &filename) + : _dlHandle(0), _filename(filename) {} + + ~ELFPlugin() { + if (_dlHandle) + unloadPlugin(); + } + + virtual DLObject *makeDLObject() = 0; + + bool loadPlugin(); + void unloadPlugin(); +}; + +class ELFPluginProvider : public FilePluginProvider { +protected: + virtual Plugin* createPlugin(const Common::FSNode &node) const = 0; + + bool isPluginFilename(const Common::FSNode &node) const; +}; + +#endif /* BACKENDS_PLUGINS_ELF_PROVIDER_H */ + +#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/elf/elf32.h b/backends/plugins/elf/elf32.h new file mode 100644 index 0000000000..c83093fed7 --- /dev/null +++ b/backends/plugins/elf/elf32.h @@ -0,0 +1,252 @@ +/* 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: + * The contents of this file were gathered mainly from the SYSTEM V APPLICATION BINARY INTERFACE. + * Processor-specific things were garnered from processor-specific supplements to the abi. + */ + +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 4 + +/* 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" /* ELF Magic number */ + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASS32 1 /* 32-bit objects */ + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ + +#define EI_VERSION 6 +#define EV_CURRENT 1 /* Current version */ + +// 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_MIPS 8 +#define EM_PPC 20 +#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_MIPS_REGINFO 0x70000000 /* Register usage info for MIPS */ +#define PT_ARM_ARCHEXT 0x70000000 /* Platform architecture compatibility info for ARM */ +#define PT_ARM_EXIDX 0x70000001 /* Exception unwind tables for ARM */ + +// 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_MIPS_LIBLSIT 0x70000000 /* Info about dynamic shared object libs for MIPS*/ +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicts btw executables and shared objects for MIPS */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global pointer table for MIPS*/ +#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table for ARM*/ +#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map for ARM */ +#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes for ARM*/ + +// sh_flags values +#define SHF_WRITE 0 /* writable section */ +#define SHF_ALLOC 2 /* section occupies memory */ +#define SHF_EXECINSTR 4 /* machine instructions */ +#define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area for MIPS */ + +// 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 with implicit addend (info about how to relocate) +typedef struct { + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +// Relocation entry with explicit addend (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 */ + +//MIPS relocation types +#define R_MIPS_NONE 0 +#define R_MIPS_16 1 +#define R_MIPS_32 2 +#define R_MIPS_REL32 3 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_GPREL16 7 +#define R_MIPS_LITERAL 8 +#define R_MIPS_GOT16 9 +#define R_MIPS_PC16 10 +#define R_MIPS_CALL16 11 +#define R_MIPS_GPREL32 12 +#define R_MIPS_GOTHI16 13 +#define R_MIPS_GOTLO16 14 +#define R_MIPS_CALLHI16 15 +#define R_MIPS_CALLLO16 16 + +// ARM relocation types +#define R_ARM_NONE 0 +#define R_ARM_ABS32 2 +#define R_ARM_THM_CALL 10 +#define R_ARM_CALL 28 +#define R_ARM_JUMP24 29 +#define R_ARM_TARGET1 38 +#define R_ARM_V4BX 40 + +// PPC relocation types +#define R_PPC_ADDR32 1 +#define R_PPC_ADDR16_LO 4 +#define R_PPC_ADDR16_HI 5 +#define R_PPC_ADDR16_HA 6 +#define R_PPC_REL24 10 +#define R_PPC_REL32 26 + +// Mock function to get value of global pointer for MIPS +#define getGP() ({ \ + unsigned int __valgp; \ + __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ + __valgp; \ +}) + +#endif /* BACKENDS_ELF_H */ diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp new file mode 100644 index 0000000000..642ea0427a --- /dev/null +++ b/backends/plugins/elf/mips-loader.cpp @@ -0,0 +1,334 @@ +/* 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(MIPS_TARGET) + +#include "backends/plugins/elf/mips-loader.h" + +#include "common/debug.h" + +/** + * Follow the instruction of a relocation section. + * + * @param DLFile SeekableReadStream of File + * @param fileOffset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) + */ +bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rel *rel = 0; // relocation entry + + // Allocate memory for relocation table + if (!(rel = (Elf32_Rel *)malloc(size))) { + warning("elfloader: Out of memory."); + return false; + } + + // Read in our relocation table + if (!DLFile->seek(offset, SEEK_SET) || + DLFile->read(rel, size) != size) { + warning("elfloader: Relocation table load failed."); + free(rel); + return false; + } + + // Treat each relocation entry. Loop over all of them + int cnt = size / sizeof(*rel); + + debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); + + bool seenHi16 = false; // For treating HI/LO16 commands + int firstHi16 = -1; // Mark the point of the first hi16 seen + Elf32_Addr ahl = 0; // Calculated addend + int a = 0; // Addend: taken from the target + + unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives + unsigned int relocation = 0; + int debugRelocs[10] = {0}; // For debugging + int extendedHi16 = 0; // Count extended hi16 treatments + Elf32_Addr lastHiSymVal = 0; + bool hi16InShorts = false; + +#define DEBUG_NUM 2 + + // Loop over relocation entries + for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + + unsigned int origTarget = *target; // Save for debugging + + // Act differently based on the type of relocation + switch (REL_TYPE(rel[i].r_info)) { + case R_MIPS_HI16: // Absolute addressing. + if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) + firstHi16 < 0) { // Only process first in block of HI16s + firstHi16 = i; // Keep the first Hi16 we saw + seenHi16 = true; + ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up + + lastHiSymVal = sym->st_value; + hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments + if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number + debug(8, "elfloader: R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x", + i, rel[i].r_offset, ahl, *target); + } + break; + + case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) + if (!seenHi16) { // We MUST have seen HI16 first + debug(8, "elfloader: R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!", i); + free(rel); + return false; + } + + // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) + // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section + // and will be screened out above + bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); + + // Correct the bug by getting the proper value in ahl (taken from the current symbol) + if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { + ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset + ahl += (sym->st_value & 0xffff0000); + } + + ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s + a = *target & 0xffff; // Take lower 16 bits of the target + a = (a << 16) >> 16; // Sign extend them + ahl += a; // Add lower 16 bits. AHL is now complete + + // Fix: we can have LO16 access to the short segment sometimes + if (lo16InShorts) + relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset + else // It's in the regular segment + relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment + + if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now + for (int j = firstHi16; j < i; j++) { + if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s + + lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target + *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target + *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation + if (relocation & 0x8000) + (*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case + } + firstHi16 = -1; // Reset so we'll know we treated it + } else { + extendedHi16++; + } + + *target &= 0xffff0000; // Clear the lower 16 bits of current target + *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation + + if (debugRelocs[1]++ < DEBUG_NUM) + debug(8, "elfloader: R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) + debug(8, "elfloader: R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", + i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + } + break; + + case R_MIPS_26: // Absolute addressing (for jumps and branches only) + if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment + a = *target & 0x03ffffff; // Get 26 bits' worth of the addend + a = (a << 6) >> 6; // Sign extend a + relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset + *target &= 0xfc000000; // Clean lower 26 target bits + *target |= (relocation & 0x03ffffff); + + if (debugRelocs[3]++ < DEBUG_NUM) + debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } else { + if (debugRelocs[4]++ < DEBUG_NUM) + debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", + i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); + } + break; + + case R_MIPS_GPREL16: // GP Relative addressing + if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section + ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole + a = *target & 0xffff; // Get 16 bits' worth of the addend + a = (a << 16) >> 16; // Sign extend it + + relocation = a + _shortsSegment->getOffset(); + + *target &= 0xffff0000; // Clear the lower 16 bits of the target + *target |= relocation & 0xffff; + + if (debugRelocs[5]++ < DEBUG_NUM) + debug(8, "elfloader: R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x", + i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); + } + + break; + + case R_MIPS_32: // Absolute addressing + if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. + a = *target; // Get full 32 bits of addend + + if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment + relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset + else // We're in the main section + relocation = a + (Elf32_Addr)_segment; // Shift by main offset + *target = relocation; + + if (debugRelocs[6]++ < DEBUG_NUM) + debug("8, elfloader: R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x", i, a, origTarget, *target); + } + break; + + default: + warning("elfloader: Unknown relocation type %x at relocation %d.", REL_TYPE(rel[i].r_info), i); + free(rel); + return false; + } + } + + debug(2, "elfloader: Done with relocation. extendedHi16=%d", extendedHi16); + + free(rel); + return true; +} + +bool MIPSDLObject::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++) { + + 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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) + return false; + } else { // In Shorts segment + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) + return false; + } + } + } + + return true; +} + +void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { + int mainCount = 0; + int shortsCount= 0; + + // 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) { + if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { + mainCount++; + s->st_value += offset; + if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); + } else { // shorts section + shortsCount++; + s->st_value += _shortsSegment->getOffset(); + if (!_shortsSegment->inSegment((char *)s->st_value)) + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); + } + } + } +} + +bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { + char *baseAddress = 0; + + // We need to take account of non-allocated segment for shorts + if (phdr->p_flags & PF_X) { // This is a relocated segment + // Attempt to allocate memory for segment + int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here + debug(2, "elfloader: Extra mem is %x", extra); + + if (phdr->p_align < 0x10000) + phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI + + if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { + warning("elfloader: Out of memory."); + return false; + } + debug(2, "elfloader: Allocated segment @ %p", _segment); + + // Get offset to load segment into + baseAddress = (char *)_segment + phdr->p_vaddr; + _segmentSize = phdr->p_memsz + extra; + } else { // This is a shorts section. + _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); + + baseAddress = _shortsSegment->getStart(); + debug(2, "elfloader: Shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x", + _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + } + + // Set bss segment to 0 if necessary (assumes bss is at the end) + if (phdr->p_memsz > phdr->p_filesz) { + debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); + memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + } + + debug(2, "elfloader: Reading the segment into memory"); + + // Read the segment into memory + if (!DLFile->seek(phdr->p_offset, SEEK_SET) || + DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { + warning("elfloader: Segment load failed."); + return false; + } + + debug(2, "elfloader: Segment has been read into memory"); + + return true; +} + +// Unload all objects from memory +void MIPSDLObject::unload() { + discard_symtab(); + free(_segment); + _segment = 0; + + if (_shortsSegment) { + ShortsMan.deleteSegment(_shortsSegment); + _shortsSegment = 0; + } +} + +#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h new file mode 100644 index 0000000000..a3210b5b12 --- /dev/null +++ b/backends/plugins/elf/mips-loader.h @@ -0,0 +1,50 @@ + +/* 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(MIPS_TARGET) + +#include "backends/plugins/elf/elf-loader.h" +#include "backends/plugins/elf/shorts-segment-manager.h" + +class MIPSDLObject : public DLObject { +protected: + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + unsigned int _gpVal; // Value of Global Pointer + + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual void relocateSymbols(Elf32_Addr offset); + virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + virtual void unload(); + +public: + MIPSDLObject() : DLObject() { + _shortsSegment = NULL; + _gpVal = 0; + } +}; + +#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/elf/plugin.syms b/backends/plugins/elf/plugin.syms new file mode 100644 index 0000000000..24ee1a19dc --- /dev/null +++ b/backends/plugins/elf/plugin.syms @@ -0,0 +1,8 @@ +PLUGIN_getVersion +PLUGIN_getType +PLUGIN_getTypeVersion +PLUGIN_getObject +___plugin_ctors +___plugin_ctors_end +___plugin_dtors +___plugin_dtors_end diff --git a/backends/plugins/elf/ppc-loader.cpp b/backends/plugins/elf/ppc-loader.cpp new file mode 100644 index 0000000000..21a9a6c8a0 --- /dev/null +++ b/backends/plugins/elf/ppc-loader.cpp @@ -0,0 +1,128 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.cpp $ + * $Id: arm-loader.cpp 52058 2010-08-13 05:58:11Z toneman1138 $ + * + */ + +#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) + +#include "backends/plugins/elf/elf-loader.h" +#include "backends/plugins/elf/ppc-loader.h" + +#include "common/debug.h" + +bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { + Elf32_Rela *rel = NULL; + + if (!(rel = (Elf32_Rela *)malloc(size))) { + warning("elfloader: Out of memory."); + return false; + } + + if (DLFile->seek(offset, SEEK_SET) < 0 || + DLFile->read(rel, size) != size) { + warning("elfloader: Relocation table load failed."); + free(rel); + return false; + } + + int cnt = size / sizeof(*rel); + + debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + + uint32 *src; + uint32 value; + + for (int i = 0; i < cnt; i++) { + // Get the symbol this relocation entry is referring to + Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + + // Get the target instruction in the code + src = (uint32 *)((char *)relSegment + rel[i].r_offset - _segmentVMA); + value = sym->st_value + rel[i].r_addend; + + //debug(8, "elfloader: i=%05d %p +0x%04x: (0x%08x) 0x%08x ", i, src, rel[i].r_addend, sym->st_value, *src); + + switch (REL_TYPE(rel[i].r_info)) { + case R_PPC_ADDR32: + *src = value; + debug(8, "elfloader: R_PPC_ADDR32 -> 0x%08x\n", *src); + break; + case R_PPC_ADDR16_LO: + *((uint16 *) src) = value; + debug(8, "elfloader: R_PPC_ADDR16_LO -> 0x%08x\n", *src); + break; + case R_PPC_ADDR16_HI: + *(uint16 *) src = value >> 16; + debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); + break; + case R_PPC_ADDR16_HA: + *(uint16 *) src = (value + 0x8000) >> 16; + debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); + break; + case R_PPC_REL24: + *src = (*src & ~0x03fffffc) | ((value - (uint32) src) & 0x03fffffc); + debug(8, "elfloader: R_PPC_REL24 -> 0x%08x\n", *src); + break; + case R_PPC_REL32: + *src = value - (uint32) src; + debug(8, "elfloader: R_PPC_REL32 -> 0x%08x\n", *src); + break; + default: + warning("elfloader: Unknown relocation type %d\n", REL_TYPE(rel[i].r_info)); + free(rel); + return false; + } + } + + free(rel); + return true; +} + +bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { + for (int i = 0; i < ehdr->e_shnum; i++) { + Elf32_Shdr *curShdr = &(shdr[i]); + + if ((curShdr->sh_type == SHT_REL) && + curShdr->sh_entsize == sizeof(Elf32_Rel) && + (int)curShdr->sh_link == _symtab_sect && + curShdr->sh_info < ehdr->e_shnum && + (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { + warning("elfloader: REL entries not supported!\n"); + return false; + } + + if ((curShdr->sh_type == SHT_RELA) && + curShdr->sh_entsize == sizeof(Elf32_Rela) && + (int)curShdr->sh_link == _symtab_sect && + curShdr->sh_info < ehdr->e_shnum && + (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) + return false; + } + } + + return true; +} + +#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ + diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h new file mode 100644 index 0000000000..13043924bb --- /dev/null +++ b/backends/plugins/elf/ppc-loader.h @@ -0,0 +1,40 @@ +/* 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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.h $ + * $Id: arm-loader.h 52053 2010-08-13 02:58:52Z toneman1138 $ + * + */ + +#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) + +#include "backends/plugins/elf/elf-loader.h" + +class PPCDLObject : public DLObject { +protected: + virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + +public: + PPCDLObject() : DLObject() {} +}; + +#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ + diff --git a/backends/plugins/elf/shorts-segment-manager.cpp b/backends/plugins/elf/shorts-segment-manager.cpp new file mode 100644 index 0000000000..612ef19bbe --- /dev/null +++ b/backends/plugins/elf/shorts-segment-manager.cpp @@ -0,0 +1,84 @@ +/* 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(MIPS_TARGET) + +#include "backends/plugins/elf/shorts-segment-manager.h" + +#include "common/debug.h" + +extern char __plugin_hole_start; // Indicates start of hole in program file for shorts +extern char __plugin_hole_end; // Indicates end of hole in program file +extern char _gp[]; // Value of gp register + +DECLARE_SINGLETON(ShortSegmentManager); // For singleton + +ShortSegmentManager::ShortSegmentManager() { + _shortsStart = &__plugin_hole_start ; //shorts segment begins at the plugin hole we made when linking + _shortsEnd = &__plugin_hole_end; //and ends at the end of that hole. +} + +ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { + char *lastAddress = origAddr; + Common::List::iterator i; + + // Find a block that fits, starting from the beginning + for (i = _list.begin(); i != _list.end(); ++i) { + char *currAddress = (*i)->getStart(); + + if ((int)(currAddress - lastAddress) >= size) break; + + lastAddress = (*i)->getEnd(); + } + + if ((Elf32_Addr)lastAddress & 3) + lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 + + if (lastAddress + size > _shortsEnd) { + warning("elfloader: No space in shorts segment for %x bytes. Last address is %p, max address is %p.", + size, lastAddress, _shortsEnd); + return 0; + } + + Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment + + if (lastAddress + size > _highestAddress) + _highestAddress = lastAddress + size; // Keep track of maximum + + _list.insert(i, seg); + + debug(2, "elfloader: Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.", + size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); + + return seg; +} + +void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { + debug(2, "elfloader: Deleting shorts segment from %p to %p.", seg->getStart(), seg->getEnd()); + _list.remove(seg); + delete seg; +} + +#endif /* DYNAMIC_MODULES && MIPS_TARGET */ diff --git a/backends/plugins/elf/shorts-segment-manager.h b/backends/plugins/elf/shorts-segment-manager.h new file mode 100644 index 0000000000..b3650562ed --- /dev/null +++ b/backends/plugins/elf/shorts-segment-manager.h @@ -0,0 +1,103 @@ +/* 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(MIPS_TARGET) + +#ifndef SHORTS_SEGMENT_MANAGER_H +#define SHORTS_SEGMENT_MANAGER_H + +#include "backends/plugins/elf/elf32.h" + +#include "common/singleton.h" +#include "common/list.h" + +#define ShortsMan ShortSegmentManager::instance() + +/** + * ShortSegmentManager + * + * Since MIPS is limited to 32 bits per instruction, loading data that's further away than 16 bits + * takes several instructions. Thus, small global data (which is likely to be accessed a lot from + * multiple locations) is often put into a GP-relative area (GP standing for the global pointer register) + * in MIPS processors. This class manages these segments of small global data, and is used by the + * member functions of MIPSDLObject, which query in information from this manager in order to deal with + * this segment during the loading/unloading of plugins. + * + * Since there's no true dynamic linker to change the GP register between plugins and the main engine, + * custom ld linker scripts for both the main executable and the plugins ensure the GP-area is in the + * same place for both. The ShortSegmentManager accesses this place via the symbols __plugin_hole_start + * and __plugin_hole_end, which are defined in those custom ld linker scripts. + */ +class ShortSegmentManager : public Common::Singleton { +private: + char *_shortsStart; + char *_shortsEnd; + +public: + char *getShortsStart() { + return _shortsStart; + } + + // Returns whether or not an absolute address is in the GP-relative section. + bool inGeneralSegment(char *addr) { + return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); + } + + class Segment { + private: + friend class ShortSegmentManager; + Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} + ~Segment() {} + char *_startAddress; // Start of shorts segment in memory + int _size; // Size of shorts segment + char *_origAddress; // Original address this segment was supposed to be at + public: + char *getStart() { + return _startAddress; + } + char *getEnd() { + return (_startAddress + _size); + } + Elf32_Addr getOffset() { + return (Elf32_Addr)(_startAddress - _origAddress); + } + bool inSegment(char *addr) { + return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); + } + }; + + Segment *newSegment(int size, char *origAddr); + void deleteSegment(Segment *); + +private: + ShortSegmentManager(); + friend class Common::Singleton; + Common::List _list; + char *_highestAddress; +}; + +#endif /* SHORTS_SEGMENT_MANAGER_H */ + +#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/elf32.h b/backends/plugins/elf32.h deleted file mode 100644 index c83093fed7..0000000000 --- a/backends/plugins/elf32.h +++ /dev/null @@ -1,252 +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: - * The contents of this file were gathered mainly from the SYSTEM V APPLICATION BINARY INTERFACE. - * Processor-specific things were garnered from processor-specific supplements to the abi. - */ - -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 4 - -/* 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" /* ELF Magic number */ - -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASS32 1 /* 32-bit objects */ - -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ - -#define EI_VERSION 6 -#define EV_CURRENT 1 /* Current version */ - -// 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_MIPS 8 -#define EM_PPC 20 -#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_MIPS_REGINFO 0x70000000 /* Register usage info for MIPS */ -#define PT_ARM_ARCHEXT 0x70000000 /* Platform architecture compatibility info for ARM */ -#define PT_ARM_EXIDX 0x70000001 /* Exception unwind tables for ARM */ - -// 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_MIPS_LIBLSIT 0x70000000 /* Info about dynamic shared object libs for MIPS*/ -#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicts btw executables and shared objects for MIPS */ -#define SHT_MIPS_GPTAB 0x70000003 /* Global pointer table for MIPS*/ -#define SHT_ARM_EXIDX 0x70000001 /* Exception Index table for ARM*/ -#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map for ARM */ -#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes for ARM*/ - -// sh_flags values -#define SHF_WRITE 0 /* writable section */ -#define SHF_ALLOC 2 /* section occupies memory */ -#define SHF_EXECINSTR 4 /* machine instructions */ -#define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area for MIPS */ - -// 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 with implicit addend (info about how to relocate) -typedef struct { - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ -} Elf32_Rel; - -// Relocation entry with explicit addend (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 */ - -//MIPS relocation types -#define R_MIPS_NONE 0 -#define R_MIPS_16 1 -#define R_MIPS_32 2 -#define R_MIPS_REL32 3 -#define R_MIPS_26 4 -#define R_MIPS_HI16 5 -#define R_MIPS_LO16 6 -#define R_MIPS_GPREL16 7 -#define R_MIPS_LITERAL 8 -#define R_MIPS_GOT16 9 -#define R_MIPS_PC16 10 -#define R_MIPS_CALL16 11 -#define R_MIPS_GPREL32 12 -#define R_MIPS_GOTHI16 13 -#define R_MIPS_GOTLO16 14 -#define R_MIPS_CALLHI16 15 -#define R_MIPS_CALLLO16 16 - -// ARM relocation types -#define R_ARM_NONE 0 -#define R_ARM_ABS32 2 -#define R_ARM_THM_CALL 10 -#define R_ARM_CALL 28 -#define R_ARM_JUMP24 29 -#define R_ARM_TARGET1 38 -#define R_ARM_V4BX 40 - -// PPC relocation types -#define R_PPC_ADDR32 1 -#define R_PPC_ADDR16_LO 4 -#define R_PPC_ADDR16_HI 5 -#define R_PPC_ADDR16_HA 6 -#define R_PPC_REL24 10 -#define R_PPC_REL32 26 - -// Mock function to get value of global pointer for MIPS -#define getGP() ({ \ - unsigned int __valgp; \ - __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ - __valgp; \ -}) - -#endif /* BACKENDS_ELF_H */ diff --git a/backends/plugins/mips-loader.cpp b/backends/plugins/mips-loader.cpp deleted file mode 100644 index 729c8f4224..0000000000 --- a/backends/plugins/mips-loader.cpp +++ /dev/null @@ -1,334 +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(MIPS_TARGET) - -#include "backends/plugins/mips-loader.h" - -#include "common/debug.h" - -/** - * Follow the instruction of a relocation section. - * - * @param DLFile SeekableReadStream of File - * @param fileOffset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - */ -bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rel *rel = 0; // relocation entry - - // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { - warning("elfloader: Out of memory."); - return false; - } - - // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || - DLFile->read(rel, size) != size) { - warning("elfloader: Relocation table load failed."); - free(rel); - return false; - } - - // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); - - debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); - - bool seenHi16 = false; // For treating HI/LO16 commands - int firstHi16 = -1; // Mark the point of the first hi16 seen - Elf32_Addr ahl = 0; // Calculated addend - int a = 0; // Addend: taken from the target - - unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives - unsigned int relocation = 0; - int debugRelocs[10] = {0}; // For debugging - int extendedHi16 = 0; // Count extended hi16 treatments - Elf32_Addr lastHiSymVal = 0; - bool hi16InShorts = false; - -#define DEBUG_NUM 2 - - // Loop over relocation entries - for (int i = 0; i < cnt; i++) { - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); - - unsigned int origTarget = *target; // Save for debugging - - // Act differently based on the type of relocation - switch (REL_TYPE(rel[i].r_info)) { - case R_MIPS_HI16: // Absolute addressing. - if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) - firstHi16 < 0) { // Only process first in block of HI16s - firstHi16 = i; // Keep the first Hi16 we saw - seenHi16 = true; - ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up - - lastHiSymVal = sym->st_value; - hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments - if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number - debug(8, "elfloader: R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x", - i, rel[i].r_offset, ahl, *target); - } - break; - - case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) - if (!seenHi16) { // We MUST have seen HI16 first - debug(8, "elfloader: R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!", i); - free(rel); - return false; - } - - // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) - // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section - // and will be screened out above - bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); - - // Correct the bug by getting the proper value in ahl (taken from the current symbol) - if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { - ahl -= (lastHiSymVal & 0xffff0000); // We assume gcc meant the same offset - ahl += (sym->st_value & 0xffff0000); - } - - ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s - a = *target & 0xffff; // Take lower 16 bits of the target - a = (a << 16) >> 16; // Sign extend them - ahl += a; // Add lower 16 bits. AHL is now complete - - // Fix: we can have LO16 access to the short segment sometimes - if (lo16InShorts) - relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset - else // It's in the regular segment - relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment - - if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now - for (int j = firstHi16; j < i; j++) { - if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s - - lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target - *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target - *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation - if (relocation & 0x8000) - (*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case - } - firstHi16 = -1; // Reset so we'll know we treated it - } else { - extendedHi16++; - } - - *target &= 0xffff0000; // Clear the lower 16 bits of current target - *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation - - if (debugRelocs[1]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", - i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); - } - break; - - case R_MIPS_26: // Absolute addressing (for jumps and branches only) - if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment - a = *target & 0x03ffffff; // Get 26 bits' worth of the addend - a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset - *target &= 0xfc000000; // Clean lower 26 target bits - *target |= (relocation & 0x03ffffff); - - if (debugRelocs[3]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } else { - if (debugRelocs[4]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", - i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); - } - break; - - case R_MIPS_GPREL16: // GP Relative addressing - if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section - ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole - a = *target & 0xffff; // Get 16 bits' worth of the addend - a = (a << 16) >> 16; // Sign extend it - - relocation = a + _shortsSegment->getOffset(); - - *target &= 0xffff0000; // Clear the lower 16 bits of the target - *target |= relocation & 0xffff; - - if (debugRelocs[5]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x", - i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); - } - - break; - - case R_MIPS_32: // Absolute addressing - if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. - a = *target; // Get full 32 bits of addend - - if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment - relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset - else // We're in the main section - relocation = a + (Elf32_Addr)_segment; // Shift by main offset - *target = relocation; - - if (debugRelocs[6]++ < DEBUG_NUM) - debug("8, elfloader: R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x", i, a, origTarget, *target); - } - break; - - default: - warning("elfloader: Unknown relocation type %x at relocation %d.", REL_TYPE(rel[i].r_info), i); - free(rel); - return false; - } - } - - debug(2, "elfloader: Done with relocation. extendedHi16=%d", extendedHi16); - - free(rel); - return true; -} - -bool MIPSDLObject::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++) { - - 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_Rel) && // 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) - return false; - } else { // In Shorts segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) - return false; - } - } - } - - return true; -} - -void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { - int mainCount = 0; - int shortsCount= 0; - - // 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) { - if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { - mainCount++; - s->st_value += offset; - if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) - warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); - } else { // shorts section - shortsCount++; - s->st_value += _shortsSegment->getOffset(); - if (!_shortsSegment->inSegment((char *)s->st_value)) - warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); - } - } - } -} - -bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { - char *baseAddress = 0; - - // We need to take account of non-allocated segment for shorts - if (phdr->p_flags & PF_X) { // This is a relocated segment - // Attempt to allocate memory for segment - int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here - debug(2, "elfloader: Extra mem is %x", extra); - - if (phdr->p_align < 0x10000) - phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - - if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { - warning("elfloader: Out of memory."); - return false; - } - debug(2, "elfloader: Allocated segment @ %p", _segment); - - // Get offset to load segment into - baseAddress = (char *)_segment + phdr->p_vaddr; - _segmentSize = phdr->p_memsz + extra; - } else { // This is a shorts section. - _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); - - baseAddress = _shortsSegment->getStart(); - debug(2, "elfloader: Shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x", - _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); - } - - // Set bss segment to 0 if necessary (assumes bss is at the end) - if (phdr->p_memsz > phdr->p_filesz) { - debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); - memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); - } - - debug(2, "elfloader: Reading the segment into memory"); - - // Read the segment into memory - if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { - warning("elfloader: Segment load failed."); - return false; - } - - debug(2, "elfloader: Segment has been read into memory"); - - return true; -} - -// Unload all objects from memory -void MIPSDLObject::unload() { - discard_symtab(); - free(_segment); - _segment = 0; - - if (_shortsSegment) { - ShortsMan.deleteSegment(_shortsSegment); - _shortsSegment = 0; - } -} - -#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/mips-loader.h b/backends/plugins/mips-loader.h deleted file mode 100644 index 98bda5263f..0000000000 --- a/backends/plugins/mips-loader.h +++ /dev/null @@ -1,50 +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(MIPS_TARGET) - -#include "backends/plugins/elf-loader.h" -#include "backends/plugins/shorts-segment-manager.h" - -class MIPSDLObject : public DLObject { -protected: - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - unsigned int _gpVal; // Value of Global Pointer - - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - virtual void relocateSymbols(Elf32_Addr offset); - virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - virtual void unload(); - -public: - MIPSDLObject() : DLObject() { - _shortsSegment = NULL; - _gpVal = 0; - } -}; - -#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/plugin.syms b/backends/plugins/plugin.syms deleted file mode 100644 index 24ee1a19dc..0000000000 --- a/backends/plugins/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/ppc-loader.cpp b/backends/plugins/ppc-loader.cpp deleted file mode 100644 index dcd5fceff1..0000000000 --- a/backends/plugins/ppc-loader.cpp +++ /dev/null @@ -1,128 +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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.cpp $ - * $Id: arm-loader.cpp 52058 2010-08-13 05:58:11Z toneman1138 $ - * - */ - -#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) - -#include "backends/plugins/elf-loader.h" -#include "backends/plugins/ppc-loader.h" - -#include "common/debug.h" - -bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { - Elf32_Rela *rel = NULL; - - if (!(rel = (Elf32_Rela *)malloc(size))) { - warning("elfloader: Out of memory."); - return false; - } - - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != size) { - warning("elfloader: Relocation table load failed."); - free(rel); - return false; - } - - int cnt = size / sizeof(*rel); - - debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); - - uint32 *src; - uint32 value; - - for (int i = 0; i < cnt; i++) { - // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); - - // Get the target instruction in the code - src = (uint32 *)((char *)relSegment + rel[i].r_offset - _segmentVMA); - value = sym->st_value + rel[i].r_addend; - - //debug(8, "elfloader: i=%05d %p +0x%04x: (0x%08x) 0x%08x ", i, src, rel[i].r_addend, sym->st_value, *src); - - switch (REL_TYPE(rel[i].r_info)) { - case R_PPC_ADDR32: - *src = value; - debug(8, "elfloader: R_PPC_ADDR32 -> 0x%08x\n", *src); - break; - case R_PPC_ADDR16_LO: - *((uint16 *) src) = value; - debug(8, "elfloader: R_PPC_ADDR16_LO -> 0x%08x\n", *src); - break; - case R_PPC_ADDR16_HI: - *(uint16 *) src = value >> 16; - debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); - break; - case R_PPC_ADDR16_HA: - *(uint16 *) src = (value + 0x8000) >> 16; - debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); - break; - case R_PPC_REL24: - *src = (*src & ~0x03fffffc) | ((value - (uint32) src) & 0x03fffffc); - debug(8, "elfloader: R_PPC_REL24 -> 0x%08x\n", *src); - break; - case R_PPC_REL32: - *src = value - (uint32) src; - debug(8, "elfloader: R_PPC_REL32 -> 0x%08x\n", *src); - break; - default: - warning("elfloader: Unknown relocation type %d\n", REL_TYPE(rel[i].r_info)); - free(rel); - return false; - } - } - - free(rel); - return true; -} - -bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { - for (int i = 0; i < ehdr->e_shnum; i++) { - Elf32_Shdr *curShdr = &(shdr[i]); - - if ((curShdr->sh_type == SHT_REL) && - curShdr->sh_entsize == sizeof(Elf32_Rel) && - (int)curShdr->sh_link == _symtab_sect && - curShdr->sh_info < ehdr->e_shnum && - (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { - warning("elfloader: REL entries not supported!\n"); - return false; - } - - if ((curShdr->sh_type == SHT_RELA) && - curShdr->sh_entsize == sizeof(Elf32_Rela) && - (int)curShdr->sh_link == _symtab_sect && - curShdr->sh_info < ehdr->e_shnum && - (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) - return false; - } - } - - return true; -} - -#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ - diff --git a/backends/plugins/ppc-loader.h b/backends/plugins/ppc-loader.h deleted file mode 100644 index 14d1f16720..0000000000 --- a/backends/plugins/ppc-loader.h +++ /dev/null @@ -1,40 +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: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.h $ - * $Id: arm-loader.h 52053 2010-08-13 02:58:52Z toneman1138 $ - * - */ - -#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) - -#include "backends/plugins/elf-loader.h" - -class PPCDLObject : public DLObject { -protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - -public: - PPCDLObject() : DLObject() {} -}; - -#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ - diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index 809b88920a..00ddb4647e 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -25,8 +25,8 @@ #if defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/mips-loader.h" +#include "backends/plugins/elf/elf-provider.h" +#include "backends/plugins/elf/mips-loader.h" class PS2PluginProvider : public ELFPluginProvider { class PS2Plugin : public ELFPlugin { diff --git a/backends/plugins/psp/psp-provider.h b/backends/plugins/psp/psp-provider.h index b7934179bf..18623e448c 100644 --- a/backends/plugins/psp/psp-provider.h +++ b/backends/plugins/psp/psp-provider.h @@ -28,8 +28,8 @@ #ifndef BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H #define BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/mips-loader.h" +#include "backends/plugins/elf/elf-provider.h" +#include "backends/plugins/elf/mips-loader.h" class PSPPluginProvider : public ELFPluginProvider { class PSPPlugin : public ELFPlugin { diff --git a/backends/plugins/shorts-segment-manager.cpp b/backends/plugins/shorts-segment-manager.cpp deleted file mode 100644 index 17af17aa45..0000000000 --- a/backends/plugins/shorts-segment-manager.cpp +++ /dev/null @@ -1,84 +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(MIPS_TARGET) - -#include "backends/plugins/shorts-segment-manager.h" - -#include "common/debug.h" - -extern char __plugin_hole_start; // Indicates start of hole in program file for shorts -extern char __plugin_hole_end; // Indicates end of hole in program file -extern char _gp[]; // Value of gp register - -DECLARE_SINGLETON(ShortSegmentManager); // For singleton - -ShortSegmentManager::ShortSegmentManager() { - _shortsStart = &__plugin_hole_start ; //shorts segment begins at the plugin hole we made when linking - _shortsEnd = &__plugin_hole_end; //and ends at the end of that hole. -} - -ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { - char *lastAddress = origAddr; - Common::List::iterator i; - - // Find a block that fits, starting from the beginning - for (i = _list.begin(); i != _list.end(); ++i) { - char *currAddress = (*i)->getStart(); - - if ((int)(currAddress - lastAddress) >= size) break; - - lastAddress = (*i)->getEnd(); - } - - if ((Elf32_Addr)lastAddress & 3) - lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 - - if (lastAddress + size > _shortsEnd) { - warning("elfloader: No space in shorts segment for %x bytes. Last address is %p, max address is %p.", - size, lastAddress, _shortsEnd); - return 0; - } - - Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment - - if (lastAddress + size > _highestAddress) - _highestAddress = lastAddress + size; // Keep track of maximum - - _list.insert(i, seg); - - debug(2, "elfloader: Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.", - size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); - - return seg; -} - -void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { - debug(2, "elfloader: Deleting shorts segment from %p to %p.", seg->getStart(), seg->getEnd()); - _list.remove(seg); - delete seg; -} - -#endif /* DYNAMIC_MODULES && MIPS_TARGET */ diff --git a/backends/plugins/shorts-segment-manager.h b/backends/plugins/shorts-segment-manager.h deleted file mode 100644 index bf583c021a..0000000000 --- a/backends/plugins/shorts-segment-manager.h +++ /dev/null @@ -1,103 +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(MIPS_TARGET) - -#ifndef SHORTS_SEGMENT_MANAGER_H -#define SHORTS_SEGMENT_MANAGER_H - -#include "backends/plugins/elf32.h" - -#include "common/singleton.h" -#include "common/list.h" - -#define ShortsMan ShortSegmentManager::instance() - -/** - * ShortSegmentManager - * - * Since MIPS is limited to 32 bits per instruction, loading data that's further away than 16 bits - * takes several instructions. Thus, small global data (which is likely to be accessed a lot from - * multiple locations) is often put into a GP-relative area (GP standing for the global pointer register) - * in MIPS processors. This class manages these segments of small global data, and is used by the - * member functions of MIPSDLObject, which query in information from this manager in order to deal with - * this segment during the loading/unloading of plugins. - * - * Since there's no true dynamic linker to change the GP register between plugins and the main engine, - * custom ld linker scripts for both the main executable and the plugins ensure the GP-area is in the - * same place for both. The ShortSegmentManager accesses this place via the symbols __plugin_hole_start - * and __plugin_hole_end, which are defined in those custom ld linker scripts. - */ -class ShortSegmentManager : public Common::Singleton { -private: - char *_shortsStart; - char *_shortsEnd; - -public: - char *getShortsStart() { - return _shortsStart; - } - - // Returns whether or not an absolute address is in the GP-relative section. - bool inGeneralSegment(char *addr) { - return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); - } - - class Segment { - private: - friend class ShortSegmentManager; - Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} - ~Segment() {} - char *_startAddress; // Start of shorts segment in memory - int _size; // Size of shorts segment - char *_origAddress; // Original address this segment was supposed to be at - public: - char *getStart() { - return _startAddress; - } - char *getEnd() { - return (_startAddress + _size); - } - Elf32_Addr getOffset() { - return (Elf32_Addr)(_startAddress - _origAddress); - } - bool inSegment(char *addr) { - return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); - } - }; - - Segment *newSegment(int size, char *origAddr); - void deleteSegment(Segment *); - -private: - ShortSegmentManager(); - friend class Common::Singleton; - Common::List _list; - char *_highestAddress; -}; - -#endif /* SHORTS_SEGMENT_MANAGER_H */ - -#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/wii/wii-provider.h b/backends/plugins/wii/wii-provider.h index a299ff4add..deb143b02a 100644 --- a/backends/plugins/wii/wii-provider.h +++ b/backends/plugins/wii/wii-provider.h @@ -25,8 +25,8 @@ #if defined(DYNAMIC_MODULES) && defined(__WII__) -#include "backends/plugins/elf-provider.h" -#include "backends/plugins/ppc-loader.h" +#include "backends/plugins/elf/elf-provider.h" +#include "backends/plugins/elf/ppc-loader.h" class WiiPluginProvider : public ELFPluginProvider { class WiiPlugin : public ELFPlugin { -- cgit v1.2.3 From c4a88559a5577e816793b02a6eaaa3ab69c8ecdb Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:52:17 +0000 Subject: PLUGINS: Move platform specific code out of the generic ELF loader. Instead overwrite pure virtual functions in a backend specific class. svn-id: r52556 --- backends/module.mk | 10 +++-- backends/plugins/ds/ds-provider.cpp | 75 +++++++++++++++++++++++++++++++++++ backends/plugins/ds/ds-provider.h | 22 +++++----- backends/plugins/elf/arm-loader.h | 5 +++ backends/plugins/elf/elf-loader.cpp | 49 +++-------------------- backends/plugins/elf/elf-loader.h | 11 +++-- backends/plugins/elf/elf-provider.h | 2 +- backends/plugins/elf/mips-loader.cpp | 4 -- backends/plugins/elf/mips-loader.h | 6 +++ backends/plugins/elf/ppc-loader.h | 5 +++ backends/plugins/ps2/ps2-provider.cpp | 72 +++++++++++++++++++++++++++++++++ backends/plugins/ps2/ps2-provider.h | 21 ++++------ backends/plugins/psp/psp-provider.cpp | 75 +++++++++++++++++++++++++++++++++++ backends/plugins/psp/psp-provider.h | 19 +++------ backends/plugins/wii/wii-provider.cpp | 75 +++++++++++++++++++++++++++++++++++ backends/plugins/wii/wii-provider.h | 18 ++++----- 16 files changed, 363 insertions(+), 106 deletions(-) create mode 100644 backends/plugins/ds/ds-provider.cpp create mode 100644 backends/plugins/ps2/ps2-provider.cpp create mode 100644 backends/plugins/psp/psp-provider.cpp create mode 100644 backends/plugins/wii/wii-provider.cpp (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index eea7ec98d2..e0bdd26cf7 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -50,7 +50,8 @@ endif ifeq ($(BACKEND),ds) MODULE_OBJS += \ fs/ds/ds-fs-factory.o \ - fs/ds/ds-fs.o + fs/ds/ds-fs.o \ + plugins/ds/ds-provider.o endif ifeq ($(BACKEND),n64) @@ -61,20 +62,23 @@ endif ifeq ($(BACKEND),ps2) MODULE_OBJS += \ - fs/ps2/ps2-fs-factory.o + fs/ps2/ps2-fs-factory.o \ + plugins/ps2/ps2-provider.o endif ifeq ($(BACKEND),psp) MODULE_OBJS += \ fs/psp/psp-fs-factory.o \ fs/psp/psp-stream.o \ + plugins/psp/psp-provider.o \ saves/psp/psp-saves.o \ timer/psp/timer.o endif ifeq ($(BACKEND),wii) MODULE_OBJS += \ - fs/wii/wii-fs-factory.o + fs/wii/wii-fs-factory.o \ + plugins/wii/wii-provider.o endif # Include common rules diff --git a/backends/plugins/ds/ds-provider.cpp b/backends/plugins/ds/ds-provider.cpp new file mode 100644 index 0000000000..c188b6c9df --- /dev/null +++ b/backends/plugins/ds/ds-provider.cpp @@ -0,0 +1,75 @@ +/* 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(__DS__) + +#include +#include + +#include "backends/plugins/ds/ds-provider.h" +#include "backends/plugins/elf/arm-loader.h" + +class DSDLObject : public ARMDLObject { +public: + DSDLObject() : + ARMDLObject() { + } + + virtual ~DSDLObject() { + unload(); + } + +protected: + virtual void *allocSegment(size_t boundary, size_t size) const { + return memalign(boundary, size); + } + + virtual void freeSegment(void *segment) const { + free(segment); + } + + virtual void flushDataCache(void *ptr, uint32 len) const { + DC_FlushRange(ptr, len); + IC_InvalidateRange(ptr, len); + } +}; + +class DSPlugin : public ELFPlugin { +public: + DSPlugin(const Common::String &filename) : + ELFPlugin(filename) { + } + + virtual DLObject *makeDLObject() { + return new DSDLObject(); + } +}; + +Plugin *DSPluginProvider::createPlugin(const Common::FSNode &node) const { + return new DSPlugin(node.getPath()); +} + +#endif // defined(DYNAMIC_MODULES) && defined(__DS__) + diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h index c856937172..b7f7aaa746 100644 --- a/backends/plugins/ds/ds-provider.h +++ b/backends/plugins/ds/ds-provider.h @@ -18,28 +18,24 @@ * 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$ + * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ds/ds-provider.h $ + * $Id: ds-provider.h 52112 2010-08-16 08:41:04Z toneman1138 $ * */ #if defined(DYNAMIC_MODULES) && defined(__DS__) +#ifndef BACKENDS_PLUGINS_DS_PROVIDER_H +#define BACKENDS_PLUGINS_DS_PROVIDER_H + #include "backends/plugins/elf/elf-provider.h" -#include "backends/plugins/elf/arm-loader.h" class DSPluginProvider : public ELFPluginProvider { - class DSPlugin : public ELFPlugin { - public: - DSPlugin(const Common::String &filename) : ELFPlugin(filename) {} - - DLObject *makeDLObject() { return new ARMDLObject(); } - }; - public: - Plugin* createPlugin(const Common::FSNode &node) const { - return new DSPlugin(node.getPath()); - } + Plugin *createPlugin(const Common::FSNode &node) const; }; +#endif // BACKENDS_PLUGINS_DS_PROVIDER_H + #endif // defined(DYNAMIC_MODULES) && defined(__DS__) + diff --git a/backends/plugins/elf/arm-loader.h b/backends/plugins/elf/arm-loader.h index 52a3be5447..c4df671060 100644 --- a/backends/plugins/elf/arm-loader.h +++ b/backends/plugins/elf/arm-loader.h @@ -25,6 +25,9 @@ #if defined(DYNAMIC_MODULES) && defined(ARM_TARGET) +#ifndef BACKENDS_PLUGINS_ARM_LOADER_H +#define BACKENDS_PLUGINS_ARM_LOADER_H + #include "backends/plugins/elf/elf-loader.h" class ARMDLObject : public DLObject { @@ -36,4 +39,6 @@ public: ARMDLObject() : DLObject() {} }; +#endif /* BACKENDS_PLUGINS_ARM_LOADER_H */ + #endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index 5ce8af6295..e11f9fcce6 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -25,53 +25,12 @@ #if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) -#include -#include - -#ifdef __PSP__ -#include -#include -#endif - -#ifdef __DS__ -#include -#endif - -#ifdef __WII__ -#include -#include -#endif - #include "backends/plugins/elf/elf-loader.h" #include "common/debug.h" #include "common/file.h" #include "common/fs.h" -/** - * Flushes the data cache (Platform Specific). - */ -static void flushDataCache(void *ptr, uint32 len) { -#ifdef __DS__ - DC_FlushRange(ptr, len); - IC_InvalidateRange(ptr, len); -#endif -#ifdef __PLAYSTATION2__ - (void) ptr; - (void) len; - FlushCache(0); - FlushCache(2); -#endif -#ifdef __PSP__ - sceKernelDcacheWritebackRange(ptr, len); - sceKernelIcacheInvalidateRange(ptr, len); -#endif -#ifdef __WII__ - DCFlushRange(ptr, len); - ICInvalidateRange(ptr, len); -#endif -} - DLObject::DLObject() : _segment(0), _symtab(0), @@ -86,7 +45,6 @@ DLObject::DLObject() : } DLObject::~DLObject() { - unload(); } // Expel the symbol table from memory @@ -101,8 +59,11 @@ void DLObject::discard_symtab() { // Unload all objects from memory void DLObject::unload() { discard_symtab(); - free(_segment); + freeSegment(_segment); _segment = 0; + _segmentSize = 0; + _segmentOffset = 0; + _segmentVMA = 0; } bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { @@ -193,7 +154,7 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); - if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { + if (!(_segment = (char *) allocSegment(phdr->p_align, phdr->p_memsz + extra))) { warning("elfloader: Out of memory."); return false; } diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h index 6413c46cea..7c1d0830f3 100644 --- a/backends/plugins/elf/elf-loader.h +++ b/backends/plugins/elf/elf-loader.h @@ -25,8 +25,8 @@ #if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) -#ifndef ELF_LOADER_H -#define ELF_LOADER_H +#ifndef BACKENDS_PLUGINS_ELF_LOADER_H +#define BACKENDS_PLUGINS_ELF_LOADER_H #include @@ -65,9 +65,14 @@ protected: bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); virtual void relocateSymbols(ptrdiff_t offset); + // architecture specific virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; + // platform specific + virtual void *allocSegment(size_t boundary, size_t size) const = 0; + virtual void freeSegment(void *segment) const = 0; + virtual void flushDataCache(void *ptr, uint32 len) const = 0; public: DLObject(); virtual ~DLObject(); @@ -78,6 +83,6 @@ public: void discard_symtab(); }; -#endif /* ELF_LOADER_H */ +#endif /* BACKENDS_PLUGINS_ELF_LOADER_H */ #endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ diff --git a/backends/plugins/elf/elf-provider.h b/backends/plugins/elf/elf-provider.h index f06621f5b7..447e71ea18 100644 --- a/backends/plugins/elf/elf-provider.h +++ b/backends/plugins/elf/elf-provider.h @@ -52,7 +52,7 @@ public: ELFPlugin(const Common::String &filename) : _dlHandle(0), _filename(filename) {} - ~ELFPlugin() { + virtual ~ELFPlugin() { if (_dlHandle) unloadPlugin(); } diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 642ea0427a..027ff34698 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -321,10 +321,6 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p // Unload all objects from memory void MIPSDLObject::unload() { - discard_symtab(); - free(_segment); - _segment = 0; - if (_shortsSegment) { ShortsMan.deleteSegment(_shortsSegment); _shortsSegment = 0; diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h index a3210b5b12..28b8c7f636 100644 --- a/backends/plugins/elf/mips-loader.h +++ b/backends/plugins/elf/mips-loader.h @@ -26,6 +26,9 @@ #if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) +#ifndef BACKENDS_PLUGINS_MIPS_LOADER_H +#define BACKENDS_PLUGINS_MIPS_LOADER_H + #include "backends/plugins/elf/elf-loader.h" #include "backends/plugins/elf/shorts-segment-manager.h" @@ -47,4 +50,7 @@ public: } }; +#endif /* BACKENDS_PLUGINS_MIPS_LOADER_H */ + #endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ + diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h index 13043924bb..574ba104e6 100644 --- a/backends/plugins/elf/ppc-loader.h +++ b/backends/plugins/elf/ppc-loader.h @@ -25,6 +25,9 @@ #if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) +#ifndef BACKENDS_PLUGINS_PPC_LOADER_H +#define BACKENDS_PLUGINS_PPC_LOADER_H + #include "backends/plugins/elf/elf-loader.h" class PPCDLObject : public DLObject { @@ -36,5 +39,7 @@ public: PPCDLObject() : DLObject() {} }; +#endif /* BACKENDS_PLUGINS_PPC_LOADER_H */ + #endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ diff --git a/backends/plugins/ps2/ps2-provider.cpp b/backends/plugins/ps2/ps2-provider.cpp new file mode 100644 index 0000000000..71e715ae50 --- /dev/null +++ b/backends/plugins/ps2/ps2-provider.cpp @@ -0,0 +1,72 @@ +/* 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(__PLAYSTATION2__) + +#include "backends/plugins/ps2/ps2-provider.h" +#include "backends/plugins/elf/mips-loader.h" + +class PS2DLObject : public MIPSDLObject { +public: + PS2DLObject() : + MIPSDLObject() { + } + + virtual ~PS2DLObject() { + unload(); + } + +protected: + virtual void *allocSegment(size_t boundary, size_t size) const { + return memalign(boundary, size); + } + + virtual void freeSegment(void *segment) const { + free(segment); + } + + virtual void flushDataCache(void *, uint32) const { + FlushCache(0); + FlushCache(2); + } +}; + +class PS2Plugin : public ELFPlugin { +public: + PS2Plugin(const Common::String &filename) : + ELFPlugin(filename) { + } + + virtual DLObject *makeDLObject() { + return new PS2DLObject(); + } +}; + +Plugin *PS2PluginProvider::createPlugin(const Common::FSNode &node) const { + return new PS2Plugin(node.getPath()); +} + +#endif // defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) + diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index 00ddb4647e..8c5e8af65a 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -18,29 +18,24 @@ * 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$ + * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ds/ds-provider.h $ + * $Id: ds-provider.h 52112 2010-08-16 08:41:04Z toneman1138 $ * */ #if defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) +#ifndef BACKENDS_PLUGINS_PS2_PROVIDER_H +#define BACKENDS_PLUGINS_PS2_PROVIDER_H + #include "backends/plugins/elf/elf-provider.h" -#include "backends/plugins/elf/mips-loader.h" class PS2PluginProvider : public ELFPluginProvider { - class PS2Plugin : public ELFPlugin { - public: - PS2Plugin(const Common::String &filename) : ELFPlugin(filename) {} - - DLObject *makeDLObject() { return new MIPSDLObject(); } - }; - public: - Plugin* createPlugin(const Common::FSNode &node) const { - return new PS2Plugin(node.getPath()); - } + Plugin *createPlugin(const Common::FSNode &node) const; }; +#endif // BACKENDS_PLUGINS_PS2_PROVIDER_H + #endif // defined(DYNAMIC_MODULES) && defined(__PLAYSTATION2__) diff --git a/backends/plugins/psp/psp-provider.cpp b/backends/plugins/psp/psp-provider.cpp new file mode 100644 index 0000000000..5bf9b0cc20 --- /dev/null +++ b/backends/plugins/psp/psp-provider.cpp @@ -0,0 +1,75 @@ +/* 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(__PSP__) + +#include +#include + +#include "backends/plugins/psp/psp-provider.h" +#include "backends/plugins/elf/mips-loader.h" + +class PSPDLObject : public MIPSDLObject { +public: + PSPDLObject() : + MIPSDLObject() { + } + + virtual ~PSPDLObject() { + unload(); + } + +protected: + virtual void *allocSegment(size_t boundary, size_t size) const { + return memalign(boundary, size); + } + + virtual void freeSegment(void *segment) const { + free(segment); + } + + virtual void flushDataCache(void *ptr, uint32 len) const { + sceKernelDcacheWritebackRange(ptr, len); + sceKernelIcacheInvalidateRange(ptr, len); + } +}; + +class PSPPlugin : public ELFPlugin { +public: + PSPPlugin(const Common::String &filename) : + ELFPlugin(filename) { + } + + virtual DLObject *makeDLObject() { + return new PSPDLObject(); + } +}; + +Plugin *PSPPluginProvider::createPlugin(const Common::FSNode &node) const { + return new PSPPlugin(node.getPath()); +} + +#endif // defined(DYNAMIC_MODULES) && defined(__PSP__) + diff --git a/backends/plugins/psp/psp-provider.h b/backends/plugins/psp/psp-provider.h index 18623e448c..39e0d32caa 100644 --- a/backends/plugins/psp/psp-provider.h +++ b/backends/plugins/psp/psp-provider.h @@ -18,8 +18,8 @@ * 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$ + * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ds/ds-provider.h $ + * $Id: ds-provider.h 52112 2010-08-16 08:41:04Z toneman1138 $ * */ @@ -29,22 +29,13 @@ #define BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H #include "backends/plugins/elf/elf-provider.h" -#include "backends/plugins/elf/mips-loader.h" class PSPPluginProvider : public ELFPluginProvider { - class PSPPlugin : public ELFPlugin { - public: - PSPPlugin(const Common::String &filename) : ELFPlugin(filename) {} - - DLObject *makeDLObject() { return new MIPSDLObject(); } - }; - public: - Plugin* createPlugin(const Common::FSNode &node) const { - return new PSPPlugin(node.getPath()); - } + Plugin *createPlugin(const Common::FSNode &node) const; }; -#endif /* BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H */ +#endif // BACKENDS_PLUGINS_PSP_PROVIDER_H #endif // defined(DYNAMIC_MODULES) && defined(__PSP__) + diff --git a/backends/plugins/wii/wii-provider.cpp b/backends/plugins/wii/wii-provider.cpp new file mode 100644 index 0000000000..25f54f02de --- /dev/null +++ b/backends/plugins/wii/wii-provider.cpp @@ -0,0 +1,75 @@ +/* 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(__WII__) + +#include +#include + +#include "backends/plugins/wii/wii-provider.h" +#include "backends/plugins/elf/ppc-loader.h" + +class WiiDLObject : public PPCDLObject { +public: + WiiDLObject() : + PPCDLObject() { + } + + virtual ~WiiDLObject() { + unload(); + } + +protected: + virtual void *allocSegment(size_t boundary, size_t size) const { + return memalign(boundary, size); + } + + virtual void freeSegment(void *segment) const { + free(segment); + } + + virtual void flushDataCache(void *ptr, uint32 len) const { + DCFlushRange(ptr, len); + ICInvalidateRange(ptr, len); + } +}; + +class WiiPlugin : public ELFPlugin { +public: + WiiPlugin(const Common::String &filename) : + ELFPlugin(filename) { + } + + virtual DLObject *makeDLObject() { + return new WiiDLObject(); + } +}; + +Plugin *WiiPluginProvider::createPlugin(const Common::FSNode &node) const { + return new WiiPlugin(node.getPath()); +} + +#endif // defined(DYNAMIC_MODULES) && defined(__WII__) + diff --git a/backends/plugins/wii/wii-provider.h b/backends/plugins/wii/wii-provider.h index deb143b02a..a29f1da931 100644 --- a/backends/plugins/wii/wii-provider.h +++ b/backends/plugins/wii/wii-provider.h @@ -25,21 +25,17 @@ #if defined(DYNAMIC_MODULES) && defined(__WII__) +#ifndef BACKENDS_PLUGINS_WII_PROVIDER_H +#define BACKENDS_PLUGINS_WII_PROVIDER_H + #include "backends/plugins/elf/elf-provider.h" -#include "backends/plugins/elf/ppc-loader.h" class WiiPluginProvider : public ELFPluginProvider { - class WiiPlugin : public ELFPlugin { - public: - WiiPlugin(const Common::String &filename) : ELFPlugin(filename) {} - - DLObject *makeDLObject() { return new PPCDLObject(); } - }; - public: - Plugin* createPlugin(const Common::FSNode &node) const { - return new WiiPlugin(node.getPath()); - } + Plugin *createPlugin(const Common::FSNode &node) const; }; +#endif // BACKENDS_PLUGINS_WII_PROVIDER_H + #endif // defined(DYNAMIC_MODULES) && defined(__WII__) + -- cgit v1.2.3 From 3b2a9734d15b1ddd5955e2634639122a1d4416cb Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:52:49 +0000 Subject: PLUGINS: Type cleanup. Use our types, get rid of some casts. svn-id: r52557 --- backends/plugins/elf/arm-loader.cpp | 28 ++++---- backends/plugins/elf/arm-loader.h | 2 +- backends/plugins/elf/elf-loader.cpp | 69 +++++++++--------- backends/plugins/elf/elf-loader.h | 16 +++-- backends/plugins/elf/elf32.h | 19 ++--- backends/plugins/elf/mips-loader.cpp | 95 +++++++++++++------------ backends/plugins/elf/mips-loader.h | 4 +- backends/plugins/elf/ppc-loader.cpp | 19 +++-- backends/plugins/elf/ppc-loader.h | 2 +- backends/plugins/elf/shorts-segment-manager.cpp | 6 +- backends/plugins/elf/shorts-segment-manager.h | 24 +++++-- 11 files changed, 153 insertions(+), 131 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp index ab1129d34c..ace3b51e3c 100644 --- a/backends/plugins/elf/arm-loader.cpp +++ b/backends/plugins/elf/arm-loader.cpp @@ -38,47 +38,46 @@ * @param size Size of relocation section * @param relSegment Base address of relocated segment in memory (memory offset) */ -bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { +bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; //relocation entry // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { + if (!(rel = (Elf32_Rel *) malloc(size))) { warning("elfloader: Out of memory."); return false; } // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || - DLFile->read(rel, size) != size) { + if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; } // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); + uint32 cnt = size / sizeof(*rel); debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); - int a = 0; - unsigned int relocation = 0; + int32 a = 0; + uint32 relocation = 0; // Loop over relocation entries - for (int i = 0; i < cnt; i++) { + for (uint32 i = 0; i < cnt; i++) { // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + uint32 *target = (uint32 *) ((byte *) relSegment + rel[i].r_offset); - unsigned int origTarget = *target; //Save for debugging + uint32 origTarget = *target; //Save for debugging // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { case R_ARM_ABS32: if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset + relocation = a + Elf32_Addr(_segment); // Shift by main offset *target = relocation; @@ -115,12 +114,12 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off 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++) { + for (uint32 i = 0; i < ehdr->e_shnum; i++) { Elf32_Shdr *curShdr = &(shdr[i]); if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size - (int)curShdr->sh_link == _symtab_sect && // Check that the sh_link connects to our symbol table + int32(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 @@ -138,3 +137,4 @@ bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e } #endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ + diff --git a/backends/plugins/elf/arm-loader.h b/backends/plugins/elf/arm-loader.h index c4df671060..1d4e248a7b 100644 --- a/backends/plugins/elf/arm-loader.h +++ b/backends/plugins/elf/arm-loader.h @@ -32,7 +32,7 @@ class ARMDLObject : public DLObject { protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index e11f9fcce6..32e42daf7d 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -35,13 +35,13 @@ DLObject::DLObject() : _segment(0), _symtab(0), _strtab(0), + _segmentSize(0), + _segmentOffset(0), + _segmentVMA(0), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(0), - _dtors_end(0), - _segmentSize(0), - _segmentOffset(0), - _segmentVMA(0) { + _dtors_end(0) { } DLObject::~DLObject() { @@ -127,9 +127,9 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd return true; } -bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { +bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num) { // Read program header - if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) || + if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr) * num, SEEK_SET) || DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { warning("elfloader: Program header load failed."); return false; @@ -148,13 +148,13 @@ bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr } bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, 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 + uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); - if (!(_segment = (char *) allocSegment(phdr->p_align, phdr->p_memsz + extra))) { + _segment = (byte *) allocSegment(phdr->p_align, phdr->p_memsz + extra); + + if (!_segment) { warning("elfloader: Out of memory."); return false; } @@ -162,21 +162,20 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into - baseAddress = (char *)_segment; _segmentSize = phdr->p_memsz + extra; _segmentVMA = phdr->p_vaddr; // Set bss segment to 0 if necessary (assumes bss is at the end) if (phdr->p_memsz > phdr->p_filesz) { - debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); - memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + debug(2, "elfloader: Setting %p to %p to 0 for bss", _segment + phdr->p_filesz, _segment + phdr->p_memsz); + memset(_segment + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { + DLFile->read(_segment, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; } @@ -190,7 +189,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El Elf32_Shdr *shdr = 0; // Allocate memory for section headers - if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { + if (!(shdr = (Elf32_Shdr *) malloc(ehdr->e_shnum * sizeof(*shdr)))) { warning("elfloader: Out of memory."); return 0; } @@ -208,7 +207,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, 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++) { + for (uint32 i = 0; i < ehdr->e_shnum; i++) { if (shdr[i].sh_type == SHT_SYMTAB && shdr[i].sh_entsize == sizeof(Elf32_Sym) && shdr[i].sh_link < ehdr->e_shnum && @@ -227,7 +226,7 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh debug(2, "elfloader: Symbol section at section %d, size %x", _symtab_sect, shdr[_symtab_sect].sh_size); // Allocate memory for symbol table - if (!(_symtab = malloc(shdr[_symtab_sect].sh_size))) { + if (!(_symtab = (Elf32_Sym *) malloc(shdr[_symtab_sect].sh_size))) { warning("elfloader: Out of memory."); return -1; } @@ -248,10 +247,10 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh } bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr) { - int string_sect = shdr[_symtab_sect].sh_link; + uint32 string_sect = shdr[_symtab_sect].sh_link; // Allocate memory for string table - if (!(_strtab = (char *)malloc(shdr[string_sect].sh_size))) { + if (!(_strtab = (char *) malloc(shdr[string_sect].sh_size))) { warning("elfloader: Out of memory."); return false; } @@ -269,13 +268,14 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s void DLObject::relocateSymbols(ptrdiff_t offset) { // Loop over symbols, add relocation offset - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) { + Elf32_Sym *s = _symtab; + + for (uint32 c = _symbol_cnt; c--; s++) { // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { - s->st_value += offset; - if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) - warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); + s->st_value += offset; + if (s->st_value < Elf32_Addr(_segment) || s->st_value > Elf32_Addr(_segment) + _segmentSize) + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } } @@ -286,11 +286,10 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { Elf32_Shdr *shdr; bool ret = true; - if (readElfHeader(DLFile, &ehdr) == false) { + if (readElfHeader(DLFile, &ehdr) == false) return false; - } - for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments + for (uint32 i = 0; i < ehdr.e_phnum; i++) { //Load our segments debug(2, "elfloader: Loading segment %d", i); if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) @@ -300,13 +299,13 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { return false; } - if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == 0) + if (!(shdr = loadSectionHeaders(DLFile, &ehdr))) ret = false; if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) ret = false; - if (ret && (loadStringTable(DLFile, shdr) == false)) + if (ret && !loadStringTable(DLFile, shdr)) ret = false; if (ret) { @@ -315,7 +314,7 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { relocateSymbols(_segmentOffset); } - if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) + if (ret && !relocateRels(DLFile, &ehdr, shdr)) ret = false; free(shdr); @@ -373,6 +372,7 @@ bool DLObject::close() { if (_dtors_start && _dtors_end) for (void (**f)(void) = (void (**)(void))_dtors_start; f != _dtors_end; f++) (**f)(); + _dtors_start = _dtors_end = 0; unload(); return true; @@ -386,15 +386,16 @@ void *DLObject::symbol(const char *name) { return 0; } - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) + Elf32_Sym *s = _symtab; + + for (uint32 c = _symbol_cnt; c--; s++) // We can only import symbols that are global or weak in the plugin if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && !strcmp(name, _strtab + s->st_name)) { // We found the symbol - debug(2, "elfloader: => %p", (void*)s->st_value); - return (void*)s->st_value; + debug(2, "elfloader: => 0x%08x", s->st_value); + return (void*) s->st_value; } // We didn't find the symbol diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h index 7c1d0830f3..9b80a0236f 100644 --- a/backends/plugins/elf/elf-loader.h +++ b/backends/plugins/elf/elf-loader.h @@ -44,21 +44,23 @@ */ class DLObject { protected: - void *_segment, *_symtab; + byte *_segment; + Elf32_Sym *_symtab; char *_strtab; - int _symbol_cnt; - int _symtab_sect; - void *_dtors_start, *_dtors_end; uint32 _segmentSize; ptrdiff_t _segmentOffset; uint32 _segmentVMA; + uint32 _symbol_cnt; + int32 _symtab_sect; + void *_dtors_start, *_dtors_end; + virtual void unload(); bool load(Common::SeekableReadStream* DLFile); bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num); virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); @@ -66,13 +68,14 @@ protected: virtual void relocateSymbols(ptrdiff_t offset); // architecture specific - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) = 0; virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; // platform specific virtual void *allocSegment(size_t boundary, size_t size) const = 0; virtual void freeSegment(void *segment) const = 0; virtual void flushDataCache(void *ptr, uint32 len) const = 0; + public: DLObject(); virtual ~DLObject(); @@ -86,3 +89,4 @@ public: #endif /* BACKENDS_PLUGINS_ELF_LOADER_H */ #endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ + diff --git a/backends/plugins/elf/elf32.h b/backends/plugins/elf/elf32.h index c83093fed7..4586d8dc4c 100644 --- a/backends/plugins/elf/elf32.h +++ b/backends/plugins/elf/elf32.h @@ -26,15 +26,17 @@ #ifndef BACKENDS_ELF_H #define BACKENDS_ELF_H +#include "common/scummsys.h" + /** * ELF stuff: * The contents of this file were gathered mainly from the SYSTEM V APPLICATION BINARY INTERFACE. * Processor-specific things were garnered from processor-specific supplements to the abi. */ -typedef unsigned short Elf32_Half, Elf32_Section; -typedef unsigned int Elf32_Word, Elf32_Addr, Elf32_Off; -typedef signed int Elf32_Sword; +typedef uint16 Elf32_Half, Elf32_Section; +typedef uint32 Elf32_Word, Elf32_Addr, Elf32_Off; +typedef int32 Elf32_Sword; typedef Elf32_Half Elf32_Versym; #define EI_NIDENT (16) @@ -44,7 +46,7 @@ typedef Elf32_Half Elf32_Versym; // ELF header (contains info about the file) typedef struct { - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + byte 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 */ @@ -159,8 +161,8 @@ 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 */ + byte st_info; /* Symbol type and binding */ + byte st_other; /* Symbol visibility */ Elf32_Section st_shndx; /* Section index */ } Elf32_Sym; @@ -203,7 +205,7 @@ typedef struct } Elf32_Rela; // Access macros for the relocation info -#define REL_TYPE(x) ((unsigned char) (x)) /* Extract relocation type */ +#define REL_TYPE(x) ((byte) (x)) /* Extract relocation type */ #define REL_INDEX(x) ((x)>>8) /* Extract relocation index into symbol table */ //MIPS relocation types @@ -244,9 +246,10 @@ typedef struct // Mock function to get value of global pointer for MIPS #define getGP() ({ \ - unsigned int __valgp; \ + uint32 __valgp; \ __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ __valgp; \ }) #endif /* BACKENDS_ELF_H */ + diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 027ff34698..bf6bb08319 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -37,51 +37,50 @@ * @param size Size of relocation section * @param relSegment Base address of relocated segment in memory (memory offset) */ -bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { +bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; // relocation entry // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { + if (!(rel = (Elf32_Rel *) malloc(size))) { warning("elfloader: Out of memory."); return false; } // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || - DLFile->read(rel, size) != size) { + if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; } // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); + uint32 cnt = size / sizeof(*rel); debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); - bool seenHi16 = false; // For treating HI/LO16 commands - int firstHi16 = -1; // Mark the point of the first hi16 seen - Elf32_Addr ahl = 0; // Calculated addend - int a = 0; // Addend: taken from the target + bool seenHi16 = false; // For treating HI/LO16 commands + int32 firstHi16 = -1; // Mark the point of the first hi16 seen + Elf32_Addr ahl = 0; // Calculated addend + int32 a = 0; // Addend: taken from the target - unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives - unsigned int relocation = 0; - int debugRelocs[10] = {0}; // For debugging - int extendedHi16 = 0; // Count extended hi16 treatments + uint32 *lastTarget = 0; // For processing hi16 when lo16 arrives + uint32 relocation = 0; + uint debugRelocs[10] = { 0 }; // For debugging + uint extendedHi16 = 0; // Count extended hi16 treatments Elf32_Addr lastHiSymVal = 0; bool hi16InShorts = false; #define DEBUG_NUM 2 // Loop over relocation entries - for (int i = 0; i < cnt; i++) { + for (uint32 i = 0; i < cnt; i++) { // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + uint32 *target = (uint32 *) ((byte *)relSegment + rel[i].r_offset); - unsigned int origTarget = *target; // Save for debugging + uint32 origTarget = *target; // Save for debugging // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { @@ -93,7 +92,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up lastHiSymVal = sym->st_value; - hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments + hi16InShorts = ShortsMan.inGeneralSegment((char *) sym->st_value); // Fix for problem with switching btw segments if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number debug(8, "elfloader: R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x", i, rel[i].r_offset, ahl, *target); @@ -111,7 +110,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section // and will be screened out above - bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); + bool lo16InShorts = ShortsMan.inGeneralSegment((char *) sym->st_value); // Correct the bug by getting the proper value in ahl (taken from the current symbol) if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { @@ -128,13 +127,14 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (lo16InShorts) relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset else // It's in the regular segment - relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment + relocation = ahl + Elf32_Addr(_segment); // Add in the new offset for the segment if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now - for (int j = firstHi16; j < i; j++) { - if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s + for (uint32 j = firstHi16; j < i; j++) { + if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) + continue; // Skip over non-Hi16s - lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target + lastTarget = (uint32 *) ((char *) relSegment + rel[j].r_offset); // get hi16 target *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation if (relocation & 0x8000) @@ -161,7 +161,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment a = *target & 0x03ffffff; // Get 26 bits' worth of the addend a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset + relocation = ((a << 2) + Elf32_Addr(_segment)) >> 2; // a already points to the target. Subtract our offset *target &= 0xfc000000; // Clean lower 26 target bits *target |= (relocation & 0x03ffffff); @@ -177,7 +177,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of case R_MIPS_GPREL16: // GP Relative addressing if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section - ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole + ShortsMan.inGeneralSegment((char *) sym->st_value)) { // Only relocate things in the plugin hole a = *target & 0xffff; // Get 16 bits' worth of the addend a = (a << 16) >> 16; // Sign extend it @@ -197,10 +197,10 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. a = *target; // Get full 32 bits of addend - if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment + if (ShortsMan.inGeneralSegment((char *) sym->st_value)) // Check if we're in the shorts segment relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset else // We're in the main section - relocation = a + (Elf32_Addr)_segment; // Shift by main offset + relocation = a + Elf32_Addr(_segment); // Shift by main offset *target = relocation; if (debugRelocs[6]++ < DEBUG_NUM) @@ -223,21 +223,21 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of bool MIPSDLObject::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++) { + for (uint32 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_Rel) && // Check for proper relocation size - (int)curShdr->sh_link == _symtab_sect && // Check that the sh_link connects to our symbol table + int32(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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment + if (!ShortsMan.inGeneralSegment((char *) shdr[curShdr->sh_info].sh_addr)) { // regular segment if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) return false; } else { // In Shorts segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (byte *) _shortsSegment->getOffset())) return false; } } @@ -247,23 +247,20 @@ bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr * } void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { - int mainCount = 0; - int shortsCount= 0; - // Loop over symbols, add relocation offset - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) { + Elf32_Sym *s = _symtab; + + for (uint32 c = _symbol_cnt; c--; s++) { // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { - if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { - mainCount++; + if (!ShortsMan.inGeneralSegment((char *) s->st_value)) { s->st_value += offset; - if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) + + if (s->st_value < Elf32_Addr(_segment) || s->st_value > Elf32_Addr(_segment) + _segmentSize) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } else { // shorts section - shortsCount++; s->st_value += _shortsSegment->getOffset(); - if (!_shortsSegment->inSegment((char *)s->st_value)) + if (!_shortsSegment->inSegment((char *) s->st_value)) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } @@ -271,30 +268,33 @@ void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { } bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { - char *baseAddress = 0; + byte *baseAddress = 0; // We need to take account of non-allocated segment for shorts if (phdr->p_flags & PF_X) { // This is a relocated segment // Attempt to allocate memory for segment - int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here + uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { + _segment = (byte *) allocSegment(phdr->p_align, phdr->p_memsz + extra); + + if (!_segment) { warning("elfloader: Out of memory."); return false; } + debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into - baseAddress = (char *)_segment + phdr->p_vaddr; + baseAddress = _segment + phdr->p_vaddr; _segmentSize = phdr->p_memsz + extra; } else { // This is a shorts section. - _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); + _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *) phdr->p_vaddr); - baseAddress = _shortsSegment->getStart(); + baseAddress = (byte *) _shortsSegment->getStart(); debug(2, "elfloader: Shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x", _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); } @@ -328,3 +328,4 @@ void MIPSDLObject::unload() { } #endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ + diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h index 28b8c7f636..d910e07eda 100644 --- a/backends/plugins/elf/mips-loader.h +++ b/backends/plugins/elf/mips-loader.h @@ -35,9 +35,9 @@ class MIPSDLObject : public DLObject { protected: ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - unsigned int _gpVal; // Value of Global Pointer + uint32 _gpVal; // Value of Global Pointer - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); virtual void relocateSymbols(Elf32_Addr offset); virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); diff --git a/backends/plugins/elf/ppc-loader.cpp b/backends/plugins/elf/ppc-loader.cpp index 21a9a6c8a0..dff8143e43 100644 --- a/backends/plugins/elf/ppc-loader.cpp +++ b/backends/plugins/elf/ppc-loader.cpp @@ -30,7 +30,7 @@ #include "common/debug.h" -bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { +bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rela *rel = NULL; if (!(rel = (Elf32_Rela *)malloc(size))) { @@ -38,26 +38,25 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off return false; } - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != size) { + if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; } - int cnt = size / sizeof(*rel); + uint32 cnt = size / sizeof(*rel); debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); uint32 *src; uint32 value; - for (int i = 0; i < cnt; i++) { + for (uint32 i = 0; i < cnt; i++) { // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - src = (uint32 *)((char *)relSegment + rel[i].r_offset - _segmentVMA); + src = (uint32 *) ((char *) relSegment + rel[i].r_offset - _segmentVMA); value = sym->st_value + rel[i].r_addend; //debug(8, "elfloader: i=%05d %p +0x%04x: (0x%08x) 0x%08x ", i, src, rel[i].r_addend, sym->st_value, *src); @@ -99,12 +98,12 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off } bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { - for (int i = 0; i < ehdr->e_shnum; i++) { + for (uint32 i = 0; i < ehdr->e_shnum; i++) { Elf32_Shdr *curShdr = &(shdr[i]); if ((curShdr->sh_type == SHT_REL) && curShdr->sh_entsize == sizeof(Elf32_Rel) && - (int)curShdr->sh_link == _symtab_sect && + int32(curShdr->sh_link) == _symtab_sect && curShdr->sh_info < ehdr->e_shnum && (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { warning("elfloader: REL entries not supported!\n"); @@ -113,7 +112,7 @@ bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e if ((curShdr->sh_type == SHT_RELA) && curShdr->sh_entsize == sizeof(Elf32_Rela) && - (int)curShdr->sh_link == _symtab_sect && + int32(curShdr->sh_link) == _symtab_sect && curShdr->sh_info < ehdr->e_shnum && (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h index 574ba104e6..3424586a90 100644 --- a/backends/plugins/elf/ppc-loader.h +++ b/backends/plugins/elf/ppc-loader.h @@ -32,7 +32,7 @@ class PPCDLObject : public DLObject { protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: diff --git a/backends/plugins/elf/shorts-segment-manager.cpp b/backends/plugins/elf/shorts-segment-manager.cpp index 612ef19bbe..d55ea08c73 100644 --- a/backends/plugins/elf/shorts-segment-manager.cpp +++ b/backends/plugins/elf/shorts-segment-manager.cpp @@ -40,7 +40,7 @@ ShortSegmentManager::ShortSegmentManager() { _shortsEnd = &__plugin_hole_end; //and ends at the end of that hole. } -ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { +ShortSegmentManager::Segment *ShortSegmentManager::newSegment(uint32 size, char *origAddr) { char *lastAddress = origAddr; Common::List::iterator i; @@ -48,7 +48,8 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or for (i = _list.begin(); i != _list.end(); ++i) { char *currAddress = (*i)->getStart(); - if ((int)(currAddress - lastAddress) >= size) break; + if (uint32(currAddress) - uint32(lastAddress) >= size) + break; lastAddress = (*i)->getEnd(); } @@ -82,3 +83,4 @@ void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { } #endif /* DYNAMIC_MODULES && MIPS_TARGET */ + diff --git a/backends/plugins/elf/shorts-segment-manager.h b/backends/plugins/elf/shorts-segment-manager.h index b3650562ed..c7cdcfe1f7 100644 --- a/backends/plugins/elf/shorts-segment-manager.h +++ b/backends/plugins/elf/shorts-segment-manager.h @@ -62,33 +62,44 @@ public: // Returns whether or not an absolute address is in the GP-relative section. bool inGeneralSegment(char *addr) { - return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); + return (addr >= _shortsStart && addr < _shortsEnd); } class Segment { private: friend class ShortSegmentManager; - Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} - ~Segment() {} + Segment(char *start, uint32 size, char *origAddr) : + _startAddress(start), + _size(size), + _origAddress(origAddr) { + } + + virtual ~Segment() { + } + char *_startAddress; // Start of shorts segment in memory - int _size; // Size of shorts segment + uint32 _size; // Size of shorts segment char *_origAddress; // Original address this segment was supposed to be at + public: char *getStart() { return _startAddress; } + char *getEnd() { return (_startAddress + _size); } + Elf32_Addr getOffset() { return (Elf32_Addr)(_startAddress - _origAddress); } + bool inSegment(char *addr) { - return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); + return (addr >= _startAddress && addr <= _startAddress + _size); } }; - Segment *newSegment(int size, char *origAddr); + Segment *newSegment(uint32 size, char *origAddr); void deleteSegment(Segment *); private: @@ -101,3 +112,4 @@ private: #endif /* SHORTS_SEGMENT_MANAGER_H */ #endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ + -- cgit v1.2.3 From 402c71860f0a6f254604b1fbd1a763d470c859c0 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:53:15 +0000 Subject: PLUGINS: Make the file stream a member of DLObject. No point in passing it to functions all over the place. Release the stream when it's not required anymore. svn-id: r52558 --- backends/plugins/elf/arm-loader.cpp | 9 ++--- backends/plugins/elf/arm-loader.h | 4 +- backends/plugins/elf/elf-loader.cpp | 72 +++++++++++++++++++++--------------- backends/plugins/elf/elf-loader.h | 22 ++++++----- backends/plugins/elf/mips-loader.cpp | 17 ++++----- backends/plugins/elf/mips-loader.h | 6 +-- backends/plugins/elf/ppc-loader.cpp | 26 ++++++------- backends/plugins/elf/ppc-loader.h | 4 +- 8 files changed, 86 insertions(+), 74 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp index ace3b51e3c..7534cb1d44 100644 --- a/backends/plugins/elf/arm-loader.cpp +++ b/backends/plugins/elf/arm-loader.cpp @@ -33,12 +33,11 @@ /** * Follow the instruction of a relocation section. * - * @param DLFile SeekableReadStream of File * @param fileOffset Offset into the File * @param size Size of relocation section * @param relSegment Base address of relocated segment in memory (memory offset) */ -bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { +bool ARMDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; //relocation entry // Allocate memory for relocation table @@ -48,7 +47,7 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, } // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { + if (!_file->seek(offset, SEEK_SET) || _file->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; @@ -112,7 +111,7 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, return true; } -bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +bool ARMDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Loop over sections, finding relocation sections for (uint32 i = 0; i < ehdr->e_shnum; i++) { Elf32_Shdr *curShdr = &(shdr[i]); @@ -128,7 +127,7 @@ bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e return false; } - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) + if (!relocate(curShdr->sh_offset, curShdr->sh_size, _segment)) return false; } } diff --git a/backends/plugins/elf/arm-loader.h b/backends/plugins/elf/arm-loader.h index 1d4e248a7b..3a3894d041 100644 --- a/backends/plugins/elf/arm-loader.h +++ b/backends/plugins/elf/arm-loader.h @@ -32,8 +32,8 @@ class ARMDLObject : public DLObject { protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment); + virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: ARMDLObject() : DLObject() {} diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index 32e42daf7d..0503f81c42 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -66,9 +66,11 @@ void DLObject::unload() { _segmentVMA = 0; } -bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { +bool DLObject::readElfHeader(Elf32_Ehdr *ehdr) { + assert(_file); + // Start reading the elf header. Check for errors and magic - if (DLFile->read(ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || + if (_file->read(ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { warning("elfloader: No ELF file."); return false; @@ -127,10 +129,12 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd return true; } -bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num) { +bool DLObject::readProgramHeaders(Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num) { + assert(_file); + // Read program header - if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr) * num, SEEK_SET) || - DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { + if (!_file->seek(ehdr->e_phoff + sizeof(*phdr) * num, SEEK_SET) || + _file->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { warning("elfloader: Program header load failed."); return false; } @@ -147,7 +151,7 @@ bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr return true; } -bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { +bool DLObject::loadSegment(Elf32_Phdr *phdr) { // Attempt to allocate memory for segment uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); @@ -174,8 +178,8 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory - if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(_segment, phdr->p_filesz) != phdr->p_filesz) { + if (!_file->seek(phdr->p_offset, SEEK_SET) || + _file->read(_segment, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; } @@ -185,7 +189,9 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) return true; } -Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr) { +Elf32_Shdr * DLObject::loadSectionHeaders(Elf32_Ehdr *ehdr) { + assert(_file); + Elf32_Shdr *shdr = 0; // Allocate memory for section headers @@ -195,8 +201,8 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El } // Read from file into section headers - if (!DLFile->seek(ehdr->e_shoff, SEEK_SET) || - DLFile->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != + if (!_file->seek(ehdr->e_shoff, SEEK_SET) || + _file->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != ehdr->e_shnum * sizeof(*shdr)) { warning("elfloader: Section headers load failed."); return 0; @@ -205,7 +211,9 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El return shdr; } -int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +int DLObject::loadSymbolTable(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { + assert(_file); + // Loop over sections, looking for symbol table linked to a string table for (uint32 i = 0; i < ehdr->e_shnum; i++) { if (shdr[i].sh_type == SHT_SYMTAB && @@ -232,8 +240,8 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh } // Read symbol table into memory - if (!DLFile->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) || - DLFile->read(_symtab, shdr[_symtab_sect].sh_size) != + if (!_file->seek(shdr[_symtab_sect].sh_offset, SEEK_SET) || + _file->read(_symtab, shdr[_symtab_sect].sh_size) != shdr[_symtab_sect].sh_size) { warning("elfloader: Symbol table load failed."); return -1; @@ -246,7 +254,9 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh return _symtab_sect; } -bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr) { +bool DLObject::loadStringTable(Elf32_Shdr *shdr) { + assert(_file); + uint32 string_sect = shdr[_symtab_sect].sh_link; // Allocate memory for string table @@ -256,8 +266,8 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s } // Read string table into memory - if (!DLFile->seek(shdr[string_sect].sh_offset, SEEK_SET) || - DLFile->read(_strtab, shdr[string_sect].sh_size) != + if (!_file->seek(shdr[string_sect].sh_offset, SEEK_SET) || + _file->read(_strtab, shdr[string_sect].sh_size) != shdr[string_sect].sh_size) { warning("elfloader: Symbol table strings load failed."); return false; @@ -280,32 +290,32 @@ void DLObject::relocateSymbols(ptrdiff_t offset) { } } -bool DLObject::load(Common::SeekableReadStream* DLFile) { +bool DLObject::load() { Elf32_Ehdr ehdr; Elf32_Phdr phdr; Elf32_Shdr *shdr; bool ret = true; - if (readElfHeader(DLFile, &ehdr) == false) + if (readElfHeader(&ehdr) == false) return false; for (uint32 i = 0; i < ehdr.e_phnum; i++) { //Load our segments debug(2, "elfloader: Loading segment %d", i); - if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) + if (readProgramHeaders(&ehdr, &phdr, i) == false) return false; - if (!loadSegment(DLFile, &phdr)) + if (!loadSegment(&phdr)) return false; } - if (!(shdr = loadSectionHeaders(DLFile, &ehdr))) + if (!(shdr = loadSectionHeaders(&ehdr))) ret = false; - if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) + if (ret && ((_symtab_sect = loadSymbolTable(&ehdr, shdr)) < 0)) ret = false; - if (ret && !loadStringTable(DLFile, shdr)) + if (ret && !loadStringTable(shdr)) ret = false; if (ret) { @@ -314,7 +324,7 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { relocateSymbols(_segmentOffset); } - if (ret && !relocateRels(DLFile, &ehdr, shdr)) + if (ret && !relocateRels(&ehdr, shdr)) ret = false; free(shdr); @@ -323,28 +333,30 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { } bool DLObject::open(const char *path) { - Common::SeekableReadStream* DLFile; void *ctors_start, *ctors_end; debug(2, "elfloader: open(\"%s\")", path); - Common::FSNode file(path); + _file = Common::FSNode(path).createReadStream(); - if (!(DLFile = file.createReadStream())) { - warning("elfloader: %s not found.", path); + if (!_file) { + warning("elfloader: File %s not found.", path); return false; } debug(2, "elfloader: %s found!", path); /*Try to load and relocate*/ - if (!load(DLFile)) { + if (!load()) { unload(); return false; } debug(2, "elfloader: Loaded!"); + delete _file; + _file = 0; + flushDataCache(_segment, _segmentSize); ctors_start = symbol("___plugin_ctors"); diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h index 9b80a0236f..ae226fc2b6 100644 --- a/backends/plugins/elf/elf-loader.h +++ b/backends/plugins/elf/elf-loader.h @@ -44,6 +44,8 @@ */ class DLObject { protected: + Common::SeekableReadStream* _file; + byte *_segment; Elf32_Sym *_symtab; char *_strtab; @@ -57,19 +59,19 @@ protected: void *_dtors_start, *_dtors_end; virtual void unload(); - bool load(Common::SeekableReadStream* DLFile); - - bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num); - virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); - Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - bool loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr); + bool load(); + + bool readElfHeader(Elf32_Ehdr *ehdr); + bool readProgramHeaders(Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num); + virtual bool loadSegment(Elf32_Phdr *phdr); + Elf32_Shdr *loadSectionHeaders(Elf32_Ehdr *ehdr); + int loadSymbolTable(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + bool loadStringTable(Elf32_Shdr *shdr); virtual void relocateSymbols(ptrdiff_t offset); // architecture specific - virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) = 0; - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; + virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) = 0; + virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; // platform specific virtual void *allocSegment(size_t boundary, size_t size) const = 0; diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index bf6bb08319..9d5ffe7ebe 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -32,12 +32,11 @@ /** * Follow the instruction of a relocation section. * - * @param DLFile SeekableReadStream of File * @param fileOffset Offset into the File * @param size Size of relocation section * @param relSegment Base address of relocated segment in memory (memory offset) */ -bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { +bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; // relocation entry // Allocate memory for relocation table @@ -47,7 +46,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset } // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { + if (!_file->seek(offset, SEEK_SET) || _file->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; @@ -221,7 +220,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset return true; } -bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +bool MIPSDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Loop over sections, finding relocation sections for (uint32 i = 0; i < ehdr->e_shnum; i++) { @@ -234,10 +233,10 @@ bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr * 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 (!ShortsMan.inGeneralSegment((char *) shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) + if (!relocate(curShdr->sh_offset, curShdr->sh_size, _segment)) return false; } else { // In Shorts segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (byte *) _shortsSegment->getOffset())) + if (!relocate(curShdr->sh_offset, curShdr->sh_size, (byte *) _shortsSegment->getOffset())) return false; } } @@ -267,7 +266,7 @@ void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { } } -bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { +bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { byte *baseAddress = 0; // We need to take account of non-allocated segment for shorts @@ -308,8 +307,8 @@ bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *p debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory - if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { + if (!_file->seek(phdr->p_offset, SEEK_SET) || + _file->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; } diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h index d910e07eda..bd90e968d7 100644 --- a/backends/plugins/elf/mips-loader.h +++ b/backends/plugins/elf/mips-loader.h @@ -37,10 +37,10 @@ protected: ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges uint32 _gpVal; // Value of Global Pointer - virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment); + virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); virtual void relocateSymbols(Elf32_Addr offset); - virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); + virtual bool loadSegment(Elf32_Phdr *phdr); virtual void unload(); public: diff --git a/backends/plugins/elf/ppc-loader.cpp b/backends/plugins/elf/ppc-loader.cpp index dff8143e43..5029bfe57e 100644 --- a/backends/plugins/elf/ppc-loader.cpp +++ b/backends/plugins/elf/ppc-loader.cpp @@ -30,7 +30,7 @@ #include "common/debug.h" -bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { +bool PPCDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rela *rel = NULL; if (!(rel = (Elf32_Rela *)malloc(size))) { @@ -38,7 +38,7 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, return false; } - if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { + if (!_file->seek(offset, SEEK_SET) || _file->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; @@ -46,7 +46,7 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, uint32 cnt = size / sizeof(*rel); - debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); + debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); uint32 *src; uint32 value; @@ -64,30 +64,30 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, switch (REL_TYPE(rel[i].r_info)) { case R_PPC_ADDR32: *src = value; - debug(8, "elfloader: R_PPC_ADDR32 -> 0x%08x\n", *src); + debug(8, "elfloader: R_PPC_ADDR32 -> 0x%08x", *src); break; case R_PPC_ADDR16_LO: *((uint16 *) src) = value; - debug(8, "elfloader: R_PPC_ADDR16_LO -> 0x%08x\n", *src); + debug(8, "elfloader: R_PPC_ADDR16_LO -> 0x%08x", *src); break; case R_PPC_ADDR16_HI: *(uint16 *) src = value >> 16; - debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); + debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x", *src); break; case R_PPC_ADDR16_HA: *(uint16 *) src = (value + 0x8000) >> 16; - debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x\n", *src); + debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x", *src); break; case R_PPC_REL24: *src = (*src & ~0x03fffffc) | ((value - (uint32) src) & 0x03fffffc); - debug(8, "elfloader: R_PPC_REL24 -> 0x%08x\n", *src); + debug(8, "elfloader: R_PPC_REL24 -> 0x%08x", *src); break; case R_PPC_REL32: *src = value - (uint32) src; - debug(8, "elfloader: R_PPC_REL32 -> 0x%08x\n", *src); + debug(8, "elfloader: R_PPC_REL32 -> 0x%08x", *src); break; default: - warning("elfloader: Unknown relocation type %d\n", REL_TYPE(rel[i].r_info)); + warning("elfloader: Unknown relocation type %d", REL_TYPE(rel[i].r_info)); free(rel); return false; } @@ -97,7 +97,7 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, return true; } -bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { +bool PPCDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { for (uint32 i = 0; i < ehdr->e_shnum; i++) { Elf32_Shdr *curShdr = &(shdr[i]); @@ -106,7 +106,7 @@ bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e int32(curShdr->sh_link) == _symtab_sect && curShdr->sh_info < ehdr->e_shnum && (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { - warning("elfloader: REL entries not supported!\n"); + warning("elfloader: REL entries not supported!"); return false; } @@ -115,7 +115,7 @@ bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e int32(curShdr->sh_link) == _symtab_sect && curShdr->sh_info < ehdr->e_shnum && (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) + if (!relocate(curShdr->sh_offset, curShdr->sh_size, _segment)) return false; } } diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h index 3424586a90..1bda5874ec 100644 --- a/backends/plugins/elf/ppc-loader.h +++ b/backends/plugins/elf/ppc-loader.h @@ -32,8 +32,8 @@ class PPCDLObject : public DLObject { protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); - virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); + virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment); + virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: PPCDLObject() : DLObject() {} -- cgit v1.2.3 From 8889f4c5ad8b0a2bde94e1146a9fdb087059dfcf Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 15:47:04 +0000 Subject: PLUGINS: Set svn:keywords property on all new files. svn-id: r52566 --- backends/plugins/ds/ds-provider.h | 4 ++-- backends/plugins/elf/ppc-loader.cpp | 4 ++-- backends/plugins/elf/ppc-loader.h | 4 ++-- backends/plugins/ps2/ps2-provider.h | 4 ++-- backends/plugins/wii/wii-provider.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'backends') diff --git a/backends/plugins/ds/ds-provider.h b/backends/plugins/ds/ds-provider.h index b7f7aaa746..dcb93c085f 100644 --- a/backends/plugins/ds/ds-provider.h +++ b/backends/plugins/ds/ds-provider.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ds/ds-provider.h $ - * $Id: ds-provider.h 52112 2010-08-16 08:41:04Z toneman1138 $ + * $URL$ + * $Id$ * */ diff --git a/backends/plugins/elf/ppc-loader.cpp b/backends/plugins/elf/ppc-loader.cpp index 5029bfe57e..1cd995936b 100644 --- a/backends/plugins/elf/ppc-loader.cpp +++ b/backends/plugins/elf/ppc-loader.cpp @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.cpp $ - * $Id: arm-loader.cpp 52058 2010-08-13 05:58:11Z toneman1138 $ + * $URL$ + * $Id$ * */ diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h index 1bda5874ec..37a3549c6c 100644 --- a/backends/plugins/elf/ppc-loader.h +++ b/backends/plugins/elf/ppc-loader.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/arm-loader.h $ - * $Id: arm-loader.h 52053 2010-08-13 02:58:52Z toneman1138 $ + * $URL$ + * $Id$ * */ diff --git a/backends/plugins/ps2/ps2-provider.h b/backends/plugins/ps2/ps2-provider.h index 8c5e8af65a..3d4b4b0128 100644 --- a/backends/plugins/ps2/ps2-provider.h +++ b/backends/plugins/ps2/ps2-provider.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ds/ds-provider.h $ - * $Id: ds-provider.h 52112 2010-08-16 08:41:04Z toneman1138 $ + * $URL$ + * $Id$ * */ diff --git a/backends/plugins/wii/wii-provider.h b/backends/plugins/wii/wii-provider.h index a29f1da931..4ec771490d 100644 --- a/backends/plugins/wii/wii-provider.h +++ b/backends/plugins/wii/wii-provider.h @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2010-plugins/backends/plugins/ds/ds-provider.h $ - * $Id: ds-provider.h 52112 2010-08-16 08:41:04Z toneman1138 $ + * $URL$ + * $Id$ * */ -- cgit v1.2.3 From 284b23092b8f6215d88b31af7ba7f67a58c365cc Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 15:48:22 +0000 Subject: SAVES: Revert whitespace changes to minimize the diff to trunk. svn-id: r52567 --- backends/saves/default/default-saves.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp index 55aa469309..1ab898d2d6 100644 --- a/backends/saves/default/default-saves.cpp +++ b/backends/saves/default/default-saves.cpp @@ -131,11 +131,11 @@ bool DefaultSaveFileManager::removeSavefile(const Common::String &filename) { // There is a nicely portable workaround, too: Make this method overloadable. if (remove(file.getPath().c_str()) != 0) { #ifndef _WIN32_WCE - if (errno == EACCES) + if (errno == EACCES) setError(Common::kWritePermissionDenied, "Search or write permission denied: "+file.getName()); if (errno == ENOENT) - setError(Common::kPathDoesNotExist, "removeSavefile: '"+file.getName()+"' does not exist or path is invalid"); + setError(Common::kPathDoesNotExist, "removeSavefile: '"+file.getName()+"' does not exist or path is invalid"); #endif return false; } else { -- cgit v1.2.3 From d8b85ffcb8a10b1e81a18d3e37a07d9d57d502ad Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 21:58:45 +0000 Subject: PLUGINS: Formatting. Misformatted casts in an earier commit, oops. svn-id: r52572 --- backends/plugins/ds/plugin.ld | 3 +- backends/plugins/elf/arm-loader.cpp | 6 +- backends/plugins/elf/arm-loader.h | 4 +- backends/plugins/elf/elf-loader.cpp | 20 +-- backends/plugins/elf/elf-loader.h | 2 +- backends/plugins/elf/elf-provider.cpp | 10 +- backends/plugins/elf/elf-provider.h | 8 +- backends/plugins/elf/elf32.h | 173 ++++++++++++------------ backends/plugins/elf/mips-loader.cpp | 99 ++++++++------ backends/plugins/elf/mips-loader.h | 7 +- backends/plugins/elf/ppc-loader.cpp | 12 +- backends/plugins/elf/ppc-loader.h | 4 +- backends/plugins/elf/shorts-segment-manager.cpp | 4 +- backends/plugins/ps2/plugin.ld | 2 +- backends/plugins/psp/plugin.ld | 7 +- 15 files changed, 192 insertions(+), 169 deletions(-) (limited to 'backends') diff --git a/backends/plugins/ds/plugin.ld b/backends/plugins/ds/plugin.ld index 2b2bca9745..04035b0169 100644 --- a/backends/plugins/ds/plugin.ld +++ b/backends/plugins/ds/plugin.ld @@ -1,5 +1,4 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", - "elf32-littlearm") +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) /* PHDRS specifies ELF Program Headers (or segments) to the plugin linker */ diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp index 7534cb1d44..6aac5b5e78 100644 --- a/backends/plugins/elf/arm-loader.cpp +++ b/backends/plugins/elf/arm-loader.cpp @@ -41,7 +41,7 @@ bool ARMDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) Elf32_Rel *rel = 0; //relocation entry // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *) malloc(size))) { + if (!(rel = (Elf32_Rel *)malloc(size))) { warning("elfloader: Out of memory."); return false; } @@ -67,7 +67,7 @@ bool ARMDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - uint32 *target = (uint32 *) ((byte *) relSegment + rel[i].r_offset); + uint32 *target = (uint32 *)((byte *)relSegment + rel[i].r_offset); uint32 origTarget = *target; //Save for debugging @@ -120,7 +120,7 @@ bool ARMDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size int32(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 + (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory if (curShdr->sh_type == SHT_RELA) { warning("elfloader: RELA entries not supported yet!"); diff --git a/backends/plugins/elf/arm-loader.h b/backends/plugins/elf/arm-loader.h index 3a3894d041..acc05cb143 100644 --- a/backends/plugins/elf/arm-loader.h +++ b/backends/plugins/elf/arm-loader.h @@ -36,7 +36,9 @@ protected: virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: - ARMDLObject() : DLObject() {} + ARMDLObject() : + DLObject() { + } }; #endif /* BACKENDS_PLUGINS_ARM_LOADER_H */ diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index 0503f81c42..df2bc98fb7 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -156,7 +156,7 @@ bool DLObject::loadSegment(Elf32_Phdr *phdr) { uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); - _segment = (byte *) allocSegment(phdr->p_align, phdr->p_memsz + extra); + _segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz + extra); if (!_segment) { warning("elfloader: Out of memory."); @@ -171,7 +171,8 @@ bool DLObject::loadSegment(Elf32_Phdr *phdr) { // Set bss segment to 0 if necessary (assumes bss is at the end) if (phdr->p_memsz > phdr->p_filesz) { - debug(2, "elfloader: Setting %p to %p to 0 for bss", _segment + phdr->p_filesz, _segment + phdr->p_memsz); + debug(2, "elfloader: Setting %p to %p to 0 for bss", + _segment + phdr->p_filesz, _segment + phdr->p_memsz); memset(_segment + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } @@ -195,7 +196,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Elf32_Ehdr *ehdr) { Elf32_Shdr *shdr = 0; // Allocate memory for section headers - if (!(shdr = (Elf32_Shdr *) malloc(ehdr->e_shnum * sizeof(*shdr)))) { + if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { warning("elfloader: Out of memory."); return 0; } @@ -231,10 +232,11 @@ int DLObject::loadSymbolTable(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { return -1; } - debug(2, "elfloader: Symbol section at section %d, size %x", _symtab_sect, shdr[_symtab_sect].sh_size); + debug(2, "elfloader: Symbol section at section %d, size %x", + _symtab_sect, shdr[_symtab_sect].sh_size); // Allocate memory for symbol table - if (!(_symtab = (Elf32_Sym *) malloc(shdr[_symtab_sect].sh_size))) { + if (!(_symtab = (Elf32_Sym *)malloc(shdr[_symtab_sect].sh_size))) { warning("elfloader: Out of memory."); return -1; } @@ -260,7 +262,7 @@ bool DLObject::loadStringTable(Elf32_Shdr *shdr) { uint32 string_sect = shdr[_symtab_sect].sh_link; // Allocate memory for string table - if (!(_strtab = (char *) malloc(shdr[string_sect].sh_size))) { + if (!(_strtab = (char *)malloc(shdr[string_sect].sh_size))) { warning("elfloader: Out of memory."); return false; } @@ -284,7 +286,9 @@ void DLObject::relocateSymbols(ptrdiff_t offset) { // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { s->st_value += offset; - if (s->st_value < Elf32_Addr(_segment) || s->st_value > Elf32_Addr(_segment) + _segmentSize) + + if (s->st_value < Elf32_Addr(_segment) || + s->st_value > Elf32_Addr(_segment) + _segmentSize) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } @@ -407,7 +411,7 @@ void *DLObject::symbol(const char *name) { !strcmp(name, _strtab + s->st_name)) { // We found the symbol debug(2, "elfloader: => 0x%08x", s->st_value); - return (void*) s->st_value; + return (void*)s->st_value; } // We didn't find the symbol diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h index ae226fc2b6..d31f678241 100644 --- a/backends/plugins/elf/elf-loader.h +++ b/backends/plugins/elf/elf-loader.h @@ -44,7 +44,7 @@ */ class DLObject { protected: - Common::SeekableReadStream* _file; + Common::SeekableReadStream *_file; byte *_segment; Elf32_Sym *_symtab; diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp index 9b42d4edd3..a7d2d779d8 100644 --- a/backends/plugins/elf/elf-provider.cpp +++ b/backends/plugins/elf/elf-provider.cpp @@ -55,6 +55,7 @@ DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { bool ELFPlugin::loadPlugin() { assert(!_dlHandle); + DLObject *obj = makeDLObject(); if (obj->open(_filename.c_str())) { _dlHandle = obj; @@ -78,10 +79,11 @@ bool ELFPlugin::loadPlugin() { void ELFPlugin::unloadPlugin() { DynamicPlugin::unloadPlugin(); + if (_dlHandle) { - if (!_dlHandle->close()) { + if (!_dlHandle->close()) warning("elfloader: Failed unloading plugin '%s'", _filename.c_str()); - } + delete _dlHandle; _dlHandle = 0; } @@ -90,7 +92,9 @@ void ELFPlugin::unloadPlugin() { bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { // Check the plugin suffix Common::String filename = node.getName(); - if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) + + if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg") && + !filename.hasSuffix(".PLUGIN") && !filename.hasSuffix(".plugin")) return false; return true; diff --git a/backends/plugins/elf/elf-provider.h b/backends/plugins/elf/elf-provider.h index 447e71ea18..5dc61539e1 100644 --- a/backends/plugins/elf/elf-provider.h +++ b/backends/plugins/elf/elf-provider.h @@ -49,8 +49,10 @@ protected: virtual VoidFunc findSymbol(const char *symbol); public: - ELFPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} + ELFPlugin(const Common::String &filename) : + _dlHandle(0), + _filename(filename) { + } virtual ~ELFPlugin() { if (_dlHandle) @@ -65,7 +67,7 @@ public: class ELFPluginProvider : public FilePluginProvider { protected: - virtual Plugin* createPlugin(const Common::FSNode &node) const = 0; + virtual Plugin *createPlugin(const Common::FSNode &node) const = 0; bool isPluginFilename(const Common::FSNode &node) const; }; diff --git a/backends/plugins/elf/elf32.h b/backends/plugins/elf/elf32.h index 4586d8dc4c..c59f158d6e 100644 --- a/backends/plugins/elf/elf32.h +++ b/backends/plugins/elf/elf32.h @@ -36,7 +36,7 @@ typedef uint16 Elf32_Half, Elf32_Section; typedef uint32 Elf32_Word, Elf32_Addr, Elf32_Off; -typedef int32 Elf32_Sword; +typedef int32 Elf32_Sword; typedef Elf32_Half Elf32_Versym; #define EI_NIDENT (16) @@ -46,41 +46,41 @@ typedef Elf32_Half Elf32_Versym; // ELF header (contains info about the file) typedef struct { - byte 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 */ + byte 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" /* ELF Magic number */ -#define EI_CLASS 4 /* File class byte index */ -#define ELFCLASS32 1 /* 32-bit objects */ +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASS32 1 /* 32-bit objects */ -#define EI_DATA 5 /* Data encoding byte index */ -#define ELFDATA2LSB 1 /* 2's complement, little endian */ -#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ #define EI_VERSION 6 -#define EV_CURRENT 1 /* Current version */ +#define EV_CURRENT 1 /* Current version */ // 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 */ +#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_MIPS 8 @@ -89,27 +89,27 @@ typedef struct { // 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_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_MIPS_REGINFO 0x70000000 /* Register usage info for MIPS */ -#define PT_ARM_ARCHEXT 0x70000000 /* Platform architecture compatibility info for ARM */ -#define PT_ARM_EXIDX 0x70000001 /* Exception unwind tables for ARM */ +#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_MIPS_REGINFO 0x70000000 /* Register usage info for MIPS */ +#define PT_ARM_ARCHEXT 0x70000000 /* Platform architecture compatibility info for ARM */ +#define PT_ARM_EXIDX 0x70000001 /* Exception unwind tables for ARM */ // p_flags value #define PF_X 1 /* execute */ @@ -118,31 +118,31 @@ typedef struct { // 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_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_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_MIPS_LIBLSIT 0x70000000 /* Info about dynamic shared object libs for MIPS*/ #define SHT_MIPS_CONFLICT 0x70000002 /* Conflicts btw executables and shared objects for MIPS */ #define SHT_MIPS_GPTAB 0x70000003 /* Global pointer table for MIPS*/ @@ -151,24 +151,24 @@ typedef struct { #define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes for ARM*/ // sh_flags values -#define SHF_WRITE 0 /* writable section */ -#define SHF_ALLOC 2 /* section occupies memory */ -#define SHF_EXECINSTR 4 /* machine instructions */ +#define SHF_WRITE 0 /* writable section */ +#define SHF_ALLOC 2 /* section occupies memory */ +#define SHF_EXECINSTR 4 /* machine instructions */ #define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area for MIPS */ // 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 */ - byte st_info; /* Symbol type and binding */ - byte st_other; /* Symbol visibility */ - Elf32_Section st_shndx; /* Section index */ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + byte st_info; /* Symbol type and binding */ + byte 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) +#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 */ @@ -192,16 +192,15 @@ typedef struct { // Relocation entry with implicit addend (info about how to relocate) typedef struct { - Elf32_Addr r_offset; /* Address */ - Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ } Elf32_Rel; // Relocation entry with explicit addend (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 */ +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 @@ -245,11 +244,11 @@ typedef struct #define R_PPC_REL32 26 // Mock function to get value of global pointer for MIPS -#define getGP() ({ \ - uint32 __valgp; \ +#define getGP() { \ + uint32 __valgp; \ __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ __valgp; \ -}) +} #endif /* BACKENDS_ELF_H */ diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 9d5ffe7ebe..46f2ad08b0 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -29,6 +29,8 @@ #include "common/debug.h" +#define DEBUG_NUM 2 + /** * Follow the instruction of a relocation section. * @@ -40,7 +42,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) Elf32_Rel *rel = 0; // relocation entry // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *) malloc(size))) { + if (!(rel = (Elf32_Rel *)malloc(size))) { warning("elfloader: Out of memory."); return false; } @@ -69,36 +71,34 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) Elf32_Addr lastHiSymVal = 0; bool hi16InShorts = false; -#define DEBUG_NUM 2 - // Loop over relocation entries for (uint32 i = 0; i < cnt; i++) { // Get the symbol this relocation entry is referring to Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - uint32 *target = (uint32 *) ((byte *)relSegment + rel[i].r_offset); + uint32 *target = (uint32 *)((byte *)relSegment + rel[i].r_offset); uint32 origTarget = *target; // Save for debugging // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { - case R_MIPS_HI16: // Absolute addressing. + case R_MIPS_HI16: // Absolute addressing. if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) - firstHi16 < 0) { // Only process first in block of HI16s + firstHi16 < 0) { // Only process first in block of HI16s firstHi16 = i; // Keep the first Hi16 we saw seenHi16 = true; ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up lastHiSymVal = sym->st_value; - hi16InShorts = ShortsMan.inGeneralSegment((char *) sym->st_value); // Fix for problem with switching btw segments + hi16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); // Fix for problem with switching btw segments if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number debug(8, "elfloader: R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x", i, rel[i].r_offset, ahl, *target); } break; - case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it + case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) if (!seenHi16) { // We MUST have seen HI16 first debug(8, "elfloader: R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!", i); @@ -108,8 +108,8 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section - // and will be screened out above - bool lo16InShorts = ShortsMan.inGeneralSegment((char *) sym->st_value); + // and will be screened out above + bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); // Correct the bug by getting the proper value in ahl (taken from the current symbol) if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { @@ -133,12 +133,13 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s - lastTarget = (uint32 *) ((char *) relSegment + rel[j].r_offset); // get hi16 target + lastTarget = (uint32 *)((char *)relSegment + rel[j].r_offset); // get hi16 target *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation if (relocation & 0x8000) (*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case } + firstHi16 = -1; // Reset so we'll know we treated it } else { extendedHi16++; @@ -148,37 +149,42 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation if (debugRelocs[1]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", + debug(8, "elfloader: R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, " + "lastTarget = %x, origt = %x, target = %x", i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); + if (lo16InShorts && debugRelocs[2]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x", + debug(8, "elfloader: R_MIPS_LO16s: i=%d, offset=%x, a=%x, ahl = %x, " + "lastTarget = %x, origt = %x, target = %x", i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); } break; - case R_MIPS_26: // Absolute addressing (for jumps and branches only) - if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment - a = *target & 0x03ffffff; // Get 26 bits' worth of the addend - a = (a << 6) >> 6; // Sign extend a + case R_MIPS_26: // Absolute addressing (for jumps and branches only) + if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment + a = *target & 0x03ffffff; // Get 26 bits' worth of the addend + a = (a << 6) >> 6; // Sign extend a relocation = ((a << 2) + Elf32_Addr(_segment)) >> 2; // a already points to the target. Subtract our offset - *target &= 0xfc000000; // Clean lower 26 target bits + *target &= 0xfc000000; // Clean lower 26 target bits *target |= (relocation & 0x03ffffff); if (debugRelocs[3]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", + debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, " + "a=%x, origTarget=%x, target=%x", i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } else { if (debugRelocs[4]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x", + debug(8, "elfloader: R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, " + "a=%x, origTarget=%x, target=%x", i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info, a, origTarget, *target); } break; - case R_MIPS_GPREL16: // GP Relative addressing - if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section + case R_MIPS_GPREL16: // GP Relative addressing + if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section ShortsMan.inGeneralSegment((char *) sym->st_value)) { // Only relocate things in the plugin hole - a = *target & 0xffff; // Get 16 bits' worth of the addend - a = (a << 16) >> 16; // Sign extend it + a = *target & 0xffff; // Get 16 bits' worth of the addend + a = (a << 16) >> 16; // Sign extend it relocation = a + _shortsSegment->getOffset(); @@ -186,7 +192,8 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) *target |= relocation & 0xffff; if (debugRelocs[5]++ < DEBUG_NUM) - debug(8, "elfloader: R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x", + debug(8, "elfloader: R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, " + "target=%x, offset=%x", i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); } @@ -196,15 +203,18 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. a = *target; // Get full 32 bits of addend - if (ShortsMan.inGeneralSegment((char *) sym->st_value)) // Check if we're in the shorts segment - relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset - else // We're in the main section - relocation = a + Elf32_Addr(_segment); // Shift by main offset + if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment + relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset + else // We're in the main section + relocation = a + Elf32_Addr(_segment); // Shift by main offset + *target = relocation; if (debugRelocs[6]++ < DEBUG_NUM) - debug("8, elfloader: R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x", i, a, origTarget, *target); + debug("8, elfloader: R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x", + i, a, origTarget, *target); } + break; default: @@ -223,20 +233,19 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) bool MIPSDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Loop over sections, finding relocation sections for (uint32 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_Rel) && // Check for proper relocation size + if (curShdr->sh_type == SHT_REL && // Check for a relocation section + curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size int32(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 (!ShortsMan.inGeneralSegment((char *) shdr[curShdr->sh_info].sh_addr)) { // regular segment + (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory + if (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment if (!relocate(curShdr->sh_offset, curShdr->sh_size, _segment)) return false; - } else { // In Shorts segment - if (!relocate(curShdr->sh_offset, curShdr->sh_size, (byte *) _shortsSegment->getOffset())) + } else { // In Shorts segment + if (!relocate(curShdr->sh_offset, curShdr->sh_size, (byte *)_shortsSegment->getOffset())) return false; } } @@ -252,14 +261,14 @@ void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { for (uint32 c = _symbol_cnt; c--; s++) { // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { - if (!ShortsMan.inGeneralSegment((char *) s->st_value)) { + if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { s->st_value += offset; if (s->st_value < Elf32_Addr(_segment) || s->st_value > Elf32_Addr(_segment) + _segmentSize) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } else { // shorts section s->st_value += _shortsSegment->getOffset(); - if (!_shortsSegment->inSegment((char *) s->st_value)) + if (!_shortsSegment->inSegment((char *)s->st_value)) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } @@ -278,7 +287,7 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - _segment = (byte *) allocSegment(phdr->p_align, phdr->p_memsz + extra); + _segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz + extra); if (!_segment) { warning("elfloader: Out of memory."); @@ -291,16 +300,18 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { baseAddress = _segment + phdr->p_vaddr; _segmentSize = phdr->p_memsz + extra; } else { // This is a shorts section. - _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *) phdr->p_vaddr); + _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); - baseAddress = (byte *) _shortsSegment->getStart(); + baseAddress = (byte *)_shortsSegment->getStart(); debug(2, "elfloader: Shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x", - _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); + _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, + _shortsSegment->getOffset()); } // Set bss segment to 0 if necessary (assumes bss is at the end) if (phdr->p_memsz > phdr->p_filesz) { - debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); + debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, + baseAddress + phdr->p_memsz); memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h index bd90e968d7..1a0974d153 100644 --- a/backends/plugins/elf/mips-loader.h +++ b/backends/plugins/elf/mips-loader.h @@ -34,7 +34,7 @@ class MIPSDLObject : public DLObject { protected: - ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges + ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges uint32 _gpVal; // Value of Global Pointer virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment); @@ -44,10 +44,11 @@ protected: virtual void unload(); public: - MIPSDLObject() : DLObject() { + MIPSDLObject() : + DLObject() { _shortsSegment = NULL; _gpVal = 0; - } + } }; #endif /* BACKENDS_PLUGINS_MIPS_LOADER_H */ diff --git a/backends/plugins/elf/ppc-loader.cpp b/backends/plugins/elf/ppc-loader.cpp index 1cd995936b..4be27ac9fc 100644 --- a/backends/plugins/elf/ppc-loader.cpp +++ b/backends/plugins/elf/ppc-loader.cpp @@ -56,7 +56,7 @@ bool PPCDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - src = (uint32 *) ((char *) relSegment + rel[i].r_offset - _segmentVMA); + src = (uint32 *)((char *)relSegment + rel[i].r_offset - _segmentVMA); value = sym->st_value + rel[i].r_addend; //debug(8, "elfloader: i=%05d %p +0x%04x: (0x%08x) 0x%08x ", i, src, rel[i].r_addend, sym->st_value, *src); @@ -67,23 +67,23 @@ bool PPCDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) debug(8, "elfloader: R_PPC_ADDR32 -> 0x%08x", *src); break; case R_PPC_ADDR16_LO: - *((uint16 *) src) = value; + *(uint16 *)src = value; debug(8, "elfloader: R_PPC_ADDR16_LO -> 0x%08x", *src); break; case R_PPC_ADDR16_HI: - *(uint16 *) src = value >> 16; + *(uint16 *)src = value >> 16; debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x", *src); break; case R_PPC_ADDR16_HA: - *(uint16 *) src = (value + 0x8000) >> 16; + *(uint16 *)src = (value + 0x8000) >> 16; debug(8, "elfloader: R_PPC_ADDR16_HA -> 0x%08x", *src); break; case R_PPC_REL24: - *src = (*src & ~0x03fffffc) | ((value - (uint32) src) & 0x03fffffc); + *src = (*src & ~0x03fffffc) | ((value - (uint32)src) & 0x03fffffc); debug(8, "elfloader: R_PPC_REL24 -> 0x%08x", *src); break; case R_PPC_REL32: - *src = value - (uint32) src; + *src = value - (uint32)src; debug(8, "elfloader: R_PPC_REL32 -> 0x%08x", *src); break; default: diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h index 37a3549c6c..5af9682457 100644 --- a/backends/plugins/elf/ppc-loader.h +++ b/backends/plugins/elf/ppc-loader.h @@ -36,7 +36,9 @@ protected: virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: - PPCDLObject() : DLObject() {} + PPCDLObject() : + DLObject() { + } }; #endif /* BACKENDS_PLUGINS_PPC_LOADER_H */ diff --git a/backends/plugins/elf/shorts-segment-manager.cpp b/backends/plugins/elf/shorts-segment-manager.cpp index d55ea08c73..f444e9e717 100644 --- a/backends/plugins/elf/shorts-segment-manager.cpp +++ b/backends/plugins/elf/shorts-segment-manager.cpp @@ -31,7 +31,7 @@ extern char __plugin_hole_start; // Indicates start of hole in program file for shorts extern char __plugin_hole_end; // Indicates end of hole in program file -extern char _gp[]; // Value of gp register +extern char _gp[]; // Value of gp register DECLARE_SINGLETON(ShortSegmentManager); // For singleton @@ -59,7 +59,7 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(uint32 size, char if (lastAddress + size > _shortsEnd) { warning("elfloader: No space in shorts segment for %x bytes. Last address is %p, max address is %p.", - size, lastAddress, _shortsEnd); + size, lastAddress, _shortsEnd); return 0; } diff --git a/backends/plugins/ps2/plugin.ld b/backends/plugins/ps2/plugin.ld index 9879413b98..45efe4db7a 100644 --- a/backends/plugins/ps2/plugin.ld +++ b/backends/plugins/ps2/plugin.ld @@ -3,6 +3,7 @@ PHDRS { plugin PT_LOAD ; /* Specifies that the plugin segment should be loaded from file */ shorts PT_LOAD ; /* Specifies that the shorts segment should be loaded from file */ } + SECTIONS { .text 0: { _ftext = . ; @@ -90,5 +91,4 @@ SECTIONS { *(.gnu.linkonce.sb*) *(.scommon) } - } diff --git a/backends/plugins/psp/plugin.ld b/backends/plugins/psp/plugin.ld index db4df45264..a4456d199d 100644 --- a/backends/plugins/psp/plugin.ld +++ b/backends/plugins/psp/plugin.ld @@ -1,11 +1,12 @@ -OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", - "elf32-littlemips") +OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", "elf32-littlemips") OUTPUT_ARCH(mips:allegrex) + PHDRS { plugin PT_LOAD ; shorts PT_LOAD ; } + /* Do we need any of these for elf? __DYNAMIC = 0; */ SECTIONS @@ -234,6 +235,4 @@ SECTIONS PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .); } - - } -- cgit v1.2.3 From a318934e45ffc145a8219c16dcd4b7d060e10c8e Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 21:59:07 +0000 Subject: PLUGINS: Add missing variable initialization. svn-id: r52573 --- backends/plugins/elf/elf-loader.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'backends') diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index df2bc98fb7..202444ed4b 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -32,6 +32,7 @@ #include "common/fs.h" DLObject::DLObject() : + _file(0), _segment(0), _symtab(0), _strtab(0), -- cgit v1.2.3 From a4c9de25e62c02c0f3920c4bc568f69a01b2deaa Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 21:59:29 +0000 Subject: PLUGINS: Move doxygen to the base class header. No point in documenting it on every derived class. svn-id: r52574 --- backends/plugins/elf/arm-loader.cpp | 7 ------- backends/plugins/elf/elf-loader.h | 8 ++++++++ backends/plugins/elf/mips-loader.cpp | 7 ------- 3 files changed, 8 insertions(+), 14 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp index 6aac5b5e78..388723eafb 100644 --- a/backends/plugins/elf/arm-loader.cpp +++ b/backends/plugins/elf/arm-loader.cpp @@ -30,13 +30,6 @@ #include "common/debug.h" -/** - * Follow the instruction of a relocation section. - * - * @param fileOffset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - */ bool ARMDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; //relocation entry diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h index d31f678241..ac190327f7 100644 --- a/backends/plugins/elf/elf-loader.h +++ b/backends/plugins/elf/elf-loader.h @@ -70,6 +70,14 @@ protected: virtual void relocateSymbols(ptrdiff_t offset); // architecture specific + + /** + * Follow the instruction of a relocation section. + * + * @param fileOffset Offset into the File + * @param size Size of relocation section + * @param relSegment Base address of relocated segment in memory (memory offset) + */ virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) = 0; virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 46f2ad08b0..6ad608556e 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -31,13 +31,6 @@ #define DEBUG_NUM 2 -/** - * Follow the instruction of a relocation section. - * - * @param fileOffset Offset into the File - * @param size Size of relocation section - * @param relSegment Base address of relocated segment in memory (memory offset) - */ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; // relocation entry -- cgit v1.2.3 From 4c7f5084c2e5e10942d2f5d8dfffb4a7f3258ad5 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 21:59:50 +0000 Subject: PLUGINS: Plug some memleaks. svn-id: r52575 --- backends/plugins/elf/elf-loader.cpp | 16 +++++++++++++--- backends/plugins/elf/elf-provider.cpp | 3 +-- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index 202444ed4b..7bdec22508 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -51,16 +51,20 @@ DLObject::~DLObject() { // Expel the symbol table from memory void DLObject::discard_symtab() { free(_symtab); - free(_strtab); _symtab = 0; + + free(_strtab); _strtab = 0; + _symbol_cnt = 0; } // Unload all objects from memory void DLObject::unload() { discard_symtab(); + freeSegment(_segment); + _segment = 0; _segmentSize = 0; _segmentOffset = 0; @@ -207,6 +211,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Elf32_Ehdr *ehdr) { _file->read(shdr, ehdr->e_shnum * sizeof(*shdr)) != ehdr->e_shnum * sizeof(*shdr)) { warning("elfloader: Section headers load failed."); + free(shdr); return 0; } @@ -247,6 +252,8 @@ int DLObject::loadSymbolTable(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { _file->read(_symtab, shdr[_symtab_sect].sh_size) != shdr[_symtab_sect].sh_size) { warning("elfloader: Symbol table load failed."); + free(_symtab); + _symtab = 0; return -1; } @@ -273,6 +280,8 @@ bool DLObject::loadStringTable(Elf32_Shdr *shdr) { _file->read(_strtab, shdr[string_sect].sh_size) != shdr[string_sect].sh_size) { warning("elfloader: Symbol table strings load failed."); + free(_strtab); + _strtab = 0; return false; } @@ -314,8 +323,9 @@ bool DLObject::load() { return false; } - if (!(shdr = loadSectionHeaders(&ehdr))) - ret = false; + shdr = loadSectionHeaders(&ehdr); + if (!shdr) + return false; if (ret && ((_symtab_sect = loadSymbolTable(&ehdr, shdr)) < 0)) ret = false; diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp index a7d2d779d8..7bb39d4347 100644 --- a/backends/plugins/elf/elf-provider.cpp +++ b/backends/plugins/elf/elf-provider.cpp @@ -71,8 +71,7 @@ bool ELFPlugin::loadPlugin() { bool ret = DynamicPlugin::loadPlugin(); - if (ret && _dlHandle) - _dlHandle->discard_symtab(); + _dlHandle->discard_symtab(); return ret; } -- cgit v1.2.3 From 364acaae455b465201f4467809edb7384a6c2bda Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 22:00:19 +0000 Subject: PLUGINS: Remove spurious extra allocation. Elf32_Phdr.p_align is to align the memory location of the loaded segment, not to extend its size. The size of the scratch area (like .bss and .sbss) is p_memsz-p_filesz, which has to be set to zero by the loader. svn-id: r52576 --- backends/plugins/elf/elf-loader.cpp | 10 +++------- backends/plugins/elf/mips-loader.cpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 14 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index 7bdec22508..a6e20a7f6d 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -157,11 +157,7 @@ bool DLObject::readProgramHeaders(Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half } bool DLObject::loadSegment(Elf32_Phdr *phdr) { - // Attempt to allocate memory for segment - uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here - debug(2, "elfloader: Extra mem is %x", extra); - - _segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz + extra); + _segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz); if (!_segment) { warning("elfloader: Out of memory."); @@ -171,10 +167,10 @@ bool DLObject::loadSegment(Elf32_Phdr *phdr) { debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into - _segmentSize = phdr->p_memsz + extra; + _segmentSize = phdr->p_memsz; _segmentVMA = phdr->p_vaddr; - // Set bss segment to 0 if necessary (assumes bss is at the end) + // Set .bss segment to 0 if necessary if (phdr->p_memsz > phdr->p_filesz) { debug(2, "elfloader: Setting %p to %p to 0 for bss", _segment + phdr->p_filesz, _segment + phdr->p_memsz); diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 6ad608556e..0fc1ca8728 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -273,14 +273,10 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { // We need to take account of non-allocated segment for shorts if (phdr->p_flags & PF_X) { // This is a relocated segment - // Attempt to allocate memory for segment - uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here - debug(2, "elfloader: Extra mem is %x", extra); - if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - _segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz + extra); + _segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz); if (!_segment) { warning("elfloader: Out of memory."); @@ -291,7 +287,14 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { // Get offset to load segment into baseAddress = _segment + phdr->p_vaddr; - _segmentSize = phdr->p_memsz + extra; + _segmentSize = phdr->p_memsz; + + // Set .bss segment to 0 if necessary + if (phdr->p_memsz > phdr->p_filesz) { + debug(2, "elfloader: Setting %p to %p to 0 for bss", + _segment + phdr->p_filesz, _segment + phdr->p_memsz); + memset(_segment + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + } } else { // This is a shorts section. _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); @@ -301,7 +304,7 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { _shortsSegment->getOffset()); } - // Set bss segment to 0 if necessary (assumes bss is at the end) + // Set .sbss segment to 0 if necessary if (phdr->p_memsz > phdr->p_filesz) { debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); -- cgit v1.2.3 From cd5e62bbe8234233679861f7421b850ff832efd5 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 22:00:41 +0000 Subject: PLUGINS: Added _segmentVMA to the MIPS loader. Also added 2 TODOs for all loaders not respection that offset. svn-id: r52577 --- backends/plugins/elf/arm-loader.cpp | 2 +- backends/plugins/elf/mips-loader.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp index 388723eafb..5dbbe3ff04 100644 --- a/backends/plugins/elf/arm-loader.cpp +++ b/backends/plugins/elf/arm-loader.cpp @@ -59,7 +59,7 @@ bool ARMDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) // Get the symbol this relocation entry is referring to Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); - // Get the target instruction in the code + // Get the target instruction in the code. TODO: repect _segmentVMA uint32 *target = (uint32 *)((byte *)relSegment + rel[i].r_offset); uint32 origTarget = *target; //Save for debugging diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 0fc1ca8728..af8c70fcf6 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -69,7 +69,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) // Get the symbol this relocation entry is referring to Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); - // Get the target instruction in the code + // Get the target instruction in the code. TODO: repect _segmentVMA uint32 *target = (uint32 *)((byte *)relSegment + rel[i].r_offset); uint32 origTarget = *target; // Save for debugging @@ -288,6 +288,7 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { // Get offset to load segment into baseAddress = _segment + phdr->p_vaddr; _segmentSize = phdr->p_memsz; + _segmentVMA = phdr->p_vaddr; // Set .bss segment to 0 if necessary if (phdr->p_memsz > phdr->p_filesz) { -- cgit v1.2.3 From a3190a5bb5b0757c89461c2109a9d8fc91f2d1ce Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Mon, 6 Sep 2010 12:03:15 +0000 Subject: PLUGINS: added missing call in destructor which caused crashing svn-id: r52588 --- backends/plugins/elf/mips-loader.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'backends') diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index af8c70fcf6..80f4eae027 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -328,6 +328,8 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { // Unload all objects from memory void MIPSDLObject::unload() { + DLObject::unload(); + if (_shortsSegment) { ShortsMan.deleteSegment(_shortsSegment); _shortsSegment = 0; -- cgit v1.2.3 From b77fd21969eba7e30dfc1b959746af6dfcb3f328 Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Mon, 6 Sep 2010 12:04:30 +0000 Subject: PLUGINS: fixed MIPS plugin loader Adjusted to new VMA handling and fixed a few errors which caused crashes. Also removed unneeded expansion of alignment value. svn-id: r52589 --- backends/plugins/elf/elf-loader.cpp | 3 ++- backends/plugins/elf/mips-loader.cpp | 25 ++++++++++--------------- 2 files changed, 12 insertions(+), 16 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index a6e20a7f6d..f4226b4187 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -331,7 +331,8 @@ bool DLObject::load() { if (ret) { // Offset by our segment allocated address - _segmentOffset = ptrdiff_t(_segment) - phdr.p_vaddr; + // must use _segmentVMA here for multiple segments (MIPS) + _segmentOffset = ptrdiff_t(_segment) - _segmentVMA; relocateSymbols(_segmentOffset); } diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 80f4eae027..9ec71fe4f3 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -69,7 +69,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) // Get the symbol this relocation entry is referring to Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); - // Get the target instruction in the code. TODO: repect _segmentVMA + // Get the target instruction in the code. uint32 *target = (uint32 *)((byte *)relSegment + rel[i].r_offset); uint32 origTarget = *target; // Save for debugging @@ -119,7 +119,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (lo16InShorts) relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset else // It's in the regular segment - relocation = ahl + Elf32_Addr(_segment); // Add in the new offset for the segment + relocation = ahl + Elf32_Addr(relSegment); // Add in the new offset for the segment if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now for (uint32 j = firstHi16; j < i; j++) { @@ -157,7 +157,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment a = *target & 0x03ffffff; // Get 26 bits' worth of the addend a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + Elf32_Addr(_segment)) >> 2; // a already points to the target. Subtract our offset + relocation = ((a << 2) + Elf32_Addr(relSegment)) >> 2; // a already points to the target. Subtract our offset *target &= 0xfc000000; // Clean lower 26 target bits *target |= (relocation & 0x03ffffff); @@ -199,7 +199,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset else // We're in the main section - relocation = a + Elf32_Addr(_segment); // Shift by main offset + relocation = a + Elf32_Addr(relSegment); // Shift by main offset *target = relocation; @@ -235,7 +235,7 @@ bool MIPSDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { 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 (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment - if (!relocate(curShdr->sh_offset, curShdr->sh_size, _segment)) + if (!relocate(curShdr->sh_offset, curShdr->sh_size, _segment - _segmentVMA)) return false; } else { // In Shorts segment if (!relocate(curShdr->sh_offset, curShdr->sh_size, (byte *)_shortsSegment->getOffset())) @@ -255,6 +255,9 @@ void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { + if (s->st_value < _segmentVMA) + s->st_value = _segmentVMA; // deal with symbols referring to sections, which start before the VMA + s->st_value += offset; if (s->st_value < Elf32_Addr(_segment) || s->st_value > Elf32_Addr(_segment) + _segmentSize) @@ -273,9 +276,7 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { // We need to take account of non-allocated segment for shorts if (phdr->p_flags & PF_X) { // This is a relocated segment - if (phdr->p_align < 0x10000) - phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - + // Attempt to allocate memory for segment _segment = (byte *)allocSegment(phdr->p_align, phdr->p_memsz); if (!_segment) { @@ -286,16 +287,10 @@ bool MIPSDLObject::loadSegment(Elf32_Phdr *phdr) { debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into - baseAddress = _segment + phdr->p_vaddr; + baseAddress = _segment; _segmentSize = phdr->p_memsz; _segmentVMA = phdr->p_vaddr; - // Set .bss segment to 0 if necessary - if (phdr->p_memsz > phdr->p_filesz) { - debug(2, "elfloader: Setting %p to %p to 0 for bss", - _segment + phdr->p_filesz, _segment + phdr->p_memsz); - memset(_segment + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); - } } else { // This is a shorts section. _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); -- cgit v1.2.3 From c2cafe426e8216d46a70b479ff0071a8b66b9327 Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Mon, 6 Sep 2010 13:31:27 +0000 Subject: PLUGINS: used variation of ScopedPtr to clean up load() function svn-id: r52592 --- backends/plugins/elf/elf-loader.cpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index f4226b4187..32eae2cba8 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -30,6 +30,7 @@ #include "common/debug.h" #include "common/file.h" #include "common/fs.h" +#include "common/ptr.h" DLObject::DLObject() : _file(0), @@ -303,8 +304,6 @@ void DLObject::relocateSymbols(ptrdiff_t offset) { bool DLObject::load() { Elf32_Ehdr ehdr; Elf32_Phdr phdr; - Elf32_Shdr *shdr; - bool ret = true; if (readElfHeader(&ehdr) == false) return false; @@ -319,29 +318,26 @@ bool DLObject::load() { return false; } - shdr = loadSectionHeaders(&ehdr); + Common::ScopedPtrC shdr(loadSectionHeaders(&ehdr)); if (!shdr) return false; - if (ret && ((_symtab_sect = loadSymbolTable(&ehdr, shdr)) < 0)) - ret = false; - - if (ret && !loadStringTable(shdr)) - ret = false; - - if (ret) { - // Offset by our segment allocated address - // must use _segmentVMA here for multiple segments (MIPS) - _segmentOffset = ptrdiff_t(_segment) - _segmentVMA; - relocateSymbols(_segmentOffset); - } - - if (ret && !relocateRels(&ehdr, shdr)) - ret = false; + _symtab_sect = loadSymbolTable(&ehdr, shdr); + if (_symtab_sect < 0) + return false; + + if (!loadStringTable(shdr)) + return false; + + // Offset by our segment allocated address + // must use _segmentVMA here for multiple segments (MIPS) + _segmentOffset = ptrdiff_t(_segment) - _segmentVMA; + relocateSymbols(_segmentOffset); - free(shdr); + if (!relocateRels(&ehdr, shdr)) + return false; - return ret; + return true; } bool DLObject::open(const char *path) { -- cgit v1.2.3 From ae408db07f05407c41ed4831e4e23991574588d6 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Mon, 6 Sep 2010 20:34:00 +0000 Subject: PLUGINS: Use the C++ ABI to call dtors when unloading a plugin. Avoid linking all plugins against libstdc++ to free up some memory (about ~40kb on Wii per plugin). Enable it on GameCube, Wii, DS and PSP (PS2 doesn't have __cxa_atexit support in its libc). svn-id: r52607 --- backends/plugins/elf/elf-provider.cpp | 57 +++++++++++++++++++++++++++++++++++ backends/plugins/elf/elf-provider.h | 4 ++- 2 files changed, 60 insertions(+), 1 deletion(-) (limited to 'backends') diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp index 7bb39d4347..f3f6bace07 100644 --- a/backends/plugins/elf/elf-provider.cpp +++ b/backends/plugins/elf/elf-provider.cpp @@ -25,11 +25,52 @@ #if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +#ifdef ELF_LOADER_CXA_ATEXIT +#include +#endif + #include "backends/plugins/elf/elf-provider.h" #include "backends/plugins/dynamic-plugin.h" +#include "common/debug.h" #include "common/fs.h" +/* Note about ELF_LOADER_CXA_ATEXIT: + * + * consider the code: + * + * class Foobar { + * const char *work() { + * static String foo = "bar"; + * return s.c_str(); + * } + * } + * + * When instantiating Foobar and calling work() for the first time the String + * foo will be constructed. GCC automatically registers its destruction via + * either atexit() or __cxa_atexit(). Only the latter will add information + * about which DSO did the construction (Using &__dso_handle). + * + * __cxa_atexit allows plugins to reference C++ ABI symbols in the main + * executable without code duplication (No need to link the plugin against + * libstdc++), since we can distinguish which registered exit functions belong + * to a specific DSO. When unloading a plugin, we just use the C++ ABI call + * __cxa_finalize(&__dso_handle) to call all destructors of only that DSO. + * + * Prerequisites: + * - The used libc needs to support __cxa_atexit + * - -fuse-cxa-atexit in CXXFLAGS + * - Every plugin needs its own hidden __dso_handle symbol + * This is automatically done via REGISTER_PLUGIN_DYNAMIC, see base/plugins.h + * + * When __cxa_atexit can not be used, each plugin needs to link against + * libstdc++ to embed its own set of C++ ABI symbols. When not doing so, + * registered destructors of already unloaded plugins will crash the + * application upon returning from main(). + * + * See "3.3.5 DSO Object Destruction API" of the C++ ABI + */ + DynamicPlugin::VoidFunc ELFPlugin::findSymbol(const char *symbol) { void *func = 0; @@ -71,6 +112,14 @@ bool ELFPlugin::loadPlugin() { bool ret = DynamicPlugin::loadPlugin(); +#ifdef ELF_LOADER_CXA_ATEXIT + // FIXME HACK: Reverse HACK of findSymbol() :P + VoidFunc tmp; + tmp = findSymbol("__dso_handle"); + memcpy(&_dso_handle, &tmp, sizeof(VoidFunc)); + debug(2, "elfloader: __dso_handle is %p", _dso_handle); +#endif + _dlHandle->discard_symtab(); return ret; @@ -80,6 +129,14 @@ void ELFPlugin::unloadPlugin() { DynamicPlugin::unloadPlugin(); if (_dlHandle) { +#ifdef ELF_LOADER_CXA_ATEXIT + if (_dso_handle) { + debug(2, "elfloader: calling __cxa_finalize"); + __cxxabiv1::__cxa_finalize(_dso_handle); + _dso_handle = 0; + } +#endif + if (!_dlHandle->close()) warning("elfloader: Failed unloading plugin '%s'", _filename.c_str()); diff --git a/backends/plugins/elf/elf-provider.h b/backends/plugins/elf/elf-provider.h index 5dc61539e1..6918183f1f 100644 --- a/backends/plugins/elf/elf-provider.h +++ b/backends/plugins/elf/elf-provider.h @@ -45,13 +45,15 @@ class ELFPlugin : public DynamicPlugin { protected: DLObject *_dlHandle; Common::String _filename; + void *_dso_handle; virtual VoidFunc findSymbol(const char *symbol); public: ELFPlugin(const Common::String &filename) : _dlHandle(0), - _filename(filename) { + _filename(filename), + _dso_handle(0) { } virtual ~ELFPlugin() { -- cgit v1.2.3 From d3ea6265bac8c0bf4947e6bc6f7bf248799cc966 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Mon, 6 Sep 2010 22:17:23 +0000 Subject: PLUGINS: Formatting. svn-id: r52611 --- backends/plugins/dynamic-plugin.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'backends') diff --git a/backends/plugins/dynamic-plugin.h b/backends/plugins/dynamic-plugin.h index 970ac3531d..0c6a797947 100644 --- a/backends/plugins/dynamic-plugin.h +++ b/backends/plugins/dynamic-plugin.h @@ -44,6 +44,7 @@ public: unloadPlugin(); return false; } + if (verFunc() != PLUGIN_VERSION) { warning("Plugin uses a different API version (you have: '%d', needed is: '%d')", verFunc(), PLUGIN_VERSION); unloadPlugin(); @@ -56,6 +57,7 @@ public: unloadPlugin(); return false; } + _type = (PluginType)typeFunc(); if (_type >= PLUGIN_TYPE_MAX) { warning("Plugin type unknown: %d", _type); @@ -69,6 +71,7 @@ public: unloadPlugin(); return false; } + if (typeVerFunc() != pluginTypeVersions[_type]) { warning("Plugin uses a different type API version (you have: '%d', needed is: '%d')", typeVerFunc(), pluginTypeVersions[_type]); unloadPlugin(); -- cgit v1.2.3 From 83a931dac03c6390482d21306850a02499915741 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Mon, 6 Sep 2010 22:17:46 +0000 Subject: PLUGINS: Only resolve __dso_handle if loading was successful. svn-id: r52612 --- backends/plugins/elf/elf-provider.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp index f3f6bace07..ddffde3e38 100644 --- a/backends/plugins/elf/elf-provider.cpp +++ b/backends/plugins/elf/elf-provider.cpp @@ -113,11 +113,13 @@ bool ELFPlugin::loadPlugin() { bool ret = DynamicPlugin::loadPlugin(); #ifdef ELF_LOADER_CXA_ATEXIT - // FIXME HACK: Reverse HACK of findSymbol() :P - VoidFunc tmp; - tmp = findSymbol("__dso_handle"); - memcpy(&_dso_handle, &tmp, sizeof(VoidFunc)); - debug(2, "elfloader: __dso_handle is %p", _dso_handle); + if (ret) { + // FIXME HACK: Reverse HACK of findSymbol() :P + VoidFunc tmp; + tmp = findSymbol("__dso_handle"); + memcpy(&_dso_handle, &tmp, sizeof(VoidFunc)); + debug(2, "elfloader: __dso_handle is %p", _dso_handle); + } #endif _dlHandle->discard_symtab(); -- cgit v1.2.3 From 41834499edb64965058dea33f1a3176810c52d88 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Wed, 15 Sep 2010 07:43:16 +0000 Subject: PLUGINS: Cleanup. - Unify ELF loader handling in configure - Rename ELF_LOADER_TARGET to USE_ELF_LOADER svn-id: r52728 --- backends/platform/ds/arm9/makefile | 2 +- backends/platform/ps2/Makefile.ps2 | 2 +- backends/platform/psp/Makefile | 2 +- backends/plugins/elf/arm-loader.cpp | 7 ++++--- backends/plugins/elf/arm-loader.h | 9 ++++++--- backends/plugins/elf/elf-loader.cpp | 6 ++++-- backends/plugins/elf/elf-loader.h | 10 ++++++---- backends/plugins/elf/elf-provider.cpp | 7 +++++-- backends/plugins/elf/elf-provider.h | 9 ++++++--- backends/plugins/elf/elf32.h | 4 ++++ backends/plugins/elf/mips-loader.cpp | 6 ++++-- backends/plugins/elf/mips-loader.h | 10 ++++++---- backends/plugins/elf/ppc-loader.cpp | 6 ++++-- backends/plugins/elf/ppc-loader.h | 10 ++++++---- backends/plugins/elf/shorts-segment-manager.cpp | 7 +++++-- backends/plugins/elf/shorts-segment-manager.h | 10 ++++++---- 16 files changed, 69 insertions(+), 38 deletions(-) (limited to 'backends') diff --git a/backends/platform/ds/arm9/makefile b/backends/platform/ds/arm9/makefile index b2512d788e..df7063c08a 100644 --- a/backends/platform/ds/arm9/makefile +++ b/backends/platform/ds/arm9/makefile @@ -237,7 +237,7 @@ CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder \ ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DELF_LOADER_TARGET -DARM -DARM_TARGET -DONE_PLUGIN_AT_A_TIME +DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_FANCY_THEMES -DVECTOR_RENDERER_FORMAT=1555 -DDISABLE_DOSBOX_OPL -DDISABLE_DEFAULT_SAVEFILEMANAGER -DUSE_ELF_LOADER -DARM -DARM_TARGET -DONE_PLUGIN_AT_A_TIME ifdef USE_MAD DEFINES += -DUSE_MAD endif diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 7319fcb21d..8c81341253 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -78,7 +78,7 @@ DEPDIR = .deps TARGET = elf/scummvm.elf DEFINES += -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -DFORCE_RTL -DDISABLE_SAVEGAME_SORTING -D_EE -D__PLAYSTATION2__ -G2 -O2 -Wall -Wno-multichar -fno-rtti -fno-exceptions -DNO_ADAPTOR -DEFINES += -DELF_LOADER_TARGET -DMIPS_TARGET -DONE_PLUGIN_AT_A_TIME +DEFINES += -DUSE_ELF_LOADER -DMIPS_TARGET -DONE_PLUGIN_AT_A_TIME INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile index 96816348fd..e564200897 100644 --- a/backends/platform/psp/Makefile +++ b/backends/platform/psp/Makefile @@ -67,7 +67,7 @@ endif # Variables for common Scummvm makefile CXX = psp-g++ CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti -DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR -DELF_LOADER_TARGET -DMIPS_TARGET +DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -DUSE_RGB_COLOR -DUSE_ELF_LOADER -DMIPS_TARGET LDFLAGS := INCDIR := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp index 5dbbe3ff04..93d3c60f84 100644 --- a/backends/plugins/elf/arm-loader.cpp +++ b/backends/plugins/elf/arm-loader.cpp @@ -23,9 +23,10 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ARM_TARGET) +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(ARM_TARGET) -#include "backends/plugins/elf/elf-loader.h" #include "backends/plugins/elf/arm-loader.h" #include "common/debug.h" @@ -128,5 +129,5 @@ bool ARMDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { return true; } -#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(ARM_TARGET) */ diff --git a/backends/plugins/elf/arm-loader.h b/backends/plugins/elf/arm-loader.h index acc05cb143..e08f8cd0a5 100644 --- a/backends/plugins/elf/arm-loader.h +++ b/backends/plugins/elf/arm-loader.h @@ -23,11 +23,13 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ARM_TARGET) - #ifndef BACKENDS_PLUGINS_ARM_LOADER_H #define BACKENDS_PLUGINS_ARM_LOADER_H +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(ARM_TARGET) + #include "backends/plugins/elf/elf-loader.h" class ARMDLObject : public DLObject { @@ -41,6 +43,7 @@ public: } }; +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(ARM_TARGET) */ + #endif /* BACKENDS_PLUGINS_ARM_LOADER_H */ -#endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index 32eae2cba8..f8f1987b13 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -23,7 +23,9 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) #include "backends/plugins/elf/elf-loader.h" @@ -423,5 +425,5 @@ void *DLObject::symbol(const char *name) { return 0; } -#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) */ diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h index ac190327f7..87907d67c9 100644 --- a/backends/plugins/elf/elf-loader.h +++ b/backends/plugins/elf/elf-loader.h @@ -23,11 +23,13 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - #ifndef BACKENDS_PLUGINS_ELF_LOADER_H #define BACKENDS_PLUGINS_ELF_LOADER_H +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) + #include #include "backends/plugins/elf/elf32.h" @@ -96,7 +98,7 @@ public: void discard_symtab(); }; -#endif /* BACKENDS_PLUGINS_ELF_LOADER_H */ +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) */ -#endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ +#endif /* BACKENDS_PLUGINS_ELF_LOADER_H */ diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp index ddffde3e38..8629de6c45 100644 --- a/backends/plugins/elf/elf-provider.cpp +++ b/backends/plugins/elf/elf-provider.cpp @@ -23,7 +23,9 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) #ifdef ELF_LOADER_CXA_ATEXIT #include @@ -158,4 +160,5 @@ bool ELFPluginProvider::isPluginFilename(const Common::FSNode &node) const { return true; } -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) +#endif // defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) + diff --git a/backends/plugins/elf/elf-provider.h b/backends/plugins/elf/elf-provider.h index 6918183f1f..92fe5d63d1 100644 --- a/backends/plugins/elf/elf-provider.h +++ b/backends/plugins/elf/elf-provider.h @@ -23,11 +23,13 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) - #ifndef BACKENDS_PLUGINS_ELF_PROVIDER_H #define BACKENDS_PLUGINS_ELF_PROVIDER_H +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) + #include "backends/plugins/elf/elf-loader.h" #include "common/fs.h" @@ -74,6 +76,7 @@ protected: bool isPluginFilename(const Common::FSNode &node) const; }; +#endif // defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) + #endif /* BACKENDS_PLUGINS_ELF_PROVIDER_H */ -#endif // defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) diff --git a/backends/plugins/elf/elf32.h b/backends/plugins/elf/elf32.h index c59f158d6e..d3a8d2e436 100644 --- a/backends/plugins/elf/elf32.h +++ b/backends/plugins/elf/elf32.h @@ -28,6 +28,8 @@ #include "common/scummsys.h" +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) + /** * ELF stuff: * The contents of this file were gathered mainly from the SYSTEM V APPLICATION BINARY INTERFACE. @@ -250,5 +252,7 @@ typedef struct { __valgp; \ } +#endif // defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) + #endif /* BACKENDS_ELF_H */ diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 9ec71fe4f3..75db067158 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -23,7 +23,9 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) #include "backends/plugins/elf/mips-loader.h" @@ -331,5 +333,5 @@ void MIPSDLObject::unload() { } } -#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) */ diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h index 1a0974d153..ef6efda21f 100644 --- a/backends/plugins/elf/mips-loader.h +++ b/backends/plugins/elf/mips-loader.h @@ -24,11 +24,13 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) - #ifndef BACKENDS_PLUGINS_MIPS_LOADER_H #define BACKENDS_PLUGINS_MIPS_LOADER_H +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) + #include "backends/plugins/elf/elf-loader.h" #include "backends/plugins/elf/shorts-segment-manager.h" @@ -51,7 +53,7 @@ public: } }; -#endif /* BACKENDS_PLUGINS_MIPS_LOADER_H */ +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) */ -#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ +#endif /* BACKENDS_PLUGINS_MIPS_LOADER_H */ diff --git a/backends/plugins/elf/ppc-loader.cpp b/backends/plugins/elf/ppc-loader.cpp index 4be27ac9fc..ec6d442876 100644 --- a/backends/plugins/elf/ppc-loader.cpp +++ b/backends/plugins/elf/ppc-loader.cpp @@ -23,7 +23,9 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(PPC_TARGET) #include "backends/plugins/elf/elf-loader.h" #include "backends/plugins/elf/ppc-loader.h" @@ -123,5 +125,5 @@ bool PPCDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { return true; } -#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(PPC_TARGET) */ diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h index 5af9682457..f9340a6a7b 100644 --- a/backends/plugins/elf/ppc-loader.h +++ b/backends/plugins/elf/ppc-loader.h @@ -23,11 +23,13 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(PPC_TARGET) - #ifndef BACKENDS_PLUGINS_PPC_LOADER_H #define BACKENDS_PLUGINS_PPC_LOADER_H +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(PPC_TARGET) + #include "backends/plugins/elf/elf-loader.h" class PPCDLObject : public DLObject { @@ -41,7 +43,7 @@ public: } }; -#endif /* BACKENDS_PLUGINS_PPC_LOADER_H */ +#endif /* defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(PPC_TARGET) */ -#endif /* defined(DYNAMIC_MODULES) && defined(PPC_TARGET) */ +#endif /* BACKENDS_PLUGINS_PPC_LOADER_H */ diff --git a/backends/plugins/elf/shorts-segment-manager.cpp b/backends/plugins/elf/shorts-segment-manager.cpp index f444e9e717..17fe650c31 100644 --- a/backends/plugins/elf/shorts-segment-manager.cpp +++ b/backends/plugins/elf/shorts-segment-manager.cpp @@ -23,7 +23,9 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) #include "backends/plugins/elf/shorts-segment-manager.h" @@ -82,5 +84,6 @@ void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { delete seg; } -#endif /* DYNAMIC_MODULES && MIPS_TARGET */ +#endif // defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) + diff --git a/backends/plugins/elf/shorts-segment-manager.h b/backends/plugins/elf/shorts-segment-manager.h index c7cdcfe1f7..219648d91d 100644 --- a/backends/plugins/elf/shorts-segment-manager.h +++ b/backends/plugins/elf/shorts-segment-manager.h @@ -23,11 +23,13 @@ * */ -#if defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) - #ifndef SHORTS_SEGMENT_MANAGER_H #define SHORTS_SEGMENT_MANAGER_H +#include "common/scummsys.h" + +#if defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) + #include "backends/plugins/elf/elf32.h" #include "common/singleton.h" @@ -109,7 +111,7 @@ private: char *_highestAddress; }; -#endif /* SHORTS_SEGMENT_MANAGER_H */ +#endif // defined(DYNAMIC_MODULES) && defined(USE_ELF_LOADER) && defined(MIPS_TARGET) -#endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ +#endif /* SHORTS_SEGMENT_MANAGER_H */ -- cgit v1.2.3 From 2596143e2bc42f5958e446ba6c156402ee1a8d53 Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Wed, 15 Sep 2010 07:44:08 +0000 Subject: PLUGINS: Additional plugin check for the ELF loader. The ELF loader does not have access to the symbols of the main executable, it just relocates symbols to it via fixed offsets. We need to make sure that loaded plugins are from the same link process to prevent crashes. An embedded build date is used for that. svn-id: r52730 --- backends/module.mk | 1 + backends/plugins/elf/elf-provider.cpp | 13 +++++++++++++ backends/plugins/elf/elf-provider.h | 2 ++ backends/plugins/elf/plugin.syms | 1 + backends/plugins/elf/version.cpp | 32 ++++++++++++++++++++++++++++++++ backends/plugins/elf/version.h | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 backends/plugins/elf/version.cpp create mode 100644 backends/plugins/elf/version.h (limited to 'backends') diff --git a/backends/module.mk b/backends/module.mk index e0bdd26cf7..b3a23f10e7 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -28,6 +28,7 @@ MODULE_OBJS := \ plugins/elf/ppc-loader.o \ plugins/elf/arm-loader.o \ plugins/elf/elf-provider.o \ + plugins/elf/version.o \ plugins/dc/dc-provider.o \ plugins/posix/posix-provider.o \ plugins/sdl/sdl-provider.o \ diff --git a/backends/plugins/elf/elf-provider.cpp b/backends/plugins/elf/elf-provider.cpp index 8629de6c45..d1c8f6aa05 100644 --- a/backends/plugins/elf/elf-provider.cpp +++ b/backends/plugins/elf/elf-provider.cpp @@ -112,6 +112,19 @@ bool ELFPlugin::loadPlugin() { return false; } + CharFunc buildDateFunc = (CharFunc)findSymbol("PLUGIN_getBuildDate"); + if (!buildDateFunc) { + unloadPlugin(); + warning("elfloader: plugin '%s' is missing symbols", _filename.c_str()); + return false; + } + + if (strncmp(gScummVMPluginBuildDate, buildDateFunc(), strlen(gScummVMPluginBuildDate))) { + unloadPlugin(); + warning("elfloader: plugin '%s' has a different build date", _filename.c_str()); + return false; + } + bool ret = DynamicPlugin::loadPlugin(); #ifdef ELF_LOADER_CXA_ATEXIT diff --git a/backends/plugins/elf/elf-provider.h b/backends/plugins/elf/elf-provider.h index 92fe5d63d1..0309ffcece 100644 --- a/backends/plugins/elf/elf-provider.h +++ b/backends/plugins/elf/elf-provider.h @@ -45,6 +45,8 @@ */ class ELFPlugin : public DynamicPlugin { protected: + typedef const char *(*CharFunc)(); + DLObject *_dlHandle; Common::String _filename; void *_dso_handle; diff --git a/backends/plugins/elf/plugin.syms b/backends/plugins/elf/plugin.syms index 24ee1a19dc..70465ae976 100644 --- a/backends/plugins/elf/plugin.syms +++ b/backends/plugins/elf/plugin.syms @@ -1,3 +1,4 @@ +PLUGIN_getBuildDate PLUGIN_getVersion PLUGIN_getType PLUGIN_getTypeVersion diff --git a/backends/plugins/elf/version.cpp b/backends/plugins/elf/version.cpp new file mode 100644 index 0000000000..0277c6ae1c --- /dev/null +++ b/backends/plugins/elf/version.cpp @@ -0,0 +1,32 @@ +/* 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$ + * + */ + +#include "backends/plugins/elf/version.h" + +#ifdef USE_ELF_LOADER +const char *gScummVMPluginBuildDate __attribute__((visibility("hidden"))) = + __DATE__ " " __TIME__ ; +#endif + diff --git a/backends/plugins/elf/version.h b/backends/plugins/elf/version.h new file mode 100644 index 0000000000..726204aeb7 --- /dev/null +++ b/backends/plugins/elf/version.h @@ -0,0 +1,35 @@ +/* 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_PLUGINS_ELF_VERSION_H +#define BACKENDS_PLUGINS_ELF_VERSION_H + +#include "common/scummsys.h" + +#ifdef USE_ELF_LOADER +extern const char *gScummVMPluginBuildDate; +#endif + +#endif + -- cgit v1.2.3 From 09cb9416907e621b531c29f18620db29c8f7510e Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Thu, 16 Sep 2010 17:37:31 +0000 Subject: PLUGINS: Fix function arguments in MIPS loader Derived virtual function wasn't overwriting base function. svn-id: r52749 --- backends/plugins/elf/mips-loader.cpp | 2 +- backends/plugins/elf/mips-loader.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 75db067158..5317dbbe6d 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -249,7 +249,7 @@ bool MIPSDLObject::relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { return true; } -void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { +void MIPSDLObject::relocateSymbols(ptrdiff_t offset) { // Loop over symbols, add relocation offset Elf32_Sym *s = _symtab; diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h index ef6efda21f..f8f31f1e7a 100644 --- a/backends/plugins/elf/mips-loader.h +++ b/backends/plugins/elf/mips-loader.h @@ -41,7 +41,7 @@ protected: virtual bool relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment); virtual bool relocateRels(Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); - virtual void relocateSymbols(Elf32_Addr offset); + virtual void relocateSymbols(ptrdiff_t offset); virtual bool loadSegment(Elf32_Phdr *phdr); virtual void unload(); -- cgit v1.2.3 From 8df4278ba8cfbf71228e1927f9db635a9a30a57f Mon Sep 17 00:00:00 2001 From: Yotam Barnoy Date: Thu, 16 Sep 2010 17:37:54 +0000 Subject: PLUGINS: fixed issue with R_MIPS_32 relocations Caused crash in some games. The problem was referring to the right segment. R_MIPS_32 relocations can be found in the Shorts segment, but still need to refer to the main segment if the symbol is found there. svn-id: r52750 --- backends/plugins/elf/mips-loader.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 5317dbbe6d..a90e22cacd 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -54,6 +54,8 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); + Elf32_Addr adjustedMainSegment = Elf32_Addr(_segment) - _segmentVMA; // adjust for VMA offset + bool seenHi16 = false; // For treating HI/LO16 commands int32 firstHi16 = -1; // Mark the point of the first hi16 seen Elf32_Addr ahl = 0; // Calculated addend @@ -121,7 +123,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (lo16InShorts) relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset else // It's in the regular segment - relocation = ahl + Elf32_Addr(relSegment); // Add in the new offset for the segment + relocation = ahl + adjustedMainSegment; // Add in the new offset for the segment if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now for (uint32 j = firstHi16; j < i; j++) { @@ -159,7 +161,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment a = *target & 0x03ffffff; // Get 26 bits' worth of the addend a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + Elf32_Addr(relSegment)) >> 2; // a already points to the target. Subtract our offset + relocation = ((a << 2) + adjustedMainSegment) >> 2; // a already points to the target. Add our offset *target &= 0xfc000000; // Clean lower 26 target bits *target |= (relocation & 0x03ffffff); @@ -201,7 +203,7 @@ bool MIPSDLObject::relocate(Elf32_Off offset, Elf32_Word size, byte *relSegment) if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset else // We're in the main section - relocation = a + Elf32_Addr(relSegment); // Shift by main offset + relocation = a + adjustedMainSegment; // Shift by main offset *target = relocation; -- cgit v1.2.3