| 561 | } |
| 562 | |
| 563 | N64Recomp::Context build_mod_context(const N64Recomp::Context& input_context, bool& good) { |
| 564 | N64Recomp::Context ret{}; |
| 565 | good = false; |
| 566 | |
| 567 | // Make a vector containing 0, 1, 2, ... section count - 1 |
| 568 | std::vector<uint16_t> section_order; |
| 569 | section_order.resize(input_context.sections.size()); |
| 570 | std::iota(section_order.begin(), section_order.end(), 0); |
| 571 | |
| 572 | // TODO this sort is currently disabled because sections seem to already be ordered |
| 573 | // by elf offset. Determine if this is always the case and remove this if so. |
| 574 | //// Sort the vector based on the rom address of the corresponding section. |
| 575 | //std::sort(section_order.begin(), section_order.end(), |
| 576 | // [&](uint16_t a, uint16_t b) { |
| 577 | // const auto& section_a = input_context.sections[a]; |
| 578 | // const auto& section_b = input_context.sections[b]; |
| 579 | // // Sort primarily by ROM address. |
| 580 | // if (section_a.rom_addr != section_b.rom_addr) { |
| 581 | // return section_a.rom_addr < section_b.rom_addr; |
| 582 | // } |
| 583 | // // Sort secondarily by RAM address. |
| 584 | // return section_a.ram_addr < section_b.ram_addr; |
| 585 | // } |
| 586 | //); |
| 587 | |
| 588 | // TODO avoid a copy here. |
| 589 | ret.rom = input_context.rom; |
| 590 | |
| 591 | // Copy the dependency data from the input context. |
| 592 | ret.dependencies_by_name = input_context.dependencies_by_name; |
| 593 | ret.import_symbols = input_context.import_symbols; |
| 594 | ret.dependency_events = input_context.dependency_events; |
| 595 | ret.dependency_events_by_name = input_context.dependency_events_by_name; |
| 596 | ret.dependency_imports_by_name = input_context.dependency_imports_by_name; |
| 597 | |
| 598 | uint32_t rom_to_ram = (uint32_t)-1; |
| 599 | size_t output_section_index = (size_t)-1; |
| 600 | ret.sections.resize(1); |
| 601 | |
| 602 | // Mapping of input section to output section for fixing up relocations. |
| 603 | std::unordered_map<uint16_t, uint16_t> input_section_to_output_section{}; |
| 604 | |
| 605 | // Iterate over the input sections in their sorted order. |
| 606 | for (uint16_t section_index : section_order) { |
| 607 | const auto& cur_section = input_context.sections[section_index]; |
| 608 | uint32_t cur_rom_to_ram = cur_section.ram_addr - cur_section.rom_addr; |
| 609 | |
| 610 | // Check if this is a non-allocated section. |
| 611 | if (cur_section.rom_addr == (uint32_t)-1) { |
| 612 | // If so, check if it has a vram address directly after the current output section. If it does, then add this |
| 613 | // section's size to the output section's bss size. |
| 614 | if (output_section_index != -1 && cur_section.size != 0) { |
| 615 | auto& section_out = ret.sections[output_section_index]; |
| 616 | uint32_t output_section_bss_start = section_out.ram_addr + section_out.size; |
| 617 | uint32_t output_section_bss_end = output_section_bss_start + section_out.bss_size; |
| 618 | // Check if the current section starts at the end of the output section, allowing for a range of matches to account for 16 byte section alignment. |
| 619 | if (cur_section.ram_addr >= output_section_bss_end && cur_section.ram_addr <= round_up_16(output_section_bss_end)) { |
| 620 | // Calculate the output section's bss size by using its non-bss end address and the current section's end address. |
no test coverage detected