summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elf.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/elf.c b/elf.c
index cc90b18..439433b 100644
--- a/elf.c
+++ b/elf.c
@@ -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;