| 481 | } |
| 482 | |
| 483 | N64Recomp::ModSymbolsError N64Recomp::parse_mod_symbols(std::span<const char> data, std::span<const uint8_t> binary, const std::unordered_map<uint32_t, uint16_t>& sections_by_vrom, Context& mod_context_out) { |
| 484 | size_t offset = 0; |
| 485 | mod_context_out = {}; |
| 486 | const FileHeader* header = reinterpret_data<FileHeader>(data, offset); |
| 487 | |
| 488 | if (header == nullptr) { |
| 489 | return ModSymbolsError::NotASymbolFile; |
| 490 | } |
| 491 | |
| 492 | if (!check_magic(header)) { |
| 493 | return ModSymbolsError::NotASymbolFile; |
| 494 | } |
| 495 | |
| 496 | bool valid = false; |
| 497 | |
| 498 | switch (header->version) { |
| 499 | case 1: |
| 500 | valid = parse_v1(data, sections_by_vrom, mod_context_out); |
| 501 | break; |
| 502 | default: |
| 503 | return ModSymbolsError::UnknownSymbolFileVersion; |
| 504 | } |
| 505 | |
| 506 | if (!valid) { |
| 507 | mod_context_out = {}; |
| 508 | return ModSymbolsError::CorruptSymbolFile; |
| 509 | } |
| 510 | |
| 511 | // Fill in the words for each function. |
| 512 | for (auto& cur_func : mod_context_out.functions) { |
| 513 | if (cur_func.rom + cur_func.words.size() * sizeof(cur_func.words[0]) > binary.size()) { |
| 514 | mod_context_out = {}; |
| 515 | return ModSymbolsError::FunctionOutOfBounds; |
| 516 | } |
| 517 | const uint32_t* func_rom = reinterpret_cast<const uint32_t*>(binary.data() + cur_func.rom); |
| 518 | for (size_t word_index = 0; word_index < cur_func.words.size(); word_index++) { |
| 519 | cur_func.words[word_index] = func_rom[word_index]; |
| 520 | } |
| 521 | } |
| 522 | |
| 523 | return ModSymbolsError::Good; |
| 524 | } |
| 525 | |
| 526 | template <typename T> |
| 527 | void vec_put(std::vector<uint8_t>& vec, const T* data) { |
nothing calls this directly
no test coverage detected