diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index bc4aa74073a6557..7633554830da3c2 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -75,11 +75,14 @@ class LLVMSymbolizer { // Overloads accepting ObjectFile does not support COFF currently Expected symbolizeCode(const ObjectFile &Obj, - object::SectionedAddress ModuleOffset); + object::SectionedAddress ModuleOffset, + bool Nearest = false); Expected symbolizeCode(const std::string &ModuleName, - object::SectionedAddress ModuleOffset); + object::SectionedAddress ModuleOffset, + bool Nearest = false); Expected symbolizeCode(ArrayRef BuildID, - object::SectionedAddress ModuleOffset); + object::SectionedAddress ModuleOffset, + bool Nearest = false); Expected symbolizeInlinedCode(const ObjectFile &Obj, object::SectionedAddress ModuleOffset); @@ -142,7 +145,8 @@ class LLVMSymbolizer { template Expected symbolizeCodeCommon(const T &ModuleSpecifier, - object::SectionedAddress ModuleOffset); + object::SectionedAddress ModuleOffset, + bool Nearest = false); template Expected symbolizeInlinedCodeCommon(const T &ModuleSpecifier, diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 36d112a5f3fb299..c36af2571dd350a 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -14,6 +14,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/BTF/BTFContext.h" +#include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/DebugInfo/PDB/PDBContext.h" @@ -24,6 +25,7 @@ #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/CRC.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataExtractor.h" @@ -52,7 +54,8 @@ LLVMSymbolizer::~LLVMSymbolizer() = default; template Expected LLVMSymbolizer::symbolizeCodeCommon(const T &ModuleSpecifier, - object::SectionedAddress ModuleOffset) { + object::SectionedAddress ModuleOffset, + bool Nearest) { auto InfoOrErr = getOrCreateModuleInfo(ModuleSpecifier); if (!InfoOrErr) @@ -70,9 +73,28 @@ LLVMSymbolizer::symbolizeCodeCommon(const T &ModuleSpecifier, if (Opts.RelativeAddresses) ModuleOffset.Address += Info->getModulePreferredBase(); - DILineInfo LineInfo = Info->symbolizeCode( - ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions), - Opts.UseSymbolTable); + DILineInfo LineInfo; + if (!Nearest) + LineInfo = Info->symbolizeCode( + ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions), + Opts.UseSymbolTable); + else { + object::SectionedAddress PrevModuleOffset = ModuleOffset; + while (LineInfo.Line = 0) { + LineInfo = Info->symbolizeCode( + ModuleOffset, + DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions), + Opts.UseSymbolTable); + if (LineInfo.Line != 0) + break; + ModuleOffset.Address++; + --PrevModuleOffset.Address; + LineInfo = Info->symbolizeCode( + PrevModuleOffset, + DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions), + Opts.UseSymbolTable); + } + } if (Opts.Demangle) LineInfo.FunctionName = DemangleName(LineInfo.FunctionName, Info); return LineInfo; @@ -80,20 +102,23 @@ LLVMSymbolizer::symbolizeCodeCommon(const T &ModuleSpecifier, Expected LLVMSymbolizer::symbolizeCode(const ObjectFile &Obj, - object::SectionedAddress ModuleOffset) { - return symbolizeCodeCommon(Obj, ModuleOffset); + object::SectionedAddress ModuleOffset, + bool Nearest) { + return symbolizeCodeCommon(Obj, ModuleOffset, Nearest); } Expected LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, - object::SectionedAddress ModuleOffset) { - return symbolizeCodeCommon(ModuleName, ModuleOffset); + object::SectionedAddress ModuleOffset, + bool Nearest) { + return symbolizeCodeCommon(ModuleName, ModuleOffset, Nearest); } Expected LLVMSymbolizer::symbolizeCode(ArrayRef BuildID, - object::SectionedAddress ModuleOffset) { - return symbolizeCodeCommon(BuildID, ModuleOffset); + object::SectionedAddress ModuleOffset, + bool Nearest) { + return symbolizeCodeCommon(BuildID, ModuleOffset, Nearest); } template