Index: llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h =================================================================== --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -103,6 +103,16 @@ Expected getOrCreateObject(const std::string &Path, const std::string &ArchName); + /// Returns binary name and architecture name(if presented) extracted from + /// ModuleName. first pair member is a binary name, second pair member is an + /// architecture + std::pair + parseModuleName(const StringRef &ModuleName) const; + + /// Search for the first occurence of specified Address in ObjectFile. + uint64_t getModuleSectionIndexForAddress(const ObjectFile &Obj, + uint64_t Address) const; + std::map> Modules; /// Contains cached results of getOrCreateObjectPair(). Index: llvm/lib/DebugInfo/Symbolize/Symbolize.cpp =================================================================== --- llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -70,6 +70,18 @@ if (Opts.RelativeAddresses) ModuleOffset.Address += Info->getModulePreferredBase(); + if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection) { + std::pair ParsedModuleName = + parseModuleName(ModuleName); + + if (auto ObjectsOrErr = getOrCreateObjectPair(ParsedModuleName.first, + ParsedModuleName.second)) + ModuleOffset.SectionIndex = getModuleSectionIndexForAddress( + *(ObjectsOrErr.get().first), ModuleOffset.Address); + else + return ObjectsOrErr.takeError(); + } + DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable); if (Opts.Demangle) @@ -97,6 +109,18 @@ if (Opts.RelativeAddresses) ModuleOffset.Address += Info->getModulePreferredBase(); + if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection) { + std::pair ParsedModuleName = + parseModuleName(ModuleName); + + if (auto ObjectsOrErr = getOrCreateObjectPair(ParsedModuleName.first, + ParsedModuleName.second)) + ModuleOffset.SectionIndex = getModuleSectionIndexForAddress( + *(ObjectsOrErr.get().first), ModuleOffset.Address); + else + return ObjectsOrErr.takeError(); + } + DIInliningInfo InlinedContext = Info->symbolizeInlinedCode( ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable); if (Opts.Demangle) { @@ -128,6 +152,18 @@ if (Opts.RelativeAddresses) ModuleOffset.Address += Info->getModulePreferredBase(); + if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection) { + std::pair ParsedModuleName = + parseModuleName(ModuleName); + + if (auto ObjectsOrErr = getOrCreateObjectPair(ParsedModuleName.first, + ParsedModuleName.second)) + ModuleOffset.SectionIndex = getModuleSectionIndexForAddress( + *(ObjectsOrErr.get().first), ModuleOffset.Address); + else + return ObjectsOrErr.takeError(); + } + DIGlobal Global = Info->symbolizeData(ModuleOffset); if (Opts.Demangle) Global.Name = DemangleName(Global.Name, Info); @@ -380,18 +416,12 @@ if (I != Modules.end()) { return I->second.get(); } - std::string BinaryName = ModuleName; - std::string ArchName = Opts.DefaultArch; - size_t ColonPos = ModuleName.find_last_of(':'); - // Verify that substring after colon form a valid arch name. - if (ColonPos != std::string::npos) { - std::string ArchStr = ModuleName.substr(ColonPos + 1); - if (Triple(ArchStr).getArch() != Triple::UnknownArch) { - BinaryName = ModuleName.substr(0, ColonPos); - ArchName = ArchStr; - } - } - auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName); + + std::pair ParsedModuleName = + parseModuleName(ModuleName); + + auto ObjectsOrErr = + getOrCreateObjectPair(ParsedModuleName.first, ParsedModuleName.second); if (!ObjectsOrErr) { // Failed to find valid object file. Modules.insert( @@ -437,6 +467,41 @@ return InsertResult.first->second.get(); } +std::pair +LLVMSymbolizer::parseModuleName(const StringRef &ModuleName) const { + StringRef BinaryName = ModuleName; + StringRef ArchName = Opts.DefaultArch; + size_t ColonPos = ModuleName.find_last_of(':'); + // Verify that substring after colon form a valid arch name. + if (ColonPos != std::string::npos) { + StringRef ArchStr = ModuleName.substr(ColonPos + 1); + if (Triple(ArchStr).getArch() != Triple::UnknownArch) { + BinaryName = ModuleName.substr(0, ColonPos); + ArchName = ArchStr; + } + } + + return std::make_pair(std::move(BinaryName), std::move(ArchName)); +} + +/// Search for the first occurence of specified Address in ObjectFile. +uint64_t +LLVMSymbolizer::getModuleSectionIndexForAddress(const ObjectFile &Obj, + uint64_t Address) const { + + for (SectionRef Sec : Obj.sections()) { + if (!Sec.isText() || Sec.isVirtual()) + continue; + + if (Address >= Sec.getAddress() && + Address <= Sec.getAddress() + Sec.getSize()) { + return Sec.getIndex(); + } + } + + return object::SectionedAddress::UndefSection; +} + namespace { // Undo these various manglings for Win32 extern "C" functions: Index: llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp =================================================================== --- llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -194,48 +194,6 @@ return !StringRef(pos, offset_length).getAsInteger(0, ModuleOffset); } -// This routine returns section index for an address. -// Assumption: would work ambiguously for object files which have sections not -// assigned to an address(since the same address could belong to various -// sections). -static uint64_t getModuleSectionIndexForAddress(const std::string &ModuleName, - uint64_t Address) { - - // following ModuleName processing was copied from - // LLVMSymbolizer::getOrCreateModuleInfo(). - // it needs to be refactored to avoid code duplication. - std::string BinaryName = ModuleName; - size_t ColonPos = ModuleName.find_last_of(':'); - // Verify that substring after colon form a valid arch name. - if (ColonPos != std::string::npos) { - std::string ArchStr = ModuleName.substr(ColonPos + 1); - if (Triple(ArchStr).getArch() != Triple::UnknownArch) { - BinaryName = ModuleName.substr(0, ColonPos); - } - } - - Expected> BinaryOrErr = createBinary(BinaryName); - - if (error(BinaryOrErr)) - return object::SectionedAddress::UndefSection; - - Binary &Binary = *BinaryOrErr->getBinary(); - - if (ObjectFile *O = dyn_cast(&Binary)) { - for (SectionRef Sec : O->sections()) { - if (!Sec.isText() || Sec.isVirtual()) - continue; - - if (Address >= Sec.getAddress() && - Address <= Sec.getAddress() + Sec.getSize()) { - return Sec.getIndex(); - } - } - } - - return object::SectionedAddress::UndefSection; -} - static void symbolizeInput(StringRef InputString, LLVMSymbolizer &Symbolizer, DIPrinter &Printer) { bool IsData = false; @@ -253,18 +211,19 @@ outs() << Delimiter; } Offset -= ClAdjustVMA; - object::SectionedAddress ModuleOffset = { - Offset, getModuleSectionIndexForAddress(ModuleName, Offset)}; if (IsData) { - auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); + auto ResOrErr = Symbolizer.symbolizeData( + ModuleName, {Offset, object::SectionedAddress::UndefSection}); Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get()); } else if (ClPrintInlining) { - auto ResOrErr = - Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset, ClDwpName); + auto ResOrErr = Symbolizer.symbolizeInlinedCode( + ModuleName, {Offset, object::SectionedAddress::UndefSection}, + ClDwpName); Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get()); } else { - auto ResOrErr = - Symbolizer.symbolizeCode(ModuleName, ModuleOffset, ClDwpName); + auto ResOrErr = Symbolizer.symbolizeCode( + ModuleName, {Offset, object::SectionedAddress::UndefSection}, + ClDwpName); Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get()); } outs() << "\n";