[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v5 12/23] RISC-V HTIF Console
From: |
Michael Clark |
Subject: |
Re: [Qemu-devel] [PATCH v5 12/23] RISC-V HTIF Console |
Date: |
Fri, 9 Feb 2018 20:33:43 +1300 |
On Fri, Feb 9, 2018 at 5:35 AM, Richard Henderson <
address@hidden> wrote:
> 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.
>
There is enough information in the structures held in the syminfo table
used by the disassembler however elf_ops.h currently throws away all
symbols that are not STT_FUNC, and we are after STT_OBJECT symbols. We
would need to add an option to load_elf to load the entire symbol table.
Also, it runs qsort on the table by address, so we'd need to do a linear
scan for the HTIF symbols by name. There are only two symbols we need:
'fromhost' and 'tohost'.
/* We are only interested in function symbols.
Throw everything else away. */
if (syms[i].st_shndx == SHN_UNDEF ||
syms[i].st_shndx >= SHN_LORESERVE ||
ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
nsyms--;
if (i < nsyms) {
syms[i] = syms[nsyms];
}
continue;
}
It would be really nice if HTIF just specified registers in device-tree;
alas it doesn't; and there is still quite a bit of code that depend on
using these magic HTIF 'fromhost' and 'tohost' symbols. riscv-tests for one
uses the HTIF mechanism and spike the official ISA simulator uses HTIF for
IO.
- [Qemu-devel] [PATCH v5 04/23] RISC-V Disassembler, (continued)
- [Qemu-devel] [PATCH v5 04/23] RISC-V Disassembler, Michael Clark, 2018/02/07
- [Qemu-devel] [PATCH v5 10/23] RISC-V Physical Memory Protection, Michael Clark, 2018/02/07
- [Qemu-devel] [PATCH v5 11/23] RISC-V Linux User Emulation, Michael Clark, 2018/02/07
- [Qemu-devel] [PATCH v5 09/23] RISC-V TCG Code Generation, Michael Clark, 2018/02/07
- [Qemu-devel] [PATCH v5 13/23] RISC-V HART Array, Michael Clark, 2018/02/07
- [Qemu-devel] [PATCH v5 12/23] RISC-V HTIF Console, Michael Clark, 2018/02/07
[Qemu-devel] [PATCH v5 14/23] SiFive RISC-V CLINT Block, Michael Clark, 2018/02/07
[Qemu-devel] [PATCH v5 15/23] SiFive RISC-V PLIC Block, Michael Clark, 2018/02/07
[Qemu-devel] [PATCH v5 16/23] RISC-V Spike Machines, Michael Clark, 2018/02/07
[Qemu-devel] [PATCH v5 17/23] RISC-V VirtIO Machine, Michael Clark, 2018/02/07
[Qemu-devel] [PATCH v5 18/23] SiFive RISC-V UART Device, Michael Clark, 2018/02/07
[Qemu-devel] [PATCH v5 19/23] SiFive RISC-V PRCI Block, Michael Clark, 2018/02/07