diff options
author | Andrew Waterman <andrew@sifive.com> | 2022-09-20 17:14:15 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-20 17:14:15 -0700 |
commit | 7c4cf010a10a1ea5ab18e8d65ab9e56a4f8b767e (patch) | |
tree | 479fd34356d472fe68288c4c42026b050f4850e7 | |
parent | 326fa00f587c43f76d94acbeaed83ffba2e07d3b (diff) | |
parent | dfd191367991cb157b53767dcc05824c826b5abd (diff) | |
download | riscv-isa-sim-7c4cf010a10a1ea5ab18e8d65ab9e56a4f8b767e.zip riscv-isa-sim-7c4cf010a10a1ea5ab18e8d65ab9e56a4f8b767e.tar.gz riscv-isa-sim-7c4cf010a10a1ea5ab18e8d65ab9e56a4f8b767e.tar.bz2 |
Merge pull request #1085 from ImanHosseini/patch1
Detect loading isa-incompatible code
-rw-r--r-- | fesvr/elfloader.cc | 6 | ||||
-rw-r--r-- | fesvr/elfloader.h | 2 | ||||
-rw-r--r-- | fesvr/htif.cc | 10 | ||||
-rw-r--r-- | fesvr/htif.h | 4 | ||||
-rw-r--r-- | fesvr/memif.h | 8 | ||||
-rw-r--r-- | riscv/sim.cc | 1 |
6 files changed, 25 insertions, 6 deletions
diff --git a/fesvr/elfloader.cc b/fesvr/elfloader.cc index 76cd6da..1bdccd3 100644 --- a/fesvr/elfloader.cc +++ b/fesvr/elfloader.cc @@ -16,7 +16,7 @@ #include <vector> #include <map> -std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry) +std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0) { int fd = open(fn, O_RDONLY); struct stat s; @@ -32,6 +32,10 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* assert(size >= sizeof(Elf64_Ehdr)); const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf; assert(IS_ELF32(*eh64) || IS_ELF64(*eh64)); + unsigned xlen = IS_ELF32(*eh64) ? 32 : 64; + if (required_xlen != 0 && required_xlen != xlen) { + throw incompat_xlen(required_xlen, xlen); + } assert(IS_ELFLE(*eh64) || IS_ELFBE(*eh64)); assert(IS_ELF_EXEC(*eh64)); assert(IS_ELF_RISCV(*eh64) || IS_ELF_EM_NONE(*eh64)); diff --git a/fesvr/elfloader.h b/fesvr/elfloader.h index 696ef47..ae4ee78 100644 --- a/fesvr/elfloader.h +++ b/fesvr/elfloader.h @@ -8,6 +8,6 @@ #include <string> class memif_t; -std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry); +std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0); #endif diff --git a/fesvr/htif.cc b/fesvr/htif.cc index ead309c..29eb7d8 100644 --- a/fesvr/htif.cc +++ b/fesvr/htif.cc @@ -82,8 +82,14 @@ htif_t::~htif_t() void htif_t::start() { - if (!targs.empty() && targs[0] != "none") + if (!targs.empty() && targs[0] != "none") { + try { load_program(); + } catch (const incompat_xlen & err) { + fprintf(stderr, "Error: cannot execute %d-bit program on RV%d hart\n", err.actual_xlen, err.expected_xlen); + exit(1); + } + } reset(); } @@ -129,7 +135,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); + return load_elf(path.c_str(), &preload_aware_memif, entry, expected_xlen); } catch (mem_trap_t& t) { bad_address("loading payload " + payload, t.get_tval()); abort(); diff --git a/fesvr/htif.h b/fesvr/htif.h index ca5b362..cf8b2d5 100644 --- a/fesvr/htif.h +++ b/fesvr/htif.h @@ -26,7 +26,7 @@ class htif_t : public chunked_memif_t int run(); bool done(); int exit_code(); - + void set_expected_xlen(unsigned int m) { expected_xlen = m; } virtual memif_t& memif() { return mem; } template<typename T> inline T from_target(target_endian<T> n) const @@ -74,7 +74,7 @@ class htif_t : public chunked_memif_t void parse_arguments(int argc, char ** argv); void register_devices(); void usage(const char * program_name); - + unsigned int expected_xlen = 0; memif_t mem; reg_t entry; bool writezeros; diff --git a/fesvr/memif.h b/fesvr/memif.h index 001c425..3f9bd2d 100644 --- a/fesvr/memif.h +++ b/fesvr/memif.h @@ -5,6 +5,7 @@ #include <stdint.h> #include <stddef.h> +#include <stdexcept> #include "byteorder.h" typedef uint64_t reg_t; @@ -79,4 +80,11 @@ protected: chunked_memif_t* cmemif; }; +class incompat_xlen : public std::exception { +public: + const unsigned expected_xlen; + const unsigned actual_xlen; + incompat_xlen(unsigned _expected_xlen, unsigned _actual_xlen) : expected_xlen(_expected_xlen), actual_xlen(_actual_xlen) {} +}; + #endif // __MEMIF_H diff --git a/riscv/sim.cc b/riscv/sim.cc index 0000537..0ef13b8 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -202,6 +202,7 @@ int sim_t::run() { host = context_t::current(); target.init(sim_thread_main, this); + htif_t::set_expected_xlen(isa.get_max_xlen()); return htif_t::run(); } |