aboutsummaryrefslogtreecommitdiff
path: root/fesvr
diff options
context:
space:
mode:
authorIman Hosseini <hosseini.iman@yahoo.com>2022-09-20 00:05:00 -0400
committerIman Hosseini <hosseini.iman@yahoo.com>2022-09-20 00:05:00 -0400
commitdfd191367991cb157b53767dcc05824c826b5abd (patch)
tree8891eff92502ba3d42a9ddf372f0f2f6e5a5e44c /fesvr
parenta0972c82d022f6f7c337b06b27c89a60af52202a (diff)
downloadspike-dfd191367991cb157b53767dcc05824c826b5abd.zip
spike-dfd191367991cb157b53767dcc05824c826b5abd.tar.gz
spike-dfd191367991cb157b53767dcc05824c826b5abd.tar.bz2
detects the loading of isa-incompatible (i.e. 32 bit code to 64bit HART) code and emits an error message to help avoid unintentionally loading wrong elf.
Diffstat (limited to 'fesvr')
-rw-r--r--fesvr/elfloader.cc6
-rw-r--r--fesvr/elfloader.h2
-rw-r--r--fesvr/htif.cc10
-rw-r--r--fesvr/htif.h4
-rw-r--r--fesvr/memif.h8
5 files changed, 24 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