X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Kernel%2Fbin%2Felf.c;h=b55011bbb946629f741c430082ce86562fdb3098;hb=16786b0b2d78359e052bd088f86aee90e1140737;hp=dbd38d2c7d98503fab5df326f5395cac583f5ff4;hpb=8bc40333b1401d7616b225945fee53d972c2f418;p=tpg%2Facess2.git diff --git a/Kernel/bin/elf.c b/Kernel/bin/elf.c index dbd38d2c..b55011bb 100644 --- a/Kernel/bin/elf.c +++ b/Kernel/bin/elf.c @@ -1,33 +1,20 @@ /* -Acess v0.1 -ELF Executable Loader Code -*/ -#include + * Acess v0.1 + * ELF Executable Loader Code + */ +#define DEBUG 0 +#include #include -#include "bin_elf.h" +#include "elf.h" -#define DEBUG 1 #define DEBUG_WARN 1 -#if DEBUG -# define DEBUGS(v...) Log(v) -#else -# define DEBUGS(v...) -# undef ENTER -# undef LOG -# undef LEAVE -# define ENTER(...) -# define LOG(...) -# define LEAVE(...) -#endif - - // === PROTOTYPES === tBinary *Elf_Load(int fp); int Elf_Relocate(void *Base); - int Elf_GetSymbol(void *Base, char *Name, Uint *ret); + int Elf_GetSymbol(void *Base, const char *Name, Uint *ret); int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base); -Uint Elf_Int_HashString(char *str); +Uint Elf_Int_HashString(const char *str); // === GLOBALS === tBinaryType gELF_Info = { @@ -47,14 +34,14 @@ tBinary *Elf_Load(int fp) int iPageCount; int count; - ENTER("ifp", fp); + ENTER("xfp", fp); // Read ELF Header VFS_Read(fp, sizeof(hdr), &hdr); // Check the file type if(hdr.ident[0] != 0x7F || hdr.ident[1] != 'E' || hdr.ident[2] != 'L' || hdr.ident[3] != 'F') { - Warning("Non-ELF File was passed to the ELF loader\n"); + Log_Warning("ELF", "Non-ELF File was passed to the ELF loader"); LEAVE('n'); return NULL; } @@ -62,14 +49,19 @@ tBinary *Elf_Load(int fp) // Check for a program header if(hdr.phoff == 0) { #if DEBUG_WARN - Warning("ELF File does not contain a program header\n"); + Log_Warning("ELF", "File does not contain a program header (phoff == 0)"); #endif LEAVE('n'); return NULL; } // Read Program Header Table - phtab = malloc(sizeof(Elf32_Phdr)*hdr.phentcount); + phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount ); + if( !phtab ) { + LEAVE('n'); + return NULL; + } + LOG("hdr.phoff = 0x%08x", hdr.phoff); VFS_Seek(fp, hdr.phoff, SEEK_SET); VFS_Read(fp, sizeof(Elf32_Phdr)*hdr.phentcount, phtab); @@ -88,7 +80,7 @@ tBinary *Elf_Load(int fp) LOG("iPageCount = %i", iPageCount); // Allocate Information Structure - ret = malloc( sizeof(tBinary) + 3*sizeof(Uint)*iPageCount ); + ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount ); // Fill Info Struct ret->Entry = hdr.entrypoint; ret->Base = -1; // Set Base to maximum value @@ -100,7 +92,17 @@ tBinary *Elf_Load(int fp) for( i = 0; i < hdr.phentcount; i++ ) { int lastSize; - LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type); + //LOG("phtab[%i].Type = 0x%x", i, phtab[i].Type); + LOG("phtab[%i] = {", i); + LOG(" .Type = 0x%08x", phtab[i].Type); + LOG(" .Offset = 0x%08x", phtab[i].Offset); + LOG(" .VAddr = 0x%08x", phtab[i].VAddr); + LOG(" .PAddr = 0x%08x", phtab[i].PAddr); + LOG(" .FileSize = 0x%08x", phtab[i].FileSize); + LOG(" .MemSize = 0x%08x", phtab[i].MemSize); + LOG(" .Flags = 0x%08x", phtab[i].Flags); + LOG(" .Align = 0x%08x", phtab[i].Align); + LOG(" }"); // Get Interpreter Name if( phtab[i].Type == PT_INTERP ) { @@ -118,24 +120,24 @@ tBinary *Elf_Load(int fp) if(phtab[i].Type != PT_LOAD) continue; // Find Base - if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr; - - k = 0; + if(phtab[i].VAddr < ret->Base) ret->Base = phtab[i].VAddr; LOG("phtab[%i] = {VAddr:0x%x,Offset:0x%x,FileSize:0x%x}", i, phtab[i].VAddr, phtab[i].Offset, phtab[i].FileSize); - if( (phtab[i].FileSize & 0xFFF) < 0x1000 - (phtab[i].VAddr & 0xFFF) ) - lastSize = phtab[i].FileSize; - else + //if( (phtab[i].FileSize & 0xFFF) < 0x1000 - (phtab[i].VAddr & 0xFFF) ) + // lastSize = phtab[i].FileSize; + //else lastSize = (phtab[i].FileSize & 0xFFF) + (phtab[i].VAddr & 0xFFF); - lastSize &= 0xFFF; + //lastSize &= 0xFFF; + + //LOG("lastSize = 0x%x", lastSize); - LOG("lastSize = 0x%x", lastSize); + lastSize = phtab[i].FileSize; // Get Pages count = ( (phtab[i].VAddr&0xFFF) + phtab[i].FileSize + 0xFFF) >> 12; - for(;kPages[j+k].Virtual = phtab[i].VAddr + (k<<12); ret->Pages[j+k].Physical = phtab[i].Offset + (k<<12); // Store the offset in the physical address @@ -151,6 +153,7 @@ tBinary *Elf_Load(int fp) ret->Pages[j+k].Size = 4096; LOG("ret->Pages[%i].Size = 0x%x", j+k, ret->Pages[j+k].Size); ret->Pages[j+k].Flags = 0; + lastSize -= ret->Pages[j+k].Size; } count = (phtab[i].MemSize + 0xFFF) >> 12; for(;kNumPages = j; @@ -277,13 +280,14 @@ int Elf_Relocate(void *Base) Elf32_Dyn *dynamicTab = NULL; // Dynamic Table Pointer char *dynstrtab = NULL; // .dynamic String Table Elf32_Sym *dynsymtab = NULL; + int bFailed = 0; ENTER("pBase", Base); // Parse Program Header to get Dynamic Table - phtab = Base + hdr->phoff; + phtab = (void *)( (tVAddr)Base + hdr->phoff ); iSegmentCount = hdr->phentcount; - for(i=0;i phtab[i].VAddr) @@ -292,10 +296,10 @@ int Elf_Relocate(void *Base) // Find Dynamic Section if(phtab[i].Type == PT_DYNAMIC) { if(dynamicTab) { - Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n"); + Log_Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n"); continue; } - dynamicTab = (void *) phtab[i].VAddr; + dynamicTab = (void *) (tVAddr) phtab[i].VAddr; j = i; // Save Dynamic Table ID break; } @@ -303,7 +307,7 @@ int Elf_Relocate(void *Base) // Check if a PT_DYNAMIC segement was found if(!dynamicTab) { - Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n"); + Log_Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n"); LEAVE('x', hdr->entrypoint); return hdr->entrypoint; } @@ -324,20 +328,20 @@ int Elf_Relocate(void *Base) // --- Symbol Table --- case DT_SYMTAB: dynamicTab[j].d_val += iBaseDiff; - dynsymtab = (void*)(dynamicTab[j].d_val); + dynsymtab = (void*) (tVAddr) dynamicTab[j].d_val; hdr->misc.SymTable = dynamicTab[j].d_val; // Saved in unused bytes of ident break; // --- String Table --- case DT_STRTAB: dynamicTab[j].d_val += iBaseDiff; - dynstrtab = (void*)(dynamicTab[j].d_val); + dynstrtab = (void*) (tVAddr) dynamicTab[j].d_val; break; // --- Hash Table -- case DT_HASH: dynamicTab[j].d_val += iBaseDiff; - iSymCount = ((Uint*)(dynamicTab[j].d_val))[1]; + iSymCount = ((Uint*)((tVAddr)dynamicTab[j].d_val))[1]; hdr->misc.HashTable = dynamicTab[j].d_val; // Saved in unused bytes of ident break; } @@ -345,7 +349,7 @@ int Elf_Relocate(void *Base) // Alter Symbols to true base - for(i=0;ientrypoint); return hdr->entrypoint; } @@ -473,7 +481,7 @@ int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symta if( !Elf_GetSymbol((void*)base, sSymName, &val) ) // Search this binary first if( !Binary_GetSymbol( sSymName, &val ) ) return 0; - //LOG("R_386_32 *0x%x += 0x%x('%s')", ptr, val, sSymName); + LOG("%08x R_386_32 *0x%x += 0x%x('%s')", r_info, ptr, val, sSymName); *ptr = val + addend; break; @@ -482,7 +490,7 @@ int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symta if( !Elf_GetSymbol( (void*)base, sSymName, &val ) ) if( !Binary_GetSymbol( sSymName, &val ) ) return 0; - //LOG("R_386_PC32 *0x%x = 0x%x + 0x%x('%s') - 0x%x", ptr, *ptr, val, sSymName, (Uint)ptr ); + LOG("%08x R_386_PC32 *0x%x = 0x%x + 0x%x('%s') - 0x%x", r_info, ptr, *ptr, val, sSymName, (Uint)ptr ); // TODO: Check if it needs the true value of ptr or the compiled value // NOTE: Testing using true value *ptr = val + addend - (Uint)ptr; @@ -493,7 +501,7 @@ int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symta if( !Elf_GetSymbol( (void*)base, sSymName, &val ) ) if( !Binary_GetSymbol( sSymName, &val ) ) return 0; - //LOG("R_386_GLOB_DAT *0x%x = 0x%x (%s)", ptr, val, sSymName); + LOG("%08x R_386_GLOB_DAT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName); *ptr = val; break; @@ -502,13 +510,13 @@ int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symta if( !Elf_GetSymbol( (void*)base, sSymName, &val ) ) if( !Binary_GetSymbol( sSymName, &val ) ) return 0; - //LOG("R_386_JMP_SLOT *0x%x = 0x%x (%s)", ptr, val, sSymName); + LOG("%08x R_386_JMP_SLOT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName); *ptr = val; break; // Base Address (B+A) case R_386_RELATIVE: - //LOG("R_386_RELATIVE *0x%x = 0x%x + 0x%x", ptr, base, addend); + LOG("%08x R_386_RELATIVE *0x%x = 0x%x + 0x%x", r_info, ptr, base, addend); *ptr = base + addend; break; @@ -520,10 +528,10 @@ int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symta } /** - * \fn int Elf_GetSymbol(void *Base, char *name, Uint *ret) + * \fn int Elf_GetSymbol(void *Base, const char *name, Uint *ret) * \brief Get a symbol from the loaded binary */ -int Elf_GetSymbol(void *Base, char *Name, Uint *ret) +int Elf_GetSymbol(void *Base, const char *Name, Uint *ret) { Elf32_Ehdr *hdr = (void*)Base; Elf32_Sym *symtab; @@ -551,7 +559,7 @@ int Elf_GetSymbol(void *Base, char *Name, Uint *ret) // Check Bucket i = pBuckets[ iNameHash ]; if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) { - *ret = symtab[ i ].value; + if(ret) *ret = symtab[ i ].value; return 1; } @@ -560,7 +568,7 @@ int Elf_GetSymbol(void *Base, char *Name, Uint *ret) { i = pChains[i]; if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) { - *ret = symtab[ i ].value; + if(ret) *ret = symtab[ i ].value; return 1; } } @@ -573,7 +581,7 @@ int Elf_GetSymbol(void *Base, char *Name, Uint *ret) * \param str String to hash * \return Hash value */ -Uint Elf_Int_HashString(char *str) +Uint Elf_Int_HashString(const char *str) { Uint h = 0, g; while(*str)