summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2016-12-26 20:36:37 +0000
committerdim <dim@FreeBSD.org>2016-12-26 20:36:37 +0000
commit06210ae42d418d50d8d9365d5c9419308ae9e7ee (patch)
treeab60b4cdd6e430dda1f292a46a77ddb744723f31 /contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
parent2dd166267f53df1c3748b4325d294b9b839de74b (diff)
downloadFreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.zip
FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.tar.gz
MFC r309124:
Upgrade our copies of clang, llvm, lldb, compiler-rt and libc++ to 3.9.0 release, and add lld 3.9.0. Also completely revamp the build system for clang, llvm, lldb and their related tools. Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11 support to build; see UPDATING for more information. Release notes for llvm, clang and lld are available here: <http://llvm.org/releases/3.9.0/docs/ReleaseNotes.html> <http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html> <http://llvm.org/releases/3.9.0/tools/lld/docs/ReleaseNotes.html> Thanks to Ed Maste, Bryan Drewery, Andrew Turner, Antoine Brodin and Jan Beich for their help. Relnotes: yes MFC r309147: Pull in r282174 from upstream llvm trunk (by Krzysztof Parzyszek): [PPC] Set SP after loading data from stack frame, if no red zone is present Follow-up to r280705: Make sure that the SP is only restored after all data is loaded from the stack frame, if there is no red zone. This completes the fix for https://llvm.org/bugs/show_bug.cgi?id=26519. Differential Revision: https://reviews.llvm.org/D24466 Reported by: Mark Millard PR: 214433 MFC r309149: Pull in r283060 from upstream llvm trunk (by Hal Finkel): [PowerPC] Refactor soft-float support, and enable PPC64 soft float This change enables soft-float for PowerPC64, and also makes soft-float disable all vector instruction sets for both 32-bit and 64-bit modes. This latter part is necessary because the PPC backend canonicalizes many Altivec vector types to floating-point types, and so soft-float breaks scalarization support for many operations. Both for embedded targets and for operating-system kernels desiring soft-float support, it seems reasonable that disabling hardware floating-point also disables vector instructions (embedded targets without hardware floating point support are unlikely to have Altivec, etc. and operating system kernels desiring not to use floating-point registers to lower syscall cost are unlikely to want to use vector registers either). If someone needs this to work, we'll need to change the fact that we promote many Altivec operations to act on v4f32. To make it possible to disable Altivec when soft-float is enabled, hardware floating-point support needs to be expressed as a positive feature, like the others, and not a negative feature, because target features cannot have dependencies on the disabling of some other feature. So +soft-float has now become -hard-float. Fixes PR26970. Pull in r283061 from upstream clang trunk (by Hal Finkel): [PowerPC] Enable soft-float for PPC64, and +soft-float -> -hard-float Enable soft-float support on PPC64, as the backend now supports it. Also, the backend now uses -hard-float instead of +soft-float, so set the target features accordingly. Fixes PR26970. Reported by: Mark Millard PR: 214433 MFC r309212: Add a few missed clang 3.9.0 files to OptionalObsoleteFiles. MFC r309262: Fix packaging for clang, lldb and lld 3.9.0 During the upgrade of clang/llvm etc to 3.9.0 in r309124, the PACKAGE directive in the usr.bin/clang/*.mk files got dropped accidentally. Restore it, with a few minor changes and additions: * Correct license in clang.ucl to NCSA * Add PACKAGE=clang for clang and most of the "ll" tools * Put lldb in its own package * Put lld in its own package Reviewed by: gjb, jmallett Differential Revision: https://reviews.freebsd.org/D8666 MFC r309656: During the bootstrap phase, when building the minimal llvm library on PowerPC, add lib/Support/Atomic.cpp. This is needed because upstream llvm revision r271821 disabled the use of std::call_once, which causes some fallback functions from Atomic.cpp to be used instead. Reported by: Mark Millard PR: 214902 MFC r309835: Tentatively apply https://reviews.llvm.org/D18730 to work around gcc PR 70528 (bogus error: constructor required before non-static data member). This should fix buildworld with the external gcc package. Reported by: https://jenkins.freebsd.org/job/FreeBSD_HEAD_amd64_gcc/ MFC r310194: Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to 3.9.1 release. Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11 support to build; see UPDATING for more information. Release notes for llvm, clang and lld will be available here: <http://releases.llvm.org/3.9.1/docs/ReleaseNotes.html> <http://releases.llvm.org/3.9.1/tools/clang/docs/ReleaseNotes.html> <http://releases.llvm.org/3.9.1/tools/lld/docs/ReleaseNotes.html> Relnotes: yes
Diffstat (limited to 'contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r--contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp383
1 files changed, 262 insertions, 121 deletions
diff --git a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
index d5ae5de..ed55c91 100644
--- a/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -22,20 +22,21 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/CodeGen/FaultMaps.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCDisassembler.h"
+#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCRelocationInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Object/Archive.h"
-#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Casting.h"
@@ -58,6 +59,7 @@
#include <cctype>
#include <cstring>
#include <system_error>
+#include <utility>
using namespace llvm;
using namespace object;
@@ -181,6 +183,11 @@ cl::opt<bool>
cl::opt<bool> PrintFaultMaps("fault-map-section",
cl::desc("Display contents of faultmap section"));
+cl::opt<DIDumpType> llvm::DwarfDumpType(
+ "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
+ cl::values(clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
+ clEnumValEnd));
+
static StringRef ToolName;
namespace {
@@ -191,7 +198,7 @@ public:
SectionFilterIterator(FilterPredicate P,
llvm::object::section_iterator const &I,
llvm::object::section_iterator const &E)
- : Predicate(P), Iterator(I), End(E) {
+ : Predicate(std::move(P)), Iterator(I), End(E) {
ScanPredicate();
}
const llvm::object::SectionRef &operator*() const { return *Iterator; }
@@ -218,7 +225,7 @@ private:
class SectionFilter {
public:
SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O)
- : Predicate(P), Object(O) {}
+ : Predicate(std::move(P)), Object(O) {}
SectionFilterIterator begin() {
return SectionFilterIterator(Predicate, Object.section_begin(),
Object.section_end());
@@ -257,6 +264,12 @@ void llvm::error(std::error_code EC) {
exit(1);
}
+LLVM_ATTRIBUTE_NORETURN void llvm::error(Twine Message) {
+ errs() << ToolName << ": " << Message << ".\n";
+ errs().flush();
+ exit(1);
+}
+
LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
std::error_code EC) {
assert(EC);
@@ -264,6 +277,52 @@ LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
exit(1);
}
+LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
+ llvm::Error E) {
+ assert(E);
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(std::move(E), OS, "");
+ OS.flush();
+ errs() << ToolName << ": '" << File << "': " << Buf;
+ exit(1);
+}
+
+LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
+ StringRef FileName,
+ llvm::Error E,
+ StringRef ArchitectureName) {
+ assert(E);
+ errs() << ToolName << ": ";
+ if (ArchiveName != "")
+ errs() << ArchiveName << "(" << FileName << ")";
+ else
+ errs() << FileName;
+ if (!ArchitectureName.empty())
+ errs() << " (for architecture " << ArchitectureName << ")";
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(std::move(E), OS, "");
+ OS.flush();
+ errs() << " " << Buf;
+ exit(1);
+}
+
+LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
+ const object::Archive::Child &C,
+ llvm::Error E,
+ StringRef ArchitectureName) {
+ ErrorOr<StringRef> NameOrErr = C.getName();
+ // TODO: if we have a error getting the name then it would be nice to print
+ // the index of which archive member this is and or its offset in the
+ // archive instead of "???" as the name.
+ if (NameOrErr.getError())
+ llvm::report_error(ArchiveName, "???", std::move(E), ArchitectureName);
+ else
+ llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E),
+ ArchitectureName);
+}
+
static const Target *getTarget(const ObjectFile *Obj = nullptr) {
// Figure out the target triple.
llvm::Triple TheTriple("unknown-unknown-unknown");
@@ -308,12 +367,15 @@ public:
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &OS, StringRef Annot,
MCSubtargetInfo const &STI) {
- outs() << format("%8" PRIx64 ":", Address);
+ OS << format("%8" PRIx64 ":", Address);
if (!NoShowRawInsn) {
- outs() << "\t";
- dumpBytes(Bytes, outs());
+ OS << "\t";
+ dumpBytes(Bytes, OS);
}
- IP.printInst(MI, outs(), "", STI);
+ if (MI)
+ IP.printInst(MI, OS, "", STI);
+ else
+ OS << " <unknown>";
}
};
PrettyPrinter PrettyPrinterInst;
@@ -334,6 +396,11 @@ public:
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &OS, StringRef Annot,
MCSubtargetInfo const &STI) override {
+ if (!MI) {
+ printLead(Bytes, Address, OS);
+ OS << " <unknown>";
+ return;
+ }
std::string Buffer;
{
raw_string_ostream TempStream(Buffer);
@@ -370,12 +437,48 @@ public:
}
};
HexagonPrettyPrinter HexagonPrettyPrinterInst;
+
+class AMDGCNPrettyPrinter : public PrettyPrinter {
+public:
+ void printInst(MCInstPrinter &IP,
+ const MCInst *MI,
+ ArrayRef<uint8_t> Bytes,
+ uint64_t Address,
+ raw_ostream &OS,
+ StringRef Annot,
+ MCSubtargetInfo const &STI) override {
+ if (!MI) {
+ OS << " <unknown>";
+ return;
+ }
+
+ SmallString<40> InstStr;
+ raw_svector_ostream IS(InstStr);
+
+ IP.printInst(MI, IS, "", STI);
+
+ OS << left_justify(IS.str(), 60) << format("// %012" PRIX64 ": ", Address);
+ typedef support::ulittle32_t U32;
+ for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
+ Bytes.size() / sizeof(U32)))
+ // D should be explicitly casted to uint32_t here as it is passed
+ // by format to snprintf as vararg.
+ OS << format("%08" PRIX32 " ", static_cast<uint32_t>(D));
+
+ if (!Annot.empty())
+ OS << "// " << Annot;
+ }
+};
+AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
+
PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
switch(Triple.getArch()) {
default:
return PrettyPrinterInst;
case Triple::hexagon:
return HexagonPrettyPrinterInst;
+ case Triple::amdgcn:
+ return AMDGCNPrettyPrinterInst;
}
}
}
@@ -429,18 +532,18 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
const Elf_Sym *symb = Obj->getSymbol(SI->getRawDataRefImpl());
StringRef Target;
if (symb->getType() == ELF::STT_SECTION) {
- ErrorOr<section_iterator> SymSI = SI->getSection();
- if (std::error_code EC = SymSI.getError())
- return EC;
+ Expected<section_iterator> SymSI = SI->getSection();
+ if (!SymSI)
+ return errorToErrorCode(SymSI.takeError());
const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
ErrorOr<StringRef> SecName = EF.getSectionName(SymSec);
if (std::error_code EC = SecName.getError())
return EC;
Target = *SecName;
} else {
- ErrorOr<StringRef> SymName = symb->getName(StrTab);
+ Expected<StringRef> SymName = symb->getName(StrTab);
if (!SymName)
- return SymName.getError();
+ return errorToErrorCode(SymName.takeError());
Target = *SymName;
}
switch (EF.getHeader()->e_machine) {
@@ -470,6 +573,7 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
res = "Unknown";
}
break;
+ case ELF::EM_LANAI:
case ELF::EM_AARCH64: {
std::string fmtbuf;
raw_string_ostream fmt(fmtbuf);
@@ -485,6 +589,7 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
case ELF::EM_ARM:
case ELF::EM_HEXAGON:
case ELF::EM_MIPS:
+ case ELF::EM_BPF:
res = Target;
break;
case ELF::EM_WEBASSEMBLY:
@@ -529,9 +634,9 @@ static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
const RelocationRef &Rel,
SmallVectorImpl<char> &Result) {
symbol_iterator SymI = Rel.getSymbol();
- ErrorOr<StringRef> SymNameOrErr = SymI->getName();
- if (std::error_code EC = SymNameOrErr.getError())
- return EC;
+ Expected<StringRef> SymNameOrErr = SymI->getName();
+ if (!SymNameOrErr)
+ return errorToErrorCode(SymNameOrErr.takeError());
StringRef SymName = *SymNameOrErr;
Result.append(SymName.begin(), SymName.end());
return std::error_code();
@@ -551,14 +656,24 @@ static void printRelocationTargetName(const MachOObjectFile *O,
for (const SymbolRef &Symbol : O->symbols()) {
std::error_code ec;
- ErrorOr<uint64_t> Addr = Symbol.getAddress();
- if ((ec = Addr.getError()))
- report_fatal_error(ec.message());
+ Expected<uint64_t> Addr = Symbol.getAddress();
+ if (!Addr) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(Addr.takeError(), OS, "");
+ OS.flush();
+ report_fatal_error(Buf);
+ }
if (*Addr != Val)
continue;
- ErrorOr<StringRef> Name = Symbol.getName();
- if (std::error_code EC = Name.getError())
- report_fatal_error(EC.message());
+ Expected<StringRef> Name = Symbol.getName();
+ if (!Name) {
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(Name.takeError(), OS, "");
+ OS.flush();
+ report_fatal_error(Buf);
+ }
fmt << *Name;
return;
}
@@ -589,8 +704,8 @@ static void printRelocationTargetName(const MachOObjectFile *O,
if (isExtern) {
symbol_iterator SI = O->symbol_begin();
advance(SI, Val);
- ErrorOr<StringRef> SOrErr = SI->getName();
- error(SOrErr.getError());
+ Expected<StringRef> SOrErr = SI->getName();
+ error(errorToErrorCode(SOrErr.takeError()));
S = *SOrErr;
} else {
section_iterator SI = O->section_begin();
@@ -828,12 +943,10 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
const Target *TheTarget = getTarget(Obj);
// Package up features to be passed to target/subtarget
- std::string FeaturesStr;
+ SubtargetFeatures Features = Obj->getFeatures();
if (MAttrs.size()) {
- SubtargetFeatures Features;
for (unsigned i = 0; i != MAttrs.size(); ++i)
Features.AddFeature(MAttrs[i]);
- FeaturesStr = Features.getString();
}
std::unique_ptr<const MCRegisterInfo> MRI(
@@ -847,7 +960,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (!AsmInfo)
report_fatal_error("error: no assembly info for target " + TripleName);
std::unique_ptr<const MCSubtargetInfo> STI(
- TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
+ TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
if (!STI)
report_fatal_error("error: no subtarget info for target " + TripleName);
std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
@@ -891,17 +1004,17 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
typedef std::vector<std::pair<uint64_t, StringRef>> SectionSymbolsTy;
std::map<SectionRef, SectionSymbolsTy> AllSymbols;
for (const SymbolRef &Symbol : Obj->symbols()) {
- ErrorOr<uint64_t> AddressOrErr = Symbol.getAddress();
- error(AddressOrErr.getError());
+ Expected<uint64_t> AddressOrErr = Symbol.getAddress();
+ error(errorToErrorCode(AddressOrErr.takeError()));
uint64_t Address = *AddressOrErr;
- ErrorOr<StringRef> Name = Symbol.getName();
- error(Name.getError());
+ Expected<StringRef> Name = Symbol.getName();
+ error(errorToErrorCode(Name.takeError()));
if (Name->empty())
continue;
- ErrorOr<section_iterator> SectionOrErr = Symbol.getSection();
- error(SectionOrErr.getError());
+ Expected<section_iterator> SectionOrErr = Symbol.getSection();
+ error(errorToErrorCode(SectionOrErr.takeError()));
section_iterator SecI = *SectionOrErr;
if (SecI == Obj->section_end())
continue;
@@ -1031,6 +1144,18 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (Start >= End)
continue;
+ if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
+ // make size 4 bytes folded
+ End = Start + ((End - Start) & ~0x3ull);
+ Start += 256; // add sizeof(amd_kernel_code_t)
+ // cut trailing zeroes - up to 256 bytes (align)
+ const uint64_t EndAlign = 256;
+ const auto Limit = End - (std::min)(EndAlign, End - Start);
+ while (End > Limit &&
+ *reinterpret_cast<const support::ulittle32_t*>(&Bytes[End - 4]) == 0)
+ End -= 4;
+ }
+
outs() << '\n' << Symbols[si].second << ":\n";
#ifndef NDEBUG
@@ -1081,72 +1206,69 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (Index >= End)
break;
- if (DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
- SectionAddr + Index, DebugOut,
- CommentStream)) {
- PIP.printInst(*IP, &Inst,
- Bytes.slice(Index, Size),
- SectionAddr + Index, outs(), "", *STI);
- outs() << CommentStream.str();
- Comments.clear();
-
- // Try to resolve the target of a call, tail call, etc. to a specific
- // symbol.
- if (MIA && (MIA->isCall(Inst) || MIA->isUnconditionalBranch(Inst) ||
- MIA->isConditionalBranch(Inst))) {
- uint64_t Target;
- if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
- // In a relocatable object, the target's section must reside in
- // the same section as the call instruction or it is accessed
- // through a relocation.
- //
- // In a non-relocatable object, the target may be in any section.
- //
- // N.B. We don't walk the relocations in the relocatable case yet.
- auto *TargetSectionSymbols = &Symbols;
- if (!Obj->isRelocatableObject()) {
- auto SectionAddress = std::upper_bound(
- SectionAddresses.begin(), SectionAddresses.end(), Target,
- [](uint64_t LHS,
- const std::pair<uint64_t, SectionRef> &RHS) {
- return LHS < RHS.first;
- });
- if (SectionAddress != SectionAddresses.begin()) {
- --SectionAddress;
- TargetSectionSymbols = &AllSymbols[SectionAddress->second];
- } else {
- TargetSectionSymbols = nullptr;
- }
+ bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
+ SectionAddr + Index, DebugOut,
+ CommentStream);
+ if (Size == 0)
+ Size = 1;
+ PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
+ Bytes.slice(Index, Size),
+ SectionAddr + Index, outs(), "", *STI);
+ outs() << CommentStream.str();
+ Comments.clear();
+
+ // Try to resolve the target of a call, tail call, etc. to a specific
+ // symbol.
+ if (MIA && (MIA->isCall(Inst) || MIA->isUnconditionalBranch(Inst) ||
+ MIA->isConditionalBranch(Inst))) {
+ uint64_t Target;
+ if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
+ // In a relocatable object, the target's section must reside in
+ // the same section as the call instruction or it is accessed
+ // through a relocation.
+ //
+ // In a non-relocatable object, the target may be in any section.
+ //
+ // N.B. We don't walk the relocations in the relocatable case yet.
+ auto *TargetSectionSymbols = &Symbols;
+ if (!Obj->isRelocatableObject()) {
+ auto SectionAddress = std::upper_bound(
+ SectionAddresses.begin(), SectionAddresses.end(), Target,
+ [](uint64_t LHS,
+ const std::pair<uint64_t, SectionRef> &RHS) {
+ return LHS < RHS.first;
+ });
+ if (SectionAddress != SectionAddresses.begin()) {
+ --SectionAddress;
+ TargetSectionSymbols = &AllSymbols[SectionAddress->second];
+ } else {
+ TargetSectionSymbols = nullptr;
}
+ }
- // Find the first symbol in the section whose offset is less than
- // or equal to the target.
- if (TargetSectionSymbols) {
- auto TargetSym = std::upper_bound(
- TargetSectionSymbols->begin(), TargetSectionSymbols->end(),
- Target, [](uint64_t LHS,
- const std::pair<uint64_t, StringRef> &RHS) {
- return LHS < RHS.first;
- });
- if (TargetSym != TargetSectionSymbols->begin()) {
- --TargetSym;
- uint64_t TargetAddress = std::get<0>(*TargetSym);
- StringRef TargetName = std::get<1>(*TargetSym);
- outs() << " <" << TargetName;
- uint64_t Disp = Target - TargetAddress;
- if (Disp)
- outs() << '+' << utohexstr(Disp);
- outs() << '>';
- }
+ // Find the first symbol in the section whose offset is less than
+ // or equal to the target.
+ if (TargetSectionSymbols) {
+ auto TargetSym = std::upper_bound(
+ TargetSectionSymbols->begin(), TargetSectionSymbols->end(),
+ Target, [](uint64_t LHS,
+ const std::pair<uint64_t, StringRef> &RHS) {
+ return LHS < RHS.first;
+ });
+ if (TargetSym != TargetSectionSymbols->begin()) {
+ --TargetSym;
+ uint64_t TargetAddress = std::get<0>(*TargetSym);
+ StringRef TargetName = std::get<1>(*TargetSym);
+ outs() << " <" << TargetName;
+ uint64_t Disp = Target - TargetAddress;
+ if (Disp)
+ outs() << "+0x" << utohexstr(Disp);
+ outs() << '>';
}
}
}
- outs() << "\n";
- } else {
- errs() << ToolName << ": warning: invalid instruction encoding\n";
- if (Size == 0)
- Size = 1; // skip illegible bytes
}
+ outs() << "\n";
// Print relocation for instruction.
while (rel_cur != rel_end) {
@@ -1270,7 +1392,8 @@ void llvm::PrintSectionContents(const ObjectFile *Obj) {
}
}
-void llvm::PrintSymbolTable(const ObjectFile *o) {
+void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName,
+ StringRef ArchitectureName) {
outs() << "SYMBOL TABLE:\n";
if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) {
@@ -1278,20 +1401,26 @@ void llvm::PrintSymbolTable(const ObjectFile *o) {
return;
}
for (const SymbolRef &Symbol : o->symbols()) {
- ErrorOr<uint64_t> AddressOrError = Symbol.getAddress();
- error(AddressOrError.getError());
+ Expected<uint64_t> AddressOrError = Symbol.getAddress();
+ if (!AddressOrError)
+ report_error(ArchiveName, o->getFileName(), AddressOrError.takeError());
uint64_t Address = *AddressOrError;
- SymbolRef::Type Type = Symbol.getType();
+ Expected<SymbolRef::Type> TypeOrError = Symbol.getType();
+ if (!TypeOrError)
+ report_error(ArchiveName, o->getFileName(), TypeOrError.takeError());
+ SymbolRef::Type Type = *TypeOrError;
uint32_t Flags = Symbol.getFlags();
- ErrorOr<section_iterator> SectionOrErr = Symbol.getSection();
- error(SectionOrErr.getError());
+ Expected<section_iterator> SectionOrErr = Symbol.getSection();
+ error(errorToErrorCode(SectionOrErr.takeError()));
section_iterator Section = *SectionOrErr;
StringRef Name;
if (Type == SymbolRef::ST_Debug && Section != o->section_end()) {
Section->getName(Name);
} else {
- ErrorOr<StringRef> NameOrErr = Symbol.getName();
- error(NameOrErr.getError());
+ Expected<StringRef> NameOrErr = Symbol.getName();
+ if (!NameOrErr)
+ report_error(ArchiveName, o->getFileName(), NameOrErr.takeError(),
+ ArchitectureName);
Name = *NameOrErr;
}
@@ -1523,12 +1652,16 @@ static void printFirstPrivateFileHeader(const ObjectFile *o) {
report_fatal_error("Invalid/Unsupported object file format");
}
-static void DumpObject(const ObjectFile *o) {
+static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
+ StringRef ArchiveName = a != nullptr ? a->getFileName() : "";
// Avoid other output when using a raw option.
if (!RawClangAST) {
outs() << '\n';
- outs() << o->getFileName()
- << ":\tfile format " << o->getFileFormatName() << "\n\n";
+ if (a)
+ outs() << a->getFileName() << "(" << o->getFileName() << ")";
+ else
+ outs() << o->getFileName();
+ outs() << ":\tfile format " << o->getFileFormatName() << "\n\n";
}
if (Disassemble)
@@ -1540,7 +1673,7 @@ static void DumpObject(const ObjectFile *o) {
if (SectionContents)
PrintSectionContents(o);
if (SymbolTable)
- PrintSymbolTable(o);
+ PrintSymbolTable(o, ArchiveName);
if (UnwindInfo)
PrintUnwindInfo(o);
if (PrivateHeaders)
@@ -1561,23 +1694,30 @@ static void DumpObject(const ObjectFile *o) {
printRawClangAST(o);
if (PrintFaultMaps)
printFaultMaps(o);
+ if (DwarfDumpType != DIDT_Null) {
+ std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*o));
+ // Dump the complete DWARF structure.
+ DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
+ }
}
/// @brief Dump each object file in \a a;
static void DumpArchive(const Archive *a) {
- for (auto &ErrorOrChild : a->children()) {
- if (std::error_code EC = ErrorOrChild.getError())
- report_error(a->getFileName(), EC);
- const Archive::Child &C = *ErrorOrChild;
- ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
- if (std::error_code EC = ChildOrErr.getError())
- if (EC != object_error::invalid_file_type)
- report_error(a->getFileName(), EC);
+ Error Err;
+ for (auto &C : a->children(Err)) {
+ Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
+ if (!ChildOrErr) {
+ if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
+ report_error(a->getFileName(), C, std::move(E));
+ continue;
+ }
if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
- DumpObject(o);
+ DumpObject(o, a);
else
report_error(a->getFileName(), object_error::invalid_file_type);
}
+ if (Err)
+ report_error(a->getFileName(), std::move(Err));
}
/// @brief Open file and figure out how to dump it.
@@ -1592,9 +1732,9 @@ static void DumpInput(StringRef file) {
}
// Attempt to open the binary.
- ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
- if (std::error_code EC = BinaryOrErr.getError())
- report_error(file, EC);
+ Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
+ if (!BinaryOrErr)
+ report_error(file, BinaryOrErr.takeError());
Binary &Binary = *BinaryOrErr.get().getBinary();
if (Archive *a = dyn_cast<Archive>(&Binary))
@@ -1607,7 +1747,7 @@ static void DumpInput(StringRef file) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
- sys::PrintStackTraceOnErrorSignal();
+ sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
@@ -1654,7 +1794,8 @@ int main(int argc, char **argv) {
&& !(DylibId && MachOOpt)
&& !(ObjcMetaData && MachOOpt)
&& !(FilterSections.size() != 0 && MachOOpt)
- && !PrintFaultMaps) {
+ && !PrintFaultMaps
+ && DwarfDumpType == DIDT_Null) {
cl::PrintHelpMessage();
return 2;
}
OpenPOWER on IntegriCloud