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 d5ae5de4b5a3..ed55c918b58a 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;    } | 
