| 458 | } |
| 459 | |
| 460 | std::vector<CacheSymbol> SharedCacheMachOHeader::ReadSymbolTable(VirtualMemory& vm, const TableInfo &symbolInfo, const TableInfo &stringInfo) const |
| 461 | { |
| 462 | std::vector<CacheSymbol> symbolList; |
| 463 | // TODO: This assumes that 95% (or more) are going to be added. |
| 464 | symbolList.reserve(symbolInfo.entries); |
| 465 | for (uint64_t entryIndex = 0; entryIndex < symbolInfo.entries; entryIndex++) |
| 466 | { |
| 467 | nlist_64 nlist = {}; |
| 468 | if (vm.GetAddressSize() == 4) |
| 469 | { |
| 470 | // 32-bit DSC |
| 471 | struct nlist nlist32 = {}; |
| 472 | vm.Read(&nlist, symbolInfo.address + (entryIndex * sizeof(nlist32)), sizeof(nlist32)); |
| 473 | nlist.n_strx = nlist32.n_strx; |
| 474 | nlist.n_type = nlist32.n_type; |
| 475 | nlist.n_sect = nlist32.n_sect; |
| 476 | nlist.n_desc = nlist32.n_desc; |
| 477 | nlist.n_value = nlist32.n_value; |
| 478 | } |
| 479 | else |
| 480 | { |
| 481 | // 64-bit DSC |
| 482 | vm.Read(&nlist, symbolInfo.address + (entryIndex * sizeof(nlist)), sizeof(nlist)); |
| 483 | } |
| 484 | |
| 485 | auto symbolAddress = nlist.n_value; |
| 486 | if (((nlist.n_type & N_TYPE) == N_INDR) || symbolAddress == 0) |
| 487 | continue; |
| 488 | |
| 489 | if (nlist.n_strx >= stringInfo.entries) |
| 490 | { |
| 491 | // TODO: where logger? |
| 492 | LogError( |
| 493 | "Symbol entry at index %llu has a string offset of %u which is outside the strings buffer of size %llu " |
| 494 | "for symbol table %x", |
| 495 | entryIndex, nlist.n_strx, stringInfo.address, stringInfo.entries); |
| 496 | continue; |
| 497 | } |
| 498 | |
| 499 | std::string symbolName = vm.ReadCString(stringInfo.address + nlist.n_strx); |
| 500 | if (symbolName == "<redacted>") |
| 501 | continue; |
| 502 | |
| 503 | std::optional<BNSymbolType> symbolType; |
| 504 | if ((nlist.n_type & N_TYPE) == N_SECT && nlist.n_sect > 0 && (size_t)(nlist.n_sect - 1) < sections.size()) |
| 505 | symbolType = DataSymbol; |
| 506 | else if ((nlist.n_type & N_TYPE) == N_ABS) |
| 507 | symbolType = DataSymbol; |
| 508 | else if ((nlist.n_type & N_EXT)) |
| 509 | symbolType = ExternalSymbol; |
| 510 | |
| 511 | if (!symbolType.has_value()) |
| 512 | { |
| 513 | // TODO: Where logger? |
| 514 | LogError("Symbol %s at address %llx has unknown symbol type", symbolName.c_str(), symbolAddress); |
| 515 | continue; |
| 516 | } |
| 517 |
no test coverage detected