[sim] added softfloat
[riscv-isa-sim.git] / riscv / load_elf.cc
1 #include <sys/stat.h>
2 #include <fcntl.h>
3 #include <sys/mman.h>
4 #include <elf.h>
5 #include "common.h"
6 #include "load_elf.h"
7
8 void load_elf(const char* buf, size_t size, loader_t* loader)
9 {
10 demand(size >= sizeof(Elf64_Ehdr), "truncated ELF!");
11 const Elf64_Ehdr* eh = (const Elf64_Ehdr*)buf;
12
13 const uint32_t* magic = (const uint32_t*)eh->e_ident;
14 demand(*magic == *(const uint32_t*)ELFMAG, "not a host-endian ELF!");
15 demand(size >= eh->e_phoff + eh->e_phnum*sizeof(Elf64_Phdr), "bad ELF!");
16 const Elf64_Phdr* phs = (const Elf64_Phdr*)(buf+eh->e_phoff);
17
18 for(int i = 0; i < eh->e_phnum; i++)
19 {
20 const Elf64_Phdr* ph = &phs[i];
21 if(ph->p_type == SHT_PROGBITS && ph->p_memsz)
22 {
23 demand(size >= ph->p_offset + ph->p_filesz, "truncated ELF!");
24 demand(ph->p_memsz >= ph->p_filesz, "bad ELF!");
25
26 loader->write(ph->p_vaddr, ph->p_filesz, buf + ph->p_offset);
27 loader->write(ph->p_vaddr + ph->p_filesz, ph->p_memsz - ph->p_filesz);
28
29 printf("%d\n", ph->p_vaddr);
30 }
31 }
32 }
33
34 void load_elf(const char* fn, loader_t* loader)
35 {
36 int fd = open(fn, O_RDONLY);
37 demand(fd != -1, "couldn't open %s", fn);
38
39 struct stat s;
40 demand(fstat(fd,&s) != -1, "couldn't stat %s", fn);
41
42 char* addr = (char*)mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
43 demand(addr != MAP_FAILED, "couldn't mmap %s", fn);
44
45 close(fd);
46
47 load_elf(addr, s.st_size, loader);
48 }