diff options
Diffstat (limited to 'contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp')
-rw-r--r-- | contrib/llvm/tools/llvm-objdump/llvm-objdump.cpp | 383 |
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; } |