adds riscv_hart_common and signature output
This commit is contained in:
@ -36,7 +36,12 @@
|
||||
#define _RISCV_HART_COMMON
|
||||
|
||||
#include "iss/arch_if.h"
|
||||
#include "iss/log_categories.h"
|
||||
#include <cstdint>
|
||||
#include <elfio/elfio.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
@ -296,6 +301,61 @@ inline void write_reg_uint32(uint64_t offs, uint32_t& reg, const uint8_t* const
|
||||
break;
|
||||
}
|
||||
}
|
||||
struct riscv_hart_common {
|
||||
riscv_hart_common(){};
|
||||
~riscv_hart_common(){};
|
||||
std::unordered_map<std::string, uint64_t> symbol_table;
|
||||
|
||||
std::unordered_map<std::string, uint64_t> get_sym_table(std::string name) {
|
||||
if(!symbol_table.empty())
|
||||
return symbol_table;
|
||||
FILE* fp = fopen(name.c_str(), "r");
|
||||
if(fp) {
|
||||
std::array<char, 5> buf;
|
||||
auto n = fread(buf.data(), 1, 4, fp);
|
||||
fclose(fp);
|
||||
if(n != 4)
|
||||
throw std::runtime_error("input file has insufficient size");
|
||||
buf[4] = 0;
|
||||
if(strcmp(buf.data() + 1, "ELF") == 0) {
|
||||
// Create elfio reader
|
||||
ELFIO::elfio reader;
|
||||
// Load ELF data
|
||||
if(!reader.load(name))
|
||||
throw std::runtime_error("could not process elf file");
|
||||
// check elf properties
|
||||
if(reader.get_type() != ET_EXEC)
|
||||
throw std::runtime_error("wrong elf type in file");
|
||||
if(reader.get_machine() != EM_RISCV)
|
||||
throw std::runtime_error("wrong elf machine in file");
|
||||
const auto sym_sec = reader.sections[".symtab"];
|
||||
if(SHT_SYMTAB == sym_sec->get_type() || SHT_DYNSYM == sym_sec->get_type()) {
|
||||
ELFIO::symbol_section_accessor symbols(reader, sym_sec);
|
||||
auto sym_no = symbols.get_symbols_num();
|
||||
std::string name;
|
||||
ELFIO::Elf64_Addr value = 0;
|
||||
ELFIO::Elf_Xword size = 0;
|
||||
unsigned char bind = 0;
|
||||
unsigned char type = 0;
|
||||
ELFIO::Elf_Half section = 0;
|
||||
unsigned char other = 0;
|
||||
for(auto i = 0U; i < sym_no; ++i) {
|
||||
symbols.get_symbol(i, name, value, size, bind, type, section, other);
|
||||
if(name != "") {
|
||||
this->symbol_table[name] = value;
|
||||
#ifndef NDEBUG
|
||||
LOG(DEBUG) << "Found Symbol " << name;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
return symbol_table;
|
||||
}
|
||||
throw std::runtime_error(fmt::format("memory load file {} is not a valid elf file", name));
|
||||
} else
|
||||
throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name));
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace arch
|
||||
} // namespace iss
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "iss/log_categories.h"
|
||||
#include "iss/vm_if.h"
|
||||
#include "riscv_hart_common.h"
|
||||
#include <stdexcept>
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
#define FMT_HEADER_ONLY
|
||||
#endif
|
||||
@ -68,7 +69,7 @@
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
|
||||
template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_m_p : public BASE {
|
||||
template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_m_p : public BASE, public riscv_hart_common {
|
||||
protected:
|
||||
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
|
||||
const std::array<const char*, 16> trap_str = {{""
|
||||
@ -326,6 +327,8 @@ protected:
|
||||
|
||||
unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
|
||||
|
||||
std::unordered_map<std::string, uint64_t> get_symbol_table(std::string name) override { return arch.get_sym_table(name); }
|
||||
|
||||
riscv_hart_m_p<BASE, FEAT>& arch;
|
||||
};
|
||||
|
||||
@ -570,6 +573,12 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg)
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT>::load_file(std::string name, int type) {
|
||||
get_sym_table(name);
|
||||
try {
|
||||
tohost = symbol_table.at("tohost");
|
||||
fromhost = symbol_table.at("fromhost");
|
||||
} catch(std::out_of_range& e) {
|
||||
}
|
||||
FILE* fp = fopen(name.c_str(), "r");
|
||||
if(fp) {
|
||||
std::array<char, 5> buf;
|
||||
@ -604,27 +613,7 @@ template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m
|
||||
}
|
||||
}
|
||||
for(const auto sec : reader.sections) {
|
||||
if(sec->get_name() == ".symtab") {
|
||||
if(SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type()) {
|
||||
ELFIO::symbol_section_accessor symbols(reader, sec);
|
||||
auto sym_no = symbols.get_symbols_num();
|
||||
std::string name;
|
||||
ELFIO::Elf64_Addr value = 0;
|
||||
ELFIO::Elf_Xword size = 0;
|
||||
unsigned char bind = 0;
|
||||
unsigned char type = 0;
|
||||
ELFIO::Elf_Half section = 0;
|
||||
unsigned char other = 0;
|
||||
for(auto i = 0U; i < sym_no; ++i) {
|
||||
symbols.get_symbol(i, name, value, size, bind, type, section, other);
|
||||
if(name == "tohost") {
|
||||
tohost = value;
|
||||
} else if(name == "fromhost") {
|
||||
fromhost = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(sec->get_name() == ".tohost") {
|
||||
if(sec->get_name() == ".tohost") {
|
||||
tohost = sec->get_address();
|
||||
fromhost = tohost + 0x40;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
|
||||
template <typename BASE> class riscv_hart_msu_vp : public BASE {
|
||||
template <typename BASE> class riscv_hart_msu_vp : public BASE, public riscv_hart_common {
|
||||
protected:
|
||||
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
|
||||
const std::array<const char*, 16> trap_str = {{""
|
||||
@ -377,6 +377,8 @@ protected:
|
||||
|
||||
unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
|
||||
|
||||
std::unordered_map<std::string, uint64_t> get_symbol_table(std::string name) override { return arch.get_sym_table(name); }
|
||||
|
||||
riscv_hart_msu_vp<BASE>& arch;
|
||||
};
|
||||
|
||||
|
@ -68,7 +68,7 @@
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
|
||||
template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_mu_p : public BASE {
|
||||
template <typename BASE, features_e FEAT = FEAT_NONE> class riscv_hart_mu_p : public BASE, public riscv_hart_common {
|
||||
protected:
|
||||
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
|
||||
const std::array<const char*, 16> trap_str = {{""
|
||||
@ -353,6 +353,8 @@ protected:
|
||||
|
||||
unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
|
||||
|
||||
std::unordered_map<std::string, uint64_t> get_symbol_table(std::string name) override { return arch.get_sym_table(name); }
|
||||
|
||||
riscv_hart_mu_p<BASE, FEAT>& arch;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user