aboutsummaryrefslogtreecommitdiff
path: root/fesvr
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2022-03-17 15:45:19 -0700
committerAndrew Waterman <andrew@sifive.com>2022-03-17 16:14:45 -0700
commit1fea2afbf46d2641d77f2db3d6108e0897431a84 (patch)
tree877e62570692bb6aacffbd8752191876ea1bd324 /fesvr
parent70240bfe6b1d03e47ba5c10d34650cfca4bedfda (diff)
downloadspike-1fea2afbf46d2641d77f2db3d6108e0897431a84.zip
spike-1fea2afbf46d2641d77f2db3d6108e0897431a84.tar.gz
spike-1fea2afbf46d2641d77f2db3d6108e0897431a84.tar.bz2
Improve error message when HTIF accesses invalid memory
...which includes program loading.
Diffstat (limited to 'fesvr')
-rw-r--r--fesvr/htif.cc51
1 files changed, 41 insertions, 10 deletions
diff --git a/fesvr/htif.cc b/fesvr/htif.cc
index 7150039..f81878d 100644
--- a/fesvr/htif.cc
+++ b/fesvr/htif.cc
@@ -5,12 +5,14 @@
#include "elfloader.h"
#include "platform.h"
#include "byteorder.h"
+#include "trap.h"
#include <algorithm>
#include <assert.h>
#include <vector>
#include <queue>
#include <iostream>
#include <fstream>
+#include <sstream>
#include <iomanip>
#include <stdio.h>
#include <unistd.h>
@@ -86,6 +88,13 @@ void htif_t::start()
reset();
}
+static void bad_address(const std::string& situation, reg_t addr)
+{
+ std::cerr << "Access exception occurred while " << situation << ":\n";
+ std::cerr << "Memory address 0x" << std::hex << addr << " is invalid\n";
+ exit(-1);
+}
+
std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, reg_t* entry)
{
std::string path;
@@ -119,7 +128,12 @@ std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload,
htif_t* htif;
} preload_aware_memif(this);
- return load_elf(path.c_str(), &preload_aware_memif, entry);
+ try {
+ return load_elf(path.c_str(), &preload_aware_memif, entry);
+ } catch (mem_trap_t& t) {
+ bad_address("loading payload " + payload, t.get_tval());
+ abort();
+ }
}
void htif_t::load_program()
@@ -218,19 +232,36 @@ int htif_t::run()
while (!signal_exit && exitcode == 0)
{
- if (auto tohost = from_target(mem.read_uint64(tohost_addr))) {
- mem.write_uint64(tohost_addr, target_endian<uint64_t>::zero);
- command_t cmd(mem, tohost, fromhost_callback);
- device_list.handle_command(cmd);
+ uint64_t tohost;
+
+ try {
+ if ((tohost = from_target(mem.read_uint64(tohost_addr))) != 0)
+ mem.write_uint64(tohost_addr, target_endian<uint64_t>::zero);
+ } catch (mem_trap_t& t) {
+ bad_address("accessing tohost", t.get_tval());
+ }
+
+ if (tohost != 0) {
+ try {
+ command_t cmd(mem, tohost, fromhost_callback);
+ device_list.handle_command(cmd);
+ device_list.tick();
+ } catch (mem_trap_t& t) {
+ std::stringstream tohost_hex;
+ tohost_hex << std::hex << tohost;
+ bad_address("host was accessing memory on behalf of target (tohost = 0x" + tohost_hex.str() + ")", t.get_tval());
+ }
} else {
idle();
}
- device_list.tick();
-
- if (!fromhost_queue.empty() && !mem.read_uint64(fromhost_addr)) {
- mem.write_uint64(fromhost_addr, to_target(fromhost_queue.front()));
- fromhost_queue.pop();
+ try {
+ if (!fromhost_queue.empty() && !mem.read_uint64(fromhost_addr)) {
+ mem.write_uint64(fromhost_addr, to_target(fromhost_queue.front()));
+ fromhost_queue.pop();
+ }
+ } catch (mem_trap_t& t) {
+ bad_address("accessing fromhost", t.get_tval());
}
}