On 02/07/2018 05:28 PM, Michael Clark wrote: > +++ b/hw/riscv/riscv_elf.c > @@ -0,0 +1,244 @@ > +/* > + * elf.c - A simple package for manipulating symbol tables in elf binaries. > + * > + * Taken from > + * https://www.cs.cmu.edu/afs/cs.cmu.edu/academic/class/15213-f03/www/ > + * ftrace/elf.c > + * > + */ > +#include <stdio.h> > +#include <stdlib.h> > +#include <unistd.h> > +#include <string.h> > +#include <sys/stat.h> > +#include <sys/types.h> > +#include <sys/mman.h> > +#include <errno.h> > +#include <fcntl.h> > +#include <glib.h> > + > +#include "hw/riscv/riscv_elf.h" > + > +/* > + * elf_open - Map a binary into the address space and extract the > + * locations of the static and dynamic symbol tables and their string > + * tables. Return this information in a Elf object file handle that will > + * be passed to all of the other elf functions. > + */ > +Elf_obj64 *elf_open64(const char *filename) > +{ > + int i, fd; > + struct stat sbuf; > + Elf_obj64 *ep; > + Elf64_Shdr *shdr; > + > + ep = g_new(Elf_obj64, 1); > + > + /* Do some consistency checks on the binary */ > + fd = open(filename, O_RDONLY); > + if (fd == -1) { > + fprintf(stderr, "Can't open \"%s\": %s\n", filename, > strerror(errno)); > + exit(1); > + } > + if (fstat(fd, &sbuf) == -1) { > + fprintf(stderr, "Can't stat \"%s\": %s\n", filename, > strerror(errno)); > + exit(1); > + } > + if (sbuf.st_size < sizeof(Elf64_Ehdr)) { > + fprintf(stderr, "\"%s\" is not an ELF binary object\n", filename); > + exit(1); > + } > + > + /* It looks OK, so map the Elf binary into our address space */ > + ep->mlen = sbuf.st_size; > + ep->maddr = mmap(NULL, ep->mlen, PROT_READ, MAP_SHARED, fd, 0); > + if (ep->maddr == (void *)-1) { > + fprintf(stderr, "Can't mmap \"%s\": %s\n", filename, > strerror(errno)); > + exit(1); > + } > + close(fd); > + > + /* The Elf binary begins with the Elf header */ > + ep->ehdr = ep->maddr; > + > + /* check we have a 64-bit little-endian RISC-V ELF object */ > + if (ep->ehdr->e_ident[EI_MAG0] != ELFMAG0 || > + ep->ehdr->e_ident[EI_MAG1] != ELFMAG1 || > + ep->ehdr->e_ident[EI_MAG2] != ELFMAG2 || > + ep->ehdr->e_ident[EI_MAG3] != ELFMAG3 || > + ep->ehdr->e_ident[EI_CLASS] != ELFCLASS64 || > + ep->ehdr->e_ident[EI_DATA] != ELFDATA2LSB || > + ep->ehdr->e_machine != EM_RISCV) > + { > + fprintf(stderr, "\"%s\" is not a 64-bit RISC-V ELF object\n", > filename); > + exit(1); > + } > + > + /* > + * Find the static and dynamic symbol tables and their string > + * tables in the the mapped binary. The sh_link field in symbol > + * table section headers gives the section index of the string > + * table for that symbol table. > + */ > + shdr = (Elf64_Shdr *)(ep->maddr + ep->ehdr->e_shoff);
This duplicates, badly, existing code within include/hw/elf_ops.h. In particular, this fails to bswap these fields. As such, this code will only work on little-endian hosts. r~