mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-26 06:18:23 +00:00
various fixes to the loader to allow compilation
svn-id: r50305
This commit is contained in:
parent
21f2775458
commit
7bb9e70620
@ -175,8 +175,8 @@ typedef struct {
|
|||||||
} Elf32_Rela;
|
} Elf32_Rela;
|
||||||
|
|
||||||
// Access macros for the relocation info
|
// Access macros for the relocation info
|
||||||
#define REL_TYPE(x) ((unsigned char) (x)) /* Extract relocation type */
|
#define REL_TYPE(x) ((unsigned char) (x)) /* Extract relocation type */
|
||||||
#define REL_INDEX(x) ((x)>>8) /* Extract relocation index into symbol table */
|
#define REL_INDEX(x) ((x)>>8) /* Extract relocation index into symbol table */
|
||||||
|
|
||||||
// ARM relocation types
|
// ARM relocation types
|
||||||
#define R_ARM_NONE 0
|
#define R_ARM_NONE 0
|
||||||
|
@ -34,10 +34,12 @@
|
|||||||
|
|
||||||
#include "backends/platform/gp2xwiz/gp2xwiz-loader.h"
|
#include "backends/platform/gp2xwiz/gp2xwiz-loader.h"
|
||||||
|
|
||||||
|
#define __WIZ_DEBUG_PLUGINS__
|
||||||
|
|
||||||
#ifdef __WIZ_DEBUG_PLUGINS__
|
#ifdef __WIZ_DEBUG_PLUGINS__
|
||||||
#define DBG(x) printf(x, ## __VA_ARGS__)
|
#define DBG(x,...) printf(x, ## __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define DBG(x)
|
#define DBG(x,...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__)
|
#define seterror(x,...) fprintf(stderr,x, ## __VA_ARGS__)
|
||||||
@ -55,7 +57,7 @@ void DLObject::discard_symtab() {
|
|||||||
void DLObject::unload() {
|
void DLObject::unload() {
|
||||||
discard_symtab();
|
discard_symtab();
|
||||||
free(_segment);
|
free(_segment);
|
||||||
segment = NULL;
|
_segment = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +68,7 @@ void DLObject::unload() {
|
|||||||
* @param size Size of relocation section
|
* @param size Size of relocation section
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool DLObject::relocate(int fd, unsigned long offset, unsigned long size) {
|
bool DLObject::relocate(int fd, unsigned long offset, unsigned long size, void *relSegment) {
|
||||||
Elf32_Rela *rela; //relocation entry
|
Elf32_Rela *rela; //relocation entry
|
||||||
|
|
||||||
// Allocate memory for relocation table
|
// Allocate memory for relocation table
|
||||||
@ -93,15 +95,15 @@ bool DLObject::relocate(int fd, unsigned long offset, unsigned long size) {
|
|||||||
|
|
||||||
//void *target = ???;
|
//void *target = ???;
|
||||||
|
|
||||||
switch (/*relocation type*/) {
|
// switch (/*relocation type*/) {
|
||||||
//case ??? :
|
//case ??? :
|
||||||
//TODO: Cases for each relocation type.
|
//TODO: Cases for each relocation type.
|
||||||
//break;
|
//break;
|
||||||
default:
|
// default:
|
||||||
seterror("Unknown relocation type %d.", ?? ?);
|
//seterror("Unknown relocation type %d.", ?? ?);
|
||||||
free(rela);
|
free(rela);
|
||||||
return false;
|
return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +128,7 @@ bool DLObject::readElfHeader(int fd, Elf32_Ehdr *ehdr) {
|
|||||||
if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr) ||
|
if (read(fd, ehdr, sizeof(*ehdr)) != sizeof(*ehdr) ||
|
||||||
memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC
|
memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || // Check MAGIC
|
||||||
ehdr->e_type != ET_EXEC || // Check for executable
|
ehdr->e_type != ET_EXEC || // Check for executable
|
||||||
ehdr->e_machine != EM_MIPS || // Check for ARM machine type TODO: change EM_MIPS to ??_ARM and add to ELF32.H (figure out what ??_ARM should be)
|
ehdr->e_machine != EM_ARM || // Check for ARM machine type
|
||||||
ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header
|
ehdr->e_phentsize < sizeof(Elf32_Phdr) || // Check for size of program header
|
||||||
ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header
|
ehdr->e_shentsize != sizeof(Elf32_Shdr)) { // Check for size of section header
|
||||||
seterror("Invalid file type.");
|
seterror("Invalid file type.");
|
||||||
@ -281,7 +283,7 @@ bool DLObject::loadStringTable(int fd, Elf32_Shdr *shdr) {
|
|||||||
|
|
||||||
void DLObject::relocateSymbols(Elf32_Addr offset) {
|
void DLObject::relocateSymbols(Elf32_Addr offset) {
|
||||||
|
|
||||||
relocCount = 0;
|
int relocCount = 0;
|
||||||
DBG("Relocating symbols by %x\n", offset);
|
DBG("Relocating symbols by %x\n", offset);
|
||||||
|
|
||||||
// Loop over symbols, add relocation offset
|
// Loop over symbols, add relocation offset
|
||||||
@ -310,7 +312,7 @@ bool DLObject::relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr) {
|
|||||||
//Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]);
|
//Elf32_Shdr *linkShdr = &(shdr[curShdr->sh_info]);
|
||||||
|
|
||||||
if (curShdr->sh_type == SHT_REL && // Check for a relocation section
|
if (curShdr->sh_type == SHT_REL && // Check for a relocation section
|
||||||
curShdr->sh_entsize == sizeof(Elf32_Rel) && // Check for proper relocation size
|
curShdr->sh_entsize == sizeof(Elf32_Rela) && // Check for proper relocation size
|
||||||
(int)curShdr->sh_link == _symtab_sect && // Check that the sh_link connects to our symbol table
|
(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
|
curShdr->sh_info < ehdr->e_shnum && // Check that the relocated section exists
|
||||||
(shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory
|
(shdr[curShdr->sh_info].sh_flags & SHF_ALLOC)) { // Check if relocated section resides in memory
|
||||||
@ -331,7 +333,7 @@ bool DLObject::load(int fd) {
|
|||||||
Elf32_Shdr *shdr;
|
Elf32_Shdr *shdr;
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
int symtab_sect = -1;
|
//int symtab_sect = -1;
|
||||||
|
|
||||||
if (readElfHeader(fd, &ehdr) == false) {
|
if (readElfHeader(fd, &ehdr) == false) {
|
||||||
return false;
|
return false;
|
||||||
@ -375,10 +377,10 @@ bool DLObject::open(const char *path) {
|
|||||||
|
|
||||||
DBG(("open(\"%s\")\n", path));
|
DBG(("open(\"%s\")\n", path));
|
||||||
|
|
||||||
if ((fd = ::open(path, O_RDONLY)) < 0) {
|
/*if ((fd = ::open(path, O_RDONLY)) < 0) {
|
||||||
seterror("%s not found.", path);
|
seterror("%s not found.", path);
|
||||||
return false;
|
return false;
|
||||||
}
|
} TODO: reimplement this "attempt to open" code */
|
||||||
|
|
||||||
// Try to load and relocate
|
// Try to load and relocate
|
||||||
if (!load(fd)) {
|
if (!load(fd)) {
|
||||||
@ -430,14 +432,14 @@ void *DLObject::symbol(const char *name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Elf32_Sym *s = (Elf32_Sym *)_symtab;
|
Elf32_Sym *s = (Elf32_Sym *)_symtab;
|
||||||
for (int c = symbol_cnt; c--; s++)
|
for (int c = _symbol_cnt; c--; s++)
|
||||||
|
|
||||||
//TODO: Figure out which symbols should be detected here
|
//TODO: Figure out which symbols should be detected here
|
||||||
if ((s->st_info >> 4 == 1 || s->st_info >> 4 == 2) &&
|
if ((s->st_info >> 4 == 1 || s->st_info >> 4 == 2) &&
|
||||||
strtab[s->st_name] == '_' && !strcmp(name, strtab + s->st_name + 1)) {
|
_strtab[s->st_name] == '_' && !strcmp(name, _strtab + s->st_name + 1)) {
|
||||||
|
|
||||||
// We found the symbol
|
// We found the symbol
|
||||||
DBG(("=> %p\n", (void*)s->st_value));
|
DBG("=> %p\n", (void*)s->st_value);
|
||||||
return (void*)s->st_value;
|
return (void*)s->st_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,25 +32,37 @@
|
|||||||
|
|
||||||
class DLObject {
|
class DLObject {
|
||||||
protected:
|
protected:
|
||||||
char *errbuf; /* For error messages, at least MAXDLERRLEN in size */
|
char *_errbuf; /* For error messages, at least MAXDLERRLEN in size */
|
||||||
|
|
||||||
void *_segment, *_symtab;
|
void *_segment, *_symtab;
|
||||||
char *_strtab;
|
char *_strtab;
|
||||||
int _symbol_cnt;
|
int _symbol_cnt;
|
||||||
|
int _symtab_sect;
|
||||||
void *_dtors_start, *_dtors_end;
|
void *_dtors_start, *_dtors_end;
|
||||||
|
|
||||||
|
int _segmentSize;
|
||||||
|
|
||||||
void seterror(const char *fmt, ...);
|
void seterror(const char *fmt, ...);
|
||||||
void unload();
|
void unload();
|
||||||
bool relocate(int fd, unsigned long offset, unsigned long size);
|
bool relocate(int fd, unsigned long offset, unsigned long size, void *relSegment);
|
||||||
bool load(int fd);
|
bool load(int fd);
|
||||||
|
|
||||||
|
bool readElfHeader(int fd, Elf32_Ehdr *ehdr);
|
||||||
|
bool readProgramHeaders(int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr, int num);
|
||||||
|
bool loadSegment(int fd, Elf32_Phdr *phdr);
|
||||||
|
Elf32_Shdr *loadSectionHeaders(int fd, Elf32_Ehdr *ehdr);
|
||||||
|
int loadSymbolTable(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr);
|
||||||
|
bool loadStringTable(int fd, Elf32_Shdr *shdr);
|
||||||
|
void relocateSymbols(Elf32_Addr offset);
|
||||||
|
bool relocateRels(int fd, Elf32_Ehdr *ehdr, Elf32_Shdr *shdr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool open(const char *path);
|
bool open(const char *path);
|
||||||
bool close();
|
bool close();
|
||||||
void *symbol(const char *name);
|
void *symbol(const char *name);
|
||||||
void discard_symtab();
|
void discard_symtab();
|
||||||
|
|
||||||
DLObject(char *errbuf = NULL) : errbuf(_errbuf), _segment(NULL),_symtab(NULL),
|
DLObject(char *errbuf = NULL) : _errbuf(_errbuf), _segment(NULL),_symtab(NULL),
|
||||||
_strtab(NULL), _symbol_cnt(0), _dtors_start(NULL), _dtors_end(NULL) {}
|
_strtab(NULL), _symbol_cnt(0), _dtors_start(NULL), _dtors_end(NULL) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user