| 18 | } |
| 19 | |
| 20 | void SharedCacheMachOProcessor::ApplyHeader(const SharedCache& cache, SharedCacheMachOHeader& header) |
| 21 | { |
| 22 | auto typeLibraryFromName = [&](const std::string& name) -> Ref<TypeLibrary> { |
| 23 | // Check to see if we have already loaded the type library. |
| 24 | if (auto typeLib = m_view->GetTypeLibrary(name)) |
| 25 | return typeLib; |
| 26 | |
| 27 | auto typeLibs = m_view->GetDefaultPlatform()->GetTypeLibrariesByName(name); |
| 28 | if (!typeLibs.empty()) |
| 29 | return typeLibs.front(); |
| 30 | return nullptr; |
| 31 | }; |
| 32 | |
| 33 | // Add a section for the header itself. |
| 34 | std::string headerSection = fmt::format("{}::__macho_header", header.identifierPrefix); |
| 35 | uint64_t machHeaderSize = m_vm->GetAddressSize() == 8 ? sizeof(mach_header_64) : sizeof(mach_header); |
| 36 | uint64_t headerSectionSize = machHeaderSize + header.ident.sizeofcmds; |
| 37 | m_view->AddUserSection(headerSection, header.textBase, headerSectionSize, ReadOnlyDataSectionSemantics); |
| 38 | |
| 39 | ApplyHeaderSections(header); |
| 40 | ApplyHeaderDataVariables(header); |
| 41 | |
| 42 | // Pull the available type library for the image we are loading, so we can apply known types. |
| 43 | auto typeLib = typeLibraryFromName(header.installName); |
| 44 | |
| 45 | if (header.linkeditPresent && m_vm->IsAddressMapped(header.linkeditSegment.vmaddr)) |
| 46 | { |
| 47 | if (m_applyFunctions && header.functionStartsPresent) |
| 48 | { |
| 49 | auto targetPlatform = m_view->GetDefaultPlatform(); |
| 50 | auto functions = header.ReadFunctionTable(*m_vm); |
| 51 | for (const auto& func : functions) |
| 52 | m_view->AddFunctionForAnalysis(targetPlatform, func, false); |
| 53 | } |
| 54 | |
| 55 | m_view->BeginBulkModifySymbols(); |
| 56 | |
| 57 | // Apply symbols from symbol table. |
| 58 | if (header.symtab.symoff != 0) |
| 59 | { |
| 60 | // NOTE: This table is read relative to the link edit segment file base. |
| 61 | // NOTE: This does not handle the shared .symbols cache entry symbols, that is the responsibility of the caller. |
| 62 | TableInfo symbolInfo = { header.GetLinkEditFileBase() + header.symtab.symoff, header.symtab.nsyms }; |
| 63 | TableInfo stringInfo = { header.GetLinkEditFileBase() + header.symtab.stroff, header.symtab.strsize }; |
| 64 | const auto symbols = header.ReadSymbolTable(*m_vm, symbolInfo, stringInfo); |
| 65 | for (const auto& sym : symbols) |
| 66 | { |
| 67 | auto [symbol, symbolType] = sym.GetBNSymbolAndType(*m_view); |
| 68 | ApplySymbol(m_view, typeLib, symbol, symbolType); |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | // Apply symbols from export trie. |
| 73 | if (header.exportTriePresent) |
| 74 | { |
| 75 | // NOTE: This table is read relative to the link edit segment file base. |
| 76 | const auto exportSymbols = header.ReadExportSymbolTrie(*m_vm); |
| 77 | for (const auto& sym : exportSymbols) |
no test coverage detected