mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-05-14 08:12:19 +00:00
Add manual patch symbols (syms.ld) to the output overlay file and relocs
This commit is contained in:
parent
bccc4990b4
commit
3a37b4503d
3 changed files with 44 additions and 11 deletions
|
@ -565,6 +565,12 @@ namespace N64Recomp {
|
||||||
void set_all_reference_sections_relocatable() {
|
void set_all_reference_sections_relocatable() {
|
||||||
all_reference_sections_relocatable = true;
|
all_reference_sections_relocatable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_manual_patch_symbol(uint32_t vram) const {
|
||||||
|
// Zero-sized symbols between 0x8F000000 and 0x90000000 are manually specified symbols for use with patches.
|
||||||
|
// TODO make this configurable or come up with a more sensible solution for dealing with manual symbols for patches.
|
||||||
|
return vram >= 0x8F000000 && vram < 0x90000000;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Generator;
|
class Generator;
|
||||||
|
|
45
src/main.cpp
45
src/main.cpp
|
@ -866,13 +866,6 @@ int main(int argc, char** argv) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt::print(func_header_file,
|
|
||||||
"\n"
|
|
||||||
"#ifdef __cplusplus\n"
|
|
||||||
"}}\n"
|
|
||||||
"#endif\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ofstream overlay_file(config.output_func_path / "recomp_overlays.inl");
|
std::ofstream overlay_file(config.output_func_path / "recomp_overlays.inl");
|
||||||
std::string section_load_table = "static SectionTableEntry section_table[] = {\n";
|
std::string section_load_table = "static SectionTableEntry section_table[] = {\n";
|
||||||
|
@ -933,7 +926,7 @@ int main(int argc, char** argv) {
|
||||||
fmt::print(overlay_file, "static RelocEntry {}[] = {{\n", section_relocs_array_name);
|
fmt::print(overlay_file, "static RelocEntry {}[] = {{\n", section_relocs_array_name);
|
||||||
|
|
||||||
for (const N64Recomp::Reloc& reloc : section_relocs) {
|
for (const N64Recomp::Reloc& reloc : section_relocs) {
|
||||||
if (reloc.target_section != N64Recomp::SectionAbsolute) {
|
if (reloc.target_section != N64Recomp::SectionAbsolute || context.is_manual_patch_symbol(reloc.target_section_offset)) {
|
||||||
uint32_t target_section_offset;
|
uint32_t target_section_offset;
|
||||||
if (reloc.target_section == N64Recomp::SectionEvent) {
|
if (reloc.target_section == N64Recomp::SectionEvent) {
|
||||||
target_section_offset = reloc.symbol_index;
|
target_section_offset = reloc.symbol_index;
|
||||||
|
@ -1012,9 +1005,45 @@ int main(int argc, char** argv) {
|
||||||
// Add a dummy element at the end to ensure the array has a valid length because C doesn't allow zero-size arrays.
|
// Add a dummy element at the end to ensure the array has a valid length because C doesn't allow zero-size arrays.
|
||||||
fmt::print(overlay_file, " NULL\n");
|
fmt::print(overlay_file, " NULL\n");
|
||||||
fmt::print(overlay_file, "}};\n");
|
fmt::print(overlay_file, "}};\n");
|
||||||
|
|
||||||
|
// Collect manual patch symbols.
|
||||||
|
std::vector<std::pair<uint32_t, std::string>> manual_patch_syms{};
|
||||||
|
|
||||||
|
for (const auto& func : context.functions) {
|
||||||
|
if (func.words.empty() && context.is_manual_patch_symbol(func.vram)) {
|
||||||
|
manual_patch_syms.emplace_back(func.vram, func.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the manual patch symbols by vram.
|
||||||
|
std::sort(manual_patch_syms.begin(), manual_patch_syms.end(), [](const auto& lhs, const auto& rhs) {
|
||||||
|
return lhs.first < rhs.first;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Emit the manual patch symbols.
|
||||||
|
fmt::print(overlay_file,
|
||||||
|
"\n"
|
||||||
|
"static const ManualPatchSymbol manual_patch_symbols[] = {{\n"
|
||||||
|
);
|
||||||
|
for (const auto& manual_patch_sym_entry : manual_patch_syms) {
|
||||||
|
fmt::print(overlay_file, " {{ 0x{:08X}, {} }},\n", manual_patch_sym_entry.first, manual_patch_sym_entry.second);
|
||||||
|
|
||||||
|
fmt::print(func_header_file,
|
||||||
|
"void {}(uint8_t* rdram, recomp_context* ctx);\n", manual_patch_sym_entry.second);
|
||||||
|
}
|
||||||
|
// Add a dummy element at the end to ensure the array has a valid length because C doesn't allow zero-size arrays.
|
||||||
|
fmt::print(overlay_file, " {{ 0, NULL }}\n");
|
||||||
|
fmt::print(overlay_file, "}};\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt::print(func_header_file,
|
||||||
|
"\n"
|
||||||
|
"#ifdef __cplusplus\n"
|
||||||
|
"}}\n"
|
||||||
|
"#endif\n"
|
||||||
|
);
|
||||||
|
|
||||||
if (!config.output_binary_path.empty()) {
|
if (!config.output_binary_path.empty()) {
|
||||||
std::ofstream output_binary{config.output_binary_path, std::ios::binary};
|
std::ofstream output_binary{config.output_binary_path, std::ios::binary};
|
||||||
output_binary.write(reinterpret_cast<const char*>(context.rom.data()), context.rom.size());
|
output_binary.write(reinterpret_cast<const char*>(context.rom.data()), context.rom.size());
|
||||||
|
|
|
@ -46,9 +46,7 @@ JalResolutionResult resolve_jal(const N64Recomp::Context& context, size_t cur_se
|
||||||
|
|
||||||
// Zero-sized symbol handling. unless there's only one matching target.
|
// Zero-sized symbol handling. unless there's only one matching target.
|
||||||
if (target_func.words.empty()) {
|
if (target_func.words.empty()) {
|
||||||
// Allow zero-sized symbols between 0x8F000000 and 0x90000000 for use with patches.
|
if (!context.is_manual_patch_symbol(target_func.vram)) {
|
||||||
// TODO make this configurable or come up with a more sensible solution for dealing with manual symbols for patches.
|
|
||||||
if (target_func.vram < 0x8F000000 || target_func.vram > 0x90000000) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue