3 * ELF Executable Loader Code
\r
13 #define DEBUG_WARN 1
\r
15 #define MKPTR(_type,_val) ((_type*)(uintptr_t)(_val))
\r
16 #define PTRMK(_type,_val) MKPTR(_type,_val)
\r
17 #define PTR(_val) ((void*)(uintptr_t)(_val))
\r
20 # define ENTER(...) printf("%s: ---- ENTER ----\n", __func__);
\r
21 # define LOG(s, ...) printf("%s: " s, __func__, __VA_ARGS__)
\r
22 # define LOGS(s) printf("%s: " s, __func__)
\r
31 // === PROTOTYPES ===
\r
32 void *Elf_Load(int FD);
\r
33 void *Elf32Load(int FD, Elf32_Ehdr *hdr);
\r
36 void *Elf_Load(int FD)
\r
41 acess_read(FD, &hdr, sizeof(hdr));
\r
43 // Check the file type
\r
44 if(hdr.e_ident[0] != 0x7F || hdr.e_ident[1] != 'E' || hdr.e_ident[2] != 'L' || hdr.e_ident[3] != 'F') {
\r
45 Warning("Non-ELF File was passed to the ELF loader\n");
\r
49 switch(hdr.e_ident[4])
\r
52 return Elf32Load(FD, &hdr);
\r
57 void *Elf32Load(int FD, Elf32_Ehdr *hdr)
\r
64 uint32_t baseDiff = 0;
\r
68 // Check for a program header
\r
69 if(hdr->phoff == 0) {
\r
71 Warning("ELF File does not contain a program header\n");
\r
77 // Read Program Header Table
\r
78 phtab = malloc( sizeof(Elf32_Phdr) * hdr->phentcount );
\r
83 LOG("hdr.phoff = 0x%08x\n", hdr->phoff);
\r
84 acess_seek(FD, hdr->phoff, ACESS_SEEK_SET);
\r
85 acess_read(FD, phtab, sizeof(Elf32_Phdr) * hdr->phentcount);
\r
89 LOG("hdr.phentcount = %i\n", hdr->phentcount);
\r
90 for( i = 0; i < hdr->phentcount; i++ )
\r
92 // Ignore Non-LOAD types
\r
93 if(phtab[i].Type != PT_LOAD)
\r
95 iPageCount += ((phtab[i].VAddr&0xFFF) + phtab[i].MemSize + 0xFFF) >> 12;
\r
96 LOG("phtab[%i] = {VAddr:0x%x, MemSize:0x%x}\n", i, phtab[i].VAddr, phtab[i].MemSize);
\r
99 LOG("iPageCount = %i\n", iPageCount);
\r
101 // Allocate Information Structure
\r
102 //ret = malloc( sizeof(tBinary) + sizeof(tBinaryPage)*iPageCount );
\r
103 // Fill Info Struct
\r
104 //ret->Entry = hdr.entrypoint;
\r
105 //ret->Base = -1; // Set Base to maximum value
\r
106 //ret->NumPages = iPageCount;
\r
107 //ret->Interpreter = NULL;
\r
109 // Prescan for base and size
\r
112 for( i = 0; i < hdr->phentcount; i ++)
\r
114 if( phtab[i].Type != PT_LOAD )
\r
116 if( phtab[i].VAddr < base )
\r
117 base = phtab[i].VAddr;
\r
118 if( phtab[i].VAddr + phtab[i].MemSize > max )
\r
119 max = phtab[i].VAddr + phtab[i].MemSize;
\r
122 LOG("base = %08x, max = %08x\n", base, max);
\r
125 // Find a nice space (31 address bits allowed)
\r
126 base = FindFreeRange( max, 31 );
\r
127 LOG("new base = %08x\n", base);
\r
128 if( base == 0 ) return NULL;
\r
133 for( i = 0; i < hdr->phentcount; i++ )
\r
135 // Get Interpreter Name
\r
136 if( phtab[i].Type == PT_INTERP )
\r
139 //if(ret->Interpreter) continue;
\r
140 tmp = malloc(phtab[i].FileSize);
\r
141 acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);
\r
142 acess_read(FD, tmp, phtab[i].FileSize);
\r
143 //ret->Interpreter = Binary_RegInterp(tmp);
\r
144 LOG("Interpreter '%s'\n", tmp);
\r
148 // Ignore non-LOAD types
\r
149 if(phtab[i].Type != PT_LOAD) continue;
\r
151 LOG("phtab[%i] = PT_LOAD {Adj VAddr:0x%x, Offset:0x%x, FileSize:0x%x, MemSize:0x%x}\n",
\r
152 i, phtab[i].VAddr+baseDiff, phtab[i].Offset, phtab[i].FileSize, phtab[i].MemSize);
\r
154 addr = phtab[i].VAddr + baseDiff;
\r
156 if( AllocateMemory( addr, phtab[i].MemSize ) ) {
\r
157 fprintf(stderr, "Elf_Load: Unable to map memory at %x (0x%x bytes)\n",
\r
158 addr, phtab[i].MemSize);
\r
163 acess_seek(FD, phtab[i].Offset, ACESS_SEEK_SET);
\r
164 acess_read(FD, PTRMK(void, addr), phtab[i].FileSize);
\r
165 memset( PTRMK(char, addr) + phtab[i].FileSize, 0, phtab[i].MemSize - phtab[i].FileSize );
\r
172 return PTRMK(void, base);
\r