|
|
@ -6,7 +6,7 @@ |
|
|
|
|
|
|
|
struct elf_info { |
|
|
|
struct eiofxn *_fxn; |
|
|
|
Elf32_Ehdr _ehdr; |
|
|
|
Elf32_Ehdr _ehdr; |
|
|
|
}; |
|
|
|
|
|
|
|
static inline void *eio_malloc(elf_info_t ei, size_t cnt) |
|
|
@ -17,10 +17,10 @@ static inline void *eio_malloc(elf_info_t ei, size_t cnt) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static inline void eio_free(elf_info_t ei, void *ptr) |
|
|
|
static inline void eio_free(elf_info_t ei, void *ptr, size_t cnt) |
|
|
|
{ |
|
|
|
if (ei->_fxn && ei->_fxn->free) { |
|
|
|
ei->_fxn->free(ei->_fxn, ptr); |
|
|
|
ei->_fxn->free(ei->_fxn, ptr, cnt); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -47,10 +47,21 @@ static inline void eio_puts(elf_info_t ei, const char *s) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#if 0 |
|
|
|
static inline void *eio_mmap(elf_info_t ei, uint32_t base, size_t cnt) |
|
|
|
{ |
|
|
|
if (ei->_fxn && ei->_fxn->mmap) { |
|
|
|
return ei->_fxn->mmap(ei->_fxn, base, cnt); |
|
|
|
} |
|
|
|
return (void *)base; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
static int __read_ehdr(elf_info_t ei) |
|
|
|
{ |
|
|
|
int err; |
|
|
|
|
|
|
|
eio_seek(ei, 0); |
|
|
|
err = eio_read(ei, &ei->_ehdr, sizeof ei->_ehdr); |
|
|
|
if (err) { |
|
|
|
eio_puts(ei, "read elf header failed.\n"); |
|
|
@ -92,18 +103,18 @@ elf_info_t elf_open(struct eiofxn *eio) |
|
|
|
{ |
|
|
|
elf_info_t ei = NULL; |
|
|
|
|
|
|
|
if (eio && eio->malloc) { |
|
|
|
ei = eio->malloc(eio, sizeof *ei); |
|
|
|
} |
|
|
|
if (eio && eio->malloc) { |
|
|
|
ei = eio->malloc(eio, sizeof *ei); |
|
|
|
} |
|
|
|
|
|
|
|
if (ei == NULL) { |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
ei->_fxn = eio; |
|
|
|
ei->_fxn = eio; |
|
|
|
|
|
|
|
if (__read_ehdr(ei)) { |
|
|
|
eio->free(eio, ei); |
|
|
|
ei = NULL; |
|
|
|
eio->free(eio, ei, sizeof *ei); |
|
|
|
ei = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
return (ei); |
|
|
@ -113,7 +124,7 @@ void elf_close(elf_info_t ei) |
|
|
|
{ |
|
|
|
if (ei) { |
|
|
|
struct eiofxn *eio = ei->_fxn; |
|
|
|
ei->_fxn->free(eio, ei); |
|
|
|
ei->_fxn->free(eio, ei, sizeof *ei); |
|
|
|
if (eio->on_close) |
|
|
|
eio->on_close(eio); |
|
|
|
} |
|
|
@ -148,10 +159,11 @@ void elf_dump(elf_info_t ei) |
|
|
|
|
|
|
|
static int __load_exec(elf_info_t ei) |
|
|
|
{ |
|
|
|
Elf32_Phdr *phdr; |
|
|
|
Elf32_Phdr *phdr, *it; |
|
|
|
Elf32_Half phnum = ei->_ehdr.e_phnum; |
|
|
|
size_t sz; |
|
|
|
int i; |
|
|
|
int i, diff; |
|
|
|
uint8_t *ptr; |
|
|
|
|
|
|
|
if (eio_seek(ei, ei->_ehdr.e_phoff)) { |
|
|
|
return -1; |
|
|
@ -166,20 +178,44 @@ static int __load_exec(elf_info_t ei) |
|
|
|
return -3; |
|
|
|
|
|
|
|
#define dbgprintf ei->_fxn->printf |
|
|
|
for (i = 0; i < phnum; ++i) { |
|
|
|
dbgprintf(ei->_fxn, "segment[%d]\n", i); |
|
|
|
dbgprintf(ei->_fxn, "type: %d\n", phdr[i].p_type); |
|
|
|
dbgprintf(ei->_fxn, "offset: 0x%x\n", phdr[i].p_offset); |
|
|
|
dbgprintf(ei->_fxn, "vaddr: 0x%x\n", phdr[i].p_vaddr); |
|
|
|
dbgprintf(ei->_fxn, "paddr: 0x%x\n", phdr[i].p_paddr); |
|
|
|
dbgprintf(ei->_fxn, "filesz: 0x%x\n", phdr[i].p_filesz); |
|
|
|
dbgprintf(ei->_fxn, "memsz: 0x%x\n", phdr[i].p_memsz); |
|
|
|
dbgprintf(ei->_fxn, "flags: 0x%x\n", phdr[i].p_flags); |
|
|
|
dbgprintf(ei->_fxn, "align: %d\n", phdr[i].p_align); |
|
|
|
} |
|
|
|
if (dbgprintf) { |
|
|
|
for (i = 0; i < phnum; ++i) { |
|
|
|
dbgprintf(ei->_fxn, "segment[%d]\n", i); |
|
|
|
dbgprintf(ei->_fxn, "type: %d\n", phdr[i].p_type); |
|
|
|
dbgprintf(ei->_fxn, "offset: 0x%x\n", phdr[i].p_offset); |
|
|
|
dbgprintf(ei->_fxn, "vaddr: 0x%x\n", phdr[i].p_vaddr); |
|
|
|
dbgprintf(ei->_fxn, "paddr: 0x%x\n", phdr[i].p_paddr); |
|
|
|
dbgprintf(ei->_fxn, "filesz: 0x%x\n", phdr[i].p_filesz); |
|
|
|
dbgprintf(ei->_fxn, "memsz: 0x%x\n", phdr[i].p_memsz); |
|
|
|
dbgprintf(ei->_fxn, "flags: 0x%x\n", phdr[i].p_flags); |
|
|
|
dbgprintf(ei->_fxn, "align: %d\n", phdr[i].p_align); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i < phnum; ++i) { |
|
|
|
it = phdr + i; |
|
|
|
switch (it->p_type) { |
|
|
|
case PT_LOAD: |
|
|
|
ptr = (uint8_t *)it->p_vaddr; |
|
|
|
eio_seek(ei, it->p_offset); |
|
|
|
if (it->p_filesz > 0) { |
|
|
|
eio_read(ei, ptr, it->p_filesz); |
|
|
|
} |
|
|
|
diff = it->p_memsz - it->p_filesz; |
|
|
|
if (diff > 0) { |
|
|
|
memset(ptr + it->p_filesz, 0, diff); |
|
|
|
} |
|
|
|
if (dbgprintf) { |
|
|
|
dbgprintf(ei->_fxn, "load[%d] 0x%x (%d bytes): done\n", i, it->p_vaddr, it->p_filesz); |
|
|
|
} |
|
|
|
break; |
|
|
|
case PT_DYNAMIC: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
#undef dbgprintf |
|
|
|
eio_free(ei, phdr); |
|
|
|
return 0; |
|
|
|
eio_free(ei, phdr, sz); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
int elf_load(elf_info_t ei) |
|
|
|