From 3b2a9734d15b1ddd5955e2634639122a1d4416cb Mon Sep 17 00:00:00 2001 From: Andre Heider Date: Sun, 5 Sep 2010 12:52:49 +0000 Subject: PLUGINS: Type cleanup. Use our types, get rid of some casts. svn-id: r52557 --- backends/plugins/elf/arm-loader.cpp | 28 ++++---- backends/plugins/elf/arm-loader.h | 2 +- backends/plugins/elf/elf-loader.cpp | 69 +++++++++--------- backends/plugins/elf/elf-loader.h | 16 +++-- backends/plugins/elf/elf32.h | 19 ++--- backends/plugins/elf/mips-loader.cpp | 95 +++++++++++++------------ backends/plugins/elf/mips-loader.h | 4 +- backends/plugins/elf/ppc-loader.cpp | 19 +++-- backends/plugins/elf/ppc-loader.h | 2 +- backends/plugins/elf/shorts-segment-manager.cpp | 6 +- backends/plugins/elf/shorts-segment-manager.h | 24 +++++-- 11 files changed, 153 insertions(+), 131 deletions(-) (limited to 'backends') diff --git a/backends/plugins/elf/arm-loader.cpp b/backends/plugins/elf/arm-loader.cpp index ab1129d34c..ace3b51e3c 100644 --- a/backends/plugins/elf/arm-loader.cpp +++ b/backends/plugins/elf/arm-loader.cpp @@ -38,47 +38,46 @@ * @param size Size of relocation section * @param relSegment Base address of relocated segment in memory (memory offset) */ -bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { +bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; //relocation entry // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { + if (!(rel = (Elf32_Rel *) malloc(size))) { warning("elfloader: Out of memory."); return false; } // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || - DLFile->read(rel, size) != size) { + if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; } // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); + uint32 cnt = size / sizeof(*rel); debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); - int a = 0; - unsigned int relocation = 0; + int32 a = 0; + uint32 relocation = 0; // Loop over relocation entries - for (int i = 0; i < cnt; i++) { + for (uint32 i = 0; i < cnt; i++) { // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + uint32 *target = (uint32 *) ((byte *) relSegment + rel[i].r_offset); - unsigned int origTarget = *target; //Save for debugging + uint32 origTarget = *target; //Save for debugging // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { case R_ARM_ABS32: if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. a = *target; // Get full 32 bits of addend - relocation = a + (Elf32_Addr)_segment; // Shift by main offset + relocation = a + Elf32_Addr(_segment); // Shift by main offset *target = relocation; @@ -115,12 +114,12 @@ bool ARMDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Loop over sections, finding relocation sections - for (int i = 0; i < ehdr->e_shnum; i++) { + for (uint32 i = 0; i < ehdr->e_shnum; i++) { Elf32_Shdr *curShdr = &(shdr[i]); if ((curShdr->sh_type == SHT_REL || curShdr->sh_type == SHT_RELA) && // Check for a relocation section curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size - (int)curShdr->sh_link == _symtab_sect && // Check that the sh_link connects to our symbol table + int32(curShdr->sh_link) == _symtab_sect && // Check that the sh_link connects to our symbol table curShdr->sh_info < ehdr->e_shnum && // Check that the relocated section exists (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory @@ -138,3 +137,4 @@ bool ARMDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e } #endif /* defined(DYNAMIC_MODULES) && defined(ARM_TARGET) */ + diff --git a/backends/plugins/elf/arm-loader.h b/backends/plugins/elf/arm-loader.h index c4df671060..1d4e248a7b 100644 --- a/backends/plugins/elf/arm-loader.h +++ b/backends/plugins/elf/arm-loader.h @@ -32,7 +32,7 @@ class ARMDLObject : public DLObject { protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: diff --git a/backends/plugins/elf/elf-loader.cpp b/backends/plugins/elf/elf-loader.cpp index e11f9fcce6..32e42daf7d 100644 --- a/backends/plugins/elf/elf-loader.cpp +++ b/backends/plugins/elf/elf-loader.cpp @@ -35,13 +35,13 @@ DLObject::DLObject() : _segment(0), _symtab(0), _strtab(0), + _segmentSize(0), + _segmentOffset(0), + _segmentVMA(0), _symbol_cnt(0), _symtab_sect(-1), _dtors_start(0), - _dtors_end(0), - _segmentSize(0), - _segmentOffset(0), - _segmentVMA(0) { + _dtors_end(0) { } DLObject::~DLObject() { @@ -127,9 +127,9 @@ bool DLObject::readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehd return true; } -bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num) { +bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num) { // Read program header - if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr)*num, SEEK_SET) || + if (!DLFile->seek(ehdr->e_phoff + sizeof(*phdr) * num, SEEK_SET) || DLFile->read(phdr, sizeof(*phdr)) != sizeof(*phdr)) { warning("elfloader: Program header load failed."); return false; @@ -148,13 +148,13 @@ bool DLObject::readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr } bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { - char *baseAddress = 0; - // Attempt to allocate memory for segment - int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here + uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); - if (!(_segment = (char *) allocSegment(phdr->p_align, phdr->p_memsz + extra))) { + _segment = (byte *) allocSegment(phdr->p_align, phdr->p_memsz + extra); + + if (!_segment) { warning("elfloader: Out of memory."); return false; } @@ -162,21 +162,20 @@ bool DLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into - baseAddress = (char *)_segment; _segmentSize = phdr->p_memsz + extra; _segmentVMA = phdr->p_vaddr; // Set bss segment to 0 if necessary (assumes bss is at the end) if (phdr->p_memsz > phdr->p_filesz) { - debug(2, "elfloader: Setting %p to %p to 0 for bss", baseAddress + phdr->p_filesz, baseAddress + phdr->p_memsz); - memset(baseAddress + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + debug(2, "elfloader: Setting %p to %p to 0 for bss", _segment + phdr->p_filesz, _segment + phdr->p_memsz); + memset(_segment + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); } debug(2, "elfloader: Reading the segment into memory"); // Read the segment into memory if (!DLFile->seek(phdr->p_offset, SEEK_SET) || - DLFile->read(baseAddress, phdr->p_filesz) != phdr->p_filesz) { + DLFile->read(_segment, phdr->p_filesz) != phdr->p_filesz) { warning("elfloader: Segment load failed."); return false; } @@ -190,7 +189,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El Elf32_Shdr *shdr = 0; // Allocate memory for section headers - if (!(shdr = (Elf32_Shdr *)malloc(ehdr->e_shnum * sizeof(*shdr)))) { + if (!(shdr = (Elf32_Shdr *) malloc(ehdr->e_shnum * sizeof(*shdr)))) { warning("elfloader: Out of memory."); return 0; } @@ -208,7 +207,7 @@ Elf32_Shdr * DLObject::loadSectionHeaders(Common::SeekableReadStream* DLFile, El int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Loop over sections, looking for symbol table linked to a string table - for (int i = 0; i < ehdr->e_shnum; i++) { + for (uint32 i = 0; i < ehdr->e_shnum; i++) { if (shdr[i].sh_type == SHT_SYMTAB && shdr[i].sh_entsize == sizeof(Elf32_Sym) && shdr[i].sh_link < ehdr->e_shnum && @@ -227,7 +226,7 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh debug(2, "elfloader: Symbol section at section %d, size %x", _symtab_sect, shdr[_symtab_sect].sh_size); // Allocate memory for symbol table - if (!(_symtab = malloc(shdr[_symtab_sect].sh_size))) { + if (!(_symtab = (Elf32_Sym *) malloc(shdr[_symtab_sect].sh_size))) { warning("elfloader: Out of memory."); return -1; } @@ -248,10 +247,10 @@ int DLObject::loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *eh } bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *shdr) { - int string_sect = shdr[_symtab_sect].sh_link; + uint32 string_sect = shdr[_symtab_sect].sh_link; // Allocate memory for string table - if (!(_strtab = (char *)malloc(shdr[string_sect].sh_size))) { + if (!(_strtab = (char *) malloc(shdr[string_sect].sh_size))) { warning("elfloader: Out of memory."); return false; } @@ -269,13 +268,14 @@ bool DLObject::loadStringTable(Common::SeekableReadStream* DLFile, Elf32_Shdr *s void DLObject::relocateSymbols(ptrdiff_t offset) { // Loop over symbols, add relocation offset - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) { + Elf32_Sym *s = _symtab; + + for (uint32 c = _symbol_cnt; c--; s++) { // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { - s->st_value += offset; - if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) - warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); + s->st_value += offset; + if (s->st_value < Elf32_Addr(_segment) || s->st_value > Elf32_Addr(_segment) + _segmentSize) + warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } } @@ -286,11 +286,10 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { Elf32_Shdr *shdr; bool ret = true; - if (readElfHeader(DLFile, &ehdr) == false) { + if (readElfHeader(DLFile, &ehdr) == false) return false; - } - for (int i = 0; i < ehdr.e_phnum; i++) { //Load our segments + for (uint32 i = 0; i < ehdr.e_phnum; i++) { //Load our segments debug(2, "elfloader: Loading segment %d", i); if (readProgramHeaders(DLFile, &ehdr, &phdr, i) == false) @@ -300,13 +299,13 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { return false; } - if ((shdr = loadSectionHeaders(DLFile, &ehdr)) == 0) + if (!(shdr = loadSectionHeaders(DLFile, &ehdr))) ret = false; if (ret && ((_symtab_sect = loadSymbolTable(DLFile, &ehdr, shdr)) < 0)) ret = false; - if (ret && (loadStringTable(DLFile, shdr) == false)) + if (ret && !loadStringTable(DLFile, shdr)) ret = false; if (ret) { @@ -315,7 +314,7 @@ bool DLObject::load(Common::SeekableReadStream* DLFile) { relocateSymbols(_segmentOffset); } - if (ret && (relocateRels(DLFile, &ehdr, shdr) == false)) + if (ret && !relocateRels(DLFile, &ehdr, shdr)) ret = false; free(shdr); @@ -373,6 +372,7 @@ bool DLObject::close() { if (_dtors_start && _dtors_end) for (void (**f)(void) = (void (**)(void))_dtors_start; f != _dtors_end; f++) (**f)(); + _dtors_start = _dtors_end = 0; unload(); return true; @@ -386,15 +386,16 @@ void *DLObject::symbol(const char *name) { return 0; } - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) + Elf32_Sym *s = _symtab; + + for (uint32 c = _symbol_cnt; c--; s++) // We can only import symbols that are global or weak in the plugin if ((SYM_BIND(s->st_info) == STB_GLOBAL || SYM_BIND(s->st_info) == STB_WEAK) && !strcmp(name, _strtab + s->st_name)) { // We found the symbol - debug(2, "elfloader: => %p", (void*)s->st_value); - return (void*)s->st_value; + debug(2, "elfloader: => 0x%08x", s->st_value); + return (void*) s->st_value; } // We didn't find the symbol diff --git a/backends/plugins/elf/elf-loader.h b/backends/plugins/elf/elf-loader.h index 7c1d0830f3..9b80a0236f 100644 --- a/backends/plugins/elf/elf-loader.h +++ b/backends/plugins/elf/elf-loader.h @@ -44,21 +44,23 @@ */ class DLObject { protected: - void *_segment, *_symtab; + byte *_segment; + Elf32_Sym *_symtab; char *_strtab; - int _symbol_cnt; - int _symtab_sect; - void *_dtors_start, *_dtors_end; uint32 _segmentSize; ptrdiff_t _segmentOffset; uint32 _segmentVMA; + uint32 _symbol_cnt; + int32 _symtab_sect; + void *_dtors_start, *_dtors_end; + virtual void unload(); bool load(Common::SeekableReadStream* DLFile); bool readElfHeader(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); - bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num); + bool readProgramHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, Elf32_Half num); virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); Elf32_Shdr *loadSectionHeaders(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr); int loadSymbolTable(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); @@ -66,13 +68,14 @@ protected: virtual void relocateSymbols(ptrdiff_t offset); // architecture specific - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) = 0; + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) = 0; virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) = 0; // platform specific virtual void *allocSegment(size_t boundary, size_t size) const = 0; virtual void freeSegment(void *segment) const = 0; virtual void flushDataCache(void *ptr, uint32 len) const = 0; + public: DLObject(); virtual ~DLObject(); @@ -86,3 +89,4 @@ public: #endif /* BACKENDS_PLUGINS_ELF_LOADER_H */ #endif /* defined(DYNAMIC_MODULES) && defined(ELF_LOADER_TARGET) */ + diff --git a/backends/plugins/elf/elf32.h b/backends/plugins/elf/elf32.h index c83093fed7..4586d8dc4c 100644 --- a/backends/plugins/elf/elf32.h +++ b/backends/plugins/elf/elf32.h @@ -26,15 +26,17 @@ #ifndef BACKENDS_ELF_H #define BACKENDS_ELF_H +#include "common/scummsys.h" + /** * ELF stuff: * The contents of this file were gathered mainly from the SYSTEM V APPLICATION BINARY INTERFACE. * Processor-specific things were garnered from processor-specific supplements to the abi. */ -typedef unsigned short Elf32_Half, Elf32_Section; -typedef unsigned int Elf32_Word, Elf32_Addr, Elf32_Off; -typedef signed int Elf32_Sword; +typedef uint16 Elf32_Half, Elf32_Section; +typedef uint32 Elf32_Word, Elf32_Addr, Elf32_Off; +typedef int32 Elf32_Sword; typedef Elf32_Half Elf32_Versym; #define EI_NIDENT (16) @@ -44,7 +46,7 @@ typedef Elf32_Half Elf32_Versym; // ELF header (contains info about the file) typedef struct { - unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + byte e_ident[EI_NIDENT]; /* Magic number and other info */ Elf32_Half e_type; /* Object file type */ Elf32_Half e_machine; /* Architecture */ Elf32_Word e_version; /* Object file version */ @@ -159,8 +161,8 @@ typedef struct { Elf32_Word st_name; /* Symbol name (string tbl index) */ Elf32_Addr st_value; /* Symbol value */ Elf32_Word st_size; /* Symbol size */ - unsigned char st_info; /* Symbol type and binding */ - unsigned char st_other; /* Symbol visibility */ + byte st_info; /* Symbol type and binding */ + byte st_other; /* Symbol visibility */ Elf32_Section st_shndx; /* Section index */ } Elf32_Sym; @@ -203,7 +205,7 @@ typedef struct } Elf32_Rela; // Access macros for the relocation info -#define REL_TYPE(x) ((unsigned char) (x)) /* Extract relocation type */ +#define REL_TYPE(x) ((byte) (x)) /* Extract relocation type */ #define REL_INDEX(x) ((x)>>8) /* Extract relocation index into symbol table */ //MIPS relocation types @@ -244,9 +246,10 @@ typedef struct // Mock function to get value of global pointer for MIPS #define getGP() ({ \ - unsigned int __valgp; \ + uint32 __valgp; \ __asm__ ("add %0, $gp, $0" : "=r"(__valgp) : ); \ __valgp; \ }) #endif /* BACKENDS_ELF_H */ + diff --git a/backends/plugins/elf/mips-loader.cpp b/backends/plugins/elf/mips-loader.cpp index 027ff34698..bf6bb08319 100644 --- a/backends/plugins/elf/mips-loader.cpp +++ b/backends/plugins/elf/mips-loader.cpp @@ -37,51 +37,50 @@ * @param size Size of relocation section * @param relSegment Base address of relocated segment in memory (memory offset) */ -bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { +bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rel *rel = 0; // relocation entry // Allocate memory for relocation table - if (!(rel = (Elf32_Rel *)malloc(size))) { + if (!(rel = (Elf32_Rel *) malloc(size))) { warning("elfloader: Out of memory."); return false; } // Read in our relocation table - if (!DLFile->seek(offset, SEEK_SET) || - DLFile->read(rel, size) != size) { + if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; } // Treat each relocation entry. Loop over all of them - int cnt = size / sizeof(*rel); + uint32 cnt = size / sizeof(*rel); debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment); - bool seenHi16 = false; // For treating HI/LO16 commands - int firstHi16 = -1; // Mark the point of the first hi16 seen - Elf32_Addr ahl = 0; // Calculated addend - int a = 0; // Addend: taken from the target + bool seenHi16 = false; // For treating HI/LO16 commands + int32 firstHi16 = -1; // Mark the point of the first hi16 seen + Elf32_Addr ahl = 0; // Calculated addend + int32 a = 0; // Addend: taken from the target - unsigned int *lastTarget = 0; // For processing hi16 when lo16 arrives - unsigned int relocation = 0; - int debugRelocs[10] = {0}; // For debugging - int extendedHi16 = 0; // Count extended hi16 treatments + uint32 *lastTarget = 0; // For processing hi16 when lo16 arrives + uint32 relocation = 0; + uint debugRelocs[10] = { 0 }; // For debugging + uint extendedHi16 = 0; // Count extended hi16 treatments Elf32_Addr lastHiSymVal = 0; bool hi16InShorts = false; #define DEBUG_NUM 2 // Loop over relocation entries - for (int i = 0; i < cnt; i++) { + for (uint32 i = 0; i < cnt; i++) { // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - unsigned int *target = (unsigned int *)((char *)relSegment + rel[i].r_offset); + uint32 *target = (uint32 *) ((byte *)relSegment + rel[i].r_offset); - unsigned int origTarget = *target; // Save for debugging + uint32 origTarget = *target; // Save for debugging // Act differently based on the type of relocation switch (REL_TYPE(rel[i].r_info)) { @@ -93,7 +92,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of ahl = (*target & 0xffff) << 16; // Take lower 16 bits shifted up lastHiSymVal = sym->st_value; - hi16InShorts = (ShortsMan.inGeneralSegment((char *)sym->st_value)); // Fix for problem with switching btw segments + hi16InShorts = ShortsMan.inGeneralSegment((char *) sym->st_value); // Fix for problem with switching btw segments if (debugRelocs[0]++ < DEBUG_NUM) // Print only a set number debug(8, "elfloader: R_MIPS_HI16: i=%d, offset=%x, ahl = %x, target = %x", i, rel[i].r_offset, ahl, *target); @@ -111,7 +110,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of // Fix: bug in gcc makes LO16s connect to wrong HI16s sometimes (shorts and regular segment) // Note that we can check the entire shorts segment because the executable's shorts don't belong to this plugin section // and will be screened out above - bool lo16InShorts = ShortsMan.inGeneralSegment((char *)sym->st_value); + bool lo16InShorts = ShortsMan.inGeneralSegment((char *) sym->st_value); // Correct the bug by getting the proper value in ahl (taken from the current symbol) if ((hi16InShorts && !lo16InShorts) || (!hi16InShorts && lo16InShorts)) { @@ -128,13 +127,14 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (lo16InShorts) relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset else // It's in the regular segment - relocation = ahl + (Elf32_Addr)_segment; // Add in the new offset for the segment + relocation = ahl + Elf32_Addr(_segment); // Add in the new offset for the segment if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now - for (int j = firstHi16; j < i; j++) { - if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) continue; // Skip over non-Hi16s + for (uint32 j = firstHi16; j < i; j++) { + if (REL_TYPE(rel[j].r_info) != R_MIPS_HI16) + continue; // Skip over non-Hi16s - lastTarget = (unsigned int *)((char *)relSegment + rel[j].r_offset); // get hi16 target + lastTarget = (uint32 *) ((char *) relSegment + rel[j].r_offset); // get hi16 target *lastTarget &= 0xffff0000; // Clear the lower 16 bits of the last target *lastTarget |= (relocation >> 16) & 0xffff; // Take the upper 16 bits of the relocation if (relocation & 0x8000) @@ -161,7 +161,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment a = *target & 0x03ffffff; // Get 26 bits' worth of the addend a = (a << 6) >> 6; // Sign extend a - relocation = ((a << 2) + (Elf32_Addr)_segment) >> 2; // a already points to the target. Subtract our offset + relocation = ((a << 2) + Elf32_Addr(_segment)) >> 2; // a already points to the target. Subtract our offset *target &= 0xfc000000; // Clean lower 26 target bits *target |= (relocation & 0x03ffffff); @@ -177,7 +177,7 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of case R_MIPS_GPREL16: // GP Relative addressing if (_shortsSegment->getOffset() != 0 && // Only relocate if we shift the shorts section - ShortsMan.inGeneralSegment((char *)sym->st_value)) { // Only relocate things in the plugin hole + ShortsMan.inGeneralSegment((char *) sym->st_value)) { // Only relocate things in the plugin hole a = *target & 0xffff; // Get 16 bits' worth of the addend a = (a << 16) >> 16; // Sign extend it @@ -197,10 +197,10 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of if (sym->st_shndx < SHN_LOPROC) { // Only shift for plugin section. a = *target; // Get full 32 bits of addend - if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment + if (ShortsMan.inGeneralSegment((char *) sym->st_value)) // Check if we're in the shorts segment relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset else // We're in the main section - relocation = a + (Elf32_Addr)_segment; // Shift by main offset + relocation = a + Elf32_Addr(_segment); // Shift by main offset *target = relocation; if (debugRelocs[6]++ < DEBUG_NUM) @@ -223,21 +223,21 @@ bool MIPSDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long of bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { // Loop over sections, finding relocation sections - for (int i = 0; i < ehdr->e_shnum; i++) { + for (uint32 i = 0; i < ehdr->e_shnum; i++) { Elf32_Shdr *curShdr = &(shdr[i]); //Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]); if (curShdr->sh_type == SHT_REL && // Check for a relocation section curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size - (int)curShdr->sh_link == _symtab_sect && // Check that the sh_link connects to our symbol table + int32(curShdr->sh_link) == _symtab_sect && // Check that the sh_link connects to our symbol table curShdr->sh_info < ehdr->e_shnum && // Check that the relocated section exists (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory - if (!ShortsMan.inGeneralSegment((char *)shdr[curShdr->sh_info].sh_addr)) { // regular segment + if (!ShortsMan.inGeneralSegment((char *) shdr[curShdr->sh_info].sh_addr)) { // regular segment if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) return false; } else { // In Shorts segment - if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (void *)_shortsSegment->getOffset())) + if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, (byte *) _shortsSegment->getOffset())) return false; } } @@ -247,23 +247,20 @@ bool MIPSDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr * } void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { - int mainCount = 0; - int shortsCount= 0; - // Loop over symbols, add relocation offset - Elf32_Sym *s = (Elf32_Sym *)_symtab; - for (int c = _symbol_cnt; c--; s++) { + Elf32_Sym *s = _symtab; + + for (uint32 c = _symbol_cnt; c--; s++) { // Make sure we don't relocate special valued symbols if (s->st_shndx < SHN_LOPROC) { - if (!ShortsMan.inGeneralSegment((char *)s->st_value)) { - mainCount++; + if (!ShortsMan.inGeneralSegment((char *) s->st_value)) { s->st_value += offset; - if (s->st_value < (Elf32_Addr)_segment || s->st_value > (Elf32_Addr)_segment + _segmentSize) + + if (s->st_value < Elf32_Addr(_segment) || s->st_value > Elf32_Addr(_segment) + _segmentSize) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } else { // shorts section - shortsCount++; s->st_value += _shortsSegment->getOffset(); - if (!_shortsSegment->inSegment((char *)s->st_value)) + if (!_shortsSegment->inSegment((char *) s->st_value)) warning("elfloader: Symbol out of bounds! st_value = %x", s->st_value); } } @@ -271,30 +268,33 @@ void MIPSDLObject::relocateSymbols(Elf32_Addr offset) { } bool MIPSDLObject::loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr) { - char *baseAddress = 0; + byte *baseAddress = 0; // We need to take account of non-allocated segment for shorts if (phdr->p_flags & PF_X) { // This is a relocated segment // Attempt to allocate memory for segment - int extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here + uint32 extra = phdr->p_vaddr % phdr->p_align; // Get extra length TODO: check logic here debug(2, "elfloader: Extra mem is %x", extra); if (phdr->p_align < 0x10000) phdr->p_align = 0x10000; // Fix for wrong alignment on e.g. AGI - if (!(_segment = (char *)memalign(phdr->p_align, phdr->p_memsz + extra))) { + _segment = (byte *) allocSegment(phdr->p_align, phdr->p_memsz + extra); + + if (!_segment) { warning("elfloader: Out of memory."); return false; } + debug(2, "elfloader: Allocated segment @ %p", _segment); // Get offset to load segment into - baseAddress = (char *)_segment + phdr->p_vaddr; + baseAddress = _segment + phdr->p_vaddr; _segmentSize = phdr->p_memsz + extra; } else { // This is a shorts section. - _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *)phdr->p_vaddr); + _shortsSegment = ShortsMan.newSegment(phdr->p_memsz, (char *) phdr->p_vaddr); - baseAddress = _shortsSegment->getStart(); + baseAddress = (byte *) _shortsSegment->getStart(); debug(2, "elfloader: Shorts segment @ %p to %p. Segment wants to be at %x. Offset=%x", _shortsSegment->getStart(), _shortsSegment->getEnd(), phdr->p_vaddr, _shortsSegment->getOffset()); } @@ -328,3 +328,4 @@ void MIPSDLObject::unload() { } #endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ + diff --git a/backends/plugins/elf/mips-loader.h b/backends/plugins/elf/mips-loader.h index 28b8c7f636..d910e07eda 100644 --- a/backends/plugins/elf/mips-loader.h +++ b/backends/plugins/elf/mips-loader.h @@ -35,9 +35,9 @@ class MIPSDLObject : public DLObject { protected: ShortSegmentManager::Segment *_shortsSegment; // For assigning shorts ranges - unsigned int _gpVal; // Value of Global Pointer + uint32 _gpVal; // Value of Global Pointer - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); virtual void relocateSymbols(Elf32_Addr offset); virtual bool loadSegment(Common::SeekableReadStream* DLFile, Elf32_Phdr *phdr); diff --git a/backends/plugins/elf/ppc-loader.cpp b/backends/plugins/elf/ppc-loader.cpp index 21a9a6c8a0..dff8143e43 100644 --- a/backends/plugins/elf/ppc-loader.cpp +++ b/backends/plugins/elf/ppc-loader.cpp @@ -30,7 +30,7 @@ #include "common/debug.h" -bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment) { +bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment) { Elf32_Rela *rel = NULL; if (!(rel = (Elf32_Rela *)malloc(size))) { @@ -38,26 +38,25 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off return false; } - if (DLFile->seek(offset, SEEK_SET) < 0 || - DLFile->read(rel, size) != size) { + if (!DLFile->seek(offset, SEEK_SET) || DLFile->read(rel, size) != size) { warning("elfloader: Relocation table load failed."); free(rel); return false; } - int cnt = size / sizeof(*rel); + uint32 cnt = size / sizeof(*rel); debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p\n", cnt, relSegment); uint32 *src; uint32 value; - for (int i = 0; i < cnt; i++) { + for (uint32 i = 0; i < cnt; i++) { // Get the symbol this relocation entry is referring to - Elf32_Sym *sym = (Elf32_Sym *)(_symtab) + (REL_INDEX(rel[i].r_info)); + Elf32_Sym *sym = _symtab + (REL_INDEX(rel[i].r_info)); // Get the target instruction in the code - src = (uint32 *)((char *)relSegment + rel[i].r_offset - _segmentVMA); + src = (uint32 *) ((char *) relSegment + rel[i].r_offset - _segmentVMA); value = sym->st_value + rel[i].r_addend; //debug(8, "elfloader: i=%05d %p +0x%04x: (0x%08x) 0x%08x ", i, src, rel[i].r_addend, sym->st_value, *src); @@ -99,12 +98,12 @@ bool PPCDLObject::relocate(Common::SeekableReadStream* DLFile, unsigned long off } bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) { - for (int i = 0; i < ehdr->e_shnum; i++) { + for (uint32 i = 0; i < ehdr->e_shnum; i++) { Elf32_Shdr *curShdr = &(shdr[i]); if ((curShdr->sh_type == SHT_REL) && curShdr->sh_entsize == sizeof(Elf32_Rel) && - (int)curShdr->sh_link == _symtab_sect && + int32(curShdr->sh_link) == _symtab_sect && curShdr->sh_info < ehdr->e_shnum && (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { warning("elfloader: REL entries not supported!\n"); @@ -113,7 +112,7 @@ bool PPCDLObject::relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *e if ((curShdr->sh_type == SHT_RELA) && curShdr->sh_entsize == sizeof(Elf32_Rela) && - (int)curShdr->sh_link == _symtab_sect && + int32(curShdr->sh_link) == _symtab_sect && curShdr->sh_info < ehdr->e_shnum && (shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { if (!relocate(DLFile, curShdr->sh_offset, curShdr->sh_size, _segment)) diff --git a/backends/plugins/elf/ppc-loader.h b/backends/plugins/elf/ppc-loader.h index 574ba104e6..3424586a90 100644 --- a/backends/plugins/elf/ppc-loader.h +++ b/backends/plugins/elf/ppc-loader.h @@ -32,7 +32,7 @@ class PPCDLObject : public DLObject { protected: - virtual bool relocate(Common::SeekableReadStream* DLFile, unsigned long offset, unsigned long size, void *relSegment); + virtual bool relocate(Common::SeekableReadStream* DLFile, Elf32_Off offset, Elf32_Word size, byte *relSegment); virtual bool relocateRels(Common::SeekableReadStream* DLFile, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr); public: diff --git a/backends/plugins/elf/shorts-segment-manager.cpp b/backends/plugins/elf/shorts-segment-manager.cpp index 612ef19bbe..d55ea08c73 100644 --- a/backends/plugins/elf/shorts-segment-manager.cpp +++ b/backends/plugins/elf/shorts-segment-manager.cpp @@ -40,7 +40,7 @@ ShortSegmentManager::ShortSegmentManager() { _shortsEnd = &__plugin_hole_end; //and ends at the end of that hole. } -ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *origAddr) { +ShortSegmentManager::Segment *ShortSegmentManager::newSegment(uint32 size, char *origAddr) { char *lastAddress = origAddr; Common::List::iterator i; @@ -48,7 +48,8 @@ ShortSegmentManager::Segment *ShortSegmentManager::newSegment(int size, char *or for (i = _list.begin(); i != _list.end(); ++i) { char *currAddress = (*i)->getStart(); - if ((int)(currAddress - lastAddress) >= size) break; + if (uint32(currAddress) - uint32(lastAddress) >= size) + break; lastAddress = (*i)->getEnd(); } @@ -82,3 +83,4 @@ void ShortSegmentManager::deleteSegment(ShortSegmentManager::Segment *seg) { } #endif /* DYNAMIC_MODULES && MIPS_TARGET */ + diff --git a/backends/plugins/elf/shorts-segment-manager.h b/backends/plugins/elf/shorts-segment-manager.h index b3650562ed..c7cdcfe1f7 100644 --- a/backends/plugins/elf/shorts-segment-manager.h +++ b/backends/plugins/elf/shorts-segment-manager.h @@ -62,33 +62,44 @@ public: // Returns whether or not an absolute address is in the GP-relative section. bool inGeneralSegment(char *addr) { - return ((char *)addr >= _shortsStart && (char *)addr < _shortsEnd); + return (addr >= _shortsStart && addr < _shortsEnd); } class Segment { private: friend class ShortSegmentManager; - Segment(char *start, int size, char *origAddr) : _startAddress(start), _size(size), _origAddress(origAddr) {} - ~Segment() {} + Segment(char *start, uint32 size, char *origAddr) : + _startAddress(start), + _size(size), + _origAddress(origAddr) { + } + + virtual ~Segment() { + } + char *_startAddress; // Start of shorts segment in memory - int _size; // Size of shorts segment + uint32 _size; // Size of shorts segment char *_origAddress; // Original address this segment was supposed to be at + public: char *getStart() { return _startAddress; } + char *getEnd() { return (_startAddress + _size); } + Elf32_Addr getOffset() { return (Elf32_Addr)(_startAddress - _origAddress); } + bool inSegment(char *addr) { - return ((char *)addr >= _startAddress && (char *)addr <= _startAddress + _size); + return (addr >= _startAddress && addr <= _startAddress + _size); } }; - Segment *newSegment(int size, char *origAddr); + Segment *newSegment(uint32 size, char *origAddr); void deleteSegment(Segment *); private: @@ -101,3 +112,4 @@ private: #endif /* SHORTS_SEGMENT_MANAGER_H */ #endif /* defined(DYNAMIC_MODULES) && defined(MIPS_TARGET) */ + -- cgit v1.2.3