diff options
-rw-r--r-- | elf.c | 36 |
1 files changed, 26 insertions, 10 deletions
@@ -23,10 +23,9 @@ * http://elftoolchain.sourceforge.net/for-review/libelf-by-example-20100112.pdf */ -static int elf_read_sections(Elf *e) +static int elf_read_sections(Elf *e, struct memory *mem) { Elf_Scn *scn = NULL; - GElf_Shdr shdr; size_t shstrndx; char *name; @@ -36,25 +35,42 @@ static int elf_read_sections(Elf *e) } while ((scn = elf_nextscn(e, scn)) != NULL) { + GElf_Shdr shdr; GElf_Phdr phdr; - if (gelf_getshdr(scn, &shdr) != &shdr) { + if (gelf_getshdr(scn, &shdr) == NULL) { err("Couldn't get section header: %s\n", elf_errmsg(-1)); return -1; } - if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) { - err("Couldn't get section name: %s\n", elf_errmsg(-1)); - return -1; - } + /* Is it a .text section? */ + if (shdr.sh_type == SHT_PROGBITS + && (shdr.sh_flags & ~SHF_WRITE) == (SHF_ALLOC | SHF_EXECINSTR)) { + Elf_Data *data; + size_t n; + + if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) { + err("Couldn't get section name: %s\n", elf_errmsg(-1)); + return -1; + } - dbg("Section %zu: %s\n", elf_ndxscn(scn), name); + dbg("Section %zu: %s (size=%zu, flags=%08lx, addr=%08lx, off=%08lx)\n", elf_ndxscn(scn), name, shdr.sh_size, shdr.sh_flags, shdr.sh_addr, shdr.sh_offset); + + data = NULL; + n = 0; + while (n < shdr.sh_size && + (data = elf_getdata(scn, data)) != NULL) { + memcpy(&mem->base[(shdr.sh_addr + n) / 4], data->d_buf, data->d_size); + + n += data->d_size; + } + } } return 0; } -int elf_load(FILE *fp, const char *name, uint8_t *mem_base, size_t mem_size) +int elf_load(FILE *fp, const char *name, struct memory *mem) { int fd = fileno(fp); int ret; @@ -99,7 +115,7 @@ int elf_load(FILE *fp, const char *name, uint8_t *mem_base, size_t mem_size) goto out; } - ret = elf_read_sections(e); + ret = elf_read_sections(e, mem); out: elf_end(e); return ret; |