* ELF Executable Loader Code\r
*/\r
#define DEBUG 0\r
-#include <common.h>\r
+#include <acess.h>\r
#include <binary.h>\r
#include "elf.h"\r
\r
#define DEBUG_WARN 1\r
\r
-\r
// === PROTOTYPES ===\r
tBinary *Elf_Load(int fp);\r
int Elf_Relocate(void *Base);\r
- int Elf_GetSymbol(void *Base, char *Name, Uint *ret);\r
+ int Elf_GetSymbol(void *Base, const char *Name, Uint *ret);\r
int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base);\r
-Uint Elf_Int_HashString(char *str);\r
+Uint Elf_Int_HashString(const char *str);\r
\r
// === GLOBALS ===\r
tBinaryType gELF_Info = {\r
int iPageCount;\r
int count;\r
\r
- ENTER("ifp", fp);\r
+ ENTER("xfp", fp);\r
\r
// Read ELF Header\r
VFS_Read(fp, sizeof(hdr), &hdr);\r
\r
// Check the file type\r
if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') {\r
- Warning("Non-ELF File was passed to the ELF loader\n");\r
+ Log_Warning("ELF", "Non-ELF File was passed to the ELF loader");\r
LEAVE('n');\r
return NULL;\r
}\r
// Check for a program header\r
if(hdr.phoff == 0) {\r
#if DEBUG_WARN\r
- Warning("ELF File does not contain a program header\n");\r
+ Log_Warning("ELF", "File does not contain a program header (phoff == 0)");\r
#endif\r
LEAVE('n');\r
return NULL;\r
}\r
\r
// Read Program Header Table\r
- phtab = malloc(sizeof(Elf32_Phdr)*hdr.phentcount);\r
+ phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount );\r
+ if( !phtab ) {\r
+ LEAVE('n');\r
+ return NULL;\r
+ }\r
+ LOG("hdr.phoff = 0x%08x", hdr.phoff);\r
VFS_Seek(fp, hdr.phoff, SEEK_SET);\r
VFS_Read(fp, sizeof(Elf32_Phdr)*hdr.phentcount, phtab);\r
\r
LOG("iPageCount = %i", iPageCount);\r
\r
// Allocate Information Structure\r
- ret = malloc( sizeof(tBinary) + 3*sizeof(Uint)*iPageCount );\r
+ ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );\r
// Fill Info Struct\r
ret->Entry = hdr.entrypoint;\r
ret->Base = -1; // Set Base to maximum value\r
for( i = 0; i < hdr.phentcount; i++ )\r
{\r
int lastSize;\r
- LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type);\r
+ //LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type);\r
+ LOG("phtab[%i] = {", i);\r
+ LOG(" .Type = 0x%08x", phtab[i].Type);\r
+ LOG(" .Offset = 0x%08x", phtab[i].Offset);\r
+ LOG(" .VAddr = 0x%08x", phtab[i].VAddr);\r
+ LOG(" .PAddr = 0x%08x", phtab[i].PAddr);\r
+ LOG(" .FileSize = 0x%08x", phtab[i].FileSize);\r
+ LOG(" .MemSize = 0x%08x", phtab[i].MemSize);\r
+ LOG(" .Flags = 0x%08x", phtab[i].Flags);\r
+ LOG(" .Align = 0x%08x", phtab[i].Align);\r
+ LOG(" }");\r
// Get Interpreter Name\r
if( phtab[i].Type == PT_INTERP )\r
{\r
if(phtab[i].Type != PT_LOAD) continue;\r
\r
// Find Base\r
- if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr;
-\r
- k = 0;\r
+ if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr;\r
\r
LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}",\r
i, phtab[i].VAddr, phtab[i].Offset, phtab[i].FileSize);\r
\r
- if( (phtab[i].FileSize & 0xFFF) < 0x1000 - (phtab[i].VAddr & 0xFFF) )\r
- lastSize = phtab[i].FileSize;\r
- else\r
+ //if( (phtab[i].FileSize & 0xFFF) < 0x1000 - (phtab[i].VAddr & 0xFFF) )\r
+ // lastSize = phtab[i].FileSize;\r
+ //else\r
lastSize = (phtab[i].FileSize & 0xFFF) + (phtab[i].VAddr & 0xFFF);\r
- lastSize &= 0xFFF;\r
+ //lastSize &= 0xFFF;\r
+ \r
+ //LOG("lastSize = 0x%x", lastSize);\r
\r
- LOG("lastSize = 0x%x", lastSize);\r
+ lastSize = phtab[i].FileSize;\r
\r
// Get Pages\r
count = ( (phtab[i].VAddr&0xFFF) + phtab[i].FileSize + 0xFFF) >> 12;\r
- for(;k<count;k++)\r
+ for( k = 0; k < count; k ++ )\r
{\r
ret->Pages[j+k].Virtual = phtab[i].VAddr + (k<<12);\r
ret->Pages[j+k].Physical = phtab[i].Offset + (k<<12); // Store the offset in the physical address\r
ret->Pages[j+k].Size = 4096;\r
LOG("ret->Pages[%i].Size = 0x%x", j+k, ret->Pages[j+k].Size);\r
ret->Pages[j+k].Flags = 0;\r
+ lastSize -= ret->Pages[j+k].Size;\r
}\r
count = (phtab[i].MemSize + 0xFFF) >> 12;\r
for(;k<count;k++)\r
// Reallocate\r
ret = realloc( ret, sizeof(tBinary) + 3*sizeof(Uint)*j );\r
if(!ret) {\r
- Warning("BIN", "ElfLoad: Unable to reallocate return structure");\r
+ Log_Warning("BIN", "ElfLoad: Unable to reallocate return structure");\r
return NULL;\r
}\r
ret->NumPages = j;\r
ENTER("pBase", Base);\r
\r
// Parse Program Header to get Dynamic Table\r
- phtab = Base + hdr->phoff;\r
+ phtab = (void *)( (tVAddr)Base + hdr->phoff );\r
iSegmentCount = hdr->phentcount;\r
- for(i=0;i<iSegmentCount;i++)\r
+ for(i = 0; i < iSegmentCount; i ++ )\r
{\r
// Determine linked base address\r
if(phtab[i].Type == PT_LOAD && iRealBase > phtab[i].VAddr)\r
// Find Dynamic Section\r
if(phtab[i].Type == PT_DYNAMIC) {\r
if(dynamicTab) {\r
- Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
+ Log_Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
continue;\r
}\r
- dynamicTab = (void *) phtab[i].VAddr;\r
+ dynamicTab = (void *) (tVAddr) phtab[i].VAddr;\r
j = i; // Save Dynamic Table ID\r
break;\r
}\r
\r
// Check if a PT_DYNAMIC segement was found\r
if(!dynamicTab) {\r
- Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n");\r
+ Log_Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n");\r
LEAVE('x', hdr->entrypoint);\r
return hdr->entrypoint;\r
}\r
// --- Symbol Table ---\r
case DT_SYMTAB:\r
dynamicTab[j].d_val += iBaseDiff;\r
- dynsymtab = (void*)(dynamicTab[j].d_val);\r
+ dynsymtab = (void*) (tVAddr) dynamicTab[j].d_val;\r
hdr->misc.SymTable = dynamicTab[j].d_val; // Saved in unused bytes of ident\r
break;\r
\r
// --- String Table ---\r
case DT_STRTAB:\r
dynamicTab[j].d_val += iBaseDiff;\r
- dynstrtab = (void*)(dynamicTab[j].d_val);\r
+ dynstrtab = (void*) (tVAddr) dynamicTab[j].d_val;\r
break;\r
\r
// --- Hash Table --\r
case DT_HASH:\r
dynamicTab[j].d_val += iBaseDiff;\r
- iSymCount = ((Uint*)(dynamicTab[j].d_val))[1];\r
+ iSymCount = ((Uint*)((tVAddr)dynamicTab[j].d_val))[1];\r
hdr->misc.HashTable = dynamicTab[j].d_val; // Saved in unused bytes of ident\r
break;\r
}\r
\r
\r
// Alter Symbols to true base\r
- for(i=0;i<iSymCount;i++)\r
+ for(i = 0; i < iSymCount; i ++)\r
{\r
dynsymtab[i].value += iBaseDiff;\r
dynsymtab[i].nameOfs += (Uint)dynstrtab;\r
// --- Needed Library ---\r
case DT_NEEDED:\r
libPath = dynstrtab + dynamicTab[j].d_val;\r
- LOG("Required Library '%s' (IGNORED in kernel mode)\n", libPath);\r
+ Log_Notice("ELF", "%p - Required Library '%s' (Ignored in kernel mode)\n", Base, libPath);\r
break;\r
// --- PLT/GOT ---\r
- case DT_PLTGOT: pltgot = (void*)iBaseDiff+(dynamicTab[j].d_val); break;\r
+ case DT_PLTGOT: pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val); break;\r
case DT_JMPREL: plt = (void*)(iBaseDiff+dynamicTab[j].d_val); break;\r
case DT_PLTREL: pltType = dynamicTab[j].d_val; break;\r
case DT_PLTRELSZ: pltSz = dynamicTab[j].d_val; break;\r
case DT_REL: rel = (void*)(iBaseDiff + dynamicTab[j].d_val); break;\r
case DT_RELSZ: relSz = dynamicTab[j].d_val; break;\r
case DT_RELENT: relEntSz = dynamicTab[j].d_val; break;\r
+ \r
case DT_RELA: rela = (void*)(iBaseDiff + dynamicTab[j].d_val); break;\r
case DT_RELASZ: relaSz = dynamicTab[j].d_val; break;\r
case DT_RELAENT: relaEntSz = dynamicTab[j].d_val; break;\r
{\r
Elf32_Rel *pltRel = plt;\r
j = pltSz / sizeof(Elf32_Rel);\r
+ LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);\r
for(i = 0; i < j; i++)\r
{\r
ptr = (void*)(iBaseDiff + pltRel[i].r_offset);\r
{\r
Elf32_Rela *pltRela = plt;\r
j = pltSz / sizeof(Elf32_Rela);\r
+ LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j);\r
for(i=0;i<j;i++)\r
{\r
- ptr = (void*)((Uint)Base + pltRela[i].r_offset);\r
+ ptr = (void*)(iBaseDiff + pltRela[i].r_offset);\r
if( !Elf_Int_DoRelocate(pltRela[i].r_info, ptr, pltRela[i].r_addend, dynsymtab, (Uint)Base) ) {\r
bFailed = 1;\r
}\r
if( !Elf_GetSymbol((void*)base, sSymName, &val) ) // Search this binary first\r
if( !Binary_GetSymbol( sSymName, &val ) )\r
return 0;\r
- //LOG("R_386_32 *0x%x += 0x%x('%s')", ptr, val, sSymName);\r
+ LOG("%08x R_386_32 *0x%x += 0x%x('%s')", r_info, ptr, val, sSymName);\r
*ptr = val + addend;\r
break;\r
\r
if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
if( !Binary_GetSymbol( sSymName, &val ) )\r
return 0;\r
- //LOG("R_386_PC32 *0x%x = 0x%x + 0x%x('%s') - 0x%x", ptr, *ptr, val, sSymName, (Uint)ptr );\r
+ LOG("%08x R_386_PC32 *0x%x = 0x%x + 0x%x('%s') - 0x%x", r_info, ptr, *ptr, val, sSymName, (Uint)ptr );\r
// TODO: Check if it needs the true value of ptr or the compiled value\r
// NOTE: Testing using true value\r
*ptr = val + addend - (Uint)ptr;\r
if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
if( !Binary_GetSymbol( sSymName, &val ) )\r
return 0;\r
- //LOG("R_386_GLOB_DAT *0x%x = 0x%x (%s)", ptr, val, sSymName);\r
+ LOG("%08x R_386_GLOB_DAT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName);\r
*ptr = val;\r
break;\r
\r
if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
if( !Binary_GetSymbol( sSymName, &val ) )\r
return 0;\r
- //LOG("R_386_JMP_SLOT *0x%x = 0x%x (%s)", ptr, val, sSymName);\r
+ LOG("%08x R_386_JMP_SLOT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName);\r
*ptr = val;\r
break;\r
\r
// Base Address (B+A)\r
case R_386_RELATIVE:\r
- //LOG("R_386_RELATIVE *0x%x = 0x%x + 0x%x", ptr, base, addend);\r
+ LOG("%08x R_386_RELATIVE *0x%x = 0x%x + 0x%x", r_info, ptr, base, addend);\r
*ptr = base + addend;\r
break;\r
\r
}\r
\r
/**\r
- * \fn int Elf_GetSymbol(void *Base, char *name, Uint *ret)\r
+ * \fn int Elf_GetSymbol(void *Base, const char *name, Uint *ret)\r
* \brief Get a symbol from the loaded binary\r
*/\r
-int Elf_GetSymbol(void *Base, char *Name, Uint *ret)\r
+int Elf_GetSymbol(void *Base, const char *Name, Uint *ret)\r
{\r
Elf32_Ehdr *hdr = (void*)Base;\r
Elf32_Sym *symtab;\r
// Check Bucket\r
i = pBuckets[ iNameHash ];\r
if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) {\r
- *ret = symtab[ i ].value;\r
+ if(ret) *ret = symtab[ i ].value;\r
return 1;\r
}\r
\r
{\r
i = pChains[i];\r
if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) {\r
- *ret = symtab[ i ].value;\r
+ if(ret) *ret = symtab[ i ].value;\r
return 1;\r
}\r
}\r
* \param str String to hash\r
* \return Hash value\r
*/\r
-Uint Elf_Int_HashString(char *str)\r
+Uint Elf_Int_HashString(const char *str)\r
{\r
Uint h = 0, g;\r
while(*str)\r