Skip to content

Commit

Permalink
Make sure ELF is present when looking up call sites
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Oct 26, 2023
1 parent 2f04d96 commit 5930903
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
5 changes: 4 additions & 1 deletion lib/libriscv/elf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ namespace riscv
#endif

template <typename Class>
inline bool validate_header(const Class* hdr)
inline bool validate_header(std::string_view binary)
{
if (binary.size() < sizeof(Class))
return false;
auto* hdr = (Class *)binary.data();
if (hdr->e_ident[EI_MAG0] != 0x7F ||
hdr->e_ident[EI_MAG1] != 'E' ||
hdr->e_ident[EI_MAG2] != 'L' ||
Expand Down
17 changes: 14 additions & 3 deletions lib/libriscv/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,11 @@ namespace riscv
if (UNLIKELY(m_binary.size() < sizeof(Ehdr))) {
throw MachineException(INVALID_PROGRAM, "ELF program too short");
}
const auto* elf = (Ehdr*) m_binary.data();
if (UNLIKELY(!validate_header<Ehdr> (elf))) {
throw MachineException(INVALID_PROGRAM, "Invalid ELF header! Mixup between 32- and 64-bit?", elf->e_ident[EI_CLASS]);
if (UNLIKELY(!validate_header<Ehdr> (m_binary))) {
throw MachineException(INVALID_PROGRAM, "Invalid ELF header! Mixup between 32- and 64-bit?");
}

const auto* elf = (Ehdr*) m_binary.data();
if (UNLIKELY(elf->e_type != ET_EXEC)) {
throw MachineException(INVALID_PROGRAM, "ELF program is not an executable type. Trying to load a dynamic library?");
}
Expand Down Expand Up @@ -477,6 +478,9 @@ namespace riscv
template <int W>
typename Memory<W>::Callsite Memory<W>::lookup(address_t address) const
{
if (!validate_header<Ehdr>(this->m_binary))
return {};

const auto* sym_hdr = section_by_name(".symtab");
if (sym_hdr == nullptr) return {};
const auto* str_hdr = section_by_name(".strtab");
Expand Down Expand Up @@ -539,6 +543,13 @@ namespace riscv
[this, print_function] (const int N, const address_type<W> addr) {
// get information about the callsite
const auto site = this->lookup(addr);
if (site.address == 0 && site.offset == 0 && site.size == 0) {
// if there is nothing to print, indicate that this is
// an unknown/empty location by "printing" a zero-length string.
print_function({});
return;
}

// write information directly to stdout
char buffer[8192];
int len = 0;
Expand Down

0 comments on commit 5930903

Please sign in to comment.