diff options
Diffstat (limited to 'backends/platform')
| -rw-r--r-- | backends/platform/ds/arm9/makefile | 4 | ||||
| -rw-r--r-- | backends/platform/ds/arm9/source/plugin.ld | 218 | ||||
| -rw-r--r-- | backends/platform/ds/arm9/source/plugin.syms | 8 | ||||
| -rw-r--r-- | backends/platform/ps2/Makefile.ps2 | 8 | ||||
| -rw-r--r-- | backends/platform/ps2/plugin.ld | 94 | ||||
| -rw-r--r-- | backends/platform/ps2/plugin.syms | 8 | ||||
| -rw-r--r-- | backends/platform/ps2/ps2loader.cpp | 721 | ||||
| -rw-r--r-- | backends/platform/ps2/ps2loader.h | 137 | ||||
| -rw-r--r-- | backends/platform/psp/Makefile | 4 | ||||
| -rw-r--r-- | backends/platform/psp/plugin.ld | 239 | ||||
| -rw-r--r-- | backends/platform/psp/plugin.syms | 8 | 
11 files changed, 9 insertions, 1440 deletions
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 <string.h> -#include <stdarg.h> -#include <stdio.h> -#include <malloc.h> -#include <unistd.h> -#include <sys/fcntl.h> - -#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<Segment *>::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<ShortSegmentManager> { -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<ShortSegmentManager>; -	Common::List<Segment *> _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  | 
