* Acess v0.1\r
* ELF Executable Loader Code\r
*/\r
-#define DEBUG 1\r
+#define DEBUG 0\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
tBinary *ret;\r
Elf32_Ehdr hdr;\r
Elf32_Phdr *phtab;\r
- int i, j, k;\r
- int iPageCount;\r
- int count;\r
+ int i, j;\r
+ int iLoadCount;\r
\r
ENTER("xfp", fp);\r
\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
VFS_Read(fp, sizeof(Elf32_Phdr)*hdr.phentcount, phtab);\r
\r
// Count Pages\r
- iPageCount = 0;\r
+ iLoadCount = 0;\r
LOG("hdr.phentcount = %i", hdr.phentcount);\r
for( i = 0; i < hdr.phentcount; i++ )\r
{\r
// Ignore Non-LOAD types\r
if(phtab[i].Type != PT_LOAD)\r
continue;\r
- iPageCount += ((phtab[i].VAddr&0xFFF) + phtab[i].MemSize + 0xFFF) >> 12;\r
+ iLoadCount ++;\r
LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}", i, phtab[i].VAddr, phtab[i].MemSize);\r
}\r
\r
- LOG("iPageCount = %i", iPageCount);\r
+ LOG("iLoadCount = %i", iLoadCount);\r
\r
// Allocate Information Structure\r
- ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );\r
+ ret = malloc( sizeof(tBinary) + sizeof(tBinarySection)*iLoadCount );\r
// Fill Info Struct\r
ret->Entry = hdr.entrypoint;\r
ret->Base = -1; // Set Base to maximum value\r
- ret->NumPages = iPageCount;\r
+ ret->NumSections = iLoadCount;\r
ret->Interpreter = NULL;\r
\r
// Load Pages\r
j = 0;\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] = {", i);\r
LOG(" .Type = 0x%08x", phtab[i].Type);\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
- lastSize = (phtab[i].FileSize & 0xFFF) + (phtab[i].VAddr & 0xFFF);\r
- //lastSize &= 0xFFF;\r
- \r
- //LOG("lastSize = 0x%x", lastSize);\r
- \r
- lastSize = phtab[i].FileSize;\r
- \r
- // Get Pages\r
- count = ( (phtab[i].VAddr&0xFFF) + phtab[i].FileSize + 0xFFF) >> 12;\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
- if(k != 0) {\r
- ret->Pages[j+k].Physical -= ret->Pages[j+k].Virtual&0xFFF;\r
- ret->Pages[j+k].Virtual &= ~0xFFF;\r
- }\r
- if(k == count-1)\r
- ret->Pages[j+k].Size = lastSize; // Byte count in page\r
- else if(k == 0)\r
- ret->Pages[j+k].Size = 4096 - (phtab[i].VAddr&0xFFF);\r
- else\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
- {\r
- ret->Pages[j+k].Virtual = phtab[i].VAddr + (k<<12);\r
- ret->Pages[j+k].Physical = -1; // -1 = Fill with zeros\r
- if(k != 0) ret->Pages[j+k].Virtual &= ~0xFFF;\r
- if(k == count-1 && (phtab[i].MemSize & 0xFFF))\r
- ret->Pages[j+k].Size = phtab[i].MemSize & 0xFFF; // Byte count in page\r
- else\r
- ret->Pages[j+k].Size = 4096;\r
- ret->Pages[j+k].Flags = 0;\r
- LOG("%i - 0x%x => 0x%x - 0x%x", j+k,\r
- ret->Pages[j+k].Physical, ret->Pages[j+k].Virtual, ret->Pages[j+k].Size);\r
- }\r
- j += count;\r
- }\r
- \r
- #if 0\r
- LOG("Cleaning up overlaps");\r
- // Clear up Overlaps\r
- {\r
- struct {\r
- Uint V;\r
- Uint P;\r
- Uint S;\r
- Uint F;\r
- } *tmpRgns;\r
- count = j;\r
- tmpRgns = malloc(sizeof(*tmpRgns)*count);\r
- // Copy\r
- for(i=0;i<count;i++) {\r
- tmpRgns[i].V = ret->Pages[i].Virtual;\r
- tmpRgns[i].P = ret->Pages[i].Physical;\r
- tmpRgns[i].S = ret->Pages[i].Size;\r
- tmpRgns[i].F = ret->Pages[i].Flags;\r
- }\r
- // Compact\r
- for(i=1,j=0; i < count; i++)\r
- { \r
- if( tmpRgns[j].F == tmpRgns[i].F\r
- && tmpRgns[j].V + tmpRgns[j].S == tmpRgns[i].V\r
- && ((tmpRgns[j].P == -1 && tmpRgns[i].P == -1)\r
- || (tmpRgns[j].P + tmpRgns[j].S == tmpRgns[i].P)) )\r
- {\r
- tmpRgns[j].S += tmpRgns[i].S;\r
- } else {\r
- j ++;\r
- tmpRgns[j].V = tmpRgns[i].V;\r
- tmpRgns[j].P = tmpRgns[i].P;\r
- tmpRgns[j].F = tmpRgns[i].F;\r
- tmpRgns[j].S = tmpRgns[i].S;\r
- }\r
- }\r
+ ret->LoadSections[j].Offset = phtab[i].Offset;\r
+ ret->LoadSections[j].FileSize = phtab[i].FileSize;\r
+ ret->LoadSections[j].Virtual = phtab[i].VAddr;\r
+ ret->LoadSections[j].MemSize = phtab[i].MemSize;\r
+ ret->LoadSections[j].Flags = 0;\r
+ if( !(phtab[i].Flags & PF_W) )\r
+ ret->LoadSections[j].Flags |= BIN_SECTFLAG_RO;\r
+ if( phtab[i].Flags & PF_X )\r
+ ret->LoadSections[j].Flags |= BIN_SECTFLAG_EXEC;\r
j ++;\r
- // Count\r
- count = j; j = 0;\r
- for(i=0;i<count;i++) {\r
- //LogF(" Elf_Load: %i - 0x%x => 0x%x - 0x%x\n", i, tmpRgns[i].P, tmpRgns[i].V, tmpRgns[i].S);\r
- tmpRgns[i].S += tmpRgns[i].V & 0xFFF;\r
- if(tmpRgns[i].P != -1) tmpRgns[i].P -= tmpRgns[i].V & 0xFFF;\r
- tmpRgns[i].V &= ~0xFFF;\r
- j += (tmpRgns[i].S + 0xFFF) >> 12;\r
- //LogF(" Elf_Load: %i - 0x%x => 0x%x - 0x%x\n", i, tmpRgns[i].P, tmpRgns[i].V, tmpRgns[i].S);\r
- }\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
- return NULL;\r
- }\r
- ret->NumPages = j;\r
- // Split\r
- k = 0;\r
- for(i=0;i<count;i++) {\r
- for( j = 0; j < (tmpRgns[i].S + 0xFFF) >> 12; j++,k++ ) {\r
- ret->Pages[k].Flags = tmpRgns[i].F;\r
- ret->Pages[k].Virtual = tmpRgns[i].V + (j<<12);\r
- if(tmpRgns[i].P != -1) {\r
- ret->Pages[k].Physical = tmpRgns[i].P + (j<<12);\r
- } else\r
- ret->Pages[k].Physical = -1;\r
- ret->Pages[k].Size = tmpRgns[i].S - (j << 12);\r
- // Clamp to page size\r
- if(ret->Pages[k].Size > 0x1000) ret->Pages[k].Size = 0x1000;\r
- }\r
- }\r
- // Free Temp\r
- free(tmpRgns);\r
}\r
- #endif\r
\r
// Clean Up\r
free(phtab);\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
{\r
}\r
}\r
\r
+ if( !dynsymtab && iSymCount > 0 ) {\r
+ Log_Warning("ELF", "Elf_Relocate: No Dynamic symbol table, but count >0");\r
+ return 0;\r
+ }\r
\r
// Alter Symbols to true base\r
for(i = 0; i < iSymCount; i ++)\r
for( i = 0; i < j; i++ )\r
{\r
ptr = (void*)(iBaseDiff + rela[i].r_offset);\r
- if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, rela[i].r_addend, dynsymtab, (Uint)Base) ) {\r
+ if( !Elf_Int_DoRelocate(rela[i].r_info, ptr, rela[i].r_addend, dynsymtab, (Uint)Base) ) {\r
bFailed = 1;\r
}\r
}\r
return 0;\r
}\r
\r
- LEAVE('x', hdr->entrypoint);\r
- return hdr->entrypoint;\r
+ LEAVE('x', 1);\r
+ return 1;\r
}\r
\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
* \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