various fixes to the loader to allow compilation

svn-id: r50305
This commit is contained in:
Tony Puccinelli 2010-06-26 04:15:16 +00:00
parent 21f2775458
commit 7bb9e70620
3 changed files with 36 additions and 22 deletions

View File

@ -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

View File

@ -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;
} }

View File

@ -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) {}
}; };