From 3cb7c05906b8eb8e884013b441f352256fded011 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 10 Nov 2010 17:10:07 +0100 Subject: First bunch of rework, stil work in progress --- elf.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 elf.c (limited to 'elf.c') diff --git a/elf.c b/elf.c new file mode 100644 index 0000000..cc90b18 --- /dev/null +++ b/elf.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2010 Tobias Klauser + * + * This file is part of nios2sim-ng. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include + +#include "nios2sim-ng.h" +#include "image.h" + +/* not defined with libelf */ +#define EM_ALTERA_NIOS2 113 + +/* + * http://elftoolchain.sourceforge.net/for-review/libelf-by-example-20100112.pdf + */ + +static int elf_read_sections(Elf *e) +{ + Elf_Scn *scn = NULL; + GElf_Shdr shdr; + size_t shstrndx; + char *name; + + if (elf_getshdrstrndx(e, &shstrndx) != 0) { + err("elf_getshdrstrndx() failed: %s\n", elf_errmsg(-1)); + return -1; + } + + while ((scn = elf_nextscn(e, scn)) != NULL) { + GElf_Phdr phdr; + + if (gelf_getshdr(scn, &shdr) != &shdr) { + 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; + } + + dbg("Section %zu: %s\n", elf_ndxscn(scn), name); + } + + return 0; +} + +int elf_load(FILE *fp, const char *name, uint8_t *mem_base, size_t mem_size) +{ + int fd = fileno(fp); + int ret; + Elf *e; + GElf_Ehdr ehdr; + size_t n; + + if (unlikely(fd < 0)) { + err("Couldn't get file descriptor for '%s'\n", name); + return -1; + } + + if (elf_version(EV_CURRENT) == EV_NONE) { + err("ELF library initialization failed\n"); + return -1; + } + + ret = -1; + e = elf_begin(fd, ELF_C_READ, NULL); + if (unlikely(e == NULL)) { + err("Couldn't get ELF file handle for '%s': %s\n", name, elf_errmsg(-1)); + goto out; + } + + if (elf_kind(e) != ELF_K_ELF) { + err("'%s' is not an ELF object\n", name); + goto out; + } + + if (gelf_getclass(e) != ELFCLASS32) { + err("'%s' has invalid ELF class\n", name); + goto out; + } + + if (gelf_getehdr(e, &ehdr) == NULL) { + err("gelf_getehdr() failed: %s\n", elf_errmsg(-1)); + goto out; + } + + if (ehdr.e_type != ET_EXEC || ehdr.e_machine != EM_ALTERA_NIOS2) { + err("'%s' is not a Nios2 ELF executable (%x, %x)\n", name, ehdr.e_type, ehdr.e_machine); + goto out; + } + + ret = elf_read_sections(e); +out: + elf_end(e); + return ret; +} -- cgit v1.2.3-54-g00ecf