| 546 | } |
| 547 | |
| 548 | bool N64Recomp::Context::from_symbol_file(const std::filesystem::path& symbol_file_path, std::vector<uint8_t>&& rom, N64Recomp::Context& out, bool with_relocs) { |
| 549 | N64Recomp::Context ret{}; |
| 550 | |
| 551 | try { |
| 552 | const toml::table config_data = toml::parse_file(symbol_file_path.u8string()); |
| 553 | const toml::node_view config_sections_value = config_data["section"]; |
| 554 | |
| 555 | if (!config_sections_value.is_array()) { |
| 556 | return false; |
| 557 | } |
| 558 | |
| 559 | const toml::array* config_sections = config_sections_value.as_array(); |
| 560 | ret.section_functions.resize(config_sections->size()); |
| 561 | |
| 562 | config_sections->for_each([&ret, &rom, with_relocs](auto&& el) { |
| 563 | if constexpr (toml::is_table<decltype(el)>) { |
| 564 | std::optional<uint32_t> rom_addr = el["rom"].template value<uint32_t>(); |
| 565 | std::optional<uint32_t> vram_addr = el["vram"].template value<uint32_t>(); |
| 566 | std::optional<uint32_t> size = el["size"].template value<uint32_t>(); |
| 567 | std::optional<std::string> name = el["name"].template value<std::string>(); |
| 568 | std::optional<uint32_t> got_ram_addr = el["got_address"].template value<uint32_t>(); |
| 569 | |
| 570 | if (!rom_addr.has_value() || !vram_addr.has_value() || !size.has_value() || !name.has_value()) { |
| 571 | throw toml::parse_error("Section entry missing required field(s)", el.source()); |
| 572 | } |
| 573 | |
| 574 | uint16_t section_index = (uint16_t)ret.sections.size(); |
| 575 | |
| 576 | Section& section = ret.sections.emplace_back(Section{}); |
| 577 | section.rom_addr = rom_addr.value(); |
| 578 | section.ram_addr = vram_addr.value(); |
| 579 | section.size = size.value(); |
| 580 | section.name = name.value(); |
| 581 | section.got_ram_addr = got_ram_addr; |
| 582 | section.executable = true; |
| 583 | |
| 584 | // Read functions for the section. |
| 585 | const toml::node_view cur_functions_value = el["functions"]; |
| 586 | if (!cur_functions_value.is_array()) { |
| 587 | throw toml::parse_error("Invalid functions array", cur_functions_value.node()->source()); |
| 588 | } |
| 589 | |
| 590 | const toml::array* cur_functions = cur_functions_value.as_array(); |
| 591 | cur_functions->for_each([&ret, &rom, §ion, section_index](auto&& func_el) { |
| 592 | size_t function_index = ret.functions.size(); |
| 593 | |
| 594 | if constexpr (toml::is_table<decltype(func_el)>) { |
| 595 | std::optional<std::string> name = func_el["name"].template value<std::string>(); |
| 596 | std::optional<uint32_t> vram_addr = func_el["vram"].template value<uint32_t>(); |
| 597 | std::optional<uint32_t> func_size_ = func_el["size"].template value<uint32_t>(); |
| 598 | |
| 599 | if (!name.has_value() || !vram_addr.has_value() || !func_size_.has_value()) { |
| 600 | throw toml::parse_error("Function symbol entry is missing required field(s)", func_el.source()); |
| 601 | } |
| 602 | |
| 603 | uint32_t func_size = func_size_.value(); |
| 604 | |
| 605 | Function cur_func{}; |
nothing calls this directly
no test coverage detected