/// Load the interesting main binary symbols' addresses into /// MainBinarySymbolAddresses. void MachODebugMapParser::loadMainBinarySymbols( const MachOObjectFile &MainBinary) { section_iterator Section = MainBinary.section_end(); MainBinarySymbolAddresses.clear(); for (const auto &Sym : MainBinary.symbols()) { SymbolRef::Type Type = Sym.getType(); // Skip undefined and STAB entries. if ((Type & SymbolRef::ST_Debug) || (Type & SymbolRef::ST_Unknown)) continue; // The only symbols of interest are the global variables. These // are the only ones that need to be queried because the address // of common data won't be described in the debug map. All other // addresses should be fetched for the debug map. if (!(Sym.getFlags() & SymbolRef::SF_Global)) continue; ErrorOr<section_iterator> SectionOrErr = Sym.getSection(); if (!SectionOrErr) continue; Section = *SectionOrErr; if (Section == MainBinary.section_end() || Section->isText()) continue; uint64_t Addr = Sym.getValue(); ErrorOr<StringRef> NameOrErr = Sym.getName(); if (!NameOrErr) continue; StringRef Name = *NameOrErr; if (Name.size() == 0 || Name[0] == '\0') continue; MainBinarySymbolAddresses[Name] = Addr; } }
/// Load the interesting main binary symbols' addresses into /// MainBinarySymbolAddresses. void MachODebugMapParser::loadMainBinarySymbols( const MachOObjectFile &MainBinary) { MainBinarySymbolAddresses.clear(); for (const auto &Sym : MainBinary.symbols()) { SymbolRef::Type Type; // Skip undefined and STAB entries. if (Sym.getType(Type) || (Type & SymbolRef::ST_Debug) || (Type & SymbolRef::ST_Unknown)) continue; StringRef Name; uint64_t Addr; if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize || Sym.getName(Name) || Name.size() == 0 || Name[0] == '\0') { continue; } // FIXME: dsymutil-classic ompatibility: retain the first // symbol with a given name. We should check why we get duplicated // symbols with different addresses instead. (emacs binary has 2 // Qwindow symbols) uint64_t &AddrInMap = MainBinarySymbolAddresses[Name]; if (!AddrInMap) AddrInMap = Addr; } }
std::unique_ptr<DebugMap> MachODebugMapParser::parseOneBinary(const MachOObjectFile &MainBinary, StringRef BinaryPath) { loadMainBinarySymbols(MainBinary); Result = make_unique<DebugMap>(MainBinary.getArchTriple(), BinaryPath); MainBinaryStrings = MainBinary.getStringTableData(); for (const SymbolRef &Symbol : MainBinary.symbols()) { const DataRefImpl &DRI = Symbol.getRawDataRefImpl(); if (MainBinary.is64Bit()) handleStabDebugMapEntry(MainBinary.getSymbol64TableEntry(DRI)); else handleStabDebugMapEntry(MainBinary.getSymbolTableEntry(DRI)); } resetParserState(); return std::move(Result); }
/// Load the interesting main binary symbols' addresses into /// MainBinarySymbolAddresses. void MachODebugMapParser::loadMainBinarySymbols( const MachOObjectFile &MainBinary) { section_iterator Section = MainBinary.section_end(); MainBinarySymbolAddresses.clear(); for (const auto &Sym : MainBinary.symbols()) { Expected<SymbolRef::Type> TypeOrErr = Sym.getType(); if (!TypeOrErr) { // TODO: Actually report errors helpfully. consumeError(TypeOrErr.takeError()); continue; } SymbolRef::Type Type = *TypeOrErr; // Skip undefined and STAB entries. if ((Type == SymbolRef::ST_Debug) || (Type == SymbolRef::ST_Unknown)) continue; // The only symbols of interest are the global variables. These // are the only ones that need to be queried because the address // of common data won't be described in the debug map. All other // addresses should be fetched for the debug map. uint8_t SymType = MainBinary.getSymbolTableEntry(Sym.getRawDataRefImpl()).n_type; if (!(SymType & (MachO::N_EXT | MachO::N_PEXT))) continue; Expected<section_iterator> SectionOrErr = Sym.getSection(); if (!SectionOrErr) { // TODO: Actually report errors helpfully. consumeError(SectionOrErr.takeError()); continue; } Section = *SectionOrErr; if (Section == MainBinary.section_end() || Section->isText()) continue; uint64_t Addr = Sym.getValue(); Expected<StringRef> NameOrErr = Sym.getName(); if (!NameOrErr) { // TODO: Actually report errors helpfully. consumeError(NameOrErr.takeError()); continue; } StringRef Name = *NameOrErr; if (Name.size() == 0 || Name[0] == '\0') continue; MainBinarySymbolAddresses[Name] = Addr; } }
void MachODebugMapParser::dumpOneBinaryStab(const MachOObjectFile &MainBinary, StringRef BinaryPath) { loadMainBinarySymbols(MainBinary); MainBinaryStrings = MainBinary.getStringTableData(); raw_ostream &OS(llvm::outs()); dumpSymTabHeader(OS, getArchName(MainBinary)); uint64_t Idx = 0; for (const SymbolRef &Symbol : MainBinary.symbols()) { const DataRefImpl &DRI = Symbol.getRawDataRefImpl(); if (MainBinary.is64Bit()) dumpSymTabEntry(OS, Idx, MainBinary.getSymbol64TableEntry(DRI)); else dumpSymTabEntry(OS, Idx, MainBinary.getSymbolTableEntry(DRI)); Idx++; } OS << "\n\n"; resetParserState(); }