Skip to content

Commit 3a70f84

Browse files
authored
Merge pull request #1670 from clementleger/dev/cleger/et_dyn
add support to load ET_DYN elf
2 parents a53a71f + a316a37 commit 3a70f84

File tree

6 files changed

+25
-14
lines changed

6 files changed

+25
-14
lines changed

fesvr/elf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <stdint.h>
77

88
#define ET_EXEC 2
9+
#define ET_DYN 3
910
#define EM_RISCV 243
1011
#define EM_NONE 0
1112
#define EV_CURRENT 1
@@ -21,6 +22,7 @@
2122
#define IS_ELFLE(hdr) (IS_ELF(hdr) && (hdr).e_ident[5] == 1)
2223
#define IS_ELFBE(hdr) (IS_ELF(hdr) && (hdr).e_ident[5] == 2)
2324
#define IS_ELF_EXEC(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_type) == ET_EXEC)
25+
#define IS_ELF_DYN(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_type) == ET_DYN)
2426
#define IS_ELF_RISCV(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_machine) == EM_RISCV)
2527
#define IS_ELF_EM_NONE(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_machine) == EM_NONE)
2628
#define IS_ELF_VCURRENT(hdr) (IS_ELF(hdr) && ELF_SWAP((hdr), (hdr).e_version) == EV_CURRENT)

fesvr/elf2hex.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int main(int argc, char** argv)
4040
htif_hexwriter_t htif(base, width, depth);
4141
memif_t memif(&htif);
4242
reg_t entry;
43-
load_elf(argv[3], &memif, &entry);
43+
load_elf(argv[3], &memif, &entry, 0);
4444
std::cout << htif;
4545

4646
return 0;

fesvr/elfloader.cc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
#include <map>
1919
#include <cerrno>
2020

21-
std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0)
21+
std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry,
22+
reg_t load_offset, unsigned required_xlen = 0)
2223
{
2324
int fd = open(fn, O_RDONLY);
2425
struct stat s;
@@ -41,30 +42,34 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
4142
throw incompat_xlen(required_xlen, xlen);
4243
}
4344
assert(IS_ELFLE(*eh64) || IS_ELFBE(*eh64));
44-
assert(IS_ELF_EXEC(*eh64));
45+
assert(IS_ELF_EXEC(*eh64) || IS_ELF_DYN(*eh64));
4546
assert(IS_ELF_RISCV(*eh64) || IS_ELF_EM_NONE(*eh64));
4647
assert(IS_ELF_VCURRENT(*eh64));
4748

49+
if (IS_ELF_EXEC(*eh64)) {
50+
load_offset = 0;
51+
}
52+
4853
std::vector<uint8_t> zeros;
4954
std::map<std::string, uint64_t> symbols;
5055

5156
#define LOAD_ELF(ehdr_t, phdr_t, shdr_t, sym_t, bswap) \
5257
do { \
5358
ehdr_t* eh = (ehdr_t*)buf; \
5459
phdr_t* ph = (phdr_t*)(buf + bswap(eh->e_phoff)); \
55-
*entry = bswap(eh->e_entry); \
60+
*entry = bswap(eh->e_entry) + load_offset; \
5661
assert(size >= bswap(eh->e_phoff) + bswap(eh->e_phnum) * sizeof(*ph)); \
5762
for (unsigned i = 0; i < bswap(eh->e_phnum); i++) { \
5863
if (bswap(ph[i].p_type) == PT_LOAD && bswap(ph[i].p_memsz)) { \
64+
reg_t load_addr = bswap(ph[i].p_paddr) + load_offset; \
5965
if (bswap(ph[i].p_filesz)) { \
6066
assert(size >= bswap(ph[i].p_offset) + bswap(ph[i].p_filesz)); \
61-
memif->write(bswap(ph[i].p_paddr), bswap(ph[i].p_filesz), \
67+
memif->write(load_addr, bswap(ph[i].p_filesz), \
6268
(uint8_t*)buf + bswap(ph[i].p_offset)); \
6369
} \
6470
if (size_t pad = bswap(ph[i].p_memsz) - bswap(ph[i].p_filesz)) { \
6571
zeros.resize(pad); \
66-
memif->write(bswap(ph[i].p_paddr) + bswap(ph[i].p_filesz), pad, \
67-
zeros.data()); \
72+
memif->write(load_addr + bswap(ph[i].p_filesz), pad, zeros.data()); \
6873
} \
6974
} \
7075
} \
@@ -96,7 +101,7 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t*
96101
bswap(sh[strtabidx].sh_size) - bswap(sym[i].st_name); \
97102
assert(bswap(sym[i].st_name) < bswap(sh[strtabidx].sh_size)); \
98103
assert(strnlen(strtab + bswap(sym[i].st_name), max_len) < max_len); \
99-
symbols[strtab + bswap(sym[i].st_name)] = bswap(sym[i].st_value); \
104+
symbols[strtab + bswap(sym[i].st_name)] = bswap(sym[i].st_value) + load_offset; \
100105
} \
101106
} \
102107
} while (0)

fesvr/elfloader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <string>
99

1010
class memif_t;
11-
std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry, unsigned required_xlen = 0);
11+
std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* entry,
12+
reg_t load_offset, unsigned required_xlen = 0);
1213

1314
#endif

fesvr/htif.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ static void bad_address(const std::string& situation, reg_t addr)
103103
exit(-1);
104104
}
105105

106-
std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, reg_t* entry)
106+
std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload, reg_t* entry, reg_t load_offset)
107107
{
108108
std::string path;
109109
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,
143143
} preload_aware_memif(this);
144144

145145
try {
146-
return load_elf(path.c_str(), &preload_aware_memif, entry, expected_xlen);
146+
return load_elf(path.c_str(), &preload_aware_memif, entry, load_offset, expected_xlen);
147147
} catch (mem_trap_t& t) {
148148
bad_address("loading payload " + payload, t.get_tval());
149149
abort();
@@ -152,7 +152,7 @@ std::map<std::string, uint64_t> htif_t::load_payload(const std::string& payload,
152152

153153
void htif_t::load_program()
154154
{
155-
std::map<std::string, uint64_t> symbols = load_payload(targs[0], &entry);
155+
std::map<std::string, uint64_t> symbols = load_payload(targs[0], &entry, load_offset);
156156

157157
if (symbols.count("tohost") && symbols.count("fromhost")) {
158158
tohost_addr = symbols["tohost"];
@@ -169,7 +169,7 @@ void htif_t::load_program()
169169

170170
for (auto payload : payloads) {
171171
reg_t dummy_entry;
172-
load_payload(payload, &dummy_entry);
172+
load_payload(payload, &dummy_entry, 0);
173173
}
174174

175175
class nop_memif_t : public memif_t {

fesvr/htif.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "syscall.h"
88
#include "device.h"
99
#include "byteorder.h"
10+
#include "../riscv/platform.h"
1011
#include <string.h>
1112
#include <map>
1213
#include <vector>
@@ -58,7 +59,8 @@ class htif_t : public chunked_memif_t
5859
virtual size_t chunk_align() = 0;
5960
virtual size_t chunk_max_size() = 0;
6061

61-
virtual std::map<std::string, uint64_t> load_payload(const std::string& payload, reg_t* entry);
62+
virtual std::map<std::string, uint64_t> load_payload(const std::string& payload, reg_t* entry,
63+
reg_t load_addr);
6264
virtual void load_program();
6365
virtual void idle() {}
6466

@@ -79,6 +81,7 @@ class htif_t : public chunked_memif_t
7981
void register_devices();
8082
void usage(const char * program_name);
8183
unsigned int expected_xlen = 0;
84+
const reg_t load_offset = DRAM_BASE;
8285
memif_t mem;
8386
reg_t entry;
8487
bool writezeros;

0 commit comments

Comments
 (0)