qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v5 12/23] RISC-V HTIF Console


From: Richard Henderson
Subject: Re: [Qemu-devel] [PATCH v5 12/23] RISC-V HTIF Console
Date: Thu, 8 Feb 2018 08:35:26 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0

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~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]