--- /dev/null
+/*\r
+ * Acess v0.1\r
+ * ELF Executable Loader Code\r
+ */\r
+#define DEBUG 0\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include "common.h"\r
+#include "elf.h"\r
+\r
+#define DEBUG_WARN 1\r
+\r
+#define ENTER(...)\r
+#define LOG(...)\r
+#define LEAVE(...)\r
+\r
+// === PROTOTYPES ===\r
+ int Elf_Load(int fd);\r
+ int Elf_Relocate(void *Base);\r
+ int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret);\r
+ int Elf_Int_DoRelocate(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, intptr_t base);\r
+uint32_t Elf_Int_HashString(char *str);\r
+\r
+// === CODE ===\r
+int Elf_Load(int FD)\r
+{\r
+ Elf32_Ehdr hdr;\r
+ Elf32_Phdr *phtab;\r
+ int i, j;\r
+ int iPageCount;\r
+ uint32_t max, base = -1;\r
+ uint32_t addr;\r
+ \r
+ ENTER("xFD", FD);\r
+ \r
+ // Read ELF Header\r
+ read(FD, &hdr, sizeof(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 1;\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 1;\r
+ }\r
+ \r
+ // Read Program Header Table\r
+ phtab = malloc( sizeof(Elf32_Phdr) * hdr.phentcount );\r
+ if( !phtab ) {\r
+ LEAVE('n');\r
+ return 1;\r
+ }\r
+ LOG("hdr.phoff = 0x%08x", hdr.phoff);\r
+ lseek(FD, hdr.phoff, SEEK_SET);\r
+ read(FD, phtab, sizeof(Elf32_Phdr)*hdr.phentcount);\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
+ // Prescan for base and size\r
+ for( i = 0; i < hdr.phentcount; i ++)\r
+ {\r
+ if( phtab[i].Type != PT_LOAD )\r
+ continue;\r
+ if( phtab[i].VAddr < base )\r
+ base = phtab[i].VAddr;\r
+ if( phtab[i].VAddr > max )\r
+ max = phtab[i].VAddr;\r
+ }\r
+\r
+ LOG("base = %08x, max = %08x", base, max);\r
+ \r
+ // Load Pages\r
+ j = 0;\r
+ for( i = 0; i < hdr.phentcount; i++ )\r
+ {\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
+ lseek(FD, phtab[i].Offset, 1);\r
+ read(FD, tmp, phtab[i].FileSize);\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
+ 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
+ addr = phtab[i].VAddr;\r
+\r
+ AllocateMemory( addr, phtab[i].MemSize );\r
+ \r
+ lseek(FD, phtab[i].Offset, SEEK_SET);\r
+ read(FD, (void*)(intptr_t)addr, phtab[i].FileSize);\r
+ memset( (char*)(intptr_t)addr + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize);\r
+ }\r
+ \r
+ // Clean Up\r
+ free(phtab);\r
+ // Return\r
+ LEAVE('i', 0);\r
+ return 0;\r
+}\r
+\r
+// --- ELF RELOCATION ---\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
+ uint32_t iRealBase = -1;\r
+ intptr_t iBaseDiff;\r
+ int iSegmentCount;\r
+ int iSymCount = 0;\r
+ Elf32_Rel *rel = NULL;\r
+ Elf32_Rela *rela = NULL;\r
+ uint32_t *pltgot = NULL;\r
+ void *plt = NULL;\r
+ uint32_t *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
+ Warning("Elf_Relocate - Multiple PT_DYNAMIC segments\n");\r
+ continue;\r
+ }\r
+ dynamicTab = (void *) (intptr_t) 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
+ Warning("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 = (intptr_t)Base - iRealBase;\r
+ // Adjust Dynamic Table\r
+ dynamicTab = (void *) ((intptr_t)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*) (intptr_t) 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*) (intptr_t) dynamicTab[j].d_val;\r
+ break;\r
+ \r
+ // --- Hash Table --\r
+ case DT_HASH:\r
+ dynamicTab[j].d_val += iBaseDiff;\r
+ iSymCount = ((uint32_t*)((intptr_t)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 += (intptr_t)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( (intptr_t)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
+ Notice("%p - Required Library '%s' - TODO load DT_NEEDED\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, (intptr_t)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, (intptr_t)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, (intptr_t)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, (intptr_t)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(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, uint32_t 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(uint32_t r_info, uint32_t *ptr, uint32_t addend, Elf32_Sym *symtab, intptr_t base)\r
+{\r
+ intptr_t 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') - %p", r_info, ptr, *ptr, val, sSymName, 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 - (intptr_t)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 %p = 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 %p = 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, intptr_t *ret)\r
+ * \brief Get a symbol from the loaded binary\r
+ */\r
+int Elf_GetSymbol(void *Base, char *Name, intptr_t *ret)\r
+{\r
+ Elf32_Ehdr *hdr = (void*)Base;\r
+ Elf32_Sym *symtab;\r
+ int nbuckets = 0;\r
+ int iSymCount = 0;\r
+ int i;\r
+ uint32_t *pBuckets;\r
+ uint32_t *pChains;\r
+ uint32_t iNameHash;\r
+\r
+ if(!Base) return 0;\r
+\r
+ pBuckets = (void *)(intptr_t) hdr->misc.HashTable;\r
+ symtab = (void *)(intptr_t) 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 uint32_t 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
+uint32_t Elf_Int_HashString(char *str)\r
+{\r
+ uint32_t 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
--- /dev/null
+/**\r
+ * \file elf.h\r
+ * \brief ELF Exeutable Loader\r
+ */\r
+#ifndef _BIN_ELF_H\r
+#define _BIN_ELF_H\r
+\r
+#include <stdint.h>\r
+\r
+/**\r
+ * \brief ELF File Header\r
+ */\r
+struct sElf32_Ehdr\r
+{\r
+ union {\r
+ char ident[16]; //!< Identifier Bytes\r
+ struct {\r
+ uint32_t Ident1;\r
+ uint32_t Ident2;\r
+ uint32_t HashTable;\r
+ uint32_t SymTable;\r
+ } misc;\r
+ };\r
+ uint16_t filetype; //!< File Type\r
+ uint16_t machine; //!< Machine / Arch\r
+ uint32_t version; //!< Version (File?)\r
+ uint32_t entrypoint; //!< Entry Point\r
+ uint32_t phoff; //!< Program Header Offset\r
+ uint32_t shoff; //!< Section Header Offset\r
+ uint32_t flags; //!< Flags\r
+ uint16_t headersize; //!< Header Size\r
+ uint16_t phentsize; //!< Program Header Entry Size\r
+ uint16_t phentcount; //!< Program Header Entry Count\r
+ uint16_t shentsize; //!< Section Header Entry Size\r
+ uint16_t shentcount; //!< Section Header Entry Count\r
+ uint16_t shstrindex; //!< Section Header String Table Index\r
+} __attribute__ ((packed));\r
+\r
+/**\r
+ * \brief Executable Types\r
+ */\r
+enum eElf32_ExecTypes\r
+{\r
+ ET_NONE = 0, //!< NULL Type\r
+ ET_REL = 1, //!< Relocatable (Object)\r
+ ET_EXEC = 2, //!< Executable\r
+ ET_DYN = 3, //!< Dynamic Library\r
+ ET_CORE = 4, //!< Core?\r
+ ET_LOPROC = 0xFF00, //!< Low Impl Defined\r
+ ET_HIPROC = 0xFFFF //!< High Impl Defined\r
+};\r
+\r
+/**\r
+ \name Section IDs\r
+ \{\r
+*/\r
+#define SHN_UNDEF 0 //!< Undefined Section\r
+#define SHN_LORESERVE 0xFF00 //!< Low Reserved\r
+#define SHN_LOPROC 0xFF00 //!< Low Impl Defined\r
+#define SHN_HIPROC 0xFF1F //!< High Impl Defined\r
+#define SHN_ABS 0xFFF1 //!< Absolute Address (Base: 0, Size: -1)\r
+#define SHN_COMMON 0xFFF2 //!< Common\r
+#define SHN_HIRESERVE 0xFFFF //!< High Reserved\r
+//! \}\r
+\r
+/**\r
+ \enum eElfSectionTypes\r
+ \brief ELF Section Types\r
+*/\r
+enum eElfSectionTypes {\r
+ SHT_NULL, //0\r
+ SHT_PROGBITS, //1\r
+ SHT_SYMTAB, //2\r
+ SHT_STRTAB, //3\r
+ SHT_RELA, //4\r
+ SHT_HASH, //5\r
+ SHT_DYNAMIC, //6\r
+ SHT_NOTE, //7\r
+ SHT_NOBITS, //8\r
+ SHT_REL, //9\r
+ SHT_SHLIB, //A\r
+ SHT_DYNSYM, //B\r
+ SHT_LAST, //C\r
+ SHT_LOPROC = 0x70000000,\r
+ SHT_HIPROC = 0x7fffffff,\r
+ SHT_LOUSER = 0x80000000,\r
+ SHT_HIUSER = 0xffffffff\r
+};\r
+\r
+#define SHF_WRITE 0x1\r
+#define SHF_ALLOC 0x2\r
+#define SHF_EXECINSTR 0x4\r
+#define SHF_MASKPROC 0xf0000000\r
+\r
+struct sElf32_Shent {\r
+ uint32_t name;\r
+ uint32_t type;\r
+ uint32_t flags;\r
+ uint32_t address;\r
+ uint32_t offset;\r
+ uint32_t size;\r
+ uint32_t link;\r
+ uint32_t info;\r
+ uint32_t addralign;\r
+ uint32_t entsize;\r
+} __attribute__ ((packed)); //sizeof = 40\r
+\r
+struct elf_sym_s {\r
+ union {\r
+ uint32_t nameOfs;\r
+ char *name;\r
+ };\r
+ uint32_t value; //Address\r
+ uint32_t size;\r
+ uint8_t info;\r
+ uint8_t other;\r
+ uint16_t shndx;\r
+} __attribute__ ((packed));\r
+#define STN_UNDEF 0 // Undefined Symbol\r
+\r
+enum {\r
+ PT_NULL, //0\r
+ PT_LOAD, //1\r
+ PT_DYNAMIC, //2\r
+ PT_INTERP, //3\r
+ PT_NOTE, //4\r
+ PT_SHLIB, //5\r
+ PT_PHDR, //6\r
+ PT_LOPROC = 0x70000000,\r
+ PT_HIPROC = 0x7fffffff\r
+};\r
+\r
+struct sElf32_Phdr {\r
+ uint32_t Type;\r
+ uint32_t Offset;\r
+ uint32_t VAddr;\r
+ uint32_t PAddr;\r
+ uint32_t FileSize;\r
+ uint32_t MemSize;\r
+ uint32_t Flags;\r
+ uint32_t Align;\r
+} __attribute__ ((packed));\r
+\r
+struct elf32_rel_s {\r
+ uint32_t r_offset;\r
+ uint32_t r_info;\r
+} __attribute__ ((packed));\r
+\r
+struct elf32_rela_s {\r
+ uint32_t r_offset;\r
+ uint32_t r_info;\r
+ int32_t r_addend;\r
+} __attribute__ ((packed));\r
+\r
+enum {\r
+ R_386_NONE = 0, // none\r
+ R_386_32, // S+A\r
+ R_386_PC32, // S+A-P\r
+ R_386_GOT32, // G+A-P\r
+ R_386_PLT32, // L+A-P\r
+ R_386_COPY, // none\r
+ R_386_GLOB_DAT, // S\r
+ R_386_JMP_SLOT, // S\r
+ R_386_RELATIVE, // B+A\r
+ R_386_GOTOFF, // S+A-GOT\r
+ R_386_GOTPC, // GOT+A-P\r
+ R_386_LAST // none\r
+};\r
+\r
+#define ELF32_R_SYM(i) ((i)>>8) // Takes an info value and returns a symbol index\r
+#define ELF32_R_TYPE(i) ((i)&0xFF) // Takes an info value and returns a type\r
+#define ELF32_R_INFO(s,t) (((s)<<8)+((t)&0xFF)) // Takes a type and symbol index and returns an info value\r
+\r
+struct elf32_dyn_s {\r
+ uint32_t d_tag;\r
+ uint32_t d_val; //Also d_ptr\r
+} __attribute__ ((packed));\r
+\r
+enum {\r
+ DT_NULL, //!< Marks End of list\r
+ DT_NEEDED, //!< Offset in strtab to needed library\r
+ DT_PLTRELSZ, //!< Size in bytes of PLT\r
+ DT_PLTGOT, //!< Address of PLT/GOT\r
+ DT_HASH, //!< Address of symbol hash table\r
+ DT_STRTAB, //!< String Table address\r
+ DT_SYMTAB, //!< Symbol Table address\r
+ DT_RELA, //!< Relocation table address\r
+ DT_RELASZ, //!< Size of relocation table\r
+ DT_RELAENT, //!< Size of entry in relocation table\r
+ DT_STRSZ, //!< Size of string table\r
+ DT_SYMENT, //!< Size of symbol table entry\r
+ DT_INIT, //!< Address of initialisation function\r
+ DT_FINI, //!< Address of termination function\r
+ DT_SONAME, //!< String table offset of so name\r
+ DT_RPATH, //!< String table offset of library path\r
+ DT_SYMBOLIC,//!< Reverse order of symbol searching for library, search libs first then executable\r
+ DT_REL, //!< Relocation Entries (Elf32_Rel instead of Elf32_Rela)\r
+ DT_RELSZ, //!< Size of above table (bytes)\r
+ DT_RELENT, //!< Size of entry in above table\r
+ DT_PLTREL, //!< Relocation entry of PLT\r
+ DT_DEBUG, //!< Debugging Entry - Unknown contents\r
+ DT_TEXTREL, //!< Indicates that modifcations to a non-writeable segment may occur\r
+ DT_JMPREL, //!< Address of PLT only relocation entries\r
+ DT_LOPROC = 0x70000000, //!< Low Definable\r
+ DT_HIPROC = 0x7FFFFFFF //!< High Definable\r
+};\r
+\r
+typedef struct sElf32_Ehdr Elf32_Ehdr;\r
+typedef struct sElf32_Phdr Elf32_Phdr;\r
+typedef struct sElf32_Shent Elf32_Shent;\r
+typedef struct elf_sym_s elf_symtab;\r
+typedef struct elf_sym_s Elf32_Sym;\r
+typedef struct elf32_rel_s Elf32_Rel;\r
+typedef struct elf32_rela_s Elf32_Rela;\r
+typedef struct elf32_dyn_s Elf32_Dyn;\r
+\r
+#endif // defined(_EXE_ELF_H)\r