X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FKernel%2Fbin%2Felf.c;h=d404d6db8aa429e5406ab82bc129c2276932e36f;hb=a5759d100ffe700c4f5d42ca21528592382d425c;hp=8f51290a1fd117387fbcc2c83c7a3909d0ed7867;hpb=51ab5f489bc356940c95cc936fd0508e8f07ea97;p=tpg%2Facess2.git diff --git a/KernelLand/Kernel/bin/elf.c b/KernelLand/Kernel/bin/elf.c index 8f51290a..d404d6db 100644 --- a/KernelLand/Kernel/bin/elf.c +++ b/KernelLand/Kernel/bin/elf.c @@ -1,11 +1,48 @@ /* - * Acess v0.1 - * ELF Executable Loader Code + * Acess2 Kernel + * - By John Hodge (thePowersGang) + * + * elf.c + * - ELF Executable Loader Code */ #define DEBUG 0 #include #include -#include "elf.h" + +// ---- Import linking code from userland +#define _COMMON_H +#define SysDebug(v...) LOG(v) +#if BITS <= 32 +# define DISABLE_ELF64 +#endif +static int GetSymbol(const char *Name, void **Value, size_t *Size); +static int GetSymbol(const char *Name, void **Value, size_t *Size) { + Uint val; + if(!Binary_GetSymbol(Name, &val)) { + Log_Notice("ELF", "Lookup of '%s' failed", Name); + return 0; + } + if(Size) + *Size=0; + *Value = (void*)val; + return 1; +} +#define AddLoaded(a,b) do{}while(0) +#define LoadLibrary(a,b,c) (Log_Debug("ELF", "Module requested lib '%s'",a),0) +static int _SysSetMemFlags(tVAddr addr, int flag, int mask) { + if( mask & 1 ) { + if( flag ) { + // Re-set RO, clear COW + MM_SetFlags(addr, MM_PFLAG_RO, MM_PFLAG_RO|MM_PFLAG_COW); + } + else { + MM_SetFlags(addr, MM_PFLAG_RO|MM_PFLAG_COW, MM_PFLAG_RO|MM_PFLAG_COW); + } + } + return 0; +} +#include "../../../Usermode/Libraries/ld-acess.so_src/elf.c" +// ---- / ---- #define DEBUG_WARN 1 @@ -14,9 +51,7 @@ tBinary *Elf_Load(int fp); tBinary *Elf_Load64(int fp, Elf64_Ehdr *hdr); tBinary *Elf_Load32(int fp, Elf32_Ehdr *hdr); int Elf_Relocate(void *Base); - int Elf_Relocate32(void *Base); - 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); + int Elf_GetSymbol(void *Base, const char *Name, Uint *Ret); Uint Elf_Int_HashString(const char *str); // === GLOBALS === @@ -44,7 +79,7 @@ tBinary *Elf_Load(int fp) switch(hdr.e_ident[4]) // EI_CLASS { case ELFCLASS32: - return Elf_Load32(fp, (Elf32_Ehdr*)&hdr); + return Elf_Load32(fp, (void*)&hdr); case ELFCLASS64: return Elf_Load64(fp, &hdr); default: @@ -283,361 +318,12 @@ tBinary *Elf_Load32(int FD, Elf32_Ehdr *Header) return ret; } -// --- ELF RELOCATION --- int Elf_Relocate(void *Base) { - Elf64_Ehdr *hdr = Base; - - switch( hdr->e_ident[EI_CLASS] ) - { - case ELFCLASS32: - return Elf_Relocate32(Base); - case ELFCLASS64: - return 0; - default: - return 1; - } + return ElfRelocate(Base, (char**){NULL}, "") != NULL; } - - -/** - * \brief Relocates a loaded ELF Executable - */ -int Elf_Relocate32(void *Base) -{ - Elf32_Ehdr *hdr = Base; - Elf32_Phdr *phtab; - int i, j; // Counters - char *libPath; - Uint iRealBase = -1; - Uint iBaseDiff; - int iSegmentCount; - int iSymCount = 0; - Elf32_Rel *rel = NULL; - Elf32_Rela *rela = NULL; - Uint32 *pltgot = NULL; - void *plt = NULL; - Uint32 *ptr; - int relSz=0, relEntSz=8; - int relaSz=0, relaEntSz=8; - int pltSz=0, pltType=0; - 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 = (void *)( (tVAddr)Base + hdr->phoff ); - iSegmentCount = hdr->phentcount; - for(i = 0; i < iSegmentCount; i ++ ) - { - // Determine linked base address - if(phtab[i].Type == PT_LOAD && iRealBase > phtab[i].VAddr) - iRealBase = phtab[i].VAddr; - - // Find Dynamic Section - if(phtab[i].Type == PT_DYNAMIC) { - if(dynamicTab) { - Log_Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n"); - continue; - } - dynamicTab = (void *) (tVAddr) phtab[i].VAddr; - j = i; // Save Dynamic Table ID - break; - } - } - - // Check if a PT_DYNAMIC segement was found - if(!dynamicTab) { - Log_Warning("ELF", "Elf_Relocate: No PT_DYNAMIC segment in image, returning\n"); - LEAVE('x', 0); - return 0; - } - - // Page Align real base - iRealBase &= ~0xFFF; - - // Adjust "Real" Base - iBaseDiff = (Uint)Base - iRealBase; - // Adjust Dynamic Table - dynamicTab = (void *) ((Uint)dynamicTab + iBaseDiff); - - // === Get Symbol table and String Table === - for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++) - { - switch(dynamicTab[j].d_tag) - { - // --- Symbol Table --- - case DT_SYMTAB: - dynamicTab[j].d_val += iBaseDiff; - 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*) (tVAddr) dynamicTab[j].d_val; - break; - - // --- Hash Table -- - case DT_HASH: - dynamicTab[j].d_val += iBaseDiff; - iSymCount = ((Uint*)((tVAddr)dynamicTab[j].d_val))[1]; - hdr->misc.HashTable = dynamicTab[j].d_val; // Saved in unused bytes of ident - break; - } - } - - if( !dynsymtab && iSymCount > 0 ) { - Log_Warning("ELF", "Elf_Relocate: No Dynamic symbol table, but count >0"); - return 0; - } - - // Alter Symbols to true base - for(i = 0; i < iSymCount; i ++) - { - dynsymtab[i].value += iBaseDiff; - dynsymtab[i].nameOfs += (Uint)dynstrtab; - //LOG("Sym '%s' = 0x%x (relocated)\n", dynsymtab[i].name, dynsymtab[i].value); - } - - // === Add to loaded list (can be imported now) === - //Binary_AddLoaded( (Uint)Base ); - - // === Parse Relocation Data === - for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++) - { - switch(dynamicTab[j].d_tag) - { - // --- Shared Library Name --- - case DT_SONAME: - LOG(".so Name '%s'\n", dynstrtab+dynamicTab[j].d_val); - break; - // --- Needed Library --- - case DT_NEEDED: - libPath = dynstrtab + dynamicTab[j].d_val; - Log_Notice("ELF", "%p - Required Library '%s' (Ignored in kernel mode)\n", Base, libPath); - break; - // --- PLT/GOT --- - case DT_PLTGOT: pltgot = (void*)(iBaseDiff+dynamicTab[j].d_val); break; - case DT_JMPREL: plt = (void*)(iBaseDiff+dynamicTab[j].d_val); break; - case DT_PLTREL: pltType = dynamicTab[j].d_val; break; - case DT_PLTRELSZ: pltSz = dynamicTab[j].d_val; break; - - // --- Relocation --- - case DT_REL: rel = (void*)(iBaseDiff + dynamicTab[j].d_val); break; - case DT_RELSZ: relSz = dynamicTab[j].d_val; break; - case DT_RELENT: relEntSz = dynamicTab[j].d_val; break; - - case DT_RELA: rela = (void*)(iBaseDiff + dynamicTab[j].d_val); break; - case DT_RELASZ: relaSz = dynamicTab[j].d_val; break; - case DT_RELAENT: relaEntSz = dynamicTab[j].d_val; break; - } - } - - // Parse Relocation Entries - if(rel && relSz) - { - j = relSz / relEntSz; - for( i = 0; i < j; i++ ) - { - ptr = (void*)(iBaseDiff + rel[i].r_offset); - if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, (Uint)Base) ) { - bFailed = 1; - } - } - } - // Parse Relocation Entries - if(rela && relaSz) - { - j = relaSz / relaEntSz; - for( i = 0; i < j; i++ ) - { - ptr = (void*)(iBaseDiff + rela[i].r_offset); - if( !Elf_Int_DoRelocate(rela[i].r_info, ptr, rela[i].r_addend, dynsymtab, (Uint)Base) ) { - bFailed = 1; - } - } - } - - // === Process PLT (Procedure Linkage Table) === - if(plt && pltSz) - { - if(pltType == DT_REL) - { - Elf32_Rel *pltRel = plt; - j = pltSz / sizeof(Elf32_Rel); - LOG("PLT Rel - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j); - for(i = 0; i < j; i++) - { - ptr = (void*)(iBaseDiff + pltRel[i].r_offset); - if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, (Uint)Base) ) { - bFailed = 1; - } - } - } - else - { - Elf32_Rela *pltRela = plt; - j = pltSz / sizeof(Elf32_Rela); - LOG("PLT RelA - plt = %p, pltSz = %i (%i ents)", plt, pltSz, j); - for(i=0;imisc.HashTable; - symtab = (void *) hdr->misc.SymTable; - - nbuckets = pBuckets[0]; - iSymCount = pBuckets[1]; - pBuckets = &pBuckets[2]; - pChains = &pBuckets[ nbuckets ]; - - // Get hash - iNameHash = Elf_Int_HashString(Name); - iNameHash %= nbuckets; - - // Check Bucket - i = pBuckets[ iNameHash ]; - if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) { - if(ret) *ret = symtab[ i ].value; - return 1; - } - - // Walk Chain - while(pChains[i] != STN_UNDEF) - { - i = pChains[i]; - if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) { - if(ret) *ret = symtab[ i ].value; - return 1; - } - } - return 0; + return ElfGetSymbol(Base, Name, (void**)ret, NULL); } -/** - * \fn Uint Elf_Int_HashString(char *str) - * \brief Hash a string in the ELF format - * \param str String to hash - * \return Hash value - */ -Uint Elf_Int_HashString(const char *str) -{ - Uint h = 0, g; - while(*str) - { - h = (h << 4) + *str++; - if( (g = h & 0xf0000000) ) - h ^= g >> 24; - h &= ~g; - } - return h; -}