Index: llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h =================================================================== --- llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -74,6 +74,12 @@ DemangleName(const std::string &Name, const SymbolizableModule *DbiModuleDescriptor); + // this is a temporarily routine. It could be used to detect + // section index for an address until all places would not be patched + // with the correct SectionIndex. + uint64_t getModuleSectionIndexForAddress(const std::string &ModuleName, + uint64_t Address); + private: // Bundles together object file with code/data and object file with // corresponding debug info. These objects can be the same. @@ -103,6 +109,12 @@ Expected getOrCreateObject(const std::string &Path, const std::string &ArchName); + /// Returns binary name and architecture name(if presented) extracted from + /// ModuleName. <0> pair member is a binary name, <1> pair member is an + /// architecture + std::pair + parseModuleName(const std::string &ModuleName) 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 @@ -134,6 +134,45 @@ return Global; } +// 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). +uint64_t +LLVMSymbolizer::getModuleSectionIndexForAddress(const std::string &ModuleName, + uint64_t Address) { + + std::pair ParsedModuleName = + parseModuleName(ModuleName); + + auto ObjectsOrErr = getOrCreateObjectPair(std::get<0>(ParsedModuleName), + std::get<1>(ParsedModuleName)); + if (!ObjectsOrErr) { + // ignore error at this place. + consumeError(ObjectsOrErr.takeError()); + Modules.erase(ModuleName); + ObjectPairForPathArch.erase(std::make_pair(std::get<0>(ParsedModuleName), + std::get<1>(ParsedModuleName))); + ObjectForUBPathAndArch.erase(std::make_pair(std::get<0>(ParsedModuleName), + std::get<1>(ParsedModuleName))); + BinaryForPath.erase(std::get<0>(ParsedModuleName)); + return object::SectionedAddress::UndefSection; + } + ObjectPair Objects = ObjectsOrErr.get(); + + for (SectionRef Sec : std::get<0>(Objects)->sections()) { + if (!Sec.isText() || Sec.isVirtual()) + continue; + + if (Address >= Sec.getAddress() && + Address <= Sec.getAddress() + Sec.getSize()) { + return Sec.getIndex(); + } + } + + return object::SectionedAddress::UndefSection; +} + void LLVMSymbolizer::flush() { ObjectForUBPathAndArch.clear(); BinaryForPath.clear(); @@ -299,6 +338,23 @@ return DbgObjOrErr.get(); } +std::pair +LLVMSymbolizer::parseModuleName(const std::string &ModuleName) const { + 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; + } + } + + return std::pair(BinaryName, ArchName); +} + Expected LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, const std::string &ArchName) { @@ -380,18 +436,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(std::get<0>(ParsedModuleName), + std::get<1>(ParsedModuleName)); if (!ObjectsOrErr) { // Failed to find valid object file. Modules.insert( @@ -400,6 +450,9 @@ } ObjectPair Objects = ObjectsOrErr.get(); + if (Objects.first == nullptr) + return static_cast(nullptr); + std::unique_ptr Context; // If this is a COFF object containing PDB info, use a PDBContext to // symbolize. Otherwise, use DWARF. Index: llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp =================================================================== --- llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -147,9 +147,15 @@ // Build the function loaded notification message iJIT_Method_Load FunctionMessage = FunctionDescToIntelJITFormat(*Wrapper, Name->data(), Addr, Size); - // TODO: it is neccessary to set proper SectionIndex here. - // object::SectionedAddress::UndefSection works for only absolute addresses. - DILineInfoTable Lines = Context->getLineInfoForAddressRange({Addr, object::SectionedAddress::UndefSection}, Size); + + uint64_t SectionIndex = object::SectionedAddress::UndefSection; + auto SectOrErr = Sym.getSection(); + if (SectOrErr) { + SectionIndex = SectOrErr.get()->getIndex(); + } + + DILineInfoTable Lines = + Context->getLineInfoForAddressRange({Addr, SectionIndex}, Size); DILineInfoTable::iterator Begin = Lines.begin(); DILineInfoTable::iterator End = Lines.end(); for (DILineInfoTable::iterator It = Begin; It != End; ++It) { 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; @@ -254,7 +212,7 @@ } Offset -= ClAdjustVMA; object::SectionedAddress ModuleOffset = { - Offset, getModuleSectionIndexForAddress(ModuleName, Offset)}; + Offset, Symbolizer.getModuleSectionIndexForAddress(ModuleName, Offset)}; if (IsData) { auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get());