Reorganized directory structure
[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 }
30 }
31
32 void load_elf(const char* fn, loader_t* loader)
33 {
34 int fd = open(fn, O_RDONLY);
35 demand(fd != -1, "couldn't open %s", fn);
36
37 struct stat s;
38 demand(fstat(fd,&s) != -1, "couldn't stat %s", fn);
39
40 char* addr = (char*)mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
41 demand(addr != MAP_FAILED, "couldn't mmap %s", fn);
42
43 close(fd);
44
45 load_elf(addr, s.st_size, loader);
46 }