diff options
-rw-r--r-- | fesvr/elf.h | 2 | ||||
-rw-r--r-- | fesvr/elf2hex.cc | 2 | ||||
-rw-r--r-- | fesvr/elfloader.cc | 19 | ||||
-rw-r--r-- | fesvr/elfloader.h | 3 | ||||
-rw-r--r-- | fesvr/htif.cc | 8 | ||||
-rw-r--r-- | fesvr/htif.h | 5 |
6 files changed, 25 insertions, 14 deletions
diff --git a/fesvr/elf.h b/fesvr/elf.h index 7b38bf1..b5a2a8d 100644 --- a/fesvr/elf.h +++ b/fesvr/elf.h @@ -6,6 +6,7 @@ #include <stdint.h> #define ET_EXEC 2 +#define ET_DYN 3 #define EM_RISCV 243 #define EM_NONE 0 #define EV_CURRENT 1 @@ -21,6 +22,7 @@ #define IS_ELFLE(hdr) (IS_ELF(hdr) && (hdr).e_ident[5] == 1) #define IS_ELFBE(hdr) (IS_ELF(hdr) && (hdr).e_ident[5] == 2) #define IS_ELF_EXEC(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_type) == ET_EXEC) +#define IS_ELF_DYN(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_type) == ET_DYN) #define IS_ELF_RISCV(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_machine) == EM_RISCV) #define IS_ELF_EM_NONE(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_machine) == EM_NONE) #define IS_ELF_VCURRENT(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_version) == EV_CURRENT) diff --git a/fesvr/elf2hex.cc b/fesvr/elf2hex.cc index 327cf2d..2638823 100644 --- a/fesvr/elf2hex.cc +++ b/fesvr/elf2hex.cc @@ -40,7 +40,7 @@ int main(int argc, char** argv) htif_hexwriter_t htif(base, width, depth); memif_t memif(&htif); reg_t entry; - load_elf(argv[3], &memif, &entry); + load_elf(argv[3], &memif, &entry, 0); std::cout << htif; return 0; diff --git a/fesvr/elfloader.cc b/fesvr/elfloader.cc index 391afa0..5cab050 100644 --- a/fesvr/elfloader.cc +++ b/fesvr/elfloader.cc @@ -18,7 +18,8 @@ #include <map> #include <cerrno> -std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0) +std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, + reg_t load_offset, unsigned required_xlen = 0) { int fd = open(fn, O_RDONLY); struct stat s; @@ -41,10 +42,14 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* throw incompat_xlen(required_xlen, xlen); } assert(IS_ELFLE(*eh64) || IS_ELFBE(*eh64)); - assert(IS_ELF_EXEC(*eh64)); + assert(IS_ELF_EXEC(*eh64) || IS_ELF_DYN(*eh64)); assert(IS_ELF_RISCV(*eh64) || IS_ELF_EM_NONE(*eh64)); assert(IS_ELF_VCURRENT(*eh64)); + if (IS_ELF_EXEC(*eh64)) { + load_offset = 0; + } + std::vector<uint8_t> zeros; std::map<std::string, uint64_t> symbols; @@ -52,19 +57,19 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* do { \ ehdr_t* eh = (ehdr_t*)buf; \ phdr_t* ph = (phdr_t*)(buf + bswap(eh->e_phoff)); \ - *entry = bswap(eh->e_entry); \ + *entry = bswap(eh->e_entry) + load_offset; \ assert(size >= bswap(eh->e_phoff) + bswap(eh->e_phnum) * sizeof(*ph)); \ for (unsigned i = 0; i < bswap(eh->e_phnum); i++) { \ if (bswap(ph[i].p_type) == PT_LOAD && bswap(ph[i].p_memsz)) { \ + reg_t load_addr = bswap(ph[i].p_paddr) + load_offset; \ if (bswap(ph[i].p_filesz)) { \ assert(size >= bswap(ph[i].p_offset) + bswap(ph[i].p_filesz)); \ - memif->write(bswap(ph[i].p_paddr), bswap(ph[i].p_filesz), \ + memif->write(load_addr, bswap(ph[i].p_filesz), \ (uint8_t*)buf + bswap(ph[i].p_offset)); \ } \ if (size_t pad = bswap(ph[i].p_memsz) - bswap(ph[i].p_filesz)) { \ zeros.resize(pad); \ - memif->write(bswap(ph[i].p_paddr) + bswap(ph[i].p_filesz), pad, \ - zeros.data()); \ + memif->write(load_addr + bswap(ph[i].p_filesz), pad, zeros.data()); \ } \ } \ } \ @@ -96,7 +101,7 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* bswap(sh[strtabidx].sh_size) - bswap(sym[i].st_name); \ assert(bswap(sym[i].st_name) < bswap(sh[strtabidx].sh_size)); \ assert(strnlen(strtab + bswap(sym[i].st_name), max_len) < max_len); \ - symbols[strtab + bswap(sym[i].st_name)] = bswap(sym[i].st_value); \ + symbols[strtab + bswap(sym[i].st_name)] = bswap(sym[i].st_value) + load_offset; \ } \ } \ } while (0) diff --git a/fesvr/elfloader.h b/fesvr/elfloader.h index ae4ee78..0a250cd 100644 --- a/fesvr/elfloader.h +++ b/fesvr/elfloader.h @@ -8,6 +8,7 @@ #include <string> class memif_t; -std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0); +std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, + reg_t load_offset, unsigned required_xlen = 0); #endif diff --git a/fesvr/htif.cc b/fesvr/htif.cc index 8b5eb8d..46f15d3 100644 --- a/fesvr/htif.cc +++ b/fesvr/htif.cc @@ -103,7 +103,7 @@ static void bad_address(const std::string& situation, reg_t addr) exit(-1); } -std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, reg_t* entry) +std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, reg_t* entry, reg_t load_offset) { std::string path; if (access(payload.c_str(), F_OK) == 0) @@ -143,7 +143,7 @@ std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, } preload_aware_memif(this); try { - return load_elf(path.c_str(), &preload_aware_memif, entry, expected_xlen); + return load_elf(path.c_str(), &preload_aware_memif, entry, load_offset, expected_xlen); } catch (mem_trap_t& t) { bad_address("loading payload " + payload, t.get_tval()); abort(); @@ -152,7 +152,7 @@ std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, void htif_t::load_program() { - std::map<std::string, uint64_t> symbols = load_payload(targs[0], &entry); + std::map<std::string, uint64_t> symbols = load_payload(targs[0], &entry, load_offset); if (symbols.count("tohost") && symbols.count("fromhost")) { tohost_addr = symbols["tohost"]; @@ -169,7 +169,7 @@ void htif_t::load_program() for (auto payload : payloads) { reg_t dummy_entry; - load_payload(payload, &dummy_entry); + load_payload(payload, &dummy_entry, 0); } class nop_memif_t : public memif_t { diff --git a/fesvr/htif.h b/fesvr/htif.h index dd7c060..74511f5 100644 --- a/fesvr/htif.h +++ b/fesvr/htif.h @@ -7,6 +7,7 @@ #include "syscall.h" #include "device.h" #include "byteorder.h" +#include "../riscv/platform.h" #include <string.h> #include <map> #include <vector> @@ -58,7 +59,8 @@ class htif_t : public chunked_memif_t virtual size_t chunk_align() = 0; virtual size_t chunk_max_size() = 0; - virtual std::map<std::string, uint64_t> load_payload(const std::string& payload, reg_t* entry); + virtual std::map<std::string, uint64_t> load_payload(const std::string& payload, reg_t* entry, + reg_t load_addr); virtual void load_program(); virtual void idle() {} @@ -79,6 +81,7 @@ class htif_t : public chunked_memif_t void register_devices(); void usage(const char * program_name); unsigned int expected_xlen = 0; + const reg_t load_offset = DRAM_BASE; memif_t mem; reg_t entry; bool writezeros; |