aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objdump
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objdump')
-rw-r--r--llvm/tools/llvm-objdump/MachODump.cpp3
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.cpp64
-rw-r--r--llvm/tools/llvm-objdump/llvm-objdump.h28
3 files changed, 62 insertions, 33 deletions
diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp
index d1bfcb7..0e10403 100644
--- a/llvm/tools/llvm-objdump/MachODump.cpp
+++ b/llvm/tools/llvm-objdump/MachODump.cpp
@@ -2142,6 +2142,7 @@ static void printObjcMetaData(MachOObjectFile *O, bool verbose);
static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
StringRef ArchiveMemberName = StringRef(),
StringRef ArchitectureName = StringRef()) {
+ Dumper D(*MachOOF);
// If we are doing some processing here on the Mach-O file print the header
// info. And don't print it otherwise like in the case of printing the
// UniversalHeaders or ArchiveHeaders.
@@ -2227,7 +2228,7 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,
if (DylibId)
PrintDylibs(MachOOF, true);
if (SymbolTable)
- printSymbolTable(*MachOOF, ArchiveName, ArchitectureName);
+ D.printSymbolTable(ArchiveName, ArchitectureName);
if (UnwindInfo)
printMachOUnwindInfo(MachOOF);
if (PrivateHeaders) {
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index bce76ee..052b7f1 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -247,6 +247,15 @@ static StringRef ToolName;
std::unique_ptr<BuildIDFetcher> BIDFetcher;
ExitOnError ExitOnErr;
+void Dumper::reportUniqueWarning(Error Err) {
+ reportUniqueWarning(toString(std::move(Err)));
+}
+
+void Dumper::reportUniqueWarning(const Twine &Msg) {
+ if (Warnings.insert(StringRef(Msg.str())).second)
+ reportWarning(Msg, O.getFileName());
+}
+
namespace {
struct FilterResult {
// True if the section should not be skipped.
@@ -2168,23 +2177,22 @@ static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) {
SecondarySTI.get(), PIP, SP, InlineRelocs);
}
-void objdump::printRelocations(const ObjectFile *Obj) {
- StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
- "%08" PRIx64;
+void Dumper::printRelocations() {
+ StringRef Fmt = O.getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
// Build a mapping from relocation target to a vector of relocation
// sections. Usually, there is an only one relocation section for
// each relocated section.
MapVector<SectionRef, std::vector<SectionRef>> SecToRelSec;
uint64_t Ndx;
- for (const SectionRef &Section : ToolSectionFilter(*Obj, &Ndx)) {
- if (Obj->isELF() && (ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC))
+ for (const SectionRef &Section : ToolSectionFilter(O, &Ndx)) {
+ if (O.isELF() && (ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC))
continue;
if (Section.relocation_begin() == Section.relocation_end())
continue;
Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
if (!SecOrErr)
- reportError(Obj->getFileName(),
+ reportError(O.getFileName(),
"section (" + Twine(Ndx) +
"): unable to get a relocation target: " +
toString(SecOrErr.takeError()));
@@ -2192,9 +2200,9 @@ void objdump::printRelocations(const ObjectFile *Obj) {
}
for (std::pair<SectionRef, std::vector<SectionRef>> &P : SecToRelSec) {
- StringRef SecName = unwrapOrError(P.first.getName(), Obj->getFileName());
+ StringRef SecName = unwrapOrError(P.first.getName(), O.getFileName());
outs() << "\nRELOCATION RECORDS FOR [" << SecName << "]:\n";
- uint32_t OffsetPadding = (Obj->getBytesInAddress() > 4 ? 16 : 8);
+ uint32_t OffsetPadding = (O.getBytesInAddress() > 4 ? 16 : 8);
uint32_t TypePadding = 24;
outs() << left_justify("OFFSET", OffsetPadding) << " "
<< left_justify("TYPE", TypePadding) << " "
@@ -2209,7 +2217,7 @@ void objdump::printRelocations(const ObjectFile *Obj) {
continue;
Reloc.getTypeName(RelocName);
if (Error E = getRelocationValueString(Reloc, ValueStr))
- reportError(std::move(E), Obj->getFileName());
+ reportUniqueWarning(std::move(E));
outs() << format(Fmt.data(), Address) << " "
<< left_justify(RelocName, TypePadding) << " " << ValueStr
@@ -2374,8 +2382,8 @@ void objdump::printSectionContents(const ObjectFile *Obj) {
}
}
-void objdump::printSymbolTable(const ObjectFile &O, StringRef ArchiveName,
- StringRef ArchitectureName, bool DumpDynamic) {
+void Dumper::printSymbolTable(StringRef ArchiveName, StringRef ArchitectureName,
+ bool DumpDynamic) {
if (O.isCOFF() && !DumpDynamic) {
outs() << "\nSYMBOL TABLE:\n";
printCOFFSymbolTable(cast<const COFFObjectFile>(O));
@@ -2387,8 +2395,7 @@ void objdump::printSymbolTable(const ObjectFile &O, StringRef ArchiveName,
if (!DumpDynamic) {
outs() << "\nSYMBOL TABLE:\n";
for (auto I = O.symbol_begin(); I != O.symbol_end(); ++I)
- printSymbol(O, *I, {}, FileName, ArchiveName, ArchitectureName,
- DumpDynamic);
+ printSymbol(*I, {}, FileName, ArchiveName, ArchitectureName, DumpDynamic);
return;
}
@@ -2410,17 +2417,21 @@ void objdump::printSymbolTable(const ObjectFile &O, StringRef ArchiveName,
(void)!SymbolVersionsOrErr;
}
for (auto &Sym : Symbols)
- printSymbol(O, Sym, *SymbolVersionsOrErr, FileName, ArchiveName,
+ printSymbol(Sym, *SymbolVersionsOrErr, FileName, ArchiveName,
ArchitectureName, DumpDynamic);
}
-void objdump::printSymbol(const ObjectFile &O, const SymbolRef &Symbol,
- ArrayRef<VersionEntry> SymbolVersions,
- StringRef FileName, StringRef ArchiveName,
- StringRef ArchitectureName, bool DumpDynamic) {
+void Dumper::printSymbol(const SymbolRef &Symbol,
+ ArrayRef<VersionEntry> SymbolVersions,
+ StringRef FileName, StringRef ArchiveName,
+ StringRef ArchitectureName, bool DumpDynamic) {
const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(&O);
- uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName, ArchiveName,
- ArchitectureName);
+ Expected<uint64_t> AddrOrErr = Symbol.getAddress();
+ if (!AddrOrErr) {
+ reportUniqueWarning(AddrOrErr.takeError());
+ return;
+ }
+ uint64_t Address = *AddrOrErr;
if ((Address < StartAddress) || (Address > StopAddress))
return;
SymbolRef::Type Type =
@@ -2806,6 +2817,8 @@ static void checkForInvalidStartStopAddress(ObjectFile *Obj,
static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
const Archive::Child *C = nullptr) {
+ Dumper D(*O);
+
// Avoid other output when using a raw option.
if (!RawClangAST) {
outs() << '\n';
@@ -2819,6 +2832,9 @@ static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
if (HasStartAddressFlag || HasStopAddressFlag)
checkForInvalidStartStopAddress(O, StartAddress, StopAddress);
+ // TODO: Change print* free functions to Dumper member functions to utilitize
+ // stateful functions like reportUniqueWarning.
+
// Note: the order here matches GNU objdump for compatability.
StringRef ArchiveName = A ? A->getFileName() : "";
if (ArchiveHeaders && !MachOOpt && C)
@@ -2830,10 +2846,10 @@ static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
if (SectionHeaders)
printSectionHeaders(*O);
if (SymbolTable)
- printSymbolTable(*O, ArchiveName);
+ D.printSymbolTable(ArchiveName);
if (DynamicSymbolTable)
- printSymbolTable(*O, ArchiveName, /*ArchitectureName=*/"",
- /*DumpDynamic=*/true);
+ D.printSymbolTable(ArchiveName, /*ArchitectureName=*/"",
+ /*DumpDynamic=*/true);
if (DwarfDumpType != DIDT_Null) {
std::unique_ptr<DIContext> DICtx = DWARFContext::create(*O);
// Dump the complete DWARF structure.
@@ -2842,7 +2858,7 @@ static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
DICtx->dump(outs(), DumpOpts);
}
if (Relocations && !Disassemble)
- printRelocations(O);
+ D.printRelocations();
if (DynamicRelocations)
printDynamicRelocations(O);
if (SectionContents)
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.h b/llvm/tools/llvm-objdump/llvm-objdump.h
index 7acd892..ffc1361 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.h
+++ b/llvm/tools/llvm-objdump/llvm-objdump.h
@@ -65,6 +65,26 @@ extern bool UnwindInfo;
extern StringSet<> FoundSectionSet;
+class Dumper {
+ const object::ObjectFile &O;
+ StringSet<> Warnings;
+
+public:
+ Dumper(const object::ObjectFile &O) : O(O) {}
+
+ void reportUniqueWarning(Error Err);
+ void reportUniqueWarning(const Twine &Msg);
+
+ void printSymbolTable(StringRef ArchiveName,
+ StringRef ArchitectureName = StringRef(),
+ bool DumpDynamic = false);
+ void printSymbol(const object::SymbolRef &Symbol,
+ ArrayRef<object::VersionEntry> SymbolVersions,
+ StringRef FileName, StringRef ArchiveName,
+ StringRef ArchitectureName, bool DumpDynamic);
+ void printRelocations();
+};
+
// Various helper functions.
/// Creates a SectionFilter with a standard predicate that conditionally skips
@@ -77,17 +97,9 @@ object::SectionFilter ToolSectionFilter(const llvm::object::ObjectFile &O,
uint64_t *Idx = nullptr);
bool isRelocAddressLess(object::RelocationRef A, object::RelocationRef B);
-void printRelocations(const object::ObjectFile *O);
void printDynamicRelocations(const object::ObjectFile *O);
void printSectionHeaders(object::ObjectFile &O);
void printSectionContents(const object::ObjectFile *O);
-void printSymbolTable(const object::ObjectFile &O, StringRef ArchiveName,
- StringRef ArchitectureName = StringRef(),
- bool DumpDynamic = false);
-void printSymbol(const object::ObjectFile &O, const object::SymbolRef &Symbol,
- ArrayRef<object::VersionEntry> SymbolVersions,
- StringRef FileName, StringRef ArchiveName,
- StringRef ArchitectureName, bool DumpDynamic);
[[noreturn]] void reportError(StringRef File, const Twine &Message);
[[noreturn]] void reportError(Error E, StringRef FileName,
StringRef ArchiveName = "",