loading dols

This commit is contained in:
2026-05-12 10:44:44 +02:00
parent 5f1e3aa095
commit 0b1d14bcd5
9 changed files with 163 additions and 42 deletions
+63
View File
@@ -0,0 +1,63 @@
#include <loaders/dol.hpp>
#include <mem.hpp>
#include <ircolib/file.hpp>
#include <ircolib/mem_access.hpp>
#include <array>
#include <print>
namespace weee::core {
bool load_dol(const std::string &path, mem &mem) {
auto bin = ircolib::read_file_binary(path);
if (bin.size() <= 0)
return false;
struct header {
struct section {
ircolib::u32 offset, addr, size;
};
std::array<section, 7> text;
std::array<section, 11> data;
ircolib::u32 bss_address, bss_size, entry_point;
} hdr;
for (size_t bin_index = 0; bin_index < 0xD8; bin_index += 4) {
if (ircolib::is_inside_range_ext(bin_index, 0, 0x1c)) // text file offsets
hdr.text[bin_index / 4].offset = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
if (ircolib::is_inside_range_ext(bin_index, 0x1c, 0x48)) // data file offsets
hdr.data[(bin_index - 0x1c) / 4].offset = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
if (ircolib::is_inside_range_ext(bin_index, 0x48, 0x64)) // text loading addresses
hdr.text[(bin_index - 0x48) / 4].addr = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
if (ircolib::is_inside_range_ext(bin_index, 0x64, 0x90)) // data loading addresses
hdr.data[(bin_index - 0x64) / 4].addr = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
if (ircolib::is_inside_range_ext(bin_index, 0x90, 0xac)) // text sizes
hdr.text[(bin_index - 0x90) / 4].size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
if (ircolib::is_inside_range_ext(bin_index, 0xac, 0xd8)) // data sizes
hdr.data[(bin_index - 0xac) / 4].size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
}
hdr.bss_address = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xD8));
hdr.bss_size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xDC));
mem.set(0, hdr.bss_size, hdr.bss_address & 0x0FFFFFFF);
hdr.entry_point = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xE0));
for (const auto &section : hdr.text) {
if (section.offset == 0)
continue;
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
}
for (const auto &section : hdr.data) {
if (section.offset == 0)
continue;
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
}
return true;
}
} // namespace weee::core
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <ircolib/types.hpp>
#include <string>
namespace weee::core {
struct mem;
bool load_dol(const std::string &, mem &);
} // namespace weee::core
+48
View File
@@ -0,0 +1,48 @@
#include <loaders/elf.hpp>
#include <mem.hpp>
#include <elfio/elfio.hpp>
#include <print>
namespace weee::core {
bool load_elf(const std::string &path, mem &mem) {
ELFIO::elfio reader;
if (!reader.load(path))
return false;
size_t 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((const ircolib::u8 *)segment->get_data(), segment->get_file_size(),
segment->get_virtual_address() & 0x0FFFFFFF);
}
return true;
}
} // namespace weee::core
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <ircolib/types.hpp>
#include <string>
namespace weee::core {
struct mem;
bool load_elf(const std::string &, mem &);
} // namespace weee::core