aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp75
1 files changed, 50 insertions, 25 deletions
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 9383385..c174b7d 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -51,6 +51,7 @@
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/InitLLVM.h"
@@ -381,12 +382,7 @@ LLVM_ATTRIBUTE_NORETURN void error(Twine Message) {
exit(1);
}
-void warn(StringRef Message) {
- WithColor::warning(errs(), ToolName) << Message << ".\n";
- errs().flush();
-}
-
-static void warn(Twine Message) {
+void warn(Twine Message) {
// Output order between errs() and outs() matters especially for archive
// files where the output is per member object.
outs().flush();
@@ -548,17 +544,22 @@ protected:
DILineInfo OldLineInfo;
const ObjectFile *Obj = nullptr;
std::unique_ptr<symbolize::LLVMSymbolizer> Symbolizer;
- // File name to file contents of source
+ // File name to file contents of source.
std::unordered_map<std::string, std::unique_ptr<MemoryBuffer>> SourceCache;
- // Mark the line endings of the cached source
+ // Mark the line endings of the cached source.
std::unordered_map<std::string, std::vector<StringRef>> LineCache;
+ // Keep track of missing sources.
+ StringSet<> MissingSources;
+ // Only emit 'no debug info' warning once.
+ bool WarnedNoDebugInfo;
private:
bool cacheSource(const DILineInfo& LineInfoFile);
public:
SourcePrinter() = default;
- SourcePrinter(const ObjectFile *Obj, StringRef DefaultArch) : Obj(Obj) {
+ SourcePrinter(const ObjectFile *Obj, StringRef DefaultArch)
+ : Obj(Obj), WarnedNoDebugInfo(false) {
symbolize::LLVMSymbolizer::Options SymbolizerOpts;
SymbolizerOpts.PrintFunctions = DILineInfoSpecifier::FunctionNameKind::None;
SymbolizerOpts.Demangle = false;
@@ -568,6 +569,7 @@ public:
virtual ~SourcePrinter() = default;
virtual void printSourceLine(raw_ostream &OS,
object::SectionedAddress Address,
+ StringRef ObjectFilename,
StringRef Delimiter = "; ");
};
@@ -577,8 +579,11 @@ bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
Buffer = MemoryBuffer::getMemBuffer(*LineInfo.Source);
} else {
auto BufferOrError = MemoryBuffer::getFile(LineInfo.FileName);
- if (!BufferOrError)
+ if (!BufferOrError) {
+ if (MissingSources.insert(LineInfo.FileName).second)
+ warn("failed to find source " + LineInfo.FileName);
return false;
+ }
Buffer = std::move(*BufferOrError);
}
// Chomp the file to get lines
@@ -599,20 +604,33 @@ bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
void SourcePrinter::printSourceLine(raw_ostream &OS,
object::SectionedAddress Address,
+ StringRef ObjectFilename,
StringRef Delimiter) {
if (!Symbolizer)
return;
DILineInfo LineInfo = DILineInfo();
auto ExpectedLineInfo = Symbolizer->symbolizeCode(*Obj, Address);
+ std::string ErrorMessage;
if (!ExpectedLineInfo)
- consumeError(ExpectedLineInfo.takeError());
+ ErrorMessage = toString(ExpectedLineInfo.takeError());
else
LineInfo = *ExpectedLineInfo;
- if ((LineInfo.FileName == "<invalid>") || LineInfo.Line == 0 ||
- ((OldLineInfo.Line == LineInfo.Line) &&
- (OldLineInfo.FileName == LineInfo.FileName)))
+ if (LineInfo.FileName == DILineInfo::BadString) {
+ if (!WarnedNoDebugInfo) {
+ std::string Warning =
+ "failed to parse debug information for " + ObjectFilename.str();
+ if (!ErrorMessage.empty())
+ Warning += ": " + ErrorMessage;
+ warn(Warning);
+ WarnedNoDebugInfo = true;
+ }
+ return;
+ }
+
+ if (LineInfo.Line == 0 || ((OldLineInfo.Line == LineInfo.Line) &&
+ (OldLineInfo.FileName == LineInfo.FileName)))
return;
if (PrintLines)
@@ -623,8 +641,12 @@ void SourcePrinter::printSourceLine(raw_ostream &OS,
return;
auto LineBuffer = LineCache.find(LineInfo.FileName);
if (LineBuffer != LineCache.end()) {
- if (LineInfo.Line > LineBuffer->second.size())
+ if (LineInfo.Line > LineBuffer->second.size()) {
+ warn(formatv(
+ "debug info line number {0} exceeds the number of lines in {1}",
+ LineInfo.Line, LineInfo.FileName));
return;
+ }
// Vector begins at 0, line numbers are non-zero
OS << Delimiter << LineBuffer->second[LineInfo.Line - 1] << '\n';
}
@@ -663,10 +685,10 @@ public:
ArrayRef<uint8_t> Bytes,
object::SectionedAddress Address, raw_ostream &OS,
StringRef Annot, MCSubtargetInfo const &STI,
- SourcePrinter *SP,
+ SourcePrinter *SP, StringRef ObjectFilename,
std::vector<RelocationRef> *Rels = nullptr) {
if (SP && (PrintSource || PrintLines))
- SP->printSourceLine(OS, Address);
+ SP->printSourceLine(OS, Address, ObjectFilename);
size_t Start = OS.tell();
if (!NoLeadingAddr)
@@ -707,9 +729,10 @@ public:
void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
object::SectionedAddress Address, raw_ostream &OS,
StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
+ StringRef ObjectFilename,
std::vector<RelocationRef> *Rels) override {
if (SP && (PrintSource || PrintLines))
- SP->printSourceLine(OS, Address, "");
+ SP->printSourceLine(OS, Address, ObjectFilename, "");
if (!MI) {
printLead(Bytes, Address.Address, OS);
OS << " <unknown>";
@@ -746,7 +769,7 @@ public:
OS << Separator;
Separator = "\n";
if (SP && (PrintSource || PrintLines))
- SP->printSourceLine(OS, Address, "");
+ SP->printSourceLine(OS, Address, ObjectFilename, "");
printLead(Bytes, Address.Address, OS);
OS << Preamble;
Preamble = " ";
@@ -776,9 +799,10 @@ public:
void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
object::SectionedAddress Address, raw_ostream &OS,
StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
+ StringRef ObjectFilename,
std::vector<RelocationRef> *Rels) override {
if (SP && (PrintSource || PrintLines))
- SP->printSourceLine(OS, Address);
+ SP->printSourceLine(OS, Address, ObjectFilename);
if (MI) {
SmallString<40> InstStr;
@@ -827,9 +851,10 @@ public:
void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
object::SectionedAddress Address, raw_ostream &OS,
StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
+ StringRef ObjectFilename,
std::vector<RelocationRef> *Rels) override {
if (SP && (PrintSource || PrintLines))
- SP->printSourceLine(OS, Address);
+ SP->printSourceLine(OS, Address, ObjectFilename);
if (!NoLeadingAddr)
OS << format("%8" PRId64 ":", Address.Address / 8);
if (!NoShowRawInsn) {
@@ -1377,10 +1402,10 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
if (Size == 0)
Size = 1;
- PIP.printInst(
- *IP, Disassembled ? &Inst : nullptr, Bytes.slice(Index, Size),
- {SectionAddr + Index + VMAAdjustment, Section.getIndex()}, outs(),
- "", *STI, &SP, &Rels);
+ PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
+ Bytes.slice(Index, Size),
+ {SectionAddr + Index + VMAAdjustment, Section.getIndex()},
+ outs(), "", *STI, &SP, Obj->getFileName(), &Rels);
outs() << CommentStream.str();
Comments.clear();