aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
authorJordan Rupprecht <rupprecht@google.com>2020-02-21 15:30:51 -0800
committerJordan Rupprecht <rupprecht@google.com>2020-02-21 15:30:51 -0800
commit266877a2a8b2d1939f3b08fcfb711890fefc96e3 (patch)
treeb426be1364c670682521b5ae2128afd7577c561a /llvm/tools/llvm-objdump/llvm-objdump.cpp
parent0050e8f0cf5782217ebd78fa2b58be3aa9f8d9e2 (diff)
downloadllvm-266877a2a8b2d1939f3b08fcfb711890fefc96e3.zip
llvm-266877a2a8b2d1939f3b08fcfb711890fefc96e3.tar.gz
llvm-266877a2a8b2d1939f3b08fcfb711890fefc96e3.tar.bz2
[llvm-objdump] Print method name from debug info in disassembly output.
Summary: GNU objdump prints the method name in disassembly output, and upon further investigation this seems to come from debug info, not the symbol table. Some additional refactoring is necessary to make this work even when the line number is 0/the filename is unknown. The added test case includes a note for this scenario. See http://llvm.org/PR41341 for more info. Reviewers: dblaikie, MaskRay, jhenderson Reviewed By: MaskRay Subscribers: ormris, jvesely, aprantl, kerbowa, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D74507
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp78
1 files changed, 54 insertions, 24 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 1b98d78..c07a4ec 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -553,13 +553,20 @@ protected:
private:
bool cacheSource(const DILineInfo& LineInfoFile);
+ void printLines(raw_ostream &OS, const DILineInfo &LineInfo,
+ StringRef Delimiter);
+
+ void printSources(raw_ostream &OS, const DILineInfo &LineInfo,
+ StringRef ObjectFilename, StringRef Delimiter);
+
public:
SourcePrinter() = default;
SourcePrinter(const ObjectFile *Obj, StringRef DefaultArch)
: Obj(Obj), WarnedNoDebugInfo(false) {
symbolize::LLVMSymbolizer::Options SymbolizerOpts;
- SymbolizerOpts.PrintFunctions = DILineInfoSpecifier::FunctionNameKind::None;
- SymbolizerOpts.Demangle = false;
+ SymbolizerOpts.PrintFunctions =
+ DILineInfoSpecifier::FunctionNameKind::LinkageName;
+ SymbolizerOpts.Demangle = Demangle;
SymbolizerOpts.DefaultArch = std::string(DefaultArch);
Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts));
}
@@ -624,34 +631,57 @@ void SourcePrinter::printSourceLine(raw_ostream &OS,
reportWarning(Warning, ObjectFilename);
WarnedNoDebugInfo = true;
}
- return;
}
- if (LineInfo.Line == 0 || ((OldLineInfo.Line == LineInfo.Line) &&
- (OldLineInfo.FileName == LineInfo.FileName)))
- return;
-
if (PrintLines)
+ printLines(OS, LineInfo, Delimiter);
+ if (PrintSource)
+ printSources(OS, LineInfo, ObjectFilename, Delimiter);
+ OldLineInfo = LineInfo;
+}
+
+void SourcePrinter::printLines(raw_ostream &OS, const DILineInfo &LineInfo,
+ StringRef Delimiter) {
+ bool PrintFunctionName = LineInfo.FunctionName != DILineInfo::BadString &&
+ LineInfo.FunctionName != OldLineInfo.FunctionName;
+ if (PrintFunctionName) {
+ OS << Delimiter << LineInfo.FunctionName;
+ // If demangling is successful, FunctionName will end with "()". Print it
+ // only if demangling did not run or was unsuccessful.
+ if (!StringRef(LineInfo.FunctionName).endswith("()"))
+ OS << "()";
+ OS << ":\n";
+ }
+ if (LineInfo.FileName != DILineInfo::BadString && LineInfo.Line != 0 &&
+ (OldLineInfo.Line != LineInfo.Line ||
+ OldLineInfo.FileName != LineInfo.FileName || PrintFunctionName))
OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line << "\n";
- if (PrintSource) {
- if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
- if (!cacheSource(LineInfo))
- return;
- auto LineBuffer = LineCache.find(LineInfo.FileName);
- if (LineBuffer != LineCache.end()) {
- if (LineInfo.Line > LineBuffer->second.size()) {
- reportWarning(
- formatv(
- "debug info line number {0} exceeds the number of lines in {1}",
- LineInfo.Line, LineInfo.FileName),
- ObjectFilename);
- return;
- }
- // Vector begins at 0, line numbers are non-zero
- OS << Delimiter << LineBuffer->second[LineInfo.Line - 1] << '\n';
+}
+
+void SourcePrinter::printSources(raw_ostream &OS, const DILineInfo &LineInfo,
+ StringRef ObjectFilename,
+ StringRef Delimiter) {
+ if (LineInfo.FileName == DILineInfo::BadString || LineInfo.Line == 0 ||
+ (OldLineInfo.Line == LineInfo.Line &&
+ OldLineInfo.FileName == LineInfo.FileName))
+ return;
+
+ if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
+ if (!cacheSource(LineInfo))
+ return;
+ auto LineBuffer = LineCache.find(LineInfo.FileName);
+ if (LineBuffer != LineCache.end()) {
+ if (LineInfo.Line > LineBuffer->second.size()) {
+ reportWarning(
+ formatv(
+ "debug info line number {0} exceeds the number of lines in {1}",
+ LineInfo.Line, LineInfo.FileName),
+ ObjectFilename);
+ return;
}
+ // Vector begins at 0, line numbers are non-zero
+ OS << Delimiter << LineBuffer->second[LineInfo.Line - 1] << '\n';
}
- OldLineInfo = LineInfo;
}
static bool isAArch64Elf(const ObjectFile *Obj) {