Ticket #9098: plugins.patch
File plugins.patch, 74.1 KB (added by , 14 years ago) |
---|
-
configure
894 894 _host_os=psp 895 895 _host_cpu=mipsallegrexel 896 896 _host_alias=psp 897 LDFLAGS="$LDFLAGS -L$PSPDEV/psp/sdk/lib -specs=$_srcdir/backends/platform/psp/psp.spec" 897 CXX=psp-gcc 898 _vorbis=yes 899 _mad=yes 900 _zlib=yes 898 901 ;; 899 902 *) 900 903 if test -n "$_host"; then … … 946 949 fi 947 950 ;; 948 951 psp) 949 if test -z "$PSPDEV"; then 950 echo "Please set PSPDEV in your environment. export PSPDEV=<path to psp toolchain>" 952 PSPSDK=$(psp-config --pspsdk-path) 953 if test -z "$PSPSDK"; then 954 echo "Please set the path to PSPSDK in your environment." 951 955 exit 1 952 956 fi 953 957 ;; … … 1265 1270 # TODO nds 1266 1271 ;; 1267 1272 psp) 1268 CXXFLAGS="$CXXFLAGS -O3 -G0 -I$PSPDEV/psp/sdk/include -D_PSP_FW_VERSION=150" 1273 CXXFLAGS="$CXXFLAGS -O3 -I$PSPSDK/include -D_PSP_FW_VERSION=150" 1274 LDFLAGS="$LDFLAGS -L$PSPSDK/lib" 1269 1275 ;; 1270 1276 wince) 1271 1277 CXXFLAGS="$CXXFLAGS -O3 -march=armv4 -mtune=xscale -D_WIN32_WCE=300 -D__ARM__ -D_ARM_ -DUNICODE -DFPM_DEFAULT -DNONSTANDARD_PORT" … … 1760 1766 POST_OBJS_FLAGS := -Wl,--no-whole-archive 1761 1767 ' 1762 1768 ;; 1769 psp) 1770 _def_plugin=' 1771 #define PLUGIN_PREFIX "" 1772 #define PLUGIN_SUFFIX ".plg" 1773 ' 1774 _mak_plugins=' 1775 DYNAMIC_MODULES := 1 1776 PLUGIN_PREFIX := 1777 PLUGIN_SUFFIX := .plg 1778 PLUGIN_EXTRA_DEPS = $(EXECUTABLE) 1779 CXXFLAGS += -DDYNAMIC_MODULES 1780 LDFLAGS += -Wl,-T$(srcdir)/backends/platform/psp/main_prog.ld 1781 PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm -Wl,-Map,mapfile.txt 1782 PRE_OBJS_FLAGS := -Wl,--whole-archive 1783 POST_OBJS_FLAGS := -Wl,--no-whole-archive 1784 ' 1785 ;; 1763 1786 *) 1764 1787 _dynamic_modules=no 1765 1788 _mak_plugins= … … 2254 2277 # TODO nds 2255 2278 ;; 2256 2279 psp) 2280 find_sdlconfig 2281 SDLINC=$($_sdlconfig --cflags) 2282 SDLLIBS=$($_sdlconfig --libs) 2283 INCLUDES="$INCLUDES $SDLINC" 2284 LIBS="$LIBS $SDLLIBS" 2285 PSPLIBS="-lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet" 2286 PSPLIBS="$PSPLIBS -lpspnet_inet -lpsputility -lpspuser -lpsppower" 2287 LIBS="$LIBS $PSPLIBS -lz -lstdc++ -lc" 2257 2288 DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL" 2258 INCLUDES="$INCLUDES -I$PSPDEV/psp/include/SDL"2259 LIBS="$LIBS -lSDL"2260 2289 ;; 2261 2290 *) 2262 2291 echo "support for $_backend backend not implemented in configure script yet" … … 2307 2336 _engines_built_dynamic="" 2308 2337 _engines_skipped="" 2309 2338 2339 echo "dynamic modules = $_dynamic_modules" 2340 echo "plugins default = $_plugins_default" 2341 2310 2342 for engine in $_engines; do 2311 2343 if test "`get_engine_sub $engine`" = "no" ; then 2312 2344 # It's a main engine -
backends/plugins/psp/psp-provider.h
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/plugins/dc/dc-provider.h $ 22 * $Id: dc-provider.h 34716 2008-10-02 16:58:59Z fingolfin $ 23 * 24 */ 25 26 #ifndef BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H 27 #define BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H 28 29 #include "base/plugins.h" 30 31 #if defined(DYNAMIC_MODULES) && defined(__PSP__) 32 33 class PSPPluginProvider : public FilePluginProvider { 34 protected: 35 Plugin* createPlugin(const Common::FSNode &node) const; 36 37 bool isPluginFilename(const Common::FSNode &node) const; 38 39 virtual void addCustomDirectories(Common::StringList &dirs) const { 40 dirs.push_back("/"); 41 } 42 }; 43 44 #endif // defined(DYNAMIC_MODULES) && defined(__PSP__) 45 46 #endif /* BACKENDS_PLUGINS_PSP_PSP_PROVIDER_H */ -
backends/plugins/psp/psp-provider.cpp
Property changes on: backends/plugins/psp/psp-provider.h ___________________________________________________________________ Added: svn:executable + *
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/plugins/dc/dc-provider.cpp $ 22 * $Id: dc-provider.cpp 34716 2008-10-02 16:58:59Z fingolfin $ 23 * 24 */ 25 26 #if defined(DYNAMIC_MODULES) && defined(__PSP__) 27 28 #include "backends/plugins/psp/psp-provider.h" 29 #include "backends/plugins/dynamic-plugin.h" 30 #include "common/fs.h" 31 32 #include "backends/platform/psp/psploader.h" 33 34 35 class PSPPlugin : public DynamicPlugin { 36 protected: 37 void *_dlHandle; 38 Common::String _filename; 39 40 virtual VoidFunc findSymbol(const char *symbol) { 41 void *func = dlsym(_dlHandle, symbol); 42 if (!func) 43 warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); 44 45 // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ 46 // standard and POSIX: ISO C++ disallows casting between function pointers 47 // and data pointers, but dlsym always returns a void pointer. For details, 48 // see e.g. <http://www.trilithium.com/johan/2004/12/problem-with-dlsym/>. 49 assert(sizeof(VoidFunc) == sizeof(func)); 50 VoidFunc tmp; 51 memcpy(&tmp, &func, sizeof(VoidFunc)); 52 return tmp; 53 } 54 55 public: 56 PSPPlugin(const Common::String &filename) 57 : _dlHandle(0), _filename(filename) {} 58 59 ~PSPPlugin() { 60 if(_dlHandle) unloadPlugin(); 61 } 62 63 bool loadPlugin() { 64 assert(!_dlHandle); 65 _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); 66 67 if (!_dlHandle) { 68 warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); 69 return false; 70 } 71 72 bool ret = DynamicPlugin::loadPlugin(); 73 74 if (ret) 75 dlforgetsyms(_dlHandle); 76 77 return ret; 78 } 79 80 void unloadPlugin() { 81 DynamicPlugin::unloadPlugin(); 82 if (_dlHandle) { 83 if (dlclose(_dlHandle) != 0) 84 warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); 85 _dlHandle = 0; 86 } 87 } 88 }; 89 90 91 Plugin* PSPPluginProvider::createPlugin(const Common::FSNode &node) const { 92 return new PSPPlugin(node.getPath()); 93 } 94 95 bool PSPPluginProvider::isPluginFilename(const Common::FSNode &node) const { 96 // Check the plugin suffix 97 Common::String filename = node.getName(); 98 fprintf(stderr, "Testing name %s", filename.c_str()); 99 if (!filename.hasSuffix(".PLG") && !filename.hasSuffix(".plg")) { 100 fprintf(stderr," fail.\n"); 101 return false; 102 } 103 104 fprintf(stderr," success!\n"); 105 return true; 106 } 107 108 109 #endif // defined(DYNAMIC_MODULES) && defined(__PSP__) -
backends/platform/psp/psploader.h
Property changes on: backends/plugins/psp/psp-provider.cpp ___________________________________________________________________ Added: svn:executable + *
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/dc/dcloader.h $ 22 * $Id: dcloader.h 39494 2009-03-17 22:18:33Z marcus_c $ 23 * 24 */ 25 26 #ifndef PSPLOADER_H 27 #define PSPLOADER_H 28 29 #include "elf32.h" 30 #include "common/list.h" 31 #include "common/singleton.h" 32 33 #define MAXDLERRLEN 80 34 35 #define ShortsMan ShortSegmentManager::instance() 36 37 class ShortSegmentManager : public Common::Singleton<ShortSegmentManager> { 38 private: 39 char *_shortsStart; 40 char *_shortsEnd; 41 42 public: 43 char *getShortsStart() { return _shortsStart; } 44 bool inGeneralSegment(char *addr) { 45 return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); 46 } 47 48 class Segment { 49 private: 50 friend class ShortSegmentManager; 51 Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} 52 ~Segment() {} 53 char *_startAddress; // Start of shorts segment in memory 54 int _size; // Size of shorts segment 55 char *_origAddress; // Original address this segment was supposed to be at 56 public: 57 char *getStart() { return _startAddress; } 58 char *getEnd() { return (_startAddress + _size); } 59 Elf32_Addr getOffset() { return (Elf32_Addr)(_startAddress - _origAddress); } 60 bool inSegment(char *addr) { 61 return ((char *)addr >= _startAddress && (char *)addr < _startAddress + _size); 62 } 63 }; 64 65 Segment *newSegment(int size, char *origAddr); 66 void deleteSegment(Segment *); 67 68 private: 69 ShortSegmentManager(); 70 friend class Common::Singleton<ShortSegmentManager>; 71 Common::List<Segment *> _list; 72 char *_highestAddress; 73 }; 74 75 76 77 78 class DLObject { 79 protected: 80 char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */ 81 82 ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges 83 void *_segment, *_symtab; 84 char *_strtab; 85 int _symbol_cnt; 86 int _symtab_sect; 87 void *_dtors_start, *_dtors_end; 88 89 unsigned int _gpVal; // Value of Global Pointer 90 int _segmentSize; 91 92 void seterror(const char *fmt, ...); 93 void unload(); 94 bool relocate(int fd, unsigned long offset, unsigned long size, void *); 95 bool load(int fd); 96 97 bool readElfHeader(int fd, Elf32_Ehdr *ehdr); 98 bool readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); 99 bool loadSegment(int fd, Elf32_Phdr *phdr); 100 Elf32_Shdr *loadSectionHeaders(int fd, Elf32_Ehdr *ehdr); 101 int loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); 102 bool loadStringTable(int fd, Elf32_Shdr *shdr); 103 void relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset); 104 bool relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); 105 106 public: 107 bool open(const char *path); 108 bool close(); 109 void *symbol(const char *name); 110 void discard_symtab(); 111 112 DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _shortsSegment(NULL), _segment(NULL), _symtab(NULL), 113 _strtab(NULL), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(NULL), _dtors_end(NULL), _gpVal(0) , 114 _segmentSize(0) {} 115 }; 116 117 118 119 #define RTLD_LAZY 0 120 121 extern "C" { 122 void *dlopen(const char *filename, int flags); 123 int dlclose(void *handle); 124 void *dlsym(void *handle, const char *symbol); 125 const char *dlerror(); 126 void dlforgetsyms(void *handle); 127 } 128 129 #endif /* PSPLOADER_H */ -
backends/platform/psp/psp_main.cpp
Property changes on: backends/platform/psp/psploader.h ___________________________________________________________________ Added: svn:executable + *
23 23 * 24 24 */ 25 25 26 26 27 #define USERSPACE_ONLY //don't use kernel mode features 27 28 28 29 #ifndef USERSPACE_ONLY … … 38 39 #include <base/plugins.h> 39 40 #include "backends/platform/psp/powerman.h" 40 41 41 42 #include "backends/plugins/psp/psp-provider.h" 42 43 #include "osys_psp.h" 43 44 #include "./trace.h" 44 45 … … 153 154 g_system = new OSystem_PSP(); 154 155 assert(g_system); 155 156 157 #ifdef DYNAMIC_MODULES 158 PluginManager::instance().addPluginProvider(new PSPPluginProvider()); 159 #endif 160 156 161 int res = scummvm_main(argc, argv); 157 162 158 163 g_system->quit(); // TODO: Consider removing / replacing this! -
backends/platform/psp/plugin.syms
1 PLUGIN_getVersion 2 PLUGIN_getType 3 PLUGIN_getTypeVersion 4 PLUGIN_getObject 5 ___plugin_ctors 6 ___plugin_ctors_end 7 ___plugin_dtors 8 ___plugin_dtors_end -
backends/platform/psp/module.mk
Property changes on: backends/platform/psp/plugin.syms ___________________________________________________________________ Added: svn:executable + *
8 8 kbd_s_c.o \ 9 9 kbd_ls_c.o \ 10 10 kbd_l_c.o \ 11 trace.o 11 trace.o \ 12 psploader.o 12 13 13 14 MODULE_DIRS += \ 14 15 backends/platform/psp/ -
backends/platform/psp/plugin.ld
1 OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", 2 "elf32-littlemips") 3 OUTPUT_ARCH(mips:allegrex) 4 PHDRS 5 { 6 plugin PT_LOAD ; 7 shorts PT_LOAD ; 8 } 9 /* Do we need any of these for elf? 10 __DYNAMIC = 0; */ 11 SECTIONS 12 { 13 /* Read-only sections, merged into text segment: */ 14 . = 0; 15 .interp : { *(.interp) } : plugin 16 .reginfo : { *(.reginfo) } : plugin 17 .dynamic : { *(.dynamic) } 18 .hash : { *(.hash) } 19 .dynsym : { *(.dynsym) } 20 .dynstr : { *(.dynstr) } 21 .gnu.version : { *(.gnu.version) } 22 .gnu.version_d : { *(.gnu.version_d) } 23 .gnu.version_r : { *(.gnu.version_r) } 24 .rel.init : { *(.rel.init) } 25 .rela.init : { *(.rela.init) } 26 .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } 27 .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } 28 .rel.fini : { *(.rel.fini) } 29 .rela.fini : { *(.rela.fini) } 30 /* PSP-specific relocations. */ 31 .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } 32 .rel.lib.ent.top : { *(.rel.lib.ent.top) } 33 .rel.lib.ent : { *(.rel.lib.ent) } 34 .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } 35 .rel.lib.stub.top : { *(.rel.lib.stub.top) } 36 .rel.lib.stub : { *(.rel.lib.stub) } 37 .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } 38 .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } 39 .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } 40 .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } 41 .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } 42 .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } 43 .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } 44 .rel.data.rel.ro : { *(.rel.data.rel.ro*) } 45 .rela.data.rel.ro : { *(.rel.data.rel.ro*) } 46 .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } 47 .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } 48 .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } 49 .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } 50 .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } 51 .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } 52 .rel.ctors : { *(.rel.ctors) } 53 .rela.ctors : { *(.rela.ctors) } 54 .rel.dtors : { *(.rel.dtors) } 55 .rela.dtors : { *(.rela.dtors) } 56 .rel.got : { *(.rel.got) } 57 .rela.got : { *(.rela.got) } 58 .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } 59 .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } 60 .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } 61 .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } 62 .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } 63 .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } 64 .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } 65 .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } 66 .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } 67 .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } 68 .rel.plt : { *(.rel.plt) } 69 .rela.plt : { *(.rela.plt) } 70 .init : 71 { 72 KEEP (*(.init)) 73 } =0 74 .plt : { *(.plt) } 75 .text : 76 { 77 _ftext = . ; 78 *(.text .stub .text.* .gnu.linkonce.t.*) 79 KEEP (*(.text.*personality*)) 80 /* .gnu.warning sections are handled specially by elf32.em. */ 81 *(.gnu.warning) 82 *(.mips16.fn.*) *(.mips16.call.*) 83 } =0 84 .fini : 85 { 86 KEEP (*(.fini)) 87 } =0 88 /* PSP library stub functions. */ 89 .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } 90 PROVIDE (__etext = .); 91 PROVIDE (_etext = .); 92 PROVIDE (etext = .); 93 /* PSP library entry table and library stub table. */ 94 .lib.ent.top : { *(.lib.ent.top) } 95 .lib.ent : { *(.lib.ent) } 96 .lib.ent.btm : { *(.lib.ent.btm) } 97 .lib.stub.top : { *(.lib.stub.top) } 98 .lib.stub : { *(.lib.stub) } 99 .lib.stub.btm : { *(.lib.stub.btm) } 100 /* PSP read-only data for module info, NIDs, and Vstubs. The 101 .rodata.sceModuleInfo section must appear before the .rodata section 102 otherwise it would get absorbed into .rodata and the PSP bootloader 103 would be unable to locate the module info structure. */ 104 .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } 105 .rodata.sceResident : { *(.rodata.sceResident) } 106 .rodata.sceNid : { *(.rodata.sceNid) } 107 .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } 108 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 109 .rodata1 : { *(.rodata1) } 110 .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } 111 .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } 112 .eh_frame_hdr : { *(.eh_frame_hdr) } 113 .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 114 .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 115 /* Adjust the address for the data segment. We want to adjust up to 116 the same address within the page on the next page up. */ 117 . = ALIGN(256) + (. & (256 - 1)); 118 /* Exception handling */ 119 .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 120 .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 121 /* Thread Local Storage sections */ 122 .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 123 .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 124 /* Ensure the __preinit_array_start label is properly aligned. We 125 could instead move the label definition inside the section, but 126 the linker would then create the section even if it turns out to 127 be empty, which isn't pretty. */ 128 . = ALIGN(32 / 8); 129 PROVIDE (__preinit_array_start = .); 130 .preinit_array : { KEEP (*(.preinit_array)) } 131 PROVIDE (__preinit_array_end = .); 132 PROVIDE (__init_array_start = .); 133 .init_array : { KEEP (*(.init_array)) } 134 PROVIDE (__init_array_end = .); 135 PROVIDE (__fini_array_start = .); 136 .fini_array : { KEEP (*(.fini_array)) } 137 PROVIDE (__fini_array_end = .); 138 .ctors : 139 { 140 ___plugin_ctors = .; 141 KEEP (*(SORT(.ctors.*))) 142 KEEP (*(.ctors)) 143 ___plugin_ctors_end = .; 144 } 145 .dtors : 146 { 147 ___plugin_dtors = .; 148 KEEP (*(SORT(.dtors.*))) 149 KEEP (*(.dtors)) 150 ___plugin_dtors_end = .; 151 } 152 .jcr : { KEEP (*(.jcr)) } 153 .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } 154 .data : 155 { 156 _fdata = . ; 157 *(.data .data.* .gnu.linkonce.d.*) 158 KEEP (*(.gnu.linkonce.d.*personality*)) 159 SORT(CONSTRUCTORS) 160 } 161 .data1 : { *(.data1) } 162 . = .; 163 .bss : 164 { 165 *(.dynbss) 166 *(.bss .bss.* .gnu.linkonce.b.*) 167 *(COMMON) 168 /* Align here to ensure that the .bss section occupies space up to 169 _end. Align after .bss to ensure correct alignment even if the 170 .bss section disappears because there are no input sections. */ 171 . = ALIGN(32 / 8); 172 } 173 . = ALIGN(32 / 8); 174 _end = .; 175 PROVIDE (end = .); 176 /* Stabs debugging sections. */ 177 .stab 0 : { *(.stab) } 178 .stabstr 0 : { *(.stabstr) } 179 .stab.excl 0 : { *(.stab.excl) } 180 .stab.exclstr 0 : { *(.stab.exclstr) } 181 .stab.index 0 : { *(.stab.index) } 182 .stab.indexstr 0 : { *(.stab.indexstr) } 183 .comment 0 : { *(.comment) } 184 /* DWARF debug sections. 185 Symbols in the DWARF debugging sections are relative to the beginning 186 of the section so we begin them at 0. */ 187 /* DWARF 1 */ 188 .debug 0 : { *(.debug) } 189 .line 0 : { *(.line) } 190 /* GNU DWARF 1 extensions */ 191 .debug_srcinfo 0 : { *(.debug_srcinfo) } 192 .debug_sfnames 0 : { *(.debug_sfnames) } 193 /* DWARF 1.1 and DWARF 2 */ 194 .debug_aranges 0 : { *(.debug_aranges) } 195 .debug_pubnames 0 : { *(.debug_pubnames) } 196 /* DWARF 2 */ 197 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 198 .debug_abbrev 0 : { *(.debug_abbrev) } 199 .debug_line 0 : { *(.debug_line) } 200 .debug_frame 0 : { *(.debug_frame) } 201 .debug_str 0 : { *(.debug_str) } 202 .debug_loc 0 : { *(.debug_loc) } 203 .debug_macinfo 0 : { *(.debug_macinfo) } 204 /* SGI/MIPS DWARF 2 extensions */ 205 .debug_weaknames 0 : { *(.debug_weaknames) } 206 .debug_funcnames 0 : { *(.debug_funcnames) } 207 .debug_typenames 0 : { *(.debug_typenames) } 208 .debug_varnames 0 : { *(.debug_varnames) } 209 /DISCARD/ : { *(.comment) *(.pdr) } 210 /DISCARD/ : { *(.note.GNU-stack) } 211 212 . = __plugin_hole_start; 213 .got : { *(.got.plt) *(.got) } : shorts 214 /* We want the small data sections together, so single-instruction offsets 215 can access them all, and initialized data all before uninitialized, so 216 we can shorten the on-disk segment size. */ 217 .sdata : 218 { 219 *(.sdata .sdata.* .gnu.linkonce.s.*) 220 } 221 .lit8 : { *(.lit8) } 222 .lit4 : { *(.lit4) } 223 _edata = .; 224 PROVIDE (edata = .); 225 __bss_start = .; 226 _fbss = .; 227 .sbss : 228 { 229 PROVIDE (__sbss_start = .); 230 PROVIDE (___sbss_start = .); 231 *(.dynsbss) 232 *(.sbss .sbss.* .gnu.linkonce.sb.*) 233 *(.scommon) 234 PROVIDE (__sbss_end = .); 235 PROVIDE (___sbss_end = .); 236 } 237 238 239 } -
backends/platform/psp/elf32.h
Property changes on: backends/platform/psp/plugin.ld ___________________________________________________________________ Added: svn:executable + *
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/dc/dcloader.cpp $ 22 * $Id: dcloader.cpp 39590 2009-03-21 15:47:45Z marcus_c $ 23 * 24 */ 25 26 #ifndef BACKENDS_ELF_H 27 #define BACKENDS_ELF_H 28 29 /* ELF stuff */ 30 31 typedef unsigned short Elf32_Half, Elf32_Section; 32 typedef unsigned int Elf32_Word, Elf32_Addr, Elf32_Off; 33 typedef signed int Elf32_Sword; 34 typedef Elf32_Half Elf32_Versym; 35 36 #define EI_NIDENT (16) 37 #define SELFMAG 6 38 39 /* ELF File format structures. Look up ELF structure for more details */ 40 41 // ELF header (contains info about the file) 42 typedef struct 43 { 44 unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ 45 Elf32_Half e_type; /* Object file type */ 46 Elf32_Half e_machine; /* Architecture */ 47 Elf32_Word e_version; /* Object file version */ 48 Elf32_Addr e_entry; /* Entry point virtual address */ 49 Elf32_Off e_phoff; /* Program header table file offset */ 50 Elf32_Off e_shoff; /* Section header table file offset */ 51 Elf32_Word e_flags; /* Processor-specific flags */ 52 Elf32_Half e_ehsize; /* ELF header size in bytes */ 53 Elf32_Half e_phentsize; /* Program header table entry size */ 54 Elf32_Half e_phnum; /* Program header table entry count */ 55 Elf32_Half e_shentsize; /* Section header table entry size */ 56 Elf32_Half e_shnum; /* Section header table entry count */ 57 Elf32_Half e_shstrndx; /* Section header string table index */ 58 } Elf32_Ehdr; 59 60 // Should be in e_ident 61 #define ELFMAG "\177ELF\1\1" /* ELF Magic number */ 62 63 // e_type values 64 #define ET_NONE 0 /* no file type */ 65 #define ET_REL 1 /* relocatable */ 66 #define ET_EXEC 2 /* executable */ 67 #define ET_DYN 3 /* shared object */ 68 #define ET_CORE 4 /* core file */ 69 70 // e_machine values 71 #define EM_MIPS 8 72 73 74 // Program header (contains info about segment) 75 typedef struct 76 { 77 Elf32_Word p_type; /* Segment type */ 78 Elf32_Off p_offset; /* Segment file offset */ 79 Elf32_Addr p_vaddr; /* Segment virtual address */ 80 Elf32_Addr p_paddr; /* Segment physical address */ 81 Elf32_Word p_filesz; /* Segment size in file */ 82 Elf32_Word p_memsz; /* Segment size in memory */ 83 Elf32_Word p_flags; /* Segment flags */ 84 Elf32_Word p_align; /* Segment alignment */ 85 } Elf32_Phdr; 86 87 // p_type values 88 #define PT_NULL 0 /* ignored */ 89 #define PT_LOAD 1 /* loadable segment */ 90 #define PT_DYNAMIC 2 /* dynamic linking info */ 91 #define PT_INTERP 3 /* info about interpreter */ 92 #define PT_NOTE 4 /* note segment */ 93 #define PT_SHLIB 5 /* reserved */ 94 #define PT_PHDR 6 /* Program header table */ 95 #define PT_MIPS_REGINFO 0x70000000 /* register usage info */ 96 97 // p_flags value 98 #define PF_X 1 /* execute */ 99 #define PF_W 2 /* write */ 100 #define PF_R 4 /* read */ 101 102 // Section header (contains info about section) 103 typedef struct 104 { 105 Elf32_Word sh_name; /* Section name (string tbl index) */ 106 Elf32_Word sh_type; /* Section type */ 107 Elf32_Word sh_flags; /* Section flags */ 108 Elf32_Addr sh_addr; /* Section virtual addr at execution */ 109 Elf32_Off sh_offset; /* Section file offset */ 110 Elf32_Word sh_size; /* Section size in bytes */ 111 Elf32_Word sh_link; /* Link to another section */ 112 Elf32_Word sh_info; /* Additional section information */ 113 Elf32_Word sh_addralign; /* Section alignment */ 114 Elf32_Word sh_entsize; /* Entry size if section holds table */ 115 } Elf32_Shdr; 116 117 // sh_type values 118 #define SHT_NULL 0 /* Inactive section */ 119 #define SHT_PROGBITS 1 /* Proprietary */ 120 #define SHT_SYMTAB 2 /* Symbol table */ 121 #define SHT_STRTAB 3 /* String table */ 122 #define SHT_RELA 4 /* Relocation entries with addend */ 123 #define SHT_HASH 5 /* Symbol hash table */ 124 #define SHT_DYNAMIC 6 /* Info for dynamic linking */ 125 #define SHT_NOTE 7 /* Note section */ 126 #define SHT_NOBITS 8 /* Occupies no space */ 127 #define SHT_REL 9 /* Relocation entries without addend */ 128 #define SHT_SHLIB 10 /* Reserved */ 129 #define SHT_DYNSYM 11 /* Minimal set of dynamic linking symbols */ 130 #define SHT_MIPS_LIBLSIT 0x70000000 /* Info about dynamic shared object libs */ 131 #define SHT_MIPS_CONFLICT 0x70000002 /* Conflicts btw executables and shared objects */ 132 #define SHT_MIPS_GPTAB 0x70000003 /* Global pointer table */ 133 134 // sh_flags values 135 #define SHF_WRITE 0 /* writable section */ 136 #define SHF_ALLOC 2 /* section occupies memory */ 137 #define SHF_EXECINSTR 4 /* machine instructions */ 138 #define SHF_MIPS_GPREL 0x10000000 /* Must be made part of global data area */ 139 140 141 // Symbol entry (contain info about a symbol) 142 typedef struct 143 { 144 Elf32_Word st_name; /* Symbol name (string tbl index) */ 145 Elf32_Addr st_value; /* Symbol value */ 146 Elf32_Word st_size; /* Symbol size */ 147 unsigned char st_info; /* Symbol type and binding */ 148 unsigned char st_other; /* Symbol visibility */ 149 Elf32_Section st_shndx; /* Section index */ 150 } Elf32_Sym; 151 152 // Extract from the st_info 153 #define SYM_TYPE(x) ((x)&0xF) 154 #define SYM_BIND(x) ((x)>>4) 155 156 157 // Symbol binding values from st_info 158 #define STB_LOCAL 0 /* Symbol not visible outside object */ 159 #define STB_GLOBAL 1 /* Symbol visible to all object files */ 160 #define STB_WEAK 2 /* Similar to STB_GLOBAL */ 161 162 // Symbol type values from st_info 163 #define STT_NOTYPE 0 /* Not specified */ 164 #define STT_OBJECT 1 /* Data object e.g. variable */ 165 #define STT_FUNC 2 /* Function */ 166 #define STT_SECTION 3 /* Section */ 167 #define STT_FILE 4 /* Source file associated with object file */ 168 169 // Special section header index values from st_shndex 170 #define SHN_UNDEF 0 171 #define SHN_LOPROC 0xFF00 /* Extended values */ 172 #define SHN_ABS 0xFFF1 /* Absolute value: don't relocate */ 173 #define SHN_COMMON 0xFFF2 /* Common block. Not allocated yet */ 174 #define SHN_HIPROC 0xFF1F 175 #define SHN_HIRESERVE 0xFFFF 176 177 // Relocation entry (info about how to relocate) 178 typedef struct 179 { 180 Elf32_Addr r_offset; /* Address */ 181 Elf32_Word r_info; /* Relocation type and symbol index */ 182 } Elf32_Rel; 183 184 // Access macros for the relocation info 185 #define REL_TYPE(x) ((x)&0xFF) /* Extract relocation type */ 186 #define REL_INDEX(x) ((x)>>8) /* Extract relocation index into symbol table */ 187 188 // MIPS relocation types 189 #define R_MIPS_NONE 0 190 #define R_MIPS_16 1 191 #define R_MIPS_32 2 192 #define R_MIPS_REL32 3 193 #define R_MIPS_26 4 194 #define R_MIPS_HI16 5 195 #define R_MIPS_LO16 6 196 #define R_MIPS_GPREL16 7 197 #define R_MIPS_LITERAL 8 198 #define R_MIPS_GOT16 9 199 #define R_MIPS_PC16 10 200 #define R_MIPS_CALL16 11 201 #define R_MIPS_GPREL32 12 202 #define R_MIPS_GOTHI16 13 203 #define R_MIPS_GOTLO16 14 204 #define R_MIPS_CALLHI16 15 205 #define R_MIPS_CALLLO16 16 206 207 // Mock function to get value of global pointer 208 #define getGP() ({ \ 209 unsigned int __valgp; \ 210 __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ 211 __valgp; \ 212 }) 213 214 #endif /* BACKENDS_ELF_H */ -
backends/platform/psp/psp.mk
Property changes on: backends/platform/psp/elf32.h ___________________________________________________________________ Added: svn:executable + *
21 21 $(RM) $(PSP_EXE_STRIPPED) $(PSP_EBOOT) $(PSP_EBOOT_SFO) 22 22 23 23 psp_fixup_elf: $(PSP_EXE_STRIPPED) 24 $(PSPDEV)/bin/psp-fixup-imports $<24 psp-fixup-imports $< 25 25 26 26 pack_pbp: psp_fixup_elf $(PSP_EBOOT_SFO) 27 27 $(PACK_PBP) $(PSP_EBOOT) \ -
backends/platform/psp/main_prog.ld
1 OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", 2 "elf32-littlemips") 3 OUTPUT_ARCH(mips:allegrex) 4 ENTRY(_start) 5 /* Do we need any of these for elf? 6 __DYNAMIC = 0; */ 7 SECTIONS 8 { 9 /* Read-only sections, merged into text segment: */ 10 PROVIDE (__executable_start = 0x08900000); . = 0x08900000; 11 .interp : { *(.interp) } 12 .reginfo : { *(.reginfo) } 13 .dynamic : { *(.dynamic) } 14 .hash : { *(.hash) } 15 .dynsym : { *(.dynsym) } 16 .dynstr : { *(.dynstr) } 17 .gnu.version : { *(.gnu.version) } 18 .gnu.version_d : { *(.gnu.version_d) } 19 .gnu.version_r : { *(.gnu.version_r) } 20 .rel.init : { *(.rel.init) } 21 .rela.init : { *(.rela.init) } 22 .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } 23 .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } 24 .rel.fini : { *(.rel.fini) } 25 .rela.fini : { *(.rela.fini) } 26 /* PSP-specific relocations. */ 27 .rel.sceStub.text : { *(.rel.sceStub.text) *(SORT(.rel.sceStub.text.*)) } 28 .rel.lib.ent.top : { *(.rel.lib.ent.top) } 29 .rel.lib.ent : { *(.rel.lib.ent) } 30 .rel.lib.ent.btm : { *(.rel.lib.ent.btm) } 31 .rel.lib.stub.top : { *(.rel.lib.stub.top) } 32 .rel.lib.stub : { *(.rel.lib.stub) } 33 .rel.lib.stub.btm : { *(.rel.lib.stub.btm) } 34 .rel.rodata.sceModuleInfo : { *(.rel.rodata.sceModuleInfo) } 35 .rel.rodata.sceResident : { *(.rel.rodata.sceResident) } 36 .rel.rodata.sceNid : { *(.rel.rodata.sceNid) } 37 .rel.rodata.sceVstub : { *(.rel.rodata.sceVstub) *(SORT(.rel.rodata.sceVstub.*)) } 38 .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } 39 .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } 40 .rel.data.rel.ro : { *(.rel.data.rel.ro*) } 41 .rela.data.rel.ro : { *(.rel.data.rel.ro*) } 42 .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } 43 .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } 44 .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } 45 .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } 46 .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } 47 .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } 48 .rel.ctors : { *(.rel.ctors) } 49 .rela.ctors : { *(.rela.ctors) } 50 .rel.dtors : { *(.rel.dtors) } 51 .rela.dtors : { *(.rela.dtors) } 52 .rel.got : { *(.rel.got) } 53 .rela.got : { *(.rela.got) } 54 .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } 55 .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } 56 .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } 57 .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } 58 .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } 59 .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } 60 .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } 61 .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } 62 .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } 63 .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } 64 .rel.plt : { *(.rel.plt) } 65 .rela.plt : { *(.rela.plt) } 66 .init : 67 { 68 KEEP (*(.init)) 69 } =0 70 .plt : { *(.plt) } 71 .text : 72 { 73 _ftext = . ; 74 *(.text .stub .text.* .gnu.linkonce.t.*) 75 KEEP (*(.text.*personality*)) 76 /* .gnu.warning sections are handled specially by elf32.em. */ 77 *(.gnu.warning) 78 *(.mips16.fn.*) *(.mips16.call.*) 79 } =0 80 .fini : 81 { 82 KEEP (*(.fini)) 83 } =0 84 /* PSP library stub functions. */ 85 .sceStub.text : { *(.sceStub.text) *(SORT(.sceStub.text.*)) } 86 PROVIDE (__etext = .); 87 PROVIDE (_etext = .); 88 PROVIDE (etext = .); 89 /* PSP library entry table and library stub table. */ 90 .lib.ent.top : { *(.lib.ent.top) } 91 .lib.ent : { *(.lib.ent) } 92 .lib.ent.btm : { *(.lib.ent.btm) } 93 .lib.stub.top : { *(.lib.stub.top) } 94 .lib.stub : { *(.lib.stub) } 95 .lib.stub.btm : { *(.lib.stub.btm) } 96 /* PSP read-only data for module info, NIDs, and Vstubs. The 97 .rodata.sceModuleInfo section must appear before the .rodata section 98 otherwise it would get absorbed into .rodata and the PSP bootloader 99 would be unable to locate the module info structure. */ 100 .rodata.sceModuleInfo : { *(.rodata.sceModuleInfo) } 101 .rodata.sceResident : { *(.rodata.sceResident) } 102 .rodata.sceNid : { *(.rodata.sceNid) } 103 .rodata.sceVstub : { *(.rodata.sceVstub) *(SORT(.rodata.sceVstub.*)) } 104 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 105 .rodata1 : { *(.rodata1) } 106 .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } 107 .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } 108 .eh_frame_hdr : { *(.eh_frame_hdr) } 109 .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 110 .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 111 /* Adjust the address for the data segment. We want to adjust up to 112 the same address within the page on the next page up. */ 113 . = ALIGN(256) + (. & (256 - 1)); 114 /* Exception handling */ 115 .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 116 .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 117 /* Thread Local Storage sections */ 118 .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 119 .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 120 /* Ensure the __preinit_array_start label is properly aligned. We 121 could instead move the label definition inside the section, but 122 the linker would then create the section even if it turns out to 123 be empty, which isn't pretty. */ 124 . = ALIGN(32 / 8); 125 PROVIDE (__preinit_array_start = .); 126 .preinit_array : { KEEP (*(.preinit_array)) } 127 PROVIDE (__preinit_array_end = .); 128 PROVIDE (__init_array_start = .); 129 .init_array : { KEEP (*(.init_array)) } 130 PROVIDE (__init_array_end = .); 131 PROVIDE (__fini_array_start = .); 132 .fini_array : { KEEP (*(.fini_array)) } 133 PROVIDE (__fini_array_end = .); 134 .ctors : 135 { 136 /* gcc uses crtbegin.o to find the start of 137 the constructors, so we make sure it is 138 first. Because this is a wildcard, it 139 doesn't matter if the user does not 140 actually link against crtbegin.o; the 141 linker won't look for a file to match a 142 wildcard. The wildcard also means that it 143 doesn't matter which directory crtbegin.o 144 is in. */ 145 KEEP (*crtbegin*.o(.ctors)) 146 /* We don't want to include the .ctor section from 147 from the crtend.o file until after the sorted ctors. 148 The .ctor section from the crtend file contains the 149 end of ctors marker and it must be last */ 150 KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) 151 KEEP (*(SORT(.ctors.*))) 152 KEEP (*(.ctors)) 153 } 154 .dtors : 155 { 156 KEEP (*crtbegin*.o(.dtors)) 157 KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) 158 KEEP (*(SORT(.dtors.*))) 159 KEEP (*(.dtors)) 160 } 161 .jcr : { KEEP (*(.jcr)) } 162 .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } 163 .data : 164 { 165 _fdata = . ; 166 *(.data .data.* .gnu.linkonce.d.*) 167 KEEP (*(.gnu.linkonce.d.*personality*)) 168 SORT(CONSTRUCTORS) 169 } 170 .data1 : { *(.data1) } 171 . = .; 172 _gp = ALIGN(16) + 0x7ff0; 173 .got : { *(.got.plt) *(.got) } 174 /* We want the small data sections together, so single-instruction offsets 175 can access them all, and initialized data all before uninitialized, so 176 we can shorten the on-disk segment size. */ 177 .sdata : 178 { 179 *(.sdata .sdata.* .gnu.linkonce.s.*) 180 } 181 .lit8 : { *(.lit8) } 182 .lit4 : { *(.lit4) } 183 _edata = .; 184 PROVIDE (edata = .); 185 __bss_start = .; 186 _fbss = .; 187 .sbss : 188 { 189 PROVIDE (__sbss_start = .); 190 PROVIDE (___sbss_start = .); 191 *(.dynsbss) 192 *(.sbss .sbss.* .gnu.linkonce.sb.*) 193 *(.scommon) 194 PROVIDE (__sbss_end = .); 195 PROVIDE (___sbss_end = .); 196 } 197 /* make a gap to put the plugins' short data here */ 198 __plugin_hole_start = .; 199 . = _gp + 0x7ff0; 200 __plugin_hole_end = .; 201 .bss : 202 { 203 *(.dynbss) 204 *(.bss .bss.* .gnu.linkonce.b.*) 205 *(COMMON) 206 /* Align here to ensure that the .bss section occupies space up to 207 _end. Align after .bss to ensure correct alignment even if the 208 .bss section disappears because there are no input sections. */ 209 . = ALIGN(32 / 8); 210 } 211 . = ALIGN(32 / 8); 212 _end = .; 213 PROVIDE (end = .); 214 /* Stabs debugging sections. */ 215 .stab 0 : { *(.stab) } 216 .stabstr 0 : { *(.stabstr) } 217 .stab.excl 0 : { *(.stab.excl) } 218 .stab.exclstr 0 : { *(.stab.exclstr) } 219 .stab.index 0 : { *(.stab.index) } 220 .stab.indexstr 0 : { *(.stab.indexstr) } 221 .comment 0 : { *(.comment) } 222 /* DWARF debug sections. 223 Symbols in the DWARF debugging sections are relative to the beginning 224 of the section so we begin them at 0. */ 225 /* DWARF 1 */ 226 .debug 0 : { *(.debug) } 227 .line 0 : { *(.line) } 228 /* GNU DWARF 1 extensions */ 229 .debug_srcinfo 0 : { *(.debug_srcinfo) } 230 .debug_sfnames 0 : { *(.debug_sfnames) } 231 /* DWARF 1.1 and DWARF 2 */ 232 .debug_aranges 0 : { *(.debug_aranges) } 233 .debug_pubnames 0 : { *(.debug_pubnames) } 234 /* DWARF 2 */ 235 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 236 .debug_abbrev 0 : { *(.debug_abbrev) } 237 .debug_line 0 : { *(.debug_line) } 238 .debug_frame 0 : { *(.debug_frame) } 239 .debug_str 0 : { *(.debug_str) } 240 .debug_loc 0 : { *(.debug_loc) } 241 .debug_macinfo 0 : { *(.debug_macinfo) } 242 /* SGI/MIPS DWARF 2 extensions */ 243 .debug_weaknames 0 : { *(.debug_weaknames) } 244 .debug_funcnames 0 : { *(.debug_funcnames) } 245 .debug_typenames 0 : { *(.debug_typenames) } 246 .debug_varnames 0 : { *(.debug_varnames) } 247 /DISCARD/ : { *(.comment) *(.pdr) } 248 /DISCARD/ : { *(.note.GNU-stack) } 249 } 0 250 -
backends/platform/psp/psploader.cpp
Property changes on: backends/platform/psp/main_prog.ld ___________________________________________________________________ Added: svn:executable + *
1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/dc/dcloader.cpp $ 22 * $Id: dcloader.cpp 39590 2009-03-21 15:47:45Z marcus_c $ 23 * 24 */ 25 26 #if defined(DYNAMIC_MODULES) && defined(__PSP__) 27 28 #include <string.h> 29 #include <stdarg.h> 30 #include <stdio.h> 31 #include <malloc.h> 32 #include <unistd.h> 33 #include <sys/_default_fcntl.h> 34 35 #include <psputils.h> 36 37 #include "backends/platform/psp/psploader.h" 38 #include "backends/platform/psp/powerman.h" 39 40 //#define __PSP_DEBUG_PLUGINS__ 41 42 #ifdef __PSP_DEBUG_PLUGINS__ 43 #define DBG(x,...) fprintf(stderr,x, ## __VA_ARGS__) 44 #else 45 #define DBG(x,...) 46 #endif 47 48 #define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__) 49 50 extern char __plugin_hole_start; // Indicates start of hole in program file for shorts 51 extern char __plugin_hole_end; // Indicates end of hole in program file 52 extern char _gp[]; // Value of gp register 53 54 DECLARE_SINGLETON(ShortSegmentManager); // For singleton 55 56 // Get rid of symbol table in memory 57 void DLObject::discard_symtab() 58 { 59 free(_symtab); 60 free(_strtab); 61 _symtab = NULL; 62 _strtab = NULL; 63 _symbol_cnt = 0; 64 } 65 66 // Unload all objects from memory 67 void DLObject::unload() 68 { 69 discard_symtab(); 70 free(_segment); 71 _segment = NULL; 72 73 if(_shortsSegment) { 74 ShortsMan.deleteSegment(_shortsSegment); 75 _shortsSegment = NULL; 76 } 77 } 78 79 /** 80 * Follow the instruction of a relocation section. 81 * 82 * @param fd File Descriptor 83 * @param offset Offset into the File 84 * @param size Size of relocation section 85 * @param relSegment Base address of relocated segment in memory (memory offset) 86 * 87 */ 88 bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void *relSegment) 89 { 90 Elf32_Rel *rel = NULL; // relocation entry 91 92 // Allocate memory for relocation table 93 if (!(rel = (Elf32_Rel *)malloc(size))) { 94 seterror("Out of memory."); 95 return false; 96 } 97 98 // Read in our relocation table 99 if (lseek(fd, offset, SEEK_SET)<0 || 100 read(fd, rel, size) != (ssize_t)size) { 101 seterror("Relocation table load failed."); 102 free(rel); 103 return false; 104 } 105 106 // Treat each relocation entry. Loop over all of them 107 int cnt = size / sizeof(*rel); 108 109 DBG("Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); 110 111 bool seenHi16 = false; // For treating HI/LO16 commands 112 int firstHi16 = -1; // Mark the point of the first hi16 seen 113 Elf32_Addr ahl = 0; // Calculated addend 114 int a = 0; // Addend: taken from the target 115 116 unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives 117 unsigned int relocation = 0; 118 int debugRelocs[10] = {0}; // For debugging 119 int extendedHi16 = 0; // Count extended hi16 treatments 120 121 #define DEBUG_NUM 2 122 123 // Loop over relocation entries 124 for (int i=0; i<cnt; i++) { 125 126 // Get the symbol this relocation entry is referring to 127 Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); 128 129 // Get the target instruction in the code 130 unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); 131 132 unsigned int origTarget = *target; // Save for debugging 133 134 // Act differently based on the type of relocation 135 switch(REL_TYPE(rel[i].r_info)) { 136 137 case R_MIPS_HI16: // Absolute addressing. 138 if (sym->st_shndx < SHN_LOPROC && // Only shift for plugin section (ie. has a real section index) 139 firstHi16 < 0) { // Only process first in block of HI16s 140 firstHi16 = i; // Keep the first Hi16 we saw 141 seenHi16 = true; 142 ahl = (*target & 0xffff)<<16; // Take lower 16 bits shifted up 143 144 if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number 145 DBG("R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x\n", 146 i, rel[i].r_offset, ahl, *target); 147 } 148 break; 149 150 case R_MIPS_LO16: // Absolute addressing. Needs a HI16 to come before it 151 if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. (ie. has a real section index) 152 if (!seenHi16) { // We MUST have seen HI16 first 153 seterror("R_MIPS_LO16 w/o preceding R_MIPS_HI16 at relocation %d!\n", i); 154 free(rel); 155 return false; 156 } 157 158 ahl &= 0xffff0000; // Clean lower 16 bits for repeated LO16s 159 a = *target & 0xffff; // Take lower 16 bits of the target 160 a = (a<<16)>>16; // Sign extend them 161 ahl += a; // Add lower 16 bits. AHL is now complete 162 relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment 163 164 if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now 165 for (int j = firstHi16; j < i; j++) { 166 if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s 167 lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target 168 *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target 169 *lastTarget |= (relocation>>16) & 0xffff; // Take the upper 16 bits of the relocation 170 if (relocation & 0x8000) (*lastTarget)++; // Subtle: we need to add 1 to the HI16 in this case 171 } 172 firstHi16 = -1; // Reset so we'll know we treated it 173 } 174 else { 175 extendedHi16++; 176 } 177 178 *target &= 0xffff0000; // Clear the lower 16 bits of current target 179 *target |= relocation & 0xffff; // Take the lower 16 bits of the relocation 180 181 if (debugRelocs[1]++ < DEBUG_NUM) 182 DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", 183 i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); 184 if (ahl & 0x8000 && debugRelocs[2]++ < DEBUG_NUM) 185 DBG("R_MIPS_LO16: i=%d, offset=%x, a=%x, ahl = %x, lastTarget = %x, origt = %x, target = %x\n", 186 i, rel[i].r_offset, a, ahl, *lastTarget, origTarget, *target); 187 } 188 break; 189 190 case R_MIPS_26: // Absolute addressing 191 if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment 192 a = *target & 0x03ffffff; // Get 26 bits' worth of the addend 193 a = (a<<6)>>6; // Sign extend a 194 relocation = ((a<<2) + (Elf32_Addr)_segment)>>2; // a already points to the target. Subtract our offset 195 *target &= 0xfc000000; // Clean lower 26 target bits 196 *target |= (relocation & 0x03ffffff); 197 198 if (debugRelocs[3]++ < DEBUG_NUM) 199 DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", 200 i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info,a, origTarget, *target); 201 } 202 else { 203 if (debugRelocs[4]++ < DEBUG_NUM) 204 DBG("R_MIPS_26: i=%d, offset=%x, symbol=%d, stinfo=%x, a=%x, origTarget=%x, target=%x\n", 205 i, rel[i].r_offset, REL_INDEX(rel[i].r_info), sym->st_info,a, origTarget, *target); 206 } 207 break; 208 209 case R_MIPS_GPREL16: // GP Relative addressing 210 if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section 211 ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole 212 a = *target & 0xffff; // Get 16 bits' worth of the addend 213 a = (a<<16)>>16; // Sign extend it 214 215 relocation = a + _shortsSegment->getOffset(); 216 217 *target &= 0xffff0000; // Clear the lower 16 bits of the target 218 *target |= relocation & 0xffff; 219 220 if (debugRelocs[5]++ < DEBUG_NUM) 221 DBG("R_MIPS_GPREL16: i=%d, a=%x, gpVal=%x, origTarget=%x, target=%x, offset=%x\n", 222 i, a, _gpVal, origTarget, *target, _shortsSegment->getOffset()); 223 } 224 225 break; 226 227 case R_MIPS_32: // Absolute addressing 228 if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. 229 a = *target; // Get full 32 bits of addend 230 relocation = a + (Elf32_Addr)_segment; // Shift 231 *target = relocation; 232 233 if (debugRelocs[6]++ < DEBUG_NUM) 234 DBG("R_MIPS_32: i=%d, a=%x, origTarget=%x, target=%x\n", i, a, origTarget, *target); 235 } 236 break; 237 238 default: 239 seterror("Unknown relocation type %x at relocation %d.\n", REL_TYPE(rel[i].r_info), i); 240 free(rel); 241 return false; 242 } 243 244 } 245 246 DBG("Done with relocation. extendedHi16=%d\n\n", extendedHi16); 247 248 free(rel); 249 return true; 250 } 251 252 bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) 253 { 254 // Start reading the elf header. Check for errors 255 if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr) || 256 memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC 257 ehdr->e_type != ET_EXEC || // Check for executable 258 ehdr->e_machine != EM_MIPS || // Check for MIPS machine type 259 ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header 260 ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header 261 seterror("Invalid file type."); 262 return false; 263 } 264 265 DBG("phoff = %d, phentsz = %d, phnum = %d\n", 266 ehdr->e_phoff, ehdr->e_phentsize, ehdr->e_phnum); 267 268 return true; 269 } 270 271 bool DLObject::readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) 272 { 273 // Read program header 274 if (lseek(fd, ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET)<0 || 275 read(fd, phdr, sizeof(*phdr)) != sizeof(*phdr)) { 276 seterror("Program header load failed."); 277 return false; 278 } 279 280 // Check program header values 281 if (phdr->p_type != PT_LOAD || phdr->p_filesz > phdr->p_memsz) { 282 seterror("Invalid program header."); 283 return false; 284 } 285 286 DBG("offs = %x, filesz = %x, memsz = %x, align = %x\n", 287 phdr->p_offset, phdr->p_filesz, phdr->p_memsz, phdr->p_align); 288 289 return true; 290 291 } 292 293 bool DLObject::loadSegment(int fd, Elf32_Phdr *phdr) { 294 295 char *baseAddress = 0; 296 297 // We need to take account of non-allocated segment for shorts 298 if (phdr->p_flags & PF_X) { // This is a relocated segment 299 300 // Attempt to allocate memory for segment 301 int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here 302 DBG("extra mem is %x\n", extra); 303 304 if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI 305 306 if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { 307 seterror("Out of memory.\n"); 308 return false; 309 } 310 DBG("allocated segment @ %p\n", _segment); 311 312 // Get offset to load segment into 313 baseAddress = (char *)_segment + phdr->p_vaddr; 314 _segmentSize = phdr->p_memsz + extra; 315 } 316 else { // This is a shorts section. 317 _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); 318 319 baseAddress = _shortsSegment->getStart(); 320 DBG("shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x\n", 321 _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); 322 323 } 324 325 // Set bss segment to 0 if necessary (assumes bss is at the end) 326 if (phdr->p_memsz > phdr->p_filesz) { 327 DBG("Setting %p to %p to 0 for bss\n", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); 328 memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); 329 } 330 // Read the segment into memory 331 if (lseek(fd, phdr->p_offset, SEEK_SET) < 0 || 332 read(fd, baseAddress, phdr->p_filesz) != (ssize_t)phdr->p_filesz) { 333 seterror("Segment load failed."); 334 return false; 335 } 336 337 return true; 338 } 339 340 341 Elf32_Shdr * DLObject::loadSectionHeaders(int fd, Elf32_Ehdr *ehdr) { 342 343 Elf32_Shdr *shdr = NULL; 344 345 // Allocate memory for section headers 346 if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { 347 seterror("Out of memory."); 348 return NULL; 349 } 350 351 // Read from file into section headers 352 if (lseek(fd, ehdr->e_shoff, SEEK_SET)<0 || 353 read(fd, shdr, ehdr->e_shnum * sizeof(*shdr)) != 354 (ssize_t)(ehdr->e_shnum * sizeof(*shdr))) { 355 seterror("Section headers load failed."); 356 return NULL; 357 } 358 359 return shdr; 360 } 361 362 int DLObject::loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) 363 { 364 365 // Loop over sections, looking for symbol table linked to a string table 366 for (int i=0; i<ehdr->e_shnum; i++) { 367 //DBG("Section %d: type = %x, size = %x, entsize = %x, link = %x\n", 368 // i, shdr[i].sh_type, shdr[i].sh_size, shdr[i].sh_entsize, shdr[i].sh_link); 369 370 if (shdr[i].sh_type == SHT_SYMTAB && 371 shdr[i].sh_entsize == sizeof(Elf32_Sym) && 372 shdr[i].sh_link < ehdr->e_shnum && 373 shdr[shdr[i].sh_link].sh_type == SHT_STRTAB && 374 _symtab_sect < 0) { 375 _symtab_sect = i; 376 } 377 } 378 379 // Check for no symbol table 380 if (_symtab_sect < 0) { 381 seterror("No symbol table."); 382 return -1; 383 } 384 385 DBG("Symbol section at section %d, size %x\n", _symtab_sect, shdr[_symtab_sect].sh_size); 386 387 // Allocate memory for symbol table 388 if (!(_symtab = malloc(shdr[_symtab_sect].sh_size))) { 389 seterror("Out of memory."); 390 return -1; 391 } 392 393 // Read symbol table into memory 394 if (lseek(fd, shdr[_symtab_sect].sh_offset, SEEK_SET)<0 || 395 read(fd, _symtab, shdr[_symtab_sect].sh_size) != 396 (ssize_t)shdr[_symtab_sect].sh_size){ 397 seterror("Symbol table load failed."); 398 return -1; 399 } 400 401 // Set number of symbols 402 _symbol_cnt = shdr[_symtab_sect].sh_size / sizeof(Elf32_Sym); 403 DBG("Loaded %d symbols.\n", _symbol_cnt); 404 405 return _symtab_sect; 406 407 } 408 409 bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) { 410 411 int string_sect = shdr[_symtab_sect].sh_link; 412 413 // Allocate memory for string table 414 if (!(_strtab = (char *)malloc(shdr[string_sect].sh_size))) { 415 seterror("Out of memory."); 416 return false; 417 } 418 419 // Read string table into memory 420 if (lseek(fd, shdr[string_sect].sh_offset, SEEK_SET)<0 || 421 read(fd, _strtab, shdr[string_sect].sh_size) != 422 (ssize_t)shdr[string_sect].sh_size) { 423 seterror("Symbol table strings load failed."); 424 return false; 425 } 426 return true; 427 } 428 429 void DLObject::relocateSymbols(Elf32_Addr offset, Elf32_Addr shortsOffset) { 430 431 int shortsCount = 0, othersCount = 0; 432 DBG("Relocating symbols by %x. Shorts offset=%x\n", offset, shortsOffset); 433 434 // Loop over symbols, add relocation offset 435 Elf32_Sym *s = (Elf32_Sym *)_symtab; 436 for (int c = _symbol_cnt; c--; s++) { 437 // Make sure we don't relocate special valued symbols 438 if (s->st_shndx < SHN_LOPROC) { 439 if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { 440 othersCount++; 441 s->st_value += offset; 442 if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) 443 seterror("Symbol out of bounds! st_value = %x\n", s->st_value); 444 } 445 else { // shorts section 446 shortsCount++; 447 s->st_value += shortsOffset; 448 if (!_shortsSegment->inSegment((char *)s->st_value)) 449 seterror("Symbol out of bounds! st_value = %x\n", s->st_value); 450 } 451 452 } 453 454 } 455 456 DBG("Relocated %d short symbols, %d others.\n", shortsCount, othersCount); 457 } 458 459 bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { 460 461 // Loop over sections, finding relocation sections 462 for (int i=0; i<ehdr->e_shnum; i++) { 463 464 Elf32_Shdr *curShdr = &(shdr[i]); 465 //Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]); 466 467 if (curShdr->sh_type == SHT_REL && // Check for a relocation section 468 curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size 469 (int)curShdr->sh_link == _symtab_sect && // Check that the sh_link connects to our symbol table 470 curShdr->sh_info < ehdr->e_shnum && // Check that the relocated section exists 471 (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory 472 if (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment 473 if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, _segment)) { 474 return false; 475 } 476 } else { // In Shorts segment 477 if (!relocate(fd, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) { 478 return false; 479 } 480 } 481 482 } 483 } 484 485 return true; 486 } 487 488 489 bool DLObject::load(int fd) 490 { 491 fprintf(stderr,"In DLObject::load\n"); 492 493 Elf32_Ehdr ehdr; // ELF header 494 Elf32_Phdr phdr; // Program header 495 Elf32_Shdr *shdr; // Section header 496 bool ret = true; 497 498 if (readElfHeader(fd, &ehdr) == false) 499 { 500 return false; 501 } 502 503 for(int i=0; i<ehdr.e_phnum; i++) { // Load our 2 segments 504 505 fprintf(stderr,"Loading segment %d\n", i); 506 507 if (readProgramHeaders(fd, &ehdr, &phdr, i) == false) 508 return false; 509 510 if (!loadSegment(fd, &phdr)) 511 return false; 512 } 513 514 if ((shdr = loadSectionHeaders(fd, &ehdr)) == NULL) 515 ret = false; 516 517 if (ret && ((_symtab_sect = loadSymbolTable(fd, &ehdr, shdr)) < 0)) 518 ret = false; 519 520 if (ret && (loadStringTable(fd, shdr) == false)) 521 ret = false; 522 523 if (ret) 524 relocateSymbols((Elf32_Addr)_segment, _shortsSegment->getOffset()); // Offset by our segment allocated address 525 526 if (ret && (relocateRels(fd, &ehdr, shdr) == false)) 527 ret = false; 528 529 if (shdr) 530 free(shdr); 531 532 return ret; 533 } 534 535 bool DLObject::open(const char *path) 536 { 537 int fd; 538 void *ctors_start, *ctors_end; 539 540 DBG("open(\"%s\")\n", path); 541 542 // Get the address of the global pointer 543 _gpVal = (unsigned int)&_gp; 544 DBG("_gpVal is %x\n", _gpVal); 545 546 PowerMan.beginCriticalSection(); 547 548 if ((fd = ::open(path, O_RDONLY))<0) { 549 seterror("%s not found.", path); 550 return false; 551 } 552 553 // Try to load and relocate 554 if (!load(fd)) { 555 ::close(fd); 556 unload(); 557 return false; 558 } 559 560 ::close(fd); 561 562 PowerMan.endCriticalSection(); 563 564 // flush data cache 565 sceKernelDcacheWritebackAll(); 566 567 // Get the symbols for the global constructors and destructors 568 ctors_start = symbol("___plugin_ctors"); 569 ctors_end = symbol("___plugin_ctors_end"); 570 _dtors_start = symbol("___plugin_dtors"); 571 _dtors_end = symbol("___plugin_dtors_end"); 572 573 if (ctors_start == NULL || ctors_end == NULL || _dtors_start == NULL || 574 _dtors_end == NULL) { 575 seterror("Missing ctors/dtors."); 576 _dtors_start = _dtors_end = NULL; 577 unload(); 578 return false; 579 } 580 581 DBG("Calling constructors.\n"); 582 for (void (**f)(void) = (void (**)(void))ctors_start; f != ctors_end; f++) 583 (**f)(); 584 585 DBG("%s opened ok.\n", path); 586 return true; 587 } 588 589 bool DLObject::close() 590 { 591 if (_dtors_start != NULL && _dtors_end != NULL) 592 for (void (**f)(void) = (void (**)(void))_dtors_start; f != _dtors_end; f++) 593 (**f)(); 594 _dtors_start = _dtors_end = NULL; 595 unload(); 596 return true; 597 } 598 599 void *DLObject::symbol(const char *name) 600 { 601 DBG("symbol(\"%s\")\n", name); 602 603 if (_symtab == NULL || _strtab == NULL || _symbol_cnt < 1) { 604 seterror("No symbol table loaded."); 605 return NULL; 606 } 607 608 Elf32_Sym *s = (Elf32_Sym *)_symtab; 609 for (int c = _symbol_cnt; c--; s++) { 610 611 // We can only import symbols that are global or weak in the plugin 612 if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && 613 /*_strtab[s->st_name] == '_' && */ // Try to make this more efficient 614 !strcmp(name, _strtab+s->st_name)) { 615 616 // We found the symbol 617 DBG("=> %p\n", (void*)s->st_value); 618 return (void*)s->st_value; 619 } 620 } 621 622 seterror("Symbol \"%s\" not found.", name); 623 return NULL; 624 } 625 626 627 628 ShortSegmentManager::ShortSegmentManager() { 629 _shortsStart = &__plugin_hole_start ; 630 _shortsEnd = &__plugin_hole_end; 631 } 632 633 ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { 634 635 char *lastAddress = origAddr; 636 Common::List<Segment *>::iterator i; 637 638 // Find a block that fits, starting from the beginning 639 for (i = _list.begin(); i != _list.end(); i++) { 640 char *currAddress = (*i)->getStart(); 641 642 if ((int)(currAddress - lastAddress) >= size) break; 643 644 lastAddress = (*i)->getEnd(); 645 } 646 647 if ((Elf32_Addr)lastAddress & 3) 648 lastAddress += 4 - ((Elf32_Addr)lastAddress & 3); // Round up to multiple of 4 649 650 if (lastAddress + size > _shortsEnd) { 651 seterror("Error. No space in shorts segment for %x bytes. Last address is %p, max address is %p.\n", 652 size, lastAddress, _shortsEnd); 653 return NULL; 654 } 655 656 Segment *seg = new Segment(lastAddress, size, origAddr); // Create a new segment 657 658 if (lastAddress + size > _highestAddress) _highestAddress = lastAddress + size; // Keep track of maximum 659 660 _list.insert(i, seg); 661 662 DBG("Shorts segment size %x allocated. End = %p. Remaining space = %x. Highest so far is %p.\n", 663 size, lastAddress + size, _shortsEnd - _list.back()->getEnd(), _highestAddress); 664 665 return seg; 666 } 667 668 void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { 669 670 DBG("Deleting shorts segment from %p to %p.\n\n", seg->getStart(), seg->getEnd()); 671 _list.remove(seg); 672 delete seg; 673 } 674 675 static char dlerr[MAXDLERRLEN]; 676 677 void *dlopen(const char *filename, int flags) 678 { 679 DLObject *obj = new DLObject(dlerr); 680 if (obj->open(filename)) 681 return (void *)obj; 682 delete obj; 683 return NULL; 684 } 685 686 int dlclose(void *handle) 687 { 688 DLObject *obj = (DLObject *)handle; 689 if (obj == NULL) { 690 strcpy(dlerr, "Handle is NULL."); 691 return -1; 692 } 693 if (obj->close()) { 694 delete obj; 695 return 0; 696 } 697 return -1; 698 } 699 700 void *dlsym(void *handle, const char *symbol) 701 { 702 if (handle == NULL) { 703 strcpy(dlerr, "Handle is NULL."); 704 return NULL; 705 } 706 return ((DLObject *)handle)->symbol(symbol); 707 } 708 709 const char *dlerror() 710 { 711 return dlerr; 712 } 713 714 void dlforgetsyms(void *handle) 715 { 716 if (handle != NULL) 717 ((DLObject *)handle)->discard_symtab(); 718 } 719 720 721 #endif /* DYNAMIC_MODULES && __PSP__ */ -
backends/platform/psp/Makefile
Property changes on: backends/platform/psp/psploader.cpp ___________________________________________________________________ Added: svn:executable + *
2 2 # $URL$ 3 3 # $Id$ 4 4 5 ENABLED=STATIC_PLUGIN 5 VERBOSE_BUILD=1 6 #Use only this section to modify how the makefile behaves ------------ 6 7 7 #control build 8 DISABLE_SCALERS = true 9 DISABLE_HQ_SCALERS = true 10 8 # Scummvm engine config: choose which engines are enabled 11 9 ENABLE_SCUMM = $(ENABLED) 12 10 ENABLE_SCUMM_7_8 = $(ENABLED) 13 #ENABLE_HE = $(ENABLED)11 ENABLE_HE = $(ENABLED) 14 12 ENABLE_AGI = $(ENABLED) 15 13 ENABLE_AGOS = $(ENABLED) 16 #ENABLE_CINE = $(ENABLED)17 #ENABLE_CRUISE = $(ENABLED)14 ENABLE_CINE = $(ENABLED) 15 ENABLE_CRUISE = $(ENABLED) 18 16 ENABLE_DRASCULA = $(ENABLED) 19 17 ENABLE_GOB = $(ENABLED) 20 #ENABLE_IGOR = $(ENABLED)18 ENABLE_IGOR = $(ENABLED) 21 19 ENABLE_KYRA = $(ENABLED) 22 20 ENABLE_LURE = $(ENABLED) 23 #ENABLE_M4 = $(ENABLED)24 #ENABLE_MADE = $(ENABLED)25 #ENABLE_PARALLACTION = $(ENABLED)26 #ENABLE_QUEEN = $(ENABLED)27 #ENABLE_SAGA = $(ENABLED)21 ENABLE_M4 = $(ENABLED) 22 ENABLE_MADE = $(ENABLED) 23 ENABLE_PARALLACTION = $(ENABLED) 24 ENABLE_QUEEN = $(ENABLED) 25 ENABLE_SAGA = $(ENABLED) 28 26 ENABLE_SKY = $(ENABLED) 29 27 ENABLE_SWORD1 = $(ENABLED) 30 28 ENABLE_SWORD2 = $(ENABLED) 31 #ENABLE_TINSEL = $(ENABLED) 32 #ENABLE_TOUCHE = $(ENABLED) 29 ENABLE_TINSEL = $(ENABLED) 30 ENABLE_TOUCHE = $(ENABLED) 31 ENABLE_SCI = $(ENABLED) 32 ENABLE_IHNM = $(ENABLED) 33 33 34 #Set to 1 to enable, 0 to disable dynamic modules 35 DYNAMIC_MODULES = 1 36 #Set to 1 to enable, 0 to disable libmad and libogg 37 USE_LIBMAD = 1 38 USE_LIBOGG = 1 39 #Set to 1 to enable, 0 to disable gcc optimizations 40 GCC_OPTIMIZE = 0 41 # -------------------------------------------------------------------- 34 42 43 44 # General variables 35 45 srcdir = ../../.. 36 46 VPATH = $(srcdir) 37 HAVE_GCC3 = false 38 39 PSPSDK =$(shell psp-config --pspsdk-path)47 TARGET = scummvm-psp 48 # PSP SDK location variables 49 PSPSDK := $(shell psp-config --pspsdk-path) 40 50 PSPBIN = $(PSPSDK)/../bin 41 LDFLAGS =42 51 43 CXX = psp-g++ 52 #check PSPSDK presence 53 ifeq ($(PSPSDK),) 54 $(error $$(PSPSDK) cannot be obtained.) 55 endif 56 57 58 # Variables for common Scummvm makefile 59 #CC = psp-gcc 60 CXX = psp-g++ 61 CXXFLAGS = -O3 -Wall -Wno-multichar -fno-exceptions -fno-rtti 62 DEFINES = -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB 63 LDFLAGS := 64 INCDIR := $(srcdir) . $(srcdir)/engines/ $(PSPSDK)/include 65 INCLUDES := $(addprefix -I, $(INCDIR)) 66 #EXECUTABLE = $(TARGET) 67 DEPDIR = .deps 68 MODULE_DIRS += ./ 69 MKDIR = mkdir -p 70 RM = rm -f 71 RM_REC = rm -rf 72 AR = psp-ar cru 73 RANLIB = psp-ranlib 44 74 AS = psp-gcc 45 75 LD = psp-gcc 46 AR = psp-ar cru 47 RANLIB = psp-ranlib 76 HAVE_GCC3 = true 77 CXX_UPDATE_DEP_FLAG = -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP 78 79 # Variables for dynamic plugin building 80 PLUGIN_PREFIX = 81 PLUGIN_SUFFIX = .plg 82 PLUGIN_EXTRA_DEPS = plugin.syms scummvm-psp.elf 83 # ,--retain-symbols-file,plugin.syms 84 PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols=scummvm-psp.org.elf,-Tplugin.ld \ 85 -lstdc++ -lc -Wl,-Map,mapfile.txt 86 87 #PLUGIN_EXTRA_DEPS = plugin.ld plugin.syms scummvm-psp.elf 88 #PLUGIN_LDFLAGS = -Wl -Tplugin.ld --just-symbols=scummvm-psp.org.elf --retain-symbols-file plugin.syms 89 90 # Remove unneeded scalers 91 DISABLE_SCALERS = true 92 DISABLE_HQ_SCALERS = true 93 94 # PSP-specific variables 48 95 STRIP = psp-strip 49 MKDIR = mkdir -p50 RM = rm -f51 RM_REC = rm -rf52 96 MKSFO = mksfoex -d MEMSIZE=1 53 97 PACK_PBP = pack-pbp 54 98 FIXUP = psp-fixup-imports 55 99 56 #check PSPSDK presence 57 ifeq ($(PSPSDK),) 58 $(error $$(PSPSDK) is undefined. Use "PSPSDK := $$(shell psp-config --pspsdk-path)" in your Makefile) 100 # Test for adding different libs 101 ifeq ($(USE_LIBMAD),1) 102 DEFINES += -DUSE_MAD 103 LIBS += -lmad 59 104 endif 105 ifeq ($(USE_LIBOGG), 1) 106 DEFINES += -DUSE_VORBIS -DUSE_TREMOR 107 LIBS += -lvorbisidec 108 endif 60 109 61 # Add in PSPSDK includes and libraries. 62 INCDIR := $(srcdir) . $(srcdir)/engines/ . $(PSPSDK)/include 63 LIBDIR := $(LIBDIR) . $(PSPSDK)/lib 110 # Test for dynamic plugins 111 ifeq ($(DYNAMIC_MODULES),1) 112 ENABLED = DYNAMIC_PLUGIN 113 DEFINES += -DDYNAMIC_MODULES 114 PRE_OBJS_FLAGS = -Wl,--whole-archive 115 POST_OBJS_FLAGS = -Wl,--no-whole-archive 116 else 117 ENABLED = STATIC_PLUGIN 118 endif 64 119 65 CXXFLAGS = -O3 -Wall -D__PSP__ -DNONSTANDARD_PORT -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DUSE_ZLIB -DDISABLE_DOSBOX_OPL -Wno-multichar `$(PSPBIN)/sdl-config --cflags` 66 CXXFLAGS:= $(addprefix -I,$(INCDIR)) $(CXXFLAGS) 67 LDFLAGS := $(addprefix -L,$(LIBDIR)) $(LDFLAGS) 68 LIBS = 120 # SDL Libs and Flags 121 SDLFLAGS := $(shell sdl-config --cflags) 122 SDLLIBS := $(shell sdl-config --libs) 123 # PSP LIBS 124 PSPLIBS = -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet \ 125 -lpspnet_inet -lpsputility -lpspuser -lpsppower 69 126 70 # comment this out if you don't want to use libmad71 CXXFLAGS += -DUSE_MAD72 LIBS += -lmad127 # Add in PSPSDK includes and libraries. 128 CXXFLAGS += $(SDLFLAGS) 129 LIBS += -lz -lstdc++ -lc $(SDLLIBS) $(PSPLIBS) 73 130 74 #comment this out if you don't want to use libtremor75 CXXFLAGS+= -DUSE_VORBIS -DUSE_TREMOR76 LIBS += -lvorbisidec77 78 LIBS += `$(PSPBIN)/sdl-config --libs` -lz -lstdc++ -lc -lpspdisplay -lpspgu -lpspctrl -lpspsdk -lpspnet -lpspnet_inet -lpsputility -lpspuser -lpsppower79 80 CXXFLAGS := $(CXXFLAGS) -fno-exceptions -fno-rtti81 82 TARGET = scummvm-psp83 131 OBJS := powerman.o \ 84 132 psp_main.o \ 85 133 osys_psp.o \ … … 87 135 kbd_s_c.o \ 88 136 kbd_ls_c.o \ 89 137 kbd_l_c.o \ 90 trace.o 138 trace.o \ 139 psploader.o 91 140 92 DEPDIR = .deps 93 CXX_UPDATE_DEP_FLAG = "-Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP" 94 141 # Include common Scummvm makefile 95 142 include $(srcdir)/Makefile.common 96 143 144 # Variables for PSP-specific rules 97 145 PSP_EBOOT_SFO = param.sfo 98 146 PSP_EBOOT_TITLE = ScummVM-PSP 99 147 PSP_EBOOT = EBOOT.PBP … … 104 152 PSP_EBOOT_SND0 = NULL 105 153 PSP_EBOOT_PSAR = NULL 106 154 155 SCOBJS := $(filter %.o, $(OBJS)) 156 SCARCS := $(filter %.a, $(OBJS)) 157 SCBE := $(filter %backends.a, $(SCARCS)) 158 LDFLAGS += -Wl,-Tmain_prog.ld 159 107 160 all: $(PSP_EBOOT) 108 161 162 # --start-group $^ --end-group 109 163 $(TARGET).elf: $(OBJS) 110 $(LD) $^ $(LIBS) -o $@ 164 $(LD) $(PRE_OBJS_FLAGS) $(OBJS) $(POST_OBJS_FLAGS) $(LDFLAGS) $(LIBS) -o $@ 165 cp $(TARGET).elf $(TARGET).org.elf 111 166 $(FIXUP) $@ 112 167 113 168 $(PSP_EBOOT_SFO): … … 134 189 $(PACK_PBP) "%__SCE__$(TARGET)/$(PSP_EBOOT)" $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \ 135 190 $(PSP_EBOOT_ICON1) $(PSP_EBOOT_PIC0) $(PSP_EBOOT_PIC1) \ 136 191 $(PSP_EBOOT_SND0) NULL $(PSP_EBOOT_PSAR) 137 192 193 No newline at end of file -
backends/module.mk
32 32 plugins/posix/posix-provider.o \ 33 33 plugins/sdl/sdl-provider.o \ 34 34 plugins/win32/win32-provider.o \ 35 plugins/psp/psp-provider.o \ 35 36 saves/savefile.o \ 36 37 saves/default/default-saves.o \ 37 38 saves/posix/posix-saves.o \