aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fesvr/elf.h2
-rw-r--r--fesvr/elf2hex.cc2
-rw-r--r--fesvr/elfloader.cc19
-rw-r--r--fesvr/elfloader.h3
-rw-r--r--fesvr/htif.cc8
-rw-r--r--fesvr/htif.h5
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;