//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This program is a utility that works like traditional Unix "nm", that is, it
// prints out the names of symbols in a bitcode or object file, along with some
// information about each symbol.
//
// This "nm" supports many of the features of GNU "nm", including its different
// output formats.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/TapiFile.h"
#include "llvm/Object/TapiUniversal.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <vector>

using namespace llvm;
using namespace object;

namespace {
enum OutputFormatTy { bsd, sysv, posix, darwin };

cl::OptionCategory NMCat("llvm-nm Options");

cl::opt<OutputFormatTy> OutputFormat(
    "format", cl::desc("Specify output format"),
    cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"),
               clEnumVal(posix, "POSIX.2 format"),
               clEnumVal(darwin, "Darwin -m format")),
    cl::init(bsd), cl::cat(NMCat));
cl::alias OutputFormat2("f", cl::desc("Alias for --format"),
                        cl::aliasopt(OutputFormat));

cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
                                     cl::ZeroOrMore);

cl::opt<bool> UndefinedOnly("undefined-only",
                            cl::desc("Show only undefined symbols"),
                            cl::cat(NMCat));
cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"),
                         cl::aliasopt(UndefinedOnly), cl::Grouping);

cl::opt<bool> DynamicSyms("dynamic",
                          cl::desc("Display the dynamic symbols instead "
                                   "of normal symbols."),
                          cl::cat(NMCat));
cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"),
                       cl::aliasopt(DynamicSyms), cl::Grouping);

cl::opt<bool> DefinedOnly("defined-only", cl::desc("Show only defined symbols"),
                          cl::cat(NMCat));
cl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"),
                       cl::aliasopt(DefinedOnly), cl::Grouping);

cl::opt<bool> ExternalOnly("extern-only",
                           cl::desc("Show only external symbols"),
                           cl::ZeroOrMore, cl::cat(NMCat));
cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"),
                        cl::aliasopt(ExternalOnly), cl::Grouping,
                        cl::ZeroOrMore);

cl::opt<bool> NoWeakSymbols("no-weak", cl::desc("Show only non-weak symbols"),
                            cl::cat(NMCat));
cl::alias NoWeakSymbols2("W", cl::desc("Alias for --no-weak"),
                         cl::aliasopt(NoWeakSymbols), cl::Grouping);

cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"), cl::Grouping,
                        cl::cat(NMCat));
cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"),
                          cl::Grouping, cl::cat(NMCat));
cl::alias Portability("portability", cl::desc("Alias for --format=posix"),
                      cl::aliasopt(POSIXFormat), cl::NotHidden);
cl::opt<bool> DarwinFormat("m", cl::desc("Alias for --format=darwin"),
                           cl::Grouping, cl::cat(NMCat));

static cl::list<std::string>
    ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
              cl::ZeroOrMore, cl::cat(NMCat));
bool ArchAll = false;

cl::opt<bool> PrintFileName(
    "print-file-name",
    cl::desc("Precede each symbol with the object file it came from"),
    cl::cat(NMCat));

cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"),
                         cl::aliasopt(PrintFileName), cl::Grouping);
cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"),
                         cl::aliasopt(PrintFileName), cl::Grouping);

cl::opt<bool> DebugSyms("debug-syms",
                        cl::desc("Show all symbols, even debugger only"),
                        cl::cat(NMCat));
cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"),
                     cl::aliasopt(DebugSyms), cl::Grouping);

cl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address"),
                          cl::cat(NMCat));
cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"),
                       cl::aliasopt(NumericSort), cl::Grouping);
cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"),
                       cl::aliasopt(NumericSort), cl::Grouping);

cl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered"),
                     cl::cat(NMCat));
cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort),
                  cl::Grouping);

cl::opt<bool> Demangle("demangle", cl::ZeroOrMore,
                       cl::desc("Demangle C++ symbol names"), cl::cat(NMCat));
cl::alias DemangleC("C", cl::desc("Alias for --demangle"),
                    cl::aliasopt(Demangle), cl::Grouping);
cl::opt<bool> NoDemangle("no-demangle", cl::init(false), cl::ZeroOrMore,
                         cl::desc("Don't demangle symbol names"),
                         cl::cat(NMCat));

cl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order"),
                          cl::cat(NMCat));
cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"),
                       cl::aliasopt(ReverseSort), cl::Grouping);

cl::opt<bool> PrintSize("print-size",
                        cl::desc("Show symbol size as well as address"),
                        cl::cat(NMCat));
cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"),
                     cl::aliasopt(PrintSize), cl::Grouping);
bool MachOPrintSizeWarning = false;

cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size"),
                       cl::cat(NMCat));

cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden,
                             cl::desc("Exclude aliases from output"),
                             cl::cat(NMCat));

cl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map"),
                         cl::cat(NMCat));
cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"),
                      cl::aliasopt(ArchiveMap), cl::Grouping);

enum Radix { d, o, x };
cl::opt<Radix>
    AddressRadix("radix", cl::desc("Radix (o/d/x) for printing symbol Values"),
                 cl::values(clEnumVal(d, "decimal"), clEnumVal(o, "octal"),
                            clEnumVal(x, "hexadecimal")),
                 cl::init(x), cl::cat(NMCat));
cl::alias RadixAlias("t", cl::desc("Alias for --radix"),
                     cl::aliasopt(AddressRadix));

cl::opt<bool> JustSymbolName("just-symbol-name",
                             cl::desc("Print just the symbol's name"),
                             cl::cat(NMCat));
cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"),
                          cl::aliasopt(JustSymbolName), cl::Grouping);

cl::opt<bool>
    SpecialSyms("special-syms",
                cl::desc("Do not filter special symbols from the output"),
                cl::cat(NMCat));

cl::list<std::string> SegSect("s", cl::multi_val(2), cl::ZeroOrMore,
                              cl::value_desc("segment section"), cl::Hidden,
                              cl::desc("Dump only symbols from this segment "
                                       "and section name, Mach-O only"),
                              cl::cat(NMCat));

cl::opt<bool> FormatMachOasHex("x",
                               cl::desc("Print symbol entry in hex, "
                                        "Mach-O only"),
                               cl::Grouping, cl::cat(NMCat));
cl::opt<bool> AddDyldInfo("add-dyldinfo",
                          cl::desc("Add symbols from the dyldinfo not already "
                                   "in the symbol table, Mach-O only"),
                          cl::cat(NMCat));
cl::opt<bool> NoDyldInfo("no-dyldinfo",
                         cl::desc("Don't add any symbols from the dyldinfo, "
                                  "Mach-O only"),
                         cl::cat(NMCat));
cl::opt<bool> DyldInfoOnly("dyldinfo-only",
                           cl::desc("Show only symbols from the dyldinfo, "
                                    "Mach-O only"),
                           cl::cat(NMCat));

cl::opt<bool> NoLLVMBitcode("no-llvm-bc",
                            cl::desc("Disable LLVM bitcode reader"),
                            cl::cat(NMCat));

cl::opt<bool> AddInlinedInfo("add-inlinedinfo",
                             cl::desc("Add symbols from the inlined libraries, "
                                      "TBD(Mach-O) only"),
                             cl::cat(NMCat));

cl::extrahelp HelpResponse("\nPass @FILE as argument to read options from FILE.\n");

bool PrintAddress = true;

bool MultipleFiles = false;

bool HadError = false;

std::string ToolName;
} // anonymous namespace

static void error(Twine Message, Twine Path = Twine()) {
  HadError = true;
  WithColor::error(errs(), ToolName) << Path << ": " << Message << ".\n";
}

static bool error(std::error_code EC, Twine Path = Twine()) {
  if (EC) {
    error(EC.message(), Path);
    return true;
  }
  return false;
}

// This version of error() prints the archive name and member name, for example:
// "libx.a(foo.o)" after the ToolName before the error message.  It sets
// HadError but returns allowing the code to move on to other archive members.
static void error(llvm::Error E, StringRef FileName, const Archive::Child &C,
                  StringRef ArchitectureName = StringRef()) {
  HadError = true;
  WithColor::error(errs(), ToolName) << FileName;

  Expected<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) {
    consumeError(NameOrErr.takeError());
    errs() << "(" << "???" << ")";
  } else
    errs() << "(" << NameOrErr.get() << ")";

  if (!ArchitectureName.empty())
    errs() << " (for architecture " << ArchitectureName << ") ";

  std::string Buf;
  raw_string_ostream OS(Buf);
  logAllUnhandledErrors(std::move(E), OS);
  OS.flush();
  errs() << " " << Buf << "\n";
}

// This version of error() prints the file name and which architecture slice it
// is from, for example: "foo.o (for architecture i386)" after the ToolName
// before the error message.  It sets HadError but returns allowing the code to
// move on to other architecture slices.
static void error(llvm::Error E, StringRef FileName,
                  StringRef ArchitectureName = StringRef()) {
  HadError = true;
  WithColor::error(errs(), ToolName) << 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 << "\n";
}

namespace {
struct NMSymbol {
  uint64_t Address;
  uint64_t Size;
  char TypeChar;
  std::string Name;
  StringRef SectionName;
  StringRef TypeName;
  BasicSymbolRef Sym;
  // The Sym field above points to the native symbol in the object file,
  // for Mach-O when we are creating symbols from the dyld info the above
  // pointer is null as there is no native symbol.  In these cases the fields
  // below are filled in to represent what would have been a Mach-O nlist
  // native symbol.
  uint32_t SymFlags;
  SectionRef Section;
  uint8_t NType;
  uint8_t NSect;
  uint16_t NDesc;
  std::string IndirectName;
};
} // anonymous namespace

static bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) {
  bool ADefined;
  // Symbol flags have been checked in the caller.
  if (A.Sym.getRawDataRefImpl().p) {
    uint32_t AFlags = cantFail(A.Sym.getFlags());
    ADefined = !(AFlags & SymbolRef::SF_Undefined);
  } else {
    ADefined = A.TypeChar != 'U';
  }
  bool BDefined;
  // Symbol flags have been checked in the caller.
  if (B.Sym.getRawDataRefImpl().p) {
    uint32_t BFlags = cantFail(B.Sym.getFlags());
    BDefined = !(BFlags & SymbolRef::SF_Undefined);
  } else {
    BDefined = B.TypeChar != 'U';
  }
  return std::make_tuple(ADefined, A.Address, A.Name, A.Size) <
         std::make_tuple(BDefined, B.Address, B.Name, B.Size);
}

static bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) {
  return std::make_tuple(A.Size, A.Name, A.Address) <
         std::make_tuple(B.Size, B.Name, B.Address);
}

static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) {
  return std::make_tuple(A.Name, A.Size, A.Address) <
         std::make_tuple(B.Name, B.Size, B.Address);
}

static char isSymbolList64Bit(SymbolicFile &Obj) {
  if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj))
    return Triple(IRObj->getTargetTriple()).isArch64Bit();
  if (isa<COFFObjectFile>(Obj) || isa<COFFImportFile>(Obj))
    return false;
  if (isa<WasmObjectFile>(Obj))
    return false;
  if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
    return Tapi->is64Bit();
  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
    return MachO->is64Bit();
  return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8;
}

static StringRef CurrentFilename;
static std::vector<NMSymbol> SymbolList;

static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I);

// darwinPrintSymbol() is used to print a symbol from a Mach-O file when the
// the OutputFormat is darwin or we are printing Mach-O symbols in hex.  For
// the darwin format it produces the same output as darwin's nm(1) -m output
// and when printing Mach-O symbols in hex it produces the same output as
// darwin's nm(1) -x format.
static void darwinPrintSymbol(SymbolicFile &Obj, const NMSymbol &S,
                              char *SymbolAddrStr, const char *printBlanks,
                              const char *printDashes,
                              const char *printFormat) {
  MachO::mach_header H;
  MachO::mach_header_64 H_64;
  uint32_t Filetype = MachO::MH_OBJECT;
  uint32_t Flags = 0;
  uint8_t NType = 0;
  uint8_t NSect = 0;
  uint16_t NDesc = 0;
  uint32_t NStrx = 0;
  uint64_t NValue = 0;
  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
  if (Obj.isIR()) {
    uint32_t SymFlags = cantFail(S.Sym.getFlags());
    if (SymFlags & SymbolRef::SF_Global)
      NType |= MachO::N_EXT;
    if (SymFlags & SymbolRef::SF_Hidden)
      NType |= MachO::N_PEXT;
    if (SymFlags & SymbolRef::SF_Undefined)
      NType |= MachO::N_EXT | MachO::N_UNDF;
    else {
      // Here we have a symbol definition.  So to fake out a section name we
      // use 1, 2 and 3 for section numbers.  See below where they are used to
      // print out fake section names.
      NType |= MachO::N_SECT;
      if (SymFlags & SymbolRef::SF_Const)
        NSect = 3;
      else if (SymFlags & SymbolRef::SF_Executable)
        NSect = 1;
      else
        NSect = 2;
    }
    if (SymFlags & SymbolRef::SF_Weak)
      NDesc |= MachO::N_WEAK_DEF;
  } else {
    DataRefImpl SymDRI = S.Sym.getRawDataRefImpl();
    if (MachO->is64Bit()) {
      H_64 = MachO->MachOObjectFile::getHeader64();
      Filetype = H_64.filetype;
      Flags = H_64.flags;
      if (SymDRI.p){
        MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(SymDRI);
        NType = STE_64.n_type;
        NSect = STE_64.n_sect;
        NDesc = STE_64.n_desc;
        NStrx = STE_64.n_strx;
        NValue = STE_64.n_value;
      } else {
        NType = S.NType;
        NSect = S.NSect;
        NDesc = S.NDesc;
        NStrx = 0;
        NValue = S.Address;
      }
    } else {
      H = MachO->MachOObjectFile::getHeader();
      Filetype = H.filetype;
      Flags = H.flags;
      if (SymDRI.p){
        MachO::nlist STE = MachO->getSymbolTableEntry(SymDRI);
        NType = STE.n_type;
        NSect = STE.n_sect;
        NDesc = STE.n_desc;
        NStrx = STE.n_strx;
        NValue = STE.n_value;
      } else {
        NType = S.NType;
        NSect = S.NSect;
        NDesc = S.NDesc;
        NStrx = 0;
        NValue = S.Address;
      }
    }
  }

  // If we are printing Mach-O symbols in hex do that and return.
  if (FormatMachOasHex) {
    outs() << format(printFormat, NValue) << ' '
           << format("%02x %02x %04x %08x", NType, NSect, NDesc, NStrx) << ' '
           << S.Name;
    if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
      outs() << " (indirect for ";
      outs() << format(printFormat, NValue) << ' ';
      StringRef IndirectName;
      if (S.Sym.getRawDataRefImpl().p) {
        if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName))
          outs() << "?)";
        else
          outs() << IndirectName << ")";
      } else
        outs() << S.IndirectName << ")";
    }
    outs() << "\n";
    return;
  }

  if (PrintAddress) {
    if ((NType & MachO::N_TYPE) == MachO::N_INDR)
      strcpy(SymbolAddrStr, printBlanks);
    if (Obj.isIR() && (NType & MachO::N_TYPE) == MachO::N_TYPE)
      strcpy(SymbolAddrStr, printDashes);
    outs() << SymbolAddrStr << ' ';
  }

  switch (NType & MachO::N_TYPE) {
  case MachO::N_UNDF:
    if (NValue != 0) {
      outs() << "(common) ";
      if (MachO::GET_COMM_ALIGN(NDesc) != 0)
        outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") ";
    } else {
      if ((NType & MachO::N_TYPE) == MachO::N_PBUD)
        outs() << "(prebound ";
      else
        outs() << "(";
      if ((NDesc & MachO::REFERENCE_TYPE) ==
          MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
        outs() << "undefined [lazy bound]) ";
      else if ((NDesc & MachO::REFERENCE_TYPE) ==
               MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY)
        outs() << "undefined [private lazy bound]) ";
      else if ((NDesc & MachO::REFERENCE_TYPE) ==
               MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)
        outs() << "undefined [private]) ";
      else
        outs() << "undefined) ";
    }
    break;
  case MachO::N_ABS:
    outs() << "(absolute) ";
    break;
  case MachO::N_INDR:
    outs() << "(indirect) ";
    break;
  case MachO::N_SECT: {
    if (Obj.isIR()) {
      // For llvm bitcode files print out a fake section name using the values
      // use 1, 2 and 3 for section numbers as set above.
      if (NSect == 1)
        outs() << "(LTO,CODE) ";
      else if (NSect == 2)
        outs() << "(LTO,DATA) ";
      else if (NSect == 3)
        outs() << "(LTO,RODATA) ";
      else
        outs() << "(?,?) ";
      break;
    }
    section_iterator Sec = SectionRef();
    if (S.Sym.getRawDataRefImpl().p) {
      Expected<section_iterator> SecOrErr =
          MachO->getSymbolSection(S.Sym.getRawDataRefImpl());
      if (!SecOrErr) {
        consumeError(SecOrErr.takeError());
        outs() << "(?,?) ";
        break;
      }
      Sec = *SecOrErr;
      if (Sec == MachO->section_end()) {
        outs() << "(?,?) ";
        break;
      }
    } else {
      Sec = S.Section;
    }
    DataRefImpl Ref = Sec->getRawDataRefImpl();
    StringRef SectionName;
    if (Expected<StringRef> NameOrErr = MachO->getSectionName(Ref))
      SectionName = *NameOrErr;
    StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref);
    outs() << "(" << SegmentName << "," << SectionName << ") ";
    break;
  }
  default:
    outs() << "(?) ";
    break;
  }

  if (NType & MachO::N_EXT) {
    if (NDesc & MachO::REFERENCED_DYNAMICALLY)
      outs() << "[referenced dynamically] ";
    if (NType & MachO::N_PEXT) {
      if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF)
        outs() << "weak private external ";
      else
        outs() << "private external ";
    } else {
      if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF ||
          (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) {
        if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) ==
            (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
          outs() << "weak external automatically hidden ";
        else
          outs() << "weak external ";
      } else
        outs() << "external ";
    }
  } else {
    if (NType & MachO::N_PEXT)
      outs() << "non-external (was a private external) ";
    else
      outs() << "non-external ";
  }

  if (Filetype == MachO::MH_OBJECT) {
    if (NDesc & MachO::N_NO_DEAD_STRIP)
      outs() << "[no dead strip] ";
    if ((NType & MachO::N_TYPE) != MachO::N_UNDF &&
        NDesc & MachO::N_SYMBOL_RESOLVER)
      outs() << "[symbol resolver] ";
    if ((NType & MachO::N_TYPE) != MachO::N_UNDF && NDesc & MachO::N_ALT_ENTRY)
      outs() << "[alt entry] ";
    if ((NType & MachO::N_TYPE) != MachO::N_UNDF && NDesc & MachO::N_COLD_FUNC)
      outs() << "[cold func] ";
  }

  if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF)
    outs() << "[Thumb] ";

  if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
    outs() << S.Name << " (for ";
    StringRef IndirectName;
    if (MachO) {
      if (S.Sym.getRawDataRefImpl().p) {
        if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName))
          outs() << "?)";
        else
          outs() << IndirectName << ")";
      } else
        outs() << S.IndirectName << ")";
    } else
      outs() << "?)";
  } else
    outs() << S.Name;

  if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
      (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
       (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
    uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
    if (LibraryOrdinal != 0) {
      if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL)
        outs() << " (from executable)";
      else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL)
        outs() << " (dynamically looked up)";
      else {
        StringRef LibraryName;
        if (!MachO ||
            MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName))
          outs() << " (from bad library ordinal " << LibraryOrdinal << ")";
        else
          outs() << " (from " << LibraryName << ")";
      }
    }
  }

  outs() << "\n";
}

// Table that maps Darwin's Mach-O stab constants to strings to allow printing.
struct DarwinStabName {
  uint8_t NType;
  const char *Name;
};
static const struct DarwinStabName DarwinStabNames[] = {
    {MachO::N_GSYM, "GSYM"},
    {MachO::N_FNAME, "FNAME"},
    {MachO::N_FUN, "FUN"},
    {MachO::N_STSYM, "STSYM"},
    {MachO::N_LCSYM, "LCSYM"},
    {MachO::N_BNSYM, "BNSYM"},
    {MachO::N_PC, "PC"},
    {MachO::N_AST, "AST"},
    {MachO::N_OPT, "OPT"},
    {MachO::N_RSYM, "RSYM"},
    {MachO::N_SLINE, "SLINE"},
    {MachO::N_ENSYM, "ENSYM"},
    {MachO::N_SSYM, "SSYM"},
    {MachO::N_SO, "SO"},
    {MachO::N_OSO, "OSO"},
    {MachO::N_LSYM, "LSYM"},
    {MachO::N_BINCL, "BINCL"},
    {MachO::N_SOL, "SOL"},
    {MachO::N_PARAMS, "PARAM"},
    {MachO::N_VERSION, "VERS"},
    {MachO::N_OLEVEL, "OLEV"},
    {MachO::N_PSYM, "PSYM"},
    {MachO::N_EINCL, "EINCL"},
    {MachO::N_ENTRY, "ENTRY"},
    {MachO::N_LBRAC, "LBRAC"},
    {MachO::N_EXCL, "EXCL"},
    {MachO::N_RBRAC, "RBRAC"},
    {MachO::N_BCOMM, "BCOMM"},
    {MachO::N_ECOMM, "ECOMM"},
    {MachO::N_ECOML, "ECOML"},
    {MachO::N_LENG, "LENG"},
};

static const char *getDarwinStabString(uint8_t NType) {
  for (auto I : makeArrayRef(DarwinStabNames))
    if (I.NType == NType)
      return I.Name;
  return nullptr;
}

// darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of
// a stab n_type value in a Mach-O file.
static void darwinPrintStab(MachOObjectFile *MachO, const NMSymbol &S) {
  MachO::nlist_64 STE_64;
  MachO::nlist STE;
  uint8_t NType;
  uint8_t NSect;
  uint16_t NDesc;
  DataRefImpl SymDRI = S.Sym.getRawDataRefImpl();
  if (MachO->is64Bit()) {
    STE_64 = MachO->getSymbol64TableEntry(SymDRI);
    NType = STE_64.n_type;
    NSect = STE_64.n_sect;
    NDesc = STE_64.n_desc;
  } else {
    STE = MachO->getSymbolTableEntry(SymDRI);
    NType = STE.n_type;
    NSect = STE.n_sect;
    NDesc = STE.n_desc;
  }

  outs() << format(" %02x %04x ", NSect, NDesc);
  if (const char *stabString = getDarwinStabString(NType))
    outs() << format("%5.5s", stabString);
  else
    outs() << format("   %02x", NType);
}

static Optional<std::string> demangle(StringRef Name, bool StripUnderscore) {
  if (StripUnderscore && !Name.empty() && Name[0] == '_')
    Name = Name.substr(1);

  if (!Name.startswith("_Z"))
    return None;

  int Status;
  char *Undecorated =
      itaniumDemangle(Name.str().c_str(), nullptr, nullptr, &Status);
  if (Status != 0)
    return None;

  std::string S(Undecorated);
  free(Undecorated);
  return S;
}

static bool symbolIsDefined(const NMSymbol &Sym) {
  return Sym.TypeChar != 'U' && Sym.TypeChar != 'w' && Sym.TypeChar != 'v';
}

static void writeFileName(raw_ostream &S, StringRef ArchiveName,
                          StringRef ArchitectureName) {
  if (!ArchitectureName.empty())
    S << "(for architecture " << ArchitectureName << "):";
  if (OutputFormat == posix && !ArchiveName.empty())
    S << ArchiveName << "[" << CurrentFilename << "]: ";
  else {
    if (!ArchiveName.empty())
      S << ArchiveName << ":";
    S << CurrentFilename << ": ";
  }
}

static bool isSpecialSym(SymbolicFile &Obj, StringRef Name) {
  auto *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj);
  if (!ELFObj)
    return false;
  uint16_t EMachine = ELFObj->getEMachine();
  if (EMachine != ELF::EM_ARM && EMachine != ELF::EM_AARCH64)
    return false;
  return !Name.empty() && Name[0] == '$';
}

static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
                                   StringRef ArchiveName,
                                   StringRef ArchitectureName) {
  if (!NoSort) {
    using Comparator = bool (*)(const NMSymbol &, const NMSymbol &);
    Comparator Cmp;
    if (NumericSort)
      Cmp = &compareSymbolAddress;
    else if (SizeSort)
      Cmp = &compareSymbolSize;
    else
      Cmp = &compareSymbolName;

    if (ReverseSort)
      llvm::sort(SymbolList, [=](const NMSymbol &A, const NMSymbol &B) -> bool {
        return Cmp(B, A);
      });
    else
      llvm::sort(SymbolList, Cmp);
  }

  if (!PrintFileName) {
    if (OutputFormat == posix && MultipleFiles && printName) {
      outs() << '\n' << CurrentFilename << ":\n";
    } else if (OutputFormat == bsd && MultipleFiles && printName) {
      outs() << "\n" << CurrentFilename << ":\n";
    } else if (OutputFormat == sysv) {
      outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n";
      if (isSymbolList64Bit(Obj))
        outs() << "Name                  Value           Class        Type"
               << "         Size             Line  Section\n";
      else
        outs() << "Name                  Value   Class        Type"
               << "         Size     Line  Section\n";
    }
  }

  const char *printBlanks, *printDashes, *printFormat;
  if (isSymbolList64Bit(Obj)) {
    printBlanks = "                ";
    printDashes = "----------------";
    switch (AddressRadix) {
    case Radix::o:
      printFormat = OutputFormat == posix ? "%" PRIo64 : "%016" PRIo64;
      break;
    case Radix::x:
      printFormat = OutputFormat == posix ? "%" PRIx64 : "%016" PRIx64;
      break;
    default:
      printFormat = OutputFormat == posix ? "%" PRId64 : "%016" PRId64;
    }
  } else {
    printBlanks = "        ";
    printDashes = "--------";
    switch (AddressRadix) {
    case Radix::o:
      printFormat = OutputFormat == posix ? "%" PRIo64 : "%08" PRIo64;
      break;
    case Radix::x:
      printFormat = OutputFormat == posix ? "%" PRIx64 : "%08" PRIx64;
      break;
    default:
      printFormat = OutputFormat == posix ? "%" PRId64 : "%08" PRId64;
    }
  }

  for (const NMSymbol &S : SymbolList) {
    uint32_t SymFlags;
    std::string Name = S.Name;
    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
    if (Demangle) {
      if (Optional<std::string> Opt = demangle(S.Name, MachO))
        Name = *Opt;
    }
    if (S.Sym.getRawDataRefImpl().p) {
      Expected<uint32_t> SymFlagsOrErr = S.Sym.getFlags();
      if (!SymFlagsOrErr) {
        // TODO: Test this error.
        error(SymFlagsOrErr.takeError(), Obj.getFileName());
        return;
      }
      SymFlags = *SymFlagsOrErr;
    } else
      SymFlags = S.SymFlags;

    bool Undefined = SymFlags & SymbolRef::SF_Undefined;
    bool Global = SymFlags & SymbolRef::SF_Global;
    bool Weak = SymFlags & SymbolRef::SF_Weak;
    if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) ||
        (!Global && ExternalOnly) || (Weak && NoWeakSymbols) ||
        (!SpecialSyms && isSpecialSym(Obj, Name)))
      continue;
    if (PrintFileName)
      writeFileName(outs(), ArchiveName, ArchitectureName);
    if ((JustSymbolName ||
         (UndefinedOnly && MachO && OutputFormat != darwin)) &&
        OutputFormat != posix) {
      outs() << Name << "\n";
      continue;
    }

    char SymbolAddrStr[23], SymbolSizeStr[23];

    // If the format is SysV or the symbol isn't defined, then print spaces.
    if (OutputFormat == sysv || !symbolIsDefined(S)) {
      if (OutputFormat == posix) {
        format(printFormat, S.Address)
            .print(SymbolAddrStr, sizeof(SymbolAddrStr));
        format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
      } else {
        strcpy(SymbolAddrStr, printBlanks);
        strcpy(SymbolSizeStr, printBlanks);
      }
    }

    if (symbolIsDefined(S)) {
      // Otherwise, print the symbol address and size.
      if (Obj.isIR())
        strcpy(SymbolAddrStr, printDashes);
      else if (MachO && S.TypeChar == 'I')
        strcpy(SymbolAddrStr, printBlanks);
      else
        format(printFormat, S.Address)
            .print(SymbolAddrStr, sizeof(SymbolAddrStr));
      format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
    }

    // If OutputFormat is darwin or we are printing Mach-O symbols in hex and
    // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's
    // nm(1) -m output or hex, else if OutputFormat is darwin or we are
    // printing Mach-O symbols in hex and not a Mach-O object fall back to
    // OutputFormat bsd (see below).
    if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) {
      darwinPrintSymbol(Obj, S, SymbolAddrStr, printBlanks, printDashes,
                        printFormat);
    } else if (OutputFormat == posix) {
      outs() << Name << " " << S.TypeChar << " " << SymbolAddrStr << " "
             << (MachO ? "0" : SymbolSizeStr) << "\n";
    } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) {
      if (PrintAddress)
        outs() << SymbolAddrStr << ' ';
      if (PrintSize)
        outs() << SymbolSizeStr << ' ';
      outs() << S.TypeChar;
      if (S.TypeChar == '-' && MachO)
        darwinPrintStab(MachO, S);
      outs() << " " << Name;
      if (S.TypeChar == 'I' && MachO) {
        outs() << " (indirect for ";
        if (S.Sym.getRawDataRefImpl().p) {
          StringRef IndirectName;
          if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName))
            outs() << "?)";
          else
            outs() << IndirectName << ")";
        } else
          outs() << S.IndirectName << ")";
      }
      outs() << "\n";
    } else if (OutputFormat == sysv) {
      outs() << left_justify(Name, 20) << "|" << SymbolAddrStr << "|   "
             << S.TypeChar << "  |" << right_justify(S.TypeName, 18) << "|"
             << SymbolSizeStr << "|     |" << S.SectionName << "\n";
    }
  }

  SymbolList.clear();
}

static char getSymbolNMTypeChar(ELFObjectFileBase &Obj,
                                basic_symbol_iterator I) {
  // OK, this is ELF
  elf_symbol_iterator SymI(I);

  Expected<elf_section_iterator> SecIOrErr = SymI->getSection();
  if (!SecIOrErr) {
    consumeError(SecIOrErr.takeError());
    return '?';
  }

  uint8_t Binding = SymI->getBinding();
  if (Binding == ELF::STB_GNU_UNIQUE)
    return 'u';

  assert(Binding != ELF::STB_WEAK && "STB_WEAK not tested in calling function");
  if (Binding != ELF::STB_GLOBAL && Binding != ELF::STB_LOCAL)
    return '?';

  elf_section_iterator SecI = *SecIOrErr;
  if (SecI != Obj.section_end()) {
    uint32_t Type = SecI->getType();
    uint64_t Flags = SecI->getFlags();
    if (Flags & ELF::SHF_EXECINSTR)
      return 't';
    if (Type == ELF::SHT_NOBITS)
      return 'b';
    if (Flags & ELF::SHF_ALLOC)
      return Flags & ELF::SHF_WRITE ? 'd' : 'r';

    auto NameOrErr = SecI->getName();
    if (!NameOrErr) {
      consumeError(NameOrErr.takeError());
      return '?';
    }
    if ((*NameOrErr).startswith(".debug"))
      return 'N';
    if (!(Flags & ELF::SHF_WRITE))
      return 'n';
  }

  return '?';
}

static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
  COFFSymbolRef Symb = Obj.getCOFFSymbol(*I);
  // OK, this is COFF.
  symbol_iterator SymI(I);

  Expected<StringRef> Name = SymI->getName();
  if (!Name) {
    consumeError(Name.takeError());
    return '?';
  }

  char Ret = StringSwitch<char>(*Name)
                 .StartsWith(".debug", 'N')
                 .StartsWith(".sxdata", 'N')
                 .Default('?');

  if (Ret != '?')
    return Ret;

  uint32_t Characteristics = 0;
  if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
    Expected<section_iterator> SecIOrErr = SymI->getSection();
    if (!SecIOrErr) {
      consumeError(SecIOrErr.takeError());
      return '?';
    }
    section_iterator SecI = *SecIOrErr;
    const coff_section *Section = Obj.getCOFFSection(*SecI);
    Characteristics = Section->Characteristics;
    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Section))
      if (NameOrErr->startswith(".idata"))
        return 'i';
  }

  switch (Symb.getSectionNumber()) {
  case COFF::IMAGE_SYM_DEBUG:
    return 'n';
  default:
    // Check section type.
    if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
      return 't';
    if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
      return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r';
    if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
      return 'b';
    if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
      return 'i';
    // Check for section symbol.
    if (Symb.isSectionDefinition())
      return 's';
  }

  return '?';
}

static char getSymbolNMTypeChar(COFFImportFile &Obj) {
  switch (Obj.getCOFFImportHeader()->getType()) {
  case COFF::IMPORT_CODE:
    return 't';
  case COFF::IMPORT_DATA:
    return 'd';
  case COFF::IMPORT_CONST:
    return 'r';
  }
  return '?';
}

static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
  DataRefImpl Symb = I->getRawDataRefImpl();
  uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type
                                : Obj.getSymbolTableEntry(Symb).n_type;

  if (NType & MachO::N_STAB)
    return '-';

  switch (NType & MachO::N_TYPE) {
  case MachO::N_ABS:
    return 's';
  case MachO::N_INDR:
    return 'i';
  case MachO::N_SECT: {
    Expected<section_iterator> SecOrErr = Obj.getSymbolSection(Symb);
    if (!SecOrErr) {
      consumeError(SecOrErr.takeError());
      return 's';
    }
    section_iterator Sec = *SecOrErr;
    if (Sec == Obj.section_end())
      return 's';
    DataRefImpl Ref = Sec->getRawDataRefImpl();
    StringRef SectionName;
    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Ref))
      SectionName = *NameOrErr;
    StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref);
    if (Obj.is64Bit() && Obj.getHeader64().filetype == MachO::MH_KEXT_BUNDLE &&
        SegmentName == "__TEXT_EXEC" && SectionName == "__text")
      return 't';
    if (SegmentName == "__TEXT" && SectionName == "__text")
      return 't';
    if (SegmentName == "__DATA" && SectionName == "__data")
      return 'd';
    if (SegmentName == "__DATA" && SectionName == "__bss")
      return 'b';
    return 's';
  }
  }

  return '?';
}

static char getSymbolNMTypeChar(TapiFile &Obj, basic_symbol_iterator I) {
  return 's';
}

static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) {
  uint32_t Flags = cantFail(I->getFlags());
  if (Flags & SymbolRef::SF_Executable)
    return 't';
  return 'd';
}

static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) {
  uint32_t Flags = cantFail(I->getFlags());
  // FIXME: should we print 'b'? At the IR level we cannot be sure if this
  // will be in bss or not, but we could approximate.
  if (Flags & SymbolRef::SF_Executable)
    return 't';
  else if (Triple(Obj.getTargetTriple()).isOSDarwin() &&
           (Flags & SymbolRef::SF_Const))
    return 's';
  else
    return 'd';
}

static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) {
  return isa<ELFObjectFileBase>(&Obj) &&
         elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT;
}

// For ELF object files, Set TypeName to the symbol typename, to be printed
// in the 'Type' column of the SYSV format output.
static StringRef getNMTypeName(SymbolicFile &Obj, basic_symbol_iterator I) {
  if (isa<ELFObjectFileBase>(&Obj)) {
    elf_symbol_iterator SymI(I);
    return SymI->getELFTypeName();
  }
  return "";
}

// Return Posix nm class type tag (single letter), but also set SecName and
// section and name, to be used in format=sysv output.
static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
                                   StringRef &SecName) {
  // Symbol Flags have been checked in the caller.
  uint32_t Symflags = cantFail(I->getFlags());
  if (ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj)) {
    if (Symflags & object::SymbolRef::SF_Absolute)
      SecName = "*ABS*";
    else if (Symflags & object::SymbolRef::SF_Common)
      SecName = "*COM*";
    else if (Symflags & object::SymbolRef::SF_Undefined)
      SecName = "*UND*";
    else {
      elf_symbol_iterator SymI(I);
      Expected<elf_section_iterator> SecIOrErr = SymI->getSection();
      if (!SecIOrErr) {
        consumeError(SecIOrErr.takeError());
        return '?';
      }

      if (*SecIOrErr == ELFObj->section_end())
        return '?';

      Expected<StringRef> NameOrErr = (*SecIOrErr)->getName();
      if (!NameOrErr) {
        consumeError(NameOrErr.takeError());
        return '?';
      }
      SecName = *NameOrErr;
    }
  }

  if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) {
    char Ret = isObject(Obj, I) ? 'v' : 'w';
    return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret;
  }

  if (Symflags & object::SymbolRef::SF_Undefined)
    return 'U';

  if (Symflags & object::SymbolRef::SF_Common)
    return 'C';

  char Ret = '?';
  if (Symflags & object::SymbolRef::SF_Absolute)
    Ret = 'a';
  else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj))
    Ret = getSymbolNMTypeChar(*IR, I);
  else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj))
    Ret = getSymbolNMTypeChar(*COFF, I);
  else if (COFFImportFile *COFFImport = dyn_cast<COFFImportFile>(&Obj))
    Ret = getSymbolNMTypeChar(*COFFImport);
  else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
    Ret = getSymbolNMTypeChar(*MachO, I);
  else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj))
    Ret = getSymbolNMTypeChar(*Wasm, I);
  else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
    Ret = getSymbolNMTypeChar(*Tapi, I);
  else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) {
    if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
      return 'i';
    Ret = getSymbolNMTypeChar(*ELF, I);
    if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE)
      return Ret;
  } else
    llvm_unreachable("unknown binary format");

  if (!(Symflags & object::SymbolRef::SF_Global))
    return Ret;

  return toupper(Ret);
}

// getNsectForSegSect() is used to implement the Mach-O "-s segname sectname"
// option to dump only those symbols from that section in a Mach-O file.
// It is called once for each Mach-O file from dumpSymbolNamesFromObject()
// to get the section number for that named section from the command line
// arguments. It returns the section number for that section in the Mach-O
// file or zero it is not present.
static unsigned getNsectForSegSect(MachOObjectFile *Obj) {
  unsigned Nsect = 1;
  for (auto &S : Obj->sections()) {
    DataRefImpl Ref = S.getRawDataRefImpl();
    StringRef SectionName;
    if (Expected<StringRef> NameOrErr = Obj->getSectionName(Ref))
      SectionName = *NameOrErr;
    StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref);
    if (SegmentName == SegSect[0] && SectionName == SegSect[1])
      return Nsect;
    Nsect++;
  }
  return 0;
}

// getNsectInMachO() is used to implement the Mach-O "-s segname sectname"
// option to dump only those symbols from that section in a Mach-O file.
// It is called once for each symbol in a Mach-O file from
// dumpSymbolNamesFromObject() and returns the section number for that symbol
// if it is in a section, else it returns 0.
static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) {
  DataRefImpl Symb = Sym.getRawDataRefImpl();
  if (Obj.is64Bit()) {
    MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
    return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
  }
  MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
  return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
}

static void dumpSymbolsFromDLInfoMachO(MachOObjectFile &MachO) {
  size_t I = SymbolList.size();
  std::string ExportsNameBuffer;
  raw_string_ostream EOS(ExportsNameBuffer);
  std::string BindsNameBuffer;
  raw_string_ostream BOS(BindsNameBuffer);
  std::string LazysNameBuffer;
  raw_string_ostream LOS(LazysNameBuffer);
  std::string WeaksNameBuffer;
  raw_string_ostream WOS(WeaksNameBuffer);
  std::string FunctionStartsNameBuffer;
  raw_string_ostream FOS(FunctionStartsNameBuffer);

  MachO::mach_header H;
  MachO::mach_header_64 H_64;
  uint32_t HFlags = 0;
  if (MachO.is64Bit()) {
    H_64 = MachO.MachOObjectFile::getHeader64();
    HFlags = H_64.flags;
  } else {
    H = MachO.MachOObjectFile::getHeader();
    HFlags = H.flags;
  }
  uint64_t BaseSegmentAddress = 0;
  for (const auto &Command : MachO.load_commands()) {
    if (Command.C.cmd == MachO::LC_SEGMENT) {
      MachO::segment_command Seg = MachO.getSegmentLoadCommand(Command);
      if (Seg.fileoff == 0 && Seg.filesize != 0) {
        BaseSegmentAddress = Seg.vmaddr;
        break;
      }
    } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
      MachO::segment_command_64 Seg = MachO.getSegment64LoadCommand(Command);
      if (Seg.fileoff == 0 && Seg.filesize != 0) {
        BaseSegmentAddress = Seg.vmaddr;
        break;
      }
    }
  }
  if (DyldInfoOnly || AddDyldInfo ||
      HFlags & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) {
    unsigned ExportsAdded = 0;
    Error Err = Error::success();
    for (const llvm::object::ExportEntry &Entry : MachO.exports(Err)) {
      bool found = false;
      bool ReExport = false;
      if (!DyldInfoOnly) {
        for (const NMSymbol &S : SymbolList)
          if (S.Address == Entry.address() + BaseSegmentAddress &&
              S.Name == Entry.name()) {
            found = true;
            break;
          }
      }
      if (!found) {
        NMSymbol S = {};
        S.Address = Entry.address() + BaseSegmentAddress;
        S.Size = 0;
        S.TypeChar = '\0';
        S.Name = Entry.name().str();
        // There is no symbol in the nlist symbol table for this so we set
        // Sym effectivly to null and the rest of code in here must test for
        // it and not do things like Sym.getFlags() for it.
        S.Sym = BasicSymbolRef();
        S.SymFlags = SymbolRef::SF_Global;
        S.Section = SectionRef();
        S.NType = 0;
        S.NSect = 0;
        S.NDesc = 0;

        uint64_t EFlags = Entry.flags();
        bool Abs = ((EFlags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
                    MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
        bool Resolver = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
        ReExport = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
        bool WeakDef = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
        if (WeakDef)
          S.NDesc |= MachO::N_WEAK_DEF;
        if (Abs) {
          S.NType = MachO::N_EXT | MachO::N_ABS;
          S.TypeChar = 'A';
        } else if (ReExport) {
          S.NType = MachO::N_EXT | MachO::N_INDR;
          S.TypeChar = 'I';
        } else {
          S.NType = MachO::N_EXT | MachO::N_SECT;
          if (Resolver) {
            S.Address = Entry.other() + BaseSegmentAddress;
            if ((S.Address & 1) != 0 && !MachO.is64Bit() &&
                H.cputype == MachO::CPU_TYPE_ARM) {
              S.Address &= ~1LL;
              S.NDesc |= MachO::N_ARM_THUMB_DEF;
            }
          } else {
            S.Address = Entry.address() + BaseSegmentAddress;
          }
          StringRef SegmentName = StringRef();
          StringRef SectionName = StringRef();
          for (const SectionRef &Section : MachO.sections()) {
            S.NSect++;

            if (Expected<StringRef> NameOrErr = Section.getName())
              SectionName = *NameOrErr;
            else
              consumeError(NameOrErr.takeError());

            SegmentName =
                MachO.getSectionFinalSegmentName(Section.getRawDataRefImpl());
            if (S.Address >= Section.getAddress() &&
                S.Address < Section.getAddress() + Section.getSize()) {
              S.Section = Section;
              break;
            } else if (Entry.name() == "__mh_execute_header" &&
                       SegmentName == "__TEXT" && SectionName == "__text") {
              S.Section = Section;
              S.NDesc |= MachO::REFERENCED_DYNAMICALLY;
              break;
            }
          }
          if (SegmentName == "__TEXT" && SectionName == "__text")
            S.TypeChar = 'T';
          else if (SegmentName == "__DATA" && SectionName == "__data")
            S.TypeChar = 'D';
          else if (SegmentName == "__DATA" && SectionName == "__bss")
            S.TypeChar = 'B';
          else
            S.TypeChar = 'S';
        }
        SymbolList.push_back(S);

        EOS << Entry.name();
        EOS << '\0';
        ExportsAdded++;

        // For ReExports there are a two more things to do, first add the
        // indirect name and second create the undefined symbol using the
        // referened dynamic library.
        if (ReExport) {

          // Add the indirect name.
          if (Entry.otherName().empty())
            EOS << Entry.name();
          else
            EOS << Entry.otherName();
          EOS << '\0';

          // Now create the undefined symbol using the referened dynamic
          // library.
          NMSymbol U = {};
          U.Address = 0;
          U.Size = 0;
          U.TypeChar = 'U';
          if (Entry.otherName().empty())
            U.Name = Entry.name().str();
          else
            U.Name = Entry.otherName().str();
          // Again there is no symbol in the nlist symbol table for this so
          // we set Sym effectivly to null and the rest of code in here must
          // test for it and not do things like Sym.getFlags() for it.
          U.Sym = BasicSymbolRef();
          U.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
          U.Section = SectionRef();
          U.NType = MachO::N_EXT | MachO::N_UNDF;
          U.NSect = 0;
          U.NDesc = 0;
          // The library ordinal for this undefined symbol is in the export
          // trie Entry.other().
          MachO::SET_LIBRARY_ORDINAL(U.NDesc, Entry.other());
          SymbolList.push_back(U);

          // Finally add the undefined symbol's name.
          if (Entry.otherName().empty())
            EOS << Entry.name();
          else
            EOS << Entry.otherName();
          EOS << '\0';
          ExportsAdded++;
        }
      }
    }
    if (Err)
      error(std::move(Err), MachO.getFileName());
    // Set the symbol names and indirect names for the added symbols.
    if (ExportsAdded) {
      EOS.flush();
      const char *Q = ExportsNameBuffer.c_str();
      for (unsigned K = 0; K < ExportsAdded; K++) {
        SymbolList[I].Name = Q;
        Q += strlen(Q) + 1;
        if (SymbolList[I].TypeChar == 'I') {
          SymbolList[I].IndirectName = Q;
          Q += strlen(Q) + 1;
        }
        I++;
      }
    }

    // Add the undefined symbols from the bind entries.
    unsigned BindsAdded = 0;
    Error BErr = Error::success();
    StringRef LastSymbolName = StringRef();
    for (const llvm::object::MachOBindEntry &Entry : MachO.bindTable(BErr)) {
      bool found = false;
      if (LastSymbolName == Entry.symbolName())
        found = true;
      else if (!DyldInfoOnly) {
        for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
          if (SymbolList[J].Name == Entry.symbolName())
            found = true;
        }
      }
      if (!found) {
        LastSymbolName = Entry.symbolName();
        NMSymbol B = {};
        B.Address = 0;
        B.Size = 0;
        B.TypeChar = 'U';
        // There is no symbol in the nlist symbol table for this so we set
        // Sym effectivly to null and the rest of code in here must test for
        // it and not do things like Sym.getFlags() for it.
        B.Sym = BasicSymbolRef();
        B.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
        B.NType = MachO::N_EXT | MachO::N_UNDF;
        B.NSect = 0;
        B.NDesc = 0;
        MachO::SET_LIBRARY_ORDINAL(B.NDesc, Entry.ordinal());
        B.Name = Entry.symbolName().str();
        SymbolList.push_back(B);
        BOS << Entry.symbolName();
        BOS << '\0';
        BindsAdded++;
      }
    }
    if (BErr)
      error(std::move(BErr), MachO.getFileName());
    // Set the symbol names and indirect names for the added symbols.
    if (BindsAdded) {
      BOS.flush();
      const char *Q = BindsNameBuffer.c_str();
      for (unsigned K = 0; K < BindsAdded; K++) {
        SymbolList[I].Name = Q;
        Q += strlen(Q) + 1;
        if (SymbolList[I].TypeChar == 'I') {
          SymbolList[I].IndirectName = Q;
          Q += strlen(Q) + 1;
        }
        I++;
      }
    }

    // Add the undefined symbols from the lazy bind entries.
    unsigned LazysAdded = 0;
    Error LErr = Error::success();
    LastSymbolName = StringRef();
    for (const llvm::object::MachOBindEntry &Entry :
         MachO.lazyBindTable(LErr)) {
      bool found = false;
      if (LastSymbolName == Entry.symbolName())
        found = true;
      else {
        // Here we must check to see it this symbol is already in the
        // SymbolList as it might have already have been added above via a
        // non-lazy (bind) entry.
        for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
          if (SymbolList[J].Name == Entry.symbolName())
            found = true;
        }
      }
      if (!found) {
        LastSymbolName = Entry.symbolName();
        NMSymbol L = {};
        L.Name = Entry.symbolName().str();
        L.Address = 0;
        L.Size = 0;
        L.TypeChar = 'U';
        // There is no symbol in the nlist symbol table for this so we set
        // Sym effectivly to null and the rest of code in here must test for
        // it and not do things like Sym.getFlags() for it.
        L.Sym = BasicSymbolRef();
        L.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
        L.NType = MachO::N_EXT | MachO::N_UNDF;
        L.NSect = 0;
        // The REFERENCE_FLAG_UNDEFINED_LAZY is no longer used but here it
        // makes sence since we are creating this from a lazy bind entry.
        L.NDesc = MachO::REFERENCE_FLAG_UNDEFINED_LAZY;
        MachO::SET_LIBRARY_ORDINAL(L.NDesc, Entry.ordinal());
        SymbolList.push_back(L);
        LOS << Entry.symbolName();
        LOS << '\0';
        LazysAdded++;
      }
    }
    if (LErr)
      error(std::move(LErr), MachO.getFileName());
    // Set the symbol names and indirect names for the added symbols.
    if (LazysAdded) {
      LOS.flush();
      const char *Q = LazysNameBuffer.c_str();
      for (unsigned K = 0; K < LazysAdded; K++) {
        SymbolList[I].Name = Q;
        Q += strlen(Q) + 1;
        if (SymbolList[I].TypeChar == 'I') {
          SymbolList[I].IndirectName = Q;
          Q += strlen(Q) + 1;
        }
        I++;
      }
    }

    // Add the undefineds symbol from the weak bind entries which are not
    // strong symbols.
    unsigned WeaksAdded = 0;
    Error WErr = Error::success();
    LastSymbolName = StringRef();
    for (const llvm::object::MachOBindEntry &Entry :
         MachO.weakBindTable(WErr)) {
      bool found = false;
      unsigned J = 0;
      if (LastSymbolName == Entry.symbolName() ||
          Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
        found = true;
      } else {
        for (J = 0; J < SymbolList.size() && !found; ++J) {
          if (SymbolList[J].Name == Entry.symbolName()) {
            found = true;
            break;
          }
        }
      }
      if (!found) {
        LastSymbolName = Entry.symbolName();
        NMSymbol W = {};
        W.Name = Entry.symbolName().str();
        W.Address = 0;
        W.Size = 0;
        W.TypeChar = 'U';
        // There is no symbol in the nlist symbol table for this so we set
        // Sym effectivly to null and the rest of code in here must test for
        // it and not do things like Sym.getFlags() for it.
        W.Sym = BasicSymbolRef();
        W.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
        W.NType = MachO::N_EXT | MachO::N_UNDF;
        W.NSect = 0;
        // Odd that we are using N_WEAK_DEF on an undefined symbol but that is
        // what is created in this case by the linker when there are real
        // symbols in the nlist structs.
        W.NDesc = MachO::N_WEAK_DEF;
        SymbolList.push_back(W);
        WOS << Entry.symbolName();
        WOS << '\0';
        WeaksAdded++;
      } else {
        // This is the case the symbol was previously been found and it could
        // have been added from a bind or lazy bind symbol.  If so and not
        // a definition also mark it as weak.
        if (SymbolList[J].TypeChar == 'U')
          // See comment above about N_WEAK_DEF.
          SymbolList[J].NDesc |= MachO::N_WEAK_DEF;
      }
    }
    if (WErr)
      error(std::move(WErr), MachO.getFileName());
    // Set the symbol names and indirect names for the added symbols.
    if (WeaksAdded) {
      WOS.flush();
      const char *Q = WeaksNameBuffer.c_str();
      for (unsigned K = 0; K < WeaksAdded; K++) {
        SymbolList[I].Name = Q;
        Q += strlen(Q) + 1;
        if (SymbolList[I].TypeChar == 'I') {
          SymbolList[I].IndirectName = Q;
          Q += strlen(Q) + 1;
        }
        I++;
      }
    }

    // Trying adding symbol from the function starts table and LC_MAIN entry
    // point.
    SmallVector<uint64_t, 8> FoundFns;
    uint64_t lc_main_offset = UINT64_MAX;
    for (const auto &Command : MachO.load_commands()) {
      if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
        // We found a function starts segment, parse the addresses for
        // consumption.
        MachO::linkedit_data_command LLC =
            MachO.getLinkeditDataLoadCommand(Command);

        MachO.ReadULEB128s(LLC.dataoff, FoundFns);
      } else if (Command.C.cmd == MachO::LC_MAIN) {
        MachO::entry_point_command LCmain = MachO.getEntryPointCommand(Command);
        lc_main_offset = LCmain.entryoff;
      }
    }
    // See if these addresses are already in the symbol table.
    unsigned FunctionStartsAdded = 0;
    for (uint64_t f = 0; f < FoundFns.size(); f++) {
      bool found = false;
      for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
        if (SymbolList[J].Address == FoundFns[f] + BaseSegmentAddress)
          found = true;
      }
      // See this address is not already in the symbol table fake up an
      // nlist for it.
      if (!found) {
        NMSymbol F = {};
        F.Name = "<redacted function X>";
        F.Address = FoundFns[f] + BaseSegmentAddress;
        F.Size = 0;
        // There is no symbol in the nlist symbol table for this so we set
        // Sym effectivly to null and the rest of code in here must test for
        // it and not do things like Sym.getFlags() for it.
        F.Sym = BasicSymbolRef();
        F.SymFlags = 0;
        F.NType = MachO::N_SECT;
        F.NSect = 0;
        StringRef SegmentName = StringRef();
        StringRef SectionName = StringRef();
        for (const SectionRef &Section : MachO.sections()) {
          if (Expected<StringRef> NameOrErr = Section.getName())
            SectionName = *NameOrErr;
          else
            consumeError(NameOrErr.takeError());

          SegmentName =
              MachO.getSectionFinalSegmentName(Section.getRawDataRefImpl());
          F.NSect++;
          if (F.Address >= Section.getAddress() &&
              F.Address < Section.getAddress() + Section.getSize()) {
            F.Section = Section;
            break;
          }
        }
        if (SegmentName == "__TEXT" && SectionName == "__text")
          F.TypeChar = 't';
        else if (SegmentName == "__DATA" && SectionName == "__data")
          F.TypeChar = 'd';
        else if (SegmentName == "__DATA" && SectionName == "__bss")
          F.TypeChar = 'b';
        else
          F.TypeChar = 's';
        F.NDesc = 0;
        SymbolList.push_back(F);
        if (FoundFns[f] == lc_main_offset)
          FOS << "<redacted LC_MAIN>";
        else
          FOS << "<redacted function " << f << ">";
        FOS << '\0';
        FunctionStartsAdded++;
      }
    }
    if (FunctionStartsAdded) {
      FOS.flush();
      const char *Q = FunctionStartsNameBuffer.c_str();
      for (unsigned K = 0; K < FunctionStartsAdded; K++) {
        SymbolList[I].Name = Q;
        Q += strlen(Q) + 1;
        if (SymbolList[I].TypeChar == 'I') {
          SymbolList[I].IndirectName = Q;
          Q += strlen(Q) + 1;
        }
        I++;
      }
    }
  }
}

namespace {
struct SymbolVersion {
  std::string Name;
  bool IsDefault;
};
} // namespace

template <class ELFT>
static Expected<std::vector<SymbolVersion>>
readSymbolVersionsELF(const ELFFile<ELFT> &Obj, StringRef FileName,
                      ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
  using Elf_Shdr = typename ELFT::Shdr;

  // We called sections() earlier, so can't fail here.
  typename ELFT::ShdrRange SectionsOrErr = cantFail(Obj.sections());
  const Elf_Shdr *SymVerSec = nullptr;
  const Elf_Shdr *SymVerNeedSec = nullptr;
  const Elf_Shdr *SymVerDefSec = nullptr;
  for (const Elf_Shdr &Sec : SectionsOrErr) {
    if (Sec.sh_type == ELF::SHT_GNU_versym)
      SymVerSec = &Sec;
    else if (Sec.sh_type == ELF::SHT_GNU_verdef)
      SymVerDefSec = &Sec;
    else if (Sec.sh_type == ELF::SHT_GNU_verneed)
      SymVerNeedSec = &Sec;
  }

  if (!SymVerSec)
    return std::vector<SymbolVersion>{};

  Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr =
      Obj.loadVersionMap(SymVerNeedSec, SymVerDefSec);
  if (!MapOrErr)
    return MapOrErr.takeError();

  std::vector<SymbolVersion> Ret;
  size_t I = 0;
  for (auto It = Symbols.begin(), E = Symbols.end(); It != E; ++It) {
    ++I;
    Expected<const typename ELFT::Versym *> VerEntryOrErr =
        Obj.template getEntry<typename ELFT::Versym>(*SymVerSec, I);
    if (!VerEntryOrErr)
      return createError("unable to read an entry with index " + Twine(I) +
                         " from " + describe(Obj, *SymVerSec) + ": " +
                         toString(VerEntryOrErr.takeError()));

    Expected<uint32_t> FlagsOrErr = It->getFlags();
    if (!FlagsOrErr)
      return createError("unable to read flags for symbol with index " +
                         Twine(I) + ": " + toString(FlagsOrErr.takeError()));

    bool IsDefault;
    Expected<StringRef> VerOrErr = Obj.getSymbolVersionByIndex(
        (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr,
        (*FlagsOrErr) & SymbolRef::SF_Undefined);
    if (!VerOrErr)
      return createError("unable to get a version for entry " + Twine(I) +
                         " of " + describe(Obj, *SymVerSec) + ": " +
                         toString(VerOrErr.takeError()));

    Ret.push_back({(*VerOrErr).str(), IsDefault});
  }

  return Ret;
}

static Expected<std::vector<SymbolVersion>>
readSymbolVersionsELF(const ELFObjectFileBase &Obj,
                      ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
  if (const auto *ELF = dyn_cast<ELF32LEObjectFile>(&Obj))
    return readSymbolVersionsELF(ELF->getELFFile(), Obj.getFileName(), Symbols);
  else if (const auto *ELF = dyn_cast<ELF32BEObjectFile>(&Obj))
    return readSymbolVersionsELF(ELF->getELFFile(), Obj.getFileName(), Symbols);
  else if (const auto *ELF = dyn_cast<ELF64LEObjectFile>(&Obj))
    return readSymbolVersionsELF(ELF->getELFFile(), Obj.getFileName(), Symbols);
  return readSymbolVersionsELF(cast<ELF64BEObjectFile>(&Obj)->getELFFile(),
                               Obj.getFileName(), Symbols);
}

static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
                                      StringRef ArchiveName = {},
                                      StringRef ArchitectureName = {}) {
  auto Symbols = Obj.symbols();
  std::vector<SymbolVersion> SymbolVersions;
  if (DynamicSyms) {
    const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
    if (!E) {
      error("File format has no dynamic symbol table", Obj.getFileName());
      return;
    }
    Symbols = E->getDynamicSymbolIterators();

    if (Expected<std::vector<SymbolVersion>> VersionsOrErr =
            readSymbolVersionsELF(*E, Symbols))
      SymbolVersions = std::move(*VersionsOrErr);
    else
      WithColor::warning(errs(), ToolName)
          << "unable to read symbol versions: "
          << toString(VersionsOrErr.takeError()) << "\n";
  }

  // If a "-s segname sectname" option was specified and this is a Mach-O
  // file get the section number for that section in this object file.
  unsigned int Nsect = 0;
  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
  if (!SegSect.empty() && MachO) {
    Nsect = getNsectForSegSect(MachO);
    // If this section is not in the object file no symbols are printed.
    if (Nsect == 0)
      return;
  }
  if (!(MachO && DyldInfoOnly)) {
    size_t I = -1;
    for (BasicSymbolRef Sym : Symbols) {
      ++I;
      Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
      if (!SymFlagsOrErr) {
        error(SymFlagsOrErr.takeError(), Obj.getFileName());
        return;
      }
      if (!DebugSyms && (*SymFlagsOrErr & SymbolRef::SF_FormatSpecific))
        continue;
      if (WithoutAliases && (*SymFlagsOrErr & SymbolRef::SF_Indirect))
        continue;
      // If a "-s segname sectname" option was specified and this is a Mach-O
      // file and this section appears in this file, Nsect will be non-zero then
      // see if this symbol is a symbol from that section and if not skip it.
      if (Nsect && Nsect != getNsectInMachO(*MachO, Sym))
        continue;
      NMSymbol S = {};
      S.Size = 0;
      S.Address = 0;
      if (isa<ELFObjectFileBase>(&Obj))
        S.Size = ELFSymbolRef(Sym).getSize();
      if (PrintAddress && isa<ObjectFile>(Obj)) {
        SymbolRef SymRef(Sym);
        Expected<uint64_t> AddressOrErr = SymRef.getAddress();
        if (!AddressOrErr) {
          consumeError(AddressOrErr.takeError());
          break;
        }
        S.Address = *AddressOrErr;
      }
      S.TypeName = getNMTypeName(Obj, Sym);
      S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName);

      raw_string_ostream OS(S.Name);
      if (Error E = Sym.printName(OS)) {
        if (MachO) {
          OS << "bad string index";
          consumeError(std::move(E));
        } else
          error(std::move(E), Obj.getFileName());
      }
      if (!SymbolVersions.empty() && !SymbolVersions[I].Name.empty())
        S.Name +=
            (SymbolVersions[I].IsDefault ? "@@" : "@") + SymbolVersions[I].Name;

      S.Sym = Sym;
      SymbolList.push_back(S);
    }
  }

  // If this is a Mach-O file where the nlist symbol table is out of sync
  // with the dyld export trie then look through exports and fake up symbols
  // for the ones that are missing (also done with the -add-dyldinfo flag).
  // This is needed if strip(1) -T is run on a binary containing swift
  // language symbols for example.  The option -only-dyldinfo will fake up
  // all symbols from the dyld export trie as well as the bind info.
  if (MachO && !NoDyldInfo)
    dumpSymbolsFromDLInfoMachO(*MachO);

  CurrentFilename = Obj.getFileName();

  if (Symbols.empty() && SymbolList.empty()) {
    writeFileName(errs(), ArchiveName, ArchitectureName);
    errs() << "no symbols\n";
  }

  sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName);
}

// checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file
// and if it is and there is a list of architecture flags is specified then
// check to make sure this Mach-O file is one of those architectures or all
// architectures was specificed.  If not then an error is generated and this
// routine returns false.  Else it returns true.
static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) {
  auto *MachO = dyn_cast<MachOObjectFile>(O);

  if (!MachO || ArchAll || ArchFlags.empty())
    return true;

  MachO::mach_header H;
  MachO::mach_header_64 H_64;
  Triple T;
  const char *McpuDefault, *ArchFlag;
  if (MachO->is64Bit()) {
    H_64 = MachO->MachOObjectFile::getHeader64();
    T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype,
                                       &McpuDefault, &ArchFlag);
  } else {
    H = MachO->MachOObjectFile::getHeader();
    T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype,
                                       &McpuDefault, &ArchFlag);
  }
  const std::string ArchFlagName(ArchFlag);
  if (!llvm::is_contained(ArchFlags, ArchFlagName)) {
    error("No architecture specified", Filename);
    return false;
  }
  return true;
}

static void dumpSymbolNamesFromFile(std::string &Filename) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
      MemoryBuffer::getFileOrSTDIN(Filename);
  if (error(BufferOrErr.getError(), Filename))
    return;

  LLVMContext Context;
  LLVMContext *ContextPtr = NoLLVMBitcode ? nullptr : &Context;
  Expected<std::unique_ptr<Binary>> BinaryOrErr =
      createBinary(BufferOrErr.get()->getMemBufferRef(), ContextPtr);
  if (!BinaryOrErr) {
    error(BinaryOrErr.takeError(), Filename);
    return;
  }
  Binary &Bin = *BinaryOrErr.get();

  if (Archive *A = dyn_cast<Archive>(&Bin)) {
    if (ArchiveMap) {
      Archive::symbol_iterator I = A->symbol_begin();
      Archive::symbol_iterator E = A->symbol_end();
      if (I != E) {
        outs() << "Archive map\n";
        for (; I != E; ++I) {
          Expected<Archive::Child> C = I->getMember();
          if (!C) {
            error(C.takeError(), Filename);
            break;
          }
          Expected<StringRef> FileNameOrErr = C->getName();
          if (!FileNameOrErr) {
            error(FileNameOrErr.takeError(), Filename);
            break;
          }
          StringRef SymName = I->getName();
          outs() << SymName << " in " << FileNameOrErr.get() << "\n";
        }
        outs() << "\n";
      }
    }

    {
      Error Err = Error::success();
      for (auto &C : A->children(Err)) {
        Expected<std::unique_ptr<Binary>> ChildOrErr =
            C.getAsBinary(ContextPtr);
        if (!ChildOrErr) {
          if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
            error(std::move(E), Filename, C);
          continue;
        }
        if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
          if (!MachOPrintSizeWarning && PrintSize &&  isa<MachOObjectFile>(O)) {
            WithColor::warning(errs(), ToolName)
                << "sizes with -print-size for Mach-O files are always zero.\n";
            MachOPrintSizeWarning = true;
          }
          if (!checkMachOAndArchFlags(O, Filename))
            return;
          if (!PrintFileName) {
            outs() << "\n";
            if (isa<MachOObjectFile>(O)) {
              outs() << Filename << "(" << O->getFileName() << ")";
            } else
              outs() << O->getFileName();
            outs() << ":\n";
          }
          dumpSymbolNamesFromObject(*O, false, Filename);
        }
      }
      if (Err)
        error(std::move(Err), A->getFileName());
    }
    return;
  }
  if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
    // If we have a list of architecture flags specified dump only those.
    if (!ArchAll && !ArchFlags.empty()) {
      // Look for a slice in the universal binary that matches each ArchFlag.
      bool ArchFound;
      for (unsigned i = 0; i < ArchFlags.size(); ++i) {
        ArchFound = false;
        for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                   E = UB->end_objects();
             I != E; ++I) {
          if (ArchFlags[i] == I->getArchFlagName()) {
            ArchFound = true;
            Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
                I->getAsObjectFile();
            std::string ArchiveName;
            std::string ArchitectureName;
            ArchiveName.clear();
            ArchitectureName.clear();
            if (ObjOrErr) {
              ObjectFile &Obj = *ObjOrErr.get();
              if (ArchFlags.size() > 1) {
                if (PrintFileName)
                  ArchitectureName = I->getArchFlagName();
                else
                  outs() << "\n" << Obj.getFileName() << " (for architecture "
                         << I->getArchFlagName() << ")"
                         << ":\n";
              }
              dumpSymbolNamesFromObject(Obj, false, ArchiveName,
                                        ArchitectureName);
            } else if (auto E = isNotObjectErrorInvalidFileType(
                       ObjOrErr.takeError())) {
              error(std::move(E), Filename, ArchFlags.size() > 1 ?
                    StringRef(I->getArchFlagName()) : StringRef());
              continue;
            } else if (Expected<std::unique_ptr<Archive>> AOrErr =
                           I->getAsArchive()) {
              std::unique_ptr<Archive> &A = *AOrErr;
              Error Err = Error::success();
              for (auto &C : A->children(Err)) {
                Expected<std::unique_ptr<Binary>> ChildOrErr =
                    C.getAsBinary(ContextPtr);
                if (!ChildOrErr) {
                  if (auto E = isNotObjectErrorInvalidFileType(
                                       ChildOrErr.takeError())) {
                    error(std::move(E), Filename, C, ArchFlags.size() > 1 ?
                          StringRef(I->getArchFlagName()) : StringRef());
                  }
                  continue;
                }
                if (SymbolicFile *O =
                        dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
                  if (PrintFileName) {
                    ArchiveName = std::string(A->getFileName());
                    if (ArchFlags.size() > 1)
                      ArchitectureName = I->getArchFlagName();
                  } else {
                    outs() << "\n" << A->getFileName();
                    outs() << "(" << O->getFileName() << ")";
                    if (ArchFlags.size() > 1) {
                      outs() << " (for architecture " << I->getArchFlagName()
                             << ")";
                    }
                    outs() << ":\n";
                  }
                  dumpSymbolNamesFromObject(*O, false, ArchiveName,
                                            ArchitectureName);
                }
              }
              if (Err)
                error(std::move(Err), A->getFileName());
            } else {
              consumeError(AOrErr.takeError());
              error(Filename + " for architecture " +
                    StringRef(I->getArchFlagName()) +
                    " is not a Mach-O file or an archive file",
                    "Mach-O universal file");
            }
          }
        }
        if (!ArchFound) {
          error(ArchFlags[i],
                "file: " + Filename + " does not contain architecture");
          return;
        }
      }
      return;
    }
    // No architecture flags were specified so if this contains a slice that
    // matches the host architecture dump only that.
    if (!ArchAll) {
      Triple HostTriple = MachOObjectFile::getHostArch();
      StringRef HostArchName = HostTriple.getArchName();
      for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
                                                 E = UB->end_objects();
           I != E; ++I) {
        if (HostArchName == I->getArchFlagName()) {
          Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
          std::string ArchiveName;
          if (ObjOrErr) {
            ObjectFile &Obj = *ObjOrErr.get();
            dumpSymbolNamesFromObject(Obj, false);
          } else if (auto E = isNotObjectErrorInvalidFileType(
                     ObjOrErr.takeError())) {
            error(std::move(E), Filename);
            return;
          } else if (Expected<std::unique_ptr<Archive>> AOrErr =
                         I->getAsArchive()) {
            std::unique_ptr<Archive> &A = *AOrErr;
            Error Err = Error::success();
            for (auto &C : A->children(Err)) {
              Expected<std::unique_ptr<Binary>> ChildOrErr =
                  C.getAsBinary(ContextPtr);
              if (!ChildOrErr) {
                if (auto E = isNotObjectErrorInvalidFileType(
                                     ChildOrErr.takeError()))
                  error(std::move(E), Filename, C);
                continue;
              }
              if (SymbolicFile *O =
                      dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
                if (PrintFileName)
                  ArchiveName = std::string(A->getFileName());
                else
                  outs() << "\n" << A->getFileName() << "(" << O->getFileName()
                         << ")"
                         << ":\n";
                dumpSymbolNamesFromObject(*O, false, ArchiveName);
              }
            }
            if (Err)
              error(std::move(Err), A->getFileName());
          } else {
            consumeError(AOrErr.takeError());
            error(Filename + " for architecture " +
                  StringRef(I->getArchFlagName()) +
                  " is not a Mach-O file or an archive file",
                  "Mach-O universal file");
          }
          return;
        }
      }
    }
    // Either all architectures have been specified or none have been specified
    // and this does not contain the host architecture so dump all the slices.
    bool moreThanOneArch = UB->getNumberOfObjects() > 1;
    for (const MachOUniversalBinary::ObjectForArch &O : UB->objects()) {
      Expected<std::unique_ptr<ObjectFile>> ObjOrErr = O.getAsObjectFile();
      std::string ArchiveName;
      std::string ArchitectureName;
      ArchiveName.clear();
      ArchitectureName.clear();
      if (ObjOrErr) {
        ObjectFile &Obj = *ObjOrErr.get();
        if (PrintFileName) {
          if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
            ArchitectureName = O.getArchFlagName();
        } else {
          if (moreThanOneArch)
            outs() << "\n";
          outs() << Obj.getFileName();
          if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
            outs() << " (for architecture " << O.getArchFlagName() << ")";
          outs() << ":\n";
        }
        dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName);
      } else if (auto E = isNotObjectErrorInvalidFileType(
                 ObjOrErr.takeError())) {
        error(std::move(E), Filename, moreThanOneArch ?
              StringRef(O.getArchFlagName()) : StringRef());
        continue;
      } else if (Expected<std::unique_ptr<Archive>> AOrErr =
                  O.getAsArchive()) {
        std::unique_ptr<Archive> &A = *AOrErr;
        Error Err = Error::success();
        for (auto &C : A->children(Err)) {
          Expected<std::unique_ptr<Binary>> ChildOrErr =
            C.getAsBinary(ContextPtr);
          if (!ChildOrErr) {
            if (auto E = isNotObjectErrorInvalidFileType(
                                 ChildOrErr.takeError()))
              error(std::move(E), Filename, C, moreThanOneArch ?
                    StringRef(ArchitectureName) : StringRef());
            continue;
          }
          if (SymbolicFile *F = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
            if (PrintFileName) {
              ArchiveName = std::string(A->getFileName());
              if (isa<MachOObjectFile>(F) && moreThanOneArch)
                ArchitectureName = O.getArchFlagName();
            } else {
              outs() << "\n" << A->getFileName();
              if (isa<MachOObjectFile>(F)) {
                outs() << "(" << F->getFileName() << ")";
                if (moreThanOneArch)
                  outs() << " (for architecture " << O.getArchFlagName()
                         << ")";
              } else
                outs() << ":" << F->getFileName();
              outs() << ":\n";
            }
            dumpSymbolNamesFromObject(*F, false, ArchiveName, ArchitectureName);
          }
        }
        if (Err)
          error(std::move(Err), A->getFileName());
      } else {
        consumeError(AOrErr.takeError());
        error(Filename + " for architecture " +
              StringRef(O.getArchFlagName()) +
              " is not a Mach-O file or an archive file",
              "Mach-O universal file");
      }
    }
    return;
  }

  if (TapiUniversal *TU = dyn_cast<TapiUniversal>(&Bin)) {
    for (const TapiUniversal::ObjectForArch &I : TU->objects()) {
      StringRef ArchName = I.getArchFlagName();
      const bool ShowArch =
          ArchFlags.empty() || llvm::is_contained(ArchFlags, ArchName);
      if (!ShowArch)
        continue;
      if (!AddInlinedInfo && !I.isTopLevelLib())
        continue;
      if (auto ObjOrErr = I.getAsObjectFile()) {
        outs() << "\n"
               << I.getInstallName() << " (for architecture " << ArchName << ")"
               << ":\n";
        dumpSymbolNamesFromObject(*ObjOrErr.get(), false, {}, ArchName);
      } else if (Error E =
                     isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
        error(std::move(E), Filename, ArchName);
      }
    }

    return;
  }

  if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) {
    if (!MachOPrintSizeWarning && PrintSize &&  isa<MachOObjectFile>(O)) {
      WithColor::warning(errs(), ToolName)
          << "sizes with --print-size for Mach-O files are always zero.\n";
      MachOPrintSizeWarning = true;
    }
    if (!checkMachOAndArchFlags(O, Filename))
      return;
    dumpSymbolNamesFromObject(*O, true);
  }
}

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);
  cl::HideUnrelatedOptions(NMCat);
  cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n");

  // llvm-nm only reads binary files.
  if (error(sys::ChangeStdinToBinary()))
    return 1;

  // These calls are needed so that we can read bitcode correctly.
  llvm::InitializeAllTargetInfos();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmParsers();

  ToolName = argv[0];
  if (BSDFormat)
    OutputFormat = bsd;
  if (POSIXFormat)
    OutputFormat = posix;
  if (DarwinFormat)
    OutputFormat = darwin;

  // The relative order of these is important. If you pass --size-sort it should
  // only print out the size. However, if you pass -S --size-sort, it should
  // print out both the size and address.
  if (SizeSort && !PrintSize)
    PrintAddress = false;
  if (OutputFormat == sysv || SizeSort)
    PrintSize = true;
  if (InputFilenames.empty())
    InputFilenames.push_back("a.out");
  if (InputFilenames.size() > 1)
    MultipleFiles = true;

  // If both --demangle and --no-demangle are specified then pick the last one.
  if (NoDemangle.getPosition() > Demangle.getPosition())
    Demangle = !NoDemangle;

  for (unsigned i = 0; i < ArchFlags.size(); ++i) {
    if (ArchFlags[i] == "all") {
      ArchAll = true;
    } else {
      if (!MachOObjectFile::isValidArch(ArchFlags[i]))
        error("Unknown architecture named '" + ArchFlags[i] + "'",
              "for the --arch option");
    }
  }

  if (!SegSect.empty() && SegSect.size() != 2)
    error("bad number of arguments (must be two arguments)",
          "for the -s option");

  if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly))
    error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only");

  llvm::for_each(InputFilenames, dumpSymbolNamesFromFile);

  if (HadError)
    return 1;
}
