Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Kernel / bin / elf.c
diff --git a/Kernel/bin/elf.c b/Kernel/bin/elf.c
deleted file mode 100644 (file)
index 731d151..0000000
+++ /dev/null
@@ -1,593 +0,0 @@
-/*\r
- * Acess v0.1\r
- * ELF Executable Loader Code\r
- */\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_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base);\r
-Uint   Elf_Int_HashString(char *str);\r
-\r
-// === GLOBALS ===\r
-tBinaryType    gELF_Info = {\r
-       NULL,\r
-       0x464C457F, 0xFFFFFFFF, // '\x7FELF'\r
-       "ELF",\r
-       Elf_Load, Elf_Relocate, Elf_GetSymbol\r
-       };\r
-\r
-// === CODE ===\r
-tBinary *Elf_Load(int fp)\r
-{\r
-       tBinary *ret;\r
-       Elf32_Ehdr      hdr;\r
-       Elf32_Phdr      *phtab;\r
-        int    i, j, k;\r
-        int    iPageCount;\r
-        int    count;\r
-       \r
-       ENTER("ifp", 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
-               LEAVE('n');\r
-               return NULL;\r
-       }\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
-               #endif\r
-               LEAVE('n');\r
-               return NULL;\r
-       }\r
-       \r
-       // Read Program Header Table\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
-       // Count Pages\r
-       iPageCount = 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
-               LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}", i, phtab[i].VAddr, phtab[i].MemSize);\r
-       }\r
-       \r
-       LOG("iPageCount = %i", iPageCount);\r
-       \r
-       // Allocate Information Structure\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
-       ret->NumPages = iPageCount;\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(" .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
-                       char *tmp;\r
-                       if(ret->Interpreter)    continue;\r
-                       tmp = malloc(phtab[i].FileSize);\r
-                       VFS_Seek(fp, phtab[i].Offset, 1);\r
-                       VFS_Read(fp, phtab[i].FileSize, tmp);\r
-                       ret->Interpreter = Binary_RegInterp(tmp);\r
-                       LOG("Interpreter '%s'", tmp);\r
-                       free(tmp);\r
-                       continue;\r
-               }\r
-               // Ignore non-LOAD types\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
-               \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
-               // 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
-               }\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
-               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
-       // Return\r
-       LEAVE('p', ret);\r
-       return ret;\r
-}\r
-\r
-// --- ELF RELOCATION ---\r
-// Taken from 'ld-acess.so'\r
-/**\r
- \fn int Elf_Relocate(void *Base)\r
- \brief Relocates a loaded ELF Executable\r
-*/\r
-int Elf_Relocate(void *Base)\r
-{\r
-       Elf32_Ehdr      *hdr = Base;\r
-       Elf32_Phdr      *phtab;\r
-        int    i, j;   // Counters\r
-       char    *libPath;\r
-       Uint    iRealBase = -1;\r
-       Uint    iBaseDiff;\r
-        int    iSegmentCount;\r
-        int    iSymCount = 0;\r
-       Elf32_Rel       *rel = NULL;\r
-       Elf32_Rela      *rela = NULL;\r
-       Uint32  *pltgot = NULL;\r
-       void    *plt = NULL;\r
-       Uint32  *ptr;\r
-        int    relSz=0, relEntSz=8;\r
-        int    relaSz=0, relaEntSz=8;\r
-        int    pltSz=0, pltType=0;\r
-       Elf32_Dyn       *dynamicTab = NULL;     // Dynamic Table Pointer\r
-       char    *dynstrtab = NULL;      // .dynamic String Table\r
-       Elf32_Sym       *dynsymtab = NULL;\r
-        int    bFailed = 0;\r
-       \r
-       ENTER("pBase", Base);\r
-       \r
-       // Parse Program Header to get Dynamic Table\r
-       phtab = Base + hdr->phoff;\r
-       iSegmentCount = hdr->phentcount;\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
-                       iRealBase = phtab[i].VAddr;\r
-               \r
-               // Find Dynamic Section\r
-               if(phtab[i].Type == PT_DYNAMIC) {\r
-                       if(dynamicTab) {\r
-                               Log_Warning("ELF", "Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
-                               continue;\r
-                       }\r
-                       dynamicTab = (void *) (tVAddr) phtab[i].VAddr;\r
-                       j = i;  // Save Dynamic Table ID\r
-                       break;\r
-               }\r
-       }\r
-       \r
-       // Check if a PT_DYNAMIC segement was found\r
-       if(!dynamicTab) {\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
-       \r
-       // Page Align real base\r
-       iRealBase &= ~0xFFF;\r
-       \r
-       // Adjust "Real" Base\r
-       iBaseDiff = (Uint)Base - iRealBase;\r
-       // Adjust Dynamic Table\r
-       dynamicTab = (void *) ((Uint)dynamicTab + iBaseDiff);\r
-       \r
-       // === Get Symbol table and String Table ===\r
-       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
-       {\r
-               switch(dynamicTab[j].d_tag)\r
-               {\r
-               // --- Symbol Table ---\r
-               case DT_SYMTAB:\r
-                       dynamicTab[j].d_val += iBaseDiff;\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*) (tVAddr) dynamicTab[j].d_val;\r
-                       break;\r
-               \r
-               // --- Hash Table --\r
-               case DT_HASH:\r
-                       dynamicTab[j].d_val += iBaseDiff;\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
-\r
-       // Alter Symbols to true base\r
-       for(i = 0; i < iSymCount; i ++)\r
-       {\r
-               dynsymtab[i].value += iBaseDiff;\r
-               dynsymtab[i].nameOfs += (Uint)dynstrtab;\r
-               //LOG("Sym '%s' = 0x%x (relocated)\n", dynsymtab[i].name, dynsymtab[i].value);\r
-       }\r
-       \r
-       // === Add to loaded list (can be imported now) ===\r
-       //Binary_AddLoaded( (Uint)Base );\r
-\r
-       // === Parse Relocation Data ===\r
-       for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++)\r
-       {\r
-               switch(dynamicTab[j].d_tag)\r
-               {\r
-               // --- Shared Library Name ---\r
-               case DT_SONAME:\r
-                       LOG(".so Name '%s'\n", dynstrtab+dynamicTab[j].d_val);\r
-                       break;\r
-               // --- Needed Library ---\r
-               case DT_NEEDED:\r
-                       libPath = dynstrtab + dynamicTab[j].d_val;\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_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
-               \r
-               // --- Relocation ---\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
-       }\r
-       \r
-       // Parse Relocation Entries\r
-       if(rel && relSz)\r
-       {\r
-               j = relSz / relEntSz;\r
-               for( i = 0; i < j; i++ )\r
-               {\r
-                       ptr = (void*)(iBaseDiff + rel[i].r_offset);\r
-                       if( !Elf_Int_DoRelocate(rel[i].r_info, ptr, *ptr, dynsymtab, (Uint)Base) ) {\r
-                               bFailed = 1;\r
-                       }\r
-               }\r
-       }\r
-       // Parse Relocation Entries\r
-       if(rela && relaSz)\r
-       {\r
-               j = relaSz / relaEntSz;\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
-                               bFailed = 1;\r
-                       }\r
-               }\r
-       }\r
-       \r
-       // === Process PLT (Procedure Linkage Table) ===\r
-       if(plt && pltSz)\r
-       {\r
-               if(pltType == DT_REL)\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
-                               if( !Elf_Int_DoRelocate(pltRel[i].r_info, ptr, *ptr, dynsymtab, (Uint)Base) ) {\r
-                                       bFailed = 1;\r
-                               }\r
-                       }\r
-               }\r
-               else\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*)(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
-                       }\r
-               }\r
-       }\r
-       \r
-       if(bFailed) {\r
-               LEAVE('i', 0);\r
-               return 0;\r
-       }\r
-       \r
-       LEAVE('x', hdr->entrypoint);\r
-       return hdr->entrypoint;\r
-}\r
-\r
-/**\r
- * \fn void Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base)\r
- * \brief Performs a relocation\r
- * \param r_info       Field from relocation entry\r
- * \param ptr  Pointer to location of relocation\r
- * \param addend       Value to add to symbol\r
- * \param symtab       Symbol Table\r
- * \param base Base of loaded binary\r
- */\r
-int Elf_Int_DoRelocate(Uint r_info, Uint32 *ptr, Uint32 addend, Elf32_Sym *symtab, Uint base)\r
-{\r
-       Uint    val;\r
-        int    type = ELF32_R_TYPE(r_info);\r
-        int    sym = ELF32_R_SYM(r_info);\r
-       char    *sSymName = symtab[sym].name;\r
-       \r
-       //LogF("Elf_Int_DoRelocate: (r_info=0x%x, ptr=0x%x, addend=0x%x, .., base=0x%x)\n",\r
-       //      r_info, ptr, addend, base);\r
-       \r
-       switch( type )\r
-       {\r
-       // Standard 32 Bit Relocation (S+A)\r
-       case R_386_32:\r
-               if( !Elf_GetSymbol((void*)base, sSymName, &val) )       // Search this binary first\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_32 *0x%x += 0x%x('%s')", r_info, ptr, val, sSymName);\r
-               *ptr = val + addend;\r
-               break;\r
-               \r
-       // 32 Bit Relocation wrt. Offset (S+A-P)\r
-       case R_386_PC32:\r
-               if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\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
-               break;\r
-\r
-       // Absolute Value of a symbol (S)\r
-       case R_386_GLOB_DAT:\r
-               if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\r
-               LOG("%08x R_386_GLOB_DAT *0x%x = 0x%x (%s)", r_info, ptr, val, sSymName);\r
-               *ptr = val;\r
-               break;\r
-       \r
-       // Absolute Value of a symbol (S)\r
-       case R_386_JMP_SLOT:\r
-               if( !Elf_GetSymbol( (void*)base, sSymName, &val ) )\r
-                       if( !Binary_GetSymbol( sSymName, &val ) )\r
-                               return 0;\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("%08x R_386_RELATIVE *0x%x = 0x%x + 0x%x", r_info, ptr, base, addend);\r
-               *ptr = base + addend;\r
-               break;\r
-               \r
-       default:\r
-               LOG("Rel 0x%x: 0x%x,%i", ptr, sym, type);\r
-               break;\r
-       }\r
-       return 1;\r
-}\r
-\r
-/**\r
- * \fn int Elf_GetSymbol(void *Base, 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
-{\r
-       Elf32_Ehdr      *hdr = (void*)Base;\r
-       Elf32_Sym       *symtab;\r
-        int    nbuckets = 0;\r
-        int    iSymCount = 0;\r
-        int    i;\r
-       Uint    *pBuckets;\r
-       Uint    *pChains;\r
-       Uint    iNameHash;\r
-\r
-       if(!Base)       return 0;\r
-\r
-       pBuckets = (void *) hdr->misc.HashTable;\r
-       symtab = (void *) hdr->misc.SymTable;\r
-       \r
-       nbuckets = pBuckets[0];\r
-       iSymCount = pBuckets[1];\r
-       pBuckets = &pBuckets[2];\r
-       pChains = &pBuckets[ nbuckets ];\r
-       \r
-       // Get hash\r
-       iNameHash = Elf_Int_HashString(Name);\r
-       iNameHash %= nbuckets;\r
-\r
-       // Check Bucket\r
-       i = pBuckets[ iNameHash ];\r
-       if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[i].name, Name) == 0) {\r
-               if(ret) *ret = symtab[ i ].value;\r
-               return 1;\r
-       }\r
-       \r
-       // Walk Chain\r
-       while(pChains[i] != STN_UNDEF)\r
-       {\r
-               i = pChains[i];\r
-               if(symtab[i].shndx != SHN_UNDEF && strcmp(symtab[ i ].name, Name) == 0) {\r
-                       if(ret) *ret = symtab[ i ].value;\r
-                       return 1;\r
-               }\r
-       }\r
-       return 0;\r
-}\r
-\r
-/**\r
- * \fn Uint Elf_Int_HashString(char *str)\r
- * \brief Hash a string in the ELF format\r
- * \param str  String to hash\r
- * \return Hash value\r
- */\r
-Uint Elf_Int_HashString(char *str)\r
-{\r
-       Uint    h = 0, g;\r
-       while(*str)\r
-       {\r
-               h = (h << 4) + *str++;\r
-               if( (g = h & 0xf0000000) )\r
-                       h ^= g >> 24;\r
-               h &= ~g;\r
-       }\r
-       return h;\r
-}\r

UCC git Repository :: git.ucc.asn.au