52 lines
1.7 KiB
C++
52 lines
1.7 KiB
C++
#include <loaders/elf.hpp>
|
|
#include <mem.hpp>
|
|
#include <broadway.hpp>
|
|
#include <elfio/elfio.hpp>
|
|
#include <print>
|
|
|
|
namespace weee::core {
|
|
bool load_elf(const std::string &path, mem &mem, broadway &broadway) {
|
|
ELFIO::elfio reader;
|
|
if (!reader.load(path))
|
|
return false;
|
|
|
|
ircolib::u32 sanity_bss_check_count = 0;
|
|
|
|
for (const auto &segment : reader.segments) {
|
|
const auto segment_type = segment->get_type();
|
|
if (segment_type != ELFIO::PT_LOAD && segment_type != ELFIO::PT_TLS && segment_type != ELFIO::PT_NOTE)
|
|
continue;
|
|
|
|
if (segment->get_memory_size() == 0)
|
|
continue;
|
|
|
|
const bool exc = segment->get_flags() & ELFIO::PF_X;
|
|
const bool rd = segment->get_flags() & ELFIO::PF_R;
|
|
const bool wr = segment->get_flags() & ELFIO::PF_W;
|
|
|
|
std::println("Segment {} {}{}{} @ 0x{:08X} -> 0x{:08X}", segment->get_index(), rd ? 'R' : '_', wr ? 'W' : '_',
|
|
exc ? 'X' : '_', segment->get_virtual_address(),
|
|
segment->get_virtual_address() + segment->get_memory_size() - 1);
|
|
|
|
if (segment->get_file_size() == 0) {
|
|
sanity_bss_check_count++;
|
|
if (sanity_bss_check_count > 1) {
|
|
std::println("weee does not support multiple .bss segments");
|
|
return -2;
|
|
}
|
|
|
|
// .bss we zero out
|
|
mem.set(0, segment->get_memory_size(), segment->get_virtual_address() & 0x0FFFFFFF);
|
|
continue;
|
|
}
|
|
|
|
mem.copy((ircolib::u8 *)segment->get_data(), segment->get_file_size(),
|
|
segment->get_virtual_address() & 0x0FFFFFFF);
|
|
}
|
|
|
|
broadway.set_pc(reader.get_entry());
|
|
|
|
return true;
|
|
}
|
|
} // namespace weee::core
|