From 9c3da3844a814f69e7f5320ca311ea29ca71b1c5 Mon Sep 17 00:00:00 2001 From: angie Date: Thu, 23 May 2024 18:00:08 -0400 Subject: [PATCH] Allow registering sections and overlays --- librecomp/include/recomp_overlays.h | 24 ++++++++++++++--- librecomp/src/overlays.cpp | 42 ++++++++++++++++------------- librecomp/src/patch_loading.cpp | 2 +- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/librecomp/include/recomp_overlays.h b/librecomp/include/recomp_overlays.h index 2ee8d36..1fb23b0 100644 --- a/librecomp/include/recomp_overlays.h +++ b/librecomp/include/recomp_overlays.h @@ -4,12 +4,28 @@ #include #include "sections.h" -extern "C" SectionTableEntry* get_section_table(); -extern "C" size_t get_num_sections(); -extern "C" int* get_overlay_sections_by_index(); +namespace recomp { + namespace overlays { + struct section_table_data_t { + SectionTableEntry* code_sections; + size_t num_code_sections; + size_t total_num_sections; + }; + + struct overlays_by_index_t { + int* table; + size_t len; + }; + + void register_overlays(const section_table_data_t& sections, const overlays_by_index_t& overlays); + + extern section_table_data_t sections_info; + extern overlays_by_index_t overlays_info; + } +} extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size); extern "C" void unload_overlays(int32_t ram_addr, uint32_t size); void init_overlays(); -#endif \ No newline at end of file +#endif diff --git a/librecomp/src/overlays.cpp b/librecomp/src/overlays.cpp index 785fb78..a26026b 100644 --- a/librecomp/src/overlays.cpp +++ b/librecomp/src/overlays.cpp @@ -1,13 +1,19 @@ -#include #include +#include +#include #include + #include "recomp.h" #include "recomp_overlays.h" #include "sections.h" -constexpr size_t num_code_sections = ARRLEN(get_section_table()); +recomp::overlays::section_table_data_t recomp::overlays::sections_info {}; +recomp::overlays::overlays_by_index_t recomp::overlays::overlays_info {}; -// SectionTableEntry sections[] defined in recomp_overlays.inl +void recomp::overlays::register_overlays(const section_table_data_t& sections, const overlays_by_index_t& overlays) { + recomp::overlays::sections_info = sections; + recomp::overlays::overlays_info = overlays; +} struct LoadedSection { int32_t loaded_ram_addr; @@ -27,11 +33,13 @@ std::vector loaded_sections{}; std::unordered_map func_map{}; void load_overlay(size_t section_table_index, int32_t ram) { - const SectionTableEntry& section = get_section_table()[section_table_index]; + const SectionTableEntry& section = recomp::overlays::sections_info.code_sections[section_table_index]; + for (size_t function_index = 0; function_index < section.num_funcs; function_index++) { const FuncEntry& func = section.funcs[function_index]; func_map[ram + func.offset] = func.func; } + loaded_sections.emplace_back(ram, section_table_index); section_addresses[section.index] = ram; } @@ -51,27 +59,25 @@ int32_t* section_addresses = nullptr; extern "C" void load_overlays(uint32_t rom, int32_t ram_addr, uint32_t size) { // Search for the first section that's included in the loaded rom range // Sections were sorted by `init_overlays` so we can use the bounds functions - auto lower = std::lower_bound(&get_section_table()[0], &get_section_table()[num_code_sections], rom, + auto lower = std::lower_bound(&recomp::overlays::sections_info.code_sections[0], &recomp::overlays::sections_info.code_sections[recomp::overlays::sections_info.num_code_sections], rom, [](const SectionTableEntry& entry, uint32_t addr) { return entry.rom_addr < addr; } ); - auto upper = std::upper_bound(&get_section_table()[0], &get_section_table()[num_code_sections], (uint32_t)(rom + size), + auto upper = std::upper_bound(&recomp::overlays::sections_info.code_sections[0], &recomp::overlays::sections_info.code_sections[recomp::overlays::sections_info.num_code_sections], (uint32_t)(rom + size), [](uint32_t addr, const SectionTableEntry& entry) { return addr < entry.size + entry.rom_addr; } ); // Load the overlays that were found for (auto it = lower; it != upper; ++it) { - load_overlay(std::distance(&get_section_table()[0], it), it->rom_addr - rom + ram_addr); + load_overlay(std::distance(&recomp::overlays::sections_info.code_sections[0], it), it->rom_addr - rom + ram_addr); } } -extern "C" void unload_overlays(int32_t ram_addr, uint32_t size); - extern "C" void unload_overlay_by_id(uint32_t id) { - uint32_t section_table_index = get_overlay_sections_by_index()[id]; - const SectionTableEntry& section = get_section_table()[section_table_index]; + uint32_t section_table_index = recomp::overlays::overlays_info.table[id]; + const SectionTableEntry& section = recomp::overlays::sections_info.code_sections[section_table_index]; auto find_it = std::find_if(loaded_sections.begin(), loaded_sections.end(), [section_table_index](const LoadedSection& s) { return s.section_table_index == section_table_index; }); @@ -90,8 +96,8 @@ extern "C" void unload_overlay_by_id(uint32_t id) { } extern "C" void load_overlay_by_id(uint32_t id, uint32_t ram_addr) { - uint32_t section_table_index = get_overlay_sections_by_index()[id]; - const SectionTableEntry& section = get_section_table()[section_table_index]; + uint32_t section_table_index = recomp::overlays::overlays_info.table[id]; + const SectionTableEntry& section = recomp::overlays::sections_info.code_sections[section_table_index]; int32_t prev_address = section_addresses[section.index]; if (/*ram_addr >= 0x80000000 && ram_addr < 0x81000000) {*/ prev_address == section.ram_addr) { load_overlay(section_table_index, ram_addr); @@ -105,7 +111,7 @@ extern "C" void load_overlay_by_id(uint32_t id, uint32_t ram_addr) { extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) { for (auto it = loaded_sections.begin(); it != loaded_sections.end();) { - const auto& section = get_section_table()[it->section_table_index]; + const auto& section = recomp::overlays::sections_info.code_sections[it->section_table_index]; // Check if the unloaded region overlaps with the loaded section if (ram_addr < (it->loaded_ram_addr + section.size) && (ram_addr + size) >= it->loaded_ram_addr) { @@ -139,14 +145,14 @@ extern "C" void unload_overlays(int32_t ram_addr, uint32_t size) { void load_patch_functions(); void init_overlays() { - section_addresses = (int32_t *)malloc(get_num_sections() * sizeof(int32_t)); + section_addresses = (int32_t *)malloc(recomp::overlays::sections_info.total_num_sections * sizeof(int32_t)); - for (size_t section_index = 0; section_index < get_num_sections(); section_index++) { - section_addresses[get_section_table()[section_index].index] = get_section_table()[section_index].ram_addr; + for (size_t section_index = 0; section_index < recomp::overlays::sections_info.total_num_sections; section_index++) { + section_addresses[recomp::overlays::sections_info.code_sections[section_index].index] = recomp::overlays::sections_info.code_sections[section_index].ram_addr; } // Sort the executable sections by rom address - std::sort(&get_section_table()[0], &get_section_table()[num_code_sections], + std::sort(&recomp::overlays::sections_info.code_sections[0], &recomp::overlays::sections_info.code_sections[recomp::overlays::sections_info.num_code_sections], [](const SectionTableEntry& a, const SectionTableEntry& b) { return a.rom_addr < b.rom_addr; } diff --git a/librecomp/src/patch_loading.cpp b/librecomp/src/patch_loading.cpp index ce5475c..f87ee14 100644 --- a/librecomp/src/patch_loading.cpp +++ b/librecomp/src/patch_loading.cpp @@ -8,5 +8,5 @@ void load_special_overlay(const SectionTableEntry& section, int32_t ram); void load_patch_functions() { - load_special_overlay(get_section_table()[0], get_section_table()[0].ram_addr); + load_special_overlay(recomp::overlays::sections_info.code_sections[0], recomp::overlays::sections_info.code_sections[0].ram_addr); }