scc 2026.07
SystemC components library
elf.cpp
1#include "elf.h"
2#include <elfio/elfio.hpp>
3#include <sstream>
4#include <stdexcept>
5
6namespace util {
7uint64_t load_elf_file(std::string const& name, std::function<bool(uint64_t, uint64_t, const uint8_t*)> cb, uint8_t expected_elf_class,
8 uint16_t expected_elf_machine) {
9 // Create elfio reader
10 ELFIO::elfio reader;
11 // Load ELF data
12 if(!reader.load(name))
13 throw std::runtime_error("Could not load file");
14 // check elf properties
15 if(reader.get_class() != expected_elf_class)
16 throw std::runtime_error("ELF Class missmatch");
17 if(reader.get_type() != ELFIO::ET_EXEC && reader.get_type() != ELFIO::ET_DYN)
18 throw std::runtime_error("Input is neither an executable nor a pie executable (dyn)");
19 if(reader.get_machine() != expected_elf_machine)
20 throw std::runtime_error("ELF Machine type missmatch");
21 auto entry_address = reader.get_entry();
22 for(const auto& pseg : reader.segments) {
23 const auto fsize = pseg->get_file_size(); // 0x42c/0x0
24 const auto seg_data = pseg->get_data();
25 const auto type = pseg->get_type();
26 if(type == ELFIO::PT_LOAD && fsize > 0) {
27 if(cb(pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data))) {
28 std::ostringstream oss;
29 oss << "Problem writing " << fsize << " bytes to 0x" << std::hex << pseg->get_physical_address();
30 throw std::runtime_error(oss.str());
31 }
32 }
33 }
34 return entry_address;
35};
36
37std::unordered_map<std::string, uint64_t> read_elf_symbols(std::string const& name, uint8_t expected_elf_class,
38 uint16_t expected_elf_machine) {
39 // Create elfio reader
40 ELFIO::elfio reader;
41 // Load ELF data
42 if(!reader.load(name))
43 throw std::runtime_error("Could not load file");
44 // check elf properties
45 if(reader.get_class() != expected_elf_class)
46 throw std::runtime_error("ELF Class missmatch");
47 if(reader.get_type() != ELFIO::ET_EXEC && reader.get_type() != ELFIO::ET_DYN)
48 throw std::runtime_error("Input is neither an executable nor a pie executable (dyn)");
49 if(reader.get_machine() != expected_elf_machine)
50 throw std::runtime_error("ELF Machine type missmatch");
51 std::unordered_map<std::string, uint64_t> symbol_table;
52 const auto sym_sec = reader.sections[".symtab"];
53 if(ELFIO::SHT_SYMTAB == sym_sec->get_type() || ELFIO::SHT_DYNSYM == sym_sec->get_type()) {
54 ELFIO::symbol_section_accessor symbols(reader, sym_sec);
55 auto sym_no = symbols.get_symbols_num();
56 std::string name;
57 ELFIO::Elf64_Addr value = 0;
58 ELFIO::Elf_Xword size = 0;
59 unsigned char bind = 0;
60 unsigned char type = 0;
61 ELFIO::Elf_Half section = 0;
62 unsigned char other = 0;
63 for(auto i = 0U; i < sym_no; ++i) {
64 symbols.get_symbol(i, name, value, size, bind, type, section, other);
65 if(name != "") {
66 symbol_table[name] = value;
67 }
68 }
69 }
70 return std::move(symbol_table);
71};
72
73} // namespace util
SCC common utilities.
Definition bit_field.h:30