aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Lent <git@xanderlent.com>2020-01-25 23:25:05 -0500
committerChih-Min Chao <chihmin.chao@sifive.com>2020-02-12 23:08:01 -0800
commit0dc2193e6f7ba34a528086ed724d13f9a7526251 (patch)
treeb251a4ae12c6392f2e0b6431e7fa0e47b7eaaf08
parent0f092a4e24cc54d6b1c9c807942e9cd14b9e0f28 (diff)
downloadspike-0dc2193e6f7ba34a528086ed724d13f9a7526251.zip
spike-0dc2193e6f7ba34a528086ed724d13f9a7526251.tar.gz
spike-0dc2193e6f7ba34a528086ed724d13f9a7526251.tar.bz2
Refuse to load non-EXEC/non-RISC-V/non-V1 ELFs (#388)
Stricter validation of ELF binaries improves usability with informative assertions. This prevents users from loading ELF relocatable files and binaries compiled for their (non-RISC-V) workstations, for example. Without this patch, spike would attempt to load nearly any ELF given, but it would usually fail with an error about debug module accesses, since the given ELF causes accesses in the debug module's memory space. Even if spike successfully loaded the ELF file, it would still misbehave during simulation, for example in the case of ELF relocatable files. ELF magic numbers come from official ELF documents: TIS ELF spec v1.2, via Linux Foundation Referenced Specifications See: https://refspecs.linuxbase.org/ RISC-V magic number comes from official RISC-V ELF documents: See: riscv/riscv-elf-psabi-doc@60c25981b62c0b43d16142f8a12c8b1e98e60d4d
-rw-r--r--fesvr/elf.h7
-rw-r--r--fesvr/elfloader.cc3
2 files changed, 10 insertions, 0 deletions
diff --git a/fesvr/elf.h b/fesvr/elf.h
index b4b0add..c791685 100644
--- a/fesvr/elf.h
+++ b/fesvr/elf.h
@@ -5,6 +5,10 @@
#include <stdint.h>
+#define ET_EXEC 2
+#define EM_RISCV 243
+#define EV_CURRENT 1
+
#define IS_ELF(hdr) \
((hdr).e_ident[0] == 0x7f && (hdr).e_ident[1] == 'E' && \
(hdr).e_ident[2] == 'L' && (hdr).e_ident[3] == 'F')
@@ -13,6 +17,9 @@
#define IS_ELF64(hdr) (IS_ELF(hdr) && (hdr).e_ident[4] == 2)
#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) && (hdr).e_type == ET_EXEC)
+#define IS_ELF_RISCV(hdr) (IS_ELF(hdr) && (hdr).e_machine == EM_RISCV)
+#define IS_ELF_VCURRENT(hdr) (IS_ELF(hdr) && (hdr).e_version == EV_CURRENT)
#define PT_LOAD 1
diff --git a/fesvr/elfloader.cc b/fesvr/elfloader.cc
index 610e520..fe0fbf0 100644
--- a/fesvr/elfloader.cc
+++ b/fesvr/elfloader.cc
@@ -32,6 +32,9 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
const Elf64_Ehdr* eh64 = (const Elf64_Ehdr*)buf;
assert(IS_ELF32(*eh64) || IS_ELF64(*eh64));
assert(IS_ELFLE(*eh64));
+ assert(IS_ELF_EXEC(*eh64));
+ assert(IS_ELF_RISCV(*eh64));
+ assert(IS_ELF_VCURRENT(*eh64));
std::vector<uint8_t> zeros;
std::map<std::string, uint64_t> symbols;