mirror of https://github.com/N64Recomp/N64Recomp
Implement fixed address and globally loaded sections in mods, respect section index in mod self-section relocs (#150)
This commit is contained in:
parent
6860826da3
commit
c1a6dc93bf
|
|
@ -104,6 +104,8 @@ namespace N64Recomp {
|
|||
bool executable = false;
|
||||
bool relocatable = false; // TODO is this needed? relocs being non-empty should be an equivalent check.
|
||||
bool has_mips32_relocs = false;
|
||||
bool fixed_address = false; // Only used in mods, indicates that the section shouldn't be relocated or placed into mod memory.
|
||||
bool globally_loaded = false; // Only used in mods, indicates that the section's functions should be globally loaded. Does not actually load the section's contents into ram.
|
||||
std::optional<uint32_t> got_ram_addr = std::nullopt;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ struct FileSubHeaderV1 {
|
|||
uint32_t string_data_size;
|
||||
};
|
||||
|
||||
enum class SectionFlags : uint32_t {
|
||||
FixedAddress = 1 << 0,
|
||||
GloballyLoaded = 1 << 1,
|
||||
};
|
||||
|
||||
struct SectionHeaderV1 {
|
||||
uint32_t flags;
|
||||
uint32_t file_offset;
|
||||
|
|
@ -172,10 +177,22 @@ bool parse_v1(std::span<const char> data, const std::unordered_map<uint32_t, uin
|
|||
cur_section.bss_size = section_header->bss_size;
|
||||
cur_section.name = "mod_section_" + std::to_string(section_index);
|
||||
cur_section.relocatable = true;
|
||||
cur_section.fixed_address = (section_header->flags & static_cast<uint32_t>(SectionFlags::FixedAddress)) != 0;
|
||||
cur_section.globally_loaded = (section_header->flags & static_cast<uint32_t>(SectionFlags::GloballyLoaded)) != 0;
|
||||
|
||||
if (cur_section.fixed_address && !cur_section.globally_loaded) {
|
||||
printf("Fixed address sections that aren't globally loaded aren't currently supported\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cur_section.globally_loaded && !cur_section.fixed_address) {
|
||||
printf("A globally loaded section must have a fixed address\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t num_funcs = section_header->num_funcs;
|
||||
uint32_t num_relocs = section_header->num_relocs;
|
||||
|
||||
|
||||
const FuncV1* funcs = reinterpret_data<FuncV1>(data, offset, num_funcs);
|
||||
if (funcs == nullptr) {
|
||||
printf("Failed to read funcs (count: %d)\n", num_funcs);
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
|
|||
}
|
||||
|
||||
N64Recomp::RelocType reloc_type = N64Recomp::RelocType::R_MIPS_NONE;
|
||||
bool has_reloc = false;
|
||||
uint32_t reloc_section = 0;
|
||||
uint32_t reloc_target_section_offset = 0;
|
||||
size_t reloc_reference_symbol = (size_t)-1;
|
||||
|
|
@ -162,6 +163,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
|
|||
|
||||
// Check if this instruction has a reloc.
|
||||
if (section.relocs.size() > 0 && section.relocs[reloc_index].address == instr_vram) {
|
||||
has_reloc = true;
|
||||
// Get the reloc data for this instruction
|
||||
const auto& reloc = section.relocs[reloc_index];
|
||||
reloc_section = reloc.target_section;
|
||||
|
|
@ -257,7 +259,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
|
|||
return true;
|
||||
};
|
||||
|
||||
auto print_func_call_by_address = [&generator, reloc_target_section_offset, reloc_section, reloc_reference_symbol, reloc_type, &context, &func, &static_funcs_out, &needs_link_branch, &print_indent, &process_delay_slot, &print_link_branch]
|
||||
auto print_func_call_by_address = [&generator, reloc_target_section_offset, has_reloc, reloc_section, reloc_reference_symbol, reloc_type, &context, &func, &static_funcs_out, &needs_link_branch, &print_indent, &process_delay_slot, &print_link_branch]
|
||||
(uint32_t target_func_vram, bool tail_call = false, bool indent = false)
|
||||
{
|
||||
bool call_by_lookup = false;
|
||||
|
|
@ -294,7 +296,11 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
|
|||
}
|
||||
}
|
||||
else {
|
||||
JalResolutionResult jal_result = resolve_jal(context, func.section_index, target_func_vram, matched_func_index);
|
||||
uint32_t target_section = func.section_index;
|
||||
if (has_reloc) {
|
||||
target_section = reloc_section;
|
||||
}
|
||||
JalResolutionResult jal_result = resolve_jal(context, target_section, target_func_vram, matched_func_index);
|
||||
|
||||
switch (jal_result) {
|
||||
case JalResolutionResult::NoMatch:
|
||||
|
|
|
|||
Loading…
Reference in New Issue