loading dols
This commit is contained in:
+2
-1
@@ -19,6 +19,7 @@ set(CAPSTONE_ARCHITECTURE_DEFAULT OFF)
|
|||||||
set(CAPSTONE_PPC_SUPPORT ON)
|
set(CAPSTONE_PPC_SUPPORT ON)
|
||||||
add_subdirectory(external/capstone)
|
add_subdirectory(external/capstone)
|
||||||
|
|
||||||
add_executable(weee main.cpp core/mem.cpp)
|
add_executable(weee main.cpp core/mem.cpp core/loaders/elf.cpp
|
||||||
|
core/loaders/dol.cpp)
|
||||||
target_link_libraries(weee PUBLIC capstone)
|
target_link_libraries(weee PUBLIC capstone)
|
||||||
target_include_directories(weee PUBLIC core)
|
target_include_directories(weee PUBLIC core)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# weee
|
# weee
|
||||||
|
|
||||||
- [x] ELF
|
- [x] ELF
|
||||||
- [ ] DOL
|
- [x] DOL
|
||||||
- [ ] panda.dol
|
- [ ] panda.dol
|
||||||
- [ ] libogc simple examples
|
- [ ] libogc simple examples
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace weee::core {
|
||||||
|
struct broadway {
|
||||||
|
|
||||||
|
};
|
||||||
|
} // namespace weee::core
|
||||||
@@ -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 §ion : hdr.text) {
|
||||||
|
if (section.offset == 0)
|
||||||
|
continue;
|
||||||
|
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto §ion : hdr.data) {
|
||||||
|
if (section.offset == 0)
|
||||||
|
continue;
|
||||||
|
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} // namespace weee::core
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
Vendored
+5
@@ -30,6 +30,11 @@ static inline constexpr bool is_inside_range(const std::integral auto &addr, con
|
|||||||
return addr >= start && addr <= end;
|
return addr >= start && addr <= end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline constexpr bool is_inside_range_ext(const std::integral auto &addr, const std::integral auto &start,
|
||||||
|
const std::integral auto &end) {
|
||||||
|
return addr >= start && addr < end;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static constexpr inline T read_access(const u8 *data, const u32 index);
|
static constexpr inline T read_access(const u8 *data, const u32 index);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@@ -1,53 +1,32 @@
|
|||||||
#include <print>
|
|
||||||
#include <elfio/elfio.hpp>
|
|
||||||
#include <cflags.hpp>
|
#include <cflags.hpp>
|
||||||
#include <ircolib/mem_access.hpp>
|
#include <ircolib/mem_access.hpp>
|
||||||
#include "mem.hpp"
|
#include <loaders/elf.hpp>
|
||||||
|
#include <loaders/dol.hpp>
|
||||||
|
#include <ircolib/log.hpp>
|
||||||
|
#include <mem.hpp>
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
ELFIO::elfio reader;
|
|
||||||
|
|
||||||
weee::core::mem mem;
|
weee::core::mem mem;
|
||||||
|
|
||||||
cflags::cflags flags;
|
cflags::cflags flags;
|
||||||
flags.add_string_callback('\0', "elf", [&](const std::string &v) { reader.load(v); }, "ELF binary to load");
|
flags.add_string_callback(
|
||||||
|
'\0', "elf",
|
||||||
|
[&](const std::string &v) {
|
||||||
|
if (!weee::core::load_elf(v, mem))
|
||||||
|
ircolib::panic("Could not load '{}'", v);
|
||||||
|
},
|
||||||
|
"ELF binary to load");
|
||||||
|
|
||||||
|
flags.add_string_callback(
|
||||||
|
'\0', "dol",
|
||||||
|
[&](const std::string &v) {
|
||||||
|
if (!weee::core::load_dol(v, mem))
|
||||||
|
ircolib::panic("Could not load '{}'", v);
|
||||||
|
},
|
||||||
|
"DOL binary to load");
|
||||||
|
|
||||||
if (!flags.parse(argc, argv))
|
if (!flags.parse(argc, argv))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
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 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user