| 9 | #include "mdebug.h" |
| 10 | |
| 11 | bool read_symbols(N64Recomp::Context& context, const ELFIO::elfio& elf_file, ELFIO::section* symtab_section, const N64Recomp::ElfParsingConfig& elf_config, bool dumping_context, std::unordered_map<uint16_t, std::vector<N64Recomp::DataSymbol>>& data_syms) { |
| 12 | bool found_entrypoint_func = false; |
| 13 | ELFIO::symbol_section_accessor symbols{ elf_file, symtab_section }; |
| 14 | |
| 15 | std::unordered_map<uint16_t, uint16_t> bss_section_to_target_section{}; |
| 16 | |
| 17 | // Create a mapping of bss section to the corresponding non-bss section. This is only used when dumping context in order |
| 18 | // for patches and mods to correctly relocate symbols in bss. This mapping only matters for relocatable sections. |
| 19 | if (dumping_context) { |
| 20 | // Process bss and reloc sections |
| 21 | for (size_t cur_section_index = 0; cur_section_index < context.sections.size(); cur_section_index++) { |
| 22 | const N64Recomp::Section& cur_section = context.sections[cur_section_index]; |
| 23 | // Check if a bss section was found that corresponds with this section. |
| 24 | if (cur_section.bss_section_index != (uint16_t)-1) { |
| 25 | bss_section_to_target_section[cur_section.bss_section_index] = cur_section_index; |
| 26 | } |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | for (int sym_index = 0; sym_index < symbols.get_symbols_num(); sym_index++) { |
| 31 | std::string name; |
| 32 | ELFIO::Elf64_Addr value; |
| 33 | ELFIO::Elf_Xword size; |
| 34 | unsigned char bind; |
| 35 | unsigned char type; |
| 36 | ELFIO::Elf_Half section_index; |
| 37 | unsigned char other; |
| 38 | bool ignored = false; |
| 39 | bool reimplemented = false; |
| 40 | bool recorded_symbol = false; |
| 41 | |
| 42 | // Read symbol properties |
| 43 | symbols.get_symbol(sym_index, name, value, size, bind, type, |
| 44 | section_index, other); |
| 45 | |
| 46 | if (section_index == ELFIO::SHN_ABS && elf_config.use_absolute_symbols) { |
| 47 | uint32_t vram = static_cast<uint32_t>(value); |
| 48 | context.functions_by_vram[vram].push_back(context.functions.size()); |
| 49 | |
| 50 | context.functions.emplace_back( |
| 51 | vram, |
| 52 | 0, |
| 53 | std::vector<uint32_t>{}, |
| 54 | std::move(name), |
| 55 | 0, |
| 56 | true, |
| 57 | reimplemented, |
| 58 | false |
| 59 | ); |
| 60 | continue; |
| 61 | } |
| 62 | |
| 63 | if (section_index < context.sections.size()) { |
| 64 | // Check if this symbol is the entrypoint |
| 65 | // TODO this never fires, the check is broken due to signedness |
| 66 | if (elf_config.has_entrypoint && value == elf_config.entrypoint_address && type == ELFIO::STT_FUNC) { |
| 67 | if (found_entrypoint_func) { |
| 68 | fmt::print(stderr, "Ambiguous entrypoint: {}\n", name); |