//===-- 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/BinaryFormat/XCOFF.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/Object/XCOFFObjectFile.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/LLVMDriver.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 "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/Triple.h"
#include <vector>

using namespace llvm;
using namespace object;

namespace {
using namespace llvm::opt; // for HelpHidden in Opts.inc
enum ID {
  OPT_INVALID = 0, // This is not an option ID.
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELPTEXT, METAVAR, VALUES)                                      \
  OPT_##ID,
#include "Opts.inc"
#undef OPTION
};

#define PREFIX(NAME, VALUE)                                                    \
  static constexpr StringLiteral NAME##_init[] = VALUE;                        \
  static constexpr ArrayRef<StringLiteral> NAME(NAME##_init,                   \
                                                std::size(NAME##_init) - 1);
#include "Opts.inc"
#undef PREFIX

static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
               HELPTEXT, METAVAR, VALUES)                                      \
  {                                                                            \
      PREFIX,      NAME,      HELPTEXT,                                        \
      METAVAR,     OPT_##ID,  opt::Option::KIND##Class,                        \
      PARAM,       FLAGS,     OPT_##GROUP,                                     \
      OPT_##ALIAS, ALIASARGS, VALUES},
#include "Opts.inc"
#undef OPTION
};

class NmOptTable : public opt::GenericOptTable {
public:
  NmOptTable() : opt::GenericOptTable(InfoTable) {
    setGroupedShortOptions(true);
  }
};

enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };
enum class BitModeTy { Bit32, Bit64, Bit32_64, Any };
} // namespace

static bool ArchiveMap;
static BitModeTy BitMode;
static bool DebugSyms;
static bool DefinedOnly;
static bool Demangle;
static bool DynamicSyms;
static bool ExportSymbols;
static bool ExternalOnly;
static OutputFormatTy OutputFormat;
static bool NoLLVMBitcode;
static bool NoSort;
static bool NoWeakSymbols;
static bool NumericSort;
static bool PrintFileName;
static bool PrintSize;
static bool Quiet;
static bool ReverseSort;
static bool SpecialSyms;
static bool SizeSort;
static bool UndefinedOnly;
static bool WithoutAliases;

// XCOFF-specific options.
static bool NoRsrc;

namespace {
enum Radix { d, o, x };
} // namespace
static Radix AddressRadix;

// Mach-O specific options.
static bool ArchAll = false;
static std::vector<StringRef> ArchFlags;
static bool AddDyldInfo;
static bool AddInlinedInfo;
static bool DyldInfoOnly;
static bool FormatMachOasHex;
static bool NoDyldInfo;
static std::vector<StringRef> SegSect;
static bool MachOPrintSizeWarning = false;

// Miscellaneous states.
static bool PrintAddress = true;
static bool MultipleFiles = false;
static bool HadError = false;

static StringRef ToolName;

static void warn(Error Err, Twine FileName, Twine Context = Twine(),
                 Twine Archive = Twine()) {
  assert(Err);

  // Flush the standard output so that the warning isn't interleaved with other
  // output if stdout and stderr are writing to the same place.
  outs().flush();

  handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
    WithColor::warning(errs(), ToolName)
        << (Archive.str().empty() ? FileName : Archive + "(" + FileName + ")")
        << ": " << (Context.str().empty() ? "" : Context + ": ") << EI.message()
        << "\n";
  });
}

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;
  StringRef Visibility;

  // 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;

  bool isDefined() const {
    if (Sym.getRawDataRefImpl().p) {
      uint32_t Flags = cantFail(Sym.getFlags());
      return !(Flags & SymbolRef::SF_Undefined);
    }
    return TypeChar != 'U';
  }

  bool initializeFlags(const SymbolicFile &Obj) {
    Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
    if (!SymFlagsOrErr) {
      // TODO: Test this error.
      error(SymFlagsOrErr.takeError(), Obj.getFileName());
      return false;
    }
    SymFlags = *SymFlagsOrErr;
    return true;
  }

  bool shouldPrint() const {
    bool Undefined = SymFlags & SymbolRef::SF_Undefined;
    bool Global = SymFlags & SymbolRef::SF_Global;
    bool Weak = SymFlags & SymbolRef::SF_Weak;
    bool FormatSpecific = SymFlags & SymbolRef::SF_FormatSpecific;
    if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) ||
        (!Global && ExternalOnly) || (Weak && NoWeakSymbols) ||
        (FormatSpecific && !(SpecialSyms || DebugSyms)))
      return false;
    return true;
  }
};

bool operator<(const NMSymbol &A, const NMSymbol &B) {
  if (NumericSort)
    return std::make_tuple(A.isDefined(), A.Address, A.Name, A.Size) <
           std::make_tuple(B.isDefined(), B.Address, B.Name, B.Size);
  if (SizeSort)
    return std::make_tuple(A.Size, A.Name, A.Address) <
           std::make_tuple(B.Size, B.Name, B.Address);
  if (ExportSymbols)
    return std::make_tuple(A.Name, A.Visibility) <
           std::make_tuple(B.Name, B.Visibility);
  return std::make_tuple(A.Name, A.Size, A.Address) <
         std::make_tuple(B.Name, B.Size, B.Address);
}

bool operator>(const NMSymbol &A, const NMSymbol &B) { return B < A; }
bool operator==(const NMSymbol &A, const NMSymbol &B) {
  return !(A < B) && !(B < A);
}
} // anonymous namespace

static StringRef CurrentFilename;

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;
};
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 : ArrayRef(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 std::optional<std::string> demangle(StringRef Name) {
  std::string Demangled;
  if (nonMicrosoftDemangle(Name, Demangled))
    return Demangled;
  return std::nullopt;
}

static std::optional<std::string> demangleXCOFF(StringRef Name) {
  if (Name.empty() || Name[0] != '.')
    return demangle(Name);

  Name = Name.drop_front();
  std::optional<std::string> DemangledName = demangle(Name);
  if (DemangledName)
    return "." + *DemangledName;
  return std::nullopt;
}

static std::optional<std::string> demangleMachO(StringRef Name) {
  if (!Name.empty() && Name[0] == '_')
    Name = Name.drop_front();
  return demangle(Name);
}

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 void sortSymbolList(std::vector<NMSymbol> &SymbolList) {
  if (NoSort)
    return;

  if (ReverseSort)
    llvm::sort(SymbolList, std::greater<>());
  else
    llvm::sort(SymbolList);
}

static void printExportSymbolList(const std::vector<NMSymbol> &SymbolList) {
  for (const NMSymbol &Sym : SymbolList) {
    outs() << Sym.Name;
    if (!Sym.Visibility.empty())
      outs() << ' ' << Sym.Visibility;
    outs() << '\n';
  }
}

static void printSymbolList(SymbolicFile &Obj,
                            std::vector<NMSymbol> &SymbolList, bool printName,
                            StringRef ArchiveName, StringRef ArchitectureName) {
  if (!PrintFileName) {
    if ((OutputFormat == bsd || OutputFormat == posix ||
         OutputFormat == just_symbols) &&
        MultipleFiles && printName) {
      outs() << '\n' << CurrentFilename << ":\n";
    } else if (OutputFormat == sysv) {
      outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n";
      if (Obj.is64Bit())
        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 (Obj.is64Bit()) {
    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) {
    if (!S.shouldPrint())
      continue;

    std::string Name = S.Name;
    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
    if (Demangle) {
      function_ref<std::optional<std::string>(StringRef)> Fn = ::demangle;
      if (Obj.isXCOFF())
        Fn = demangleXCOFF;
      if (Obj.isMachO())
        Fn = demangleMachO;
      if (std::optional<std::string> Opt = Fn(S.Name))
        Name = *Opt;
    }

    if (PrintFileName)
      writeFileName(outs(), ArchiveName, ArchitectureName);
    if ((OutputFormat == just_symbols ||
         (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(XCOFFObjectFile &Obj, symbol_iterator I) {
  Expected<uint32_t> TypeOrErr = I->getType();
  if (!TypeOrErr) {
    warn(TypeOrErr.takeError(), Obj.getFileName(),
         "for symbol with index " +
             Twine(Obj.getSymbolIndex(I->getRawDataRefImpl().p)));
    return '?';
  }

  uint32_t SymType = *TypeOrErr;

  if (SymType == SymbolRef::ST_File)
    return 'f';

  // If the I->getSection() call would return an error, the earlier I->getType()
  // call will already have returned the same error first.
  section_iterator SecIter = cantFail(I->getSection());

  if (SecIter == Obj.section_end())
    return '?';

  if (Obj.isDebugSection(SecIter->getRawDataRefImpl()))
    return 'N';

  if (SecIter->isText())
    return 't';

  if (SecIter->isData())
    return 'd';

  if (SecIter->isBSS())
    return 'b';

  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) {
  auto Type = cantFail(Obj.getSymbolType(I->getRawDataRefImpl()));
  switch (Type) {
  case SymbolRef::ST_Data:
    return 'd';
  case SymbolRef::ST_Function:
    return 't';
  default:
    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_Undefined) {
    if (isa<MachOObjectFile>(Obj) || !(Symflags & object::SymbolRef::SF_Weak))
      return 'U';
    return isObject(Obj, I) ? 'v' : 'w';
  }
  if (isa<ELFObjectFileBase>(&Obj))
    if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
      return 'i';
  if (!isa<MachOObjectFile>(Obj) && (Symflags & object::SymbolRef::SF_Weak))
    return isObject(Obj, I) ? 'V' : 'W';

  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 (XCOFFObjectFile *XCOFF = dyn_cast<XCOFFObjectFile>(&Obj))
    Ret = getSymbolNMTypeChar(*XCOFF, 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)) {
    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 getSymbolNamesFromObject()
// 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
// getSymbolNamesFromObject() 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,
                                       std::vector<NMSymbol> &SymbolList) {
  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++;
      }
    }
  }
}

static bool shouldDump(SymbolicFile &Obj) {
  // The -X option is currently only implemented for XCOFF, ELF, and IR object
  // files. The option isn't fundamentally impossible with other formats, just
  // isn't implemented.
  if (!isa<XCOFFObjectFile>(Obj) && !isa<ELFObjectFileBase>(Obj) &&
      !isa<IRObjectFile>(Obj))
    return true;

  return Obj.is64Bit() ? BitMode != BitModeTy::Bit32
                       : BitMode != BitModeTy::Bit64;
}

static void getXCOFFExports(XCOFFObjectFile *XCOFFObj,
                            std::vector<NMSymbol> &SymbolList,
                            StringRef ArchiveName) {
  // Skip Shared object file.
  if (XCOFFObj->getFlags() & XCOFF::F_SHROBJ)
    return;

  for (SymbolRef Sym : XCOFFObj->symbols()) {
    // There is no visibility in old 32 bit XCOFF object file interpret.
    bool HasVisibilityAttr =
        XCOFFObj->is64Bit() || (XCOFFObj->auxiliaryHeader32() &&
                                (XCOFFObj->auxiliaryHeader32()->getVersion() ==
                                 XCOFF::NEW_XCOFF_INTERPRET));

    if (HasVisibilityAttr) {
      XCOFFSymbolRef XCOFFSym = XCOFFObj->toSymbolRef(Sym.getRawDataRefImpl());
      uint16_t SymType = XCOFFSym.getSymbolType();
      if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_INTERNAL)
        continue;
      if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_HIDDEN)
        continue;
    }

    Expected<section_iterator> SymSecOrErr = Sym.getSection();
    if (!SymSecOrErr) {
      warn(SymSecOrErr.takeError(), XCOFFObj->getFileName(),
           "for symbol with index " +
               Twine(XCOFFObj->getSymbolIndex(Sym.getRawDataRefImpl().p)),
           ArchiveName);
      continue;
    }
    section_iterator SecIter = *SymSecOrErr;
    // If the symbol is not in a text or data section, it is not exported.
    if (SecIter == XCOFFObj->section_end())
      continue;
    if (!(SecIter->isText() || SecIter->isData() || SecIter->isBSS()))
      continue;

    StringRef SymName = cantFail(Sym.getName());
    if (SymName.empty())
      continue;
    if (SymName.startswith("__sinit") || SymName.startswith("__sterm") ||
        SymName.front() == '.' || SymName.front() == '(')
      continue;

    // Check the SymName regex matching with "^__[0-9]+__".
    if (SymName.size() > 4 && SymName.startswith("__") &&
        SymName.endswith("__")) {
      if (std::all_of(SymName.begin() + 2, SymName.end() - 2, isDigit))
        continue;
    }

    if (SymName == "__rsrc" && NoRsrc)
      continue;

    if (SymName.startswith("__tf1"))
      SymName = SymName.substr(6);
    else if (SymName.startswith("__tf9"))
      SymName = SymName.substr(14);

    NMSymbol S = {};
    S.Name = SymName.str();
    S.Sym = Sym;

    if (HasVisibilityAttr) {
      XCOFFSymbolRef XCOFFSym = XCOFFObj->toSymbolRef(Sym.getRawDataRefImpl());
      uint16_t SymType = XCOFFSym.getSymbolType();
      if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_PROTECTED)
        S.Visibility = "protected";
      else if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_EXPORTED)
        S.Visibility = "export";
    }
    if (S.initializeFlags(*XCOFFObj))
      SymbolList.push_back(S);
  }
}

static Expected<SymbolicFile::basic_symbol_iterator_range>
getDynamicSyms(SymbolicFile &Obj) {
  const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
  if (!E)
    return createError("File format has no dynamic symbol table");
  return E->getDynamicSymbolIterators();
}

// Returns false if there is error found or true otherwise.
static bool getSymbolNamesFromObject(SymbolicFile &Obj,
                                     std::vector<NMSymbol> &SymbolList) {
  auto Symbols = Obj.symbols();
  std::vector<VersionEntry> SymbolVersions;

  if (DynamicSyms) {
    Expected<SymbolicFile::basic_symbol_iterator_range> SymbolsOrErr =
        getDynamicSyms(Obj);
    if (!SymbolsOrErr) {
      error(SymbolsOrErr.takeError(), Obj.getFileName());
      return false;
    }
    Symbols = *SymbolsOrErr;
    if (const auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
      if (Expected<std::vector<VersionEntry>> VersionsOrErr =
              E->readDynsymVersions())
        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 false;
  }

  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 false;
      }

      // Don't drop format specifc symbols for ARM and AArch64 ELF targets, they
      // are used to repesent mapping symbols and needed to honor the
      // --special-syms option.
      auto *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj);
      if ((!ELFObj || (ELFObj->getEMachine() != ELF::EM_ARM &&
                       ELFObj->getEMachine() != ELF::EM_AARCH64)) &&
          !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 (const XCOFFObjectFile *XCOFFObj =
              dyn_cast<const XCOFFObjectFile>(&Obj))
        S.Size = XCOFFObj->getSymbolSize(Sym.getRawDataRefImpl());

      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].IsVerDef ? "@@" : "@") + SymbolVersions[I].Name;

      S.Sym = Sym;
      if (S.initializeFlags(Obj))
        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, SymbolList);

  return true;
}

static void printObjectLabel(bool PrintArchiveName, StringRef ArchiveName,
                             StringRef ArchitectureName,
                             StringRef ObjectFileName) {
  outs() << "\n";
  if (ArchiveName.empty() || !PrintArchiveName)
    outs() << ObjectFileName;
  else
    outs() << ArchiveName << "(" << ObjectFileName << ")";
  if (!ArchitectureName.empty())
    outs() << " (for architecture " << ArchitectureName << ")";
  outs() << ":\n";
}

static Expected<bool> hasSymbols(SymbolicFile &Obj) {
  if (DynamicSyms) {
    Expected<SymbolicFile::basic_symbol_iterator_range> DynamicSymsOrErr =
        getDynamicSyms(Obj);
    if (!DynamicSymsOrErr)
      return DynamicSymsOrErr.takeError();
    return !DynamicSymsOrErr->empty();
  }
  return !Obj.symbols().empty();
}

static void dumpSymbolNamesFromObject(
    SymbolicFile &Obj, std::vector<NMSymbol> &SymbolList,
    bool PrintSymbolObject, bool PrintObjectLabel, StringRef ArchiveName = {},
    StringRef ArchitectureName = {}, StringRef ObjectName = {},
    bool PrintArchiveName = true) {
  if (!shouldDump(Obj))
    return;

  if (ExportSymbols && Obj.isXCOFF()) {
    XCOFFObjectFile *XCOFFObj = cast<XCOFFObjectFile>(&Obj);
    getXCOFFExports(XCOFFObj, SymbolList, ArchiveName);
    return;
  }

  if (PrintObjectLabel && !ExportSymbols)
    printObjectLabel(PrintArchiveName, ArchiveName, ArchitectureName,
                     ObjectName.empty() ? Obj.getFileName() : ObjectName);
  if (!getSymbolNamesFromObject(Obj, SymbolList) || ExportSymbols)
    return;
  CurrentFilename = Obj.getFileName();

  // If there is an error in hasSymbols(), the error should be encountered in
  // function getSymbolNamesFromObject first.
  if (!cantFail(hasSymbols(Obj)) && SymbolList.empty() && !Quiet) {
    writeFileName(errs(), ArchiveName, ArchitectureName);
    errs() << "no symbols\n";
  }

  sortSymbolList(SymbolList);
  printSymbolList(Obj, SymbolList, PrintSymbolObject, 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, StringRef 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 printArchiveMap(iterator_range<Archive::symbol_iterator> &map,
                            StringRef Filename) {
  for (auto I : map) {
    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";
}

static void dumpArchiveMap(Archive *A, StringRef Filename) {
  auto Map = A->symbols();
  if (!Map.empty()) {
    outs() << "Archive map\n";
    printArchiveMap(Map, Filename);
  }

  auto ECMap = A->ec_symbols();
  if (!ECMap) {
    warn(ECMap.takeError(), Filename);
  } else if (!ECMap->empty()) {
    outs() << "Archive EC map\n";
    printArchiveMap(*ECMap, Filename);
  }
}

static void dumpArchive(Archive *A, std::vector<NMSymbol> &SymbolList,
                        StringRef Filename, LLVMContext *ContextPtr) {
  if (ArchiveMap)
    dumpArchiveMap(A, Filename);

  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;
      dumpSymbolNamesFromObject(*O, SymbolList, /*PrintSymbolObject=*/false,
                                !PrintFileName, Filename,
                                /*ArchitectureName=*/{}, O->getFileName(),
                                /*PrintArchiveName=*/false);
    }
  }
  if (Err)
    error(std::move(Err), A->getFileName());
}

static void dumpMachOUniversalBinaryMatchArchFlags(
    MachOUniversalBinary *UB, std::vector<NMSymbol> &SymbolList,
    StringRef Filename, LLVMContext *ContextPtr) {
  // 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)
            ArchitectureName = I->getArchFlagName();
          dumpSymbolNamesFromObject(Obj, SymbolList,
                                    /*PrintSymbolObject=*/false,
                                    (ArchFlags.size() > 1) && !PrintFileName,
                                    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())) {
              ArchiveName = std::string(A->getFileName());
              if (ArchFlags.size() > 1)
                ArchitectureName = I->getArchFlagName();
              dumpSymbolNamesFromObject(
                  *O, SymbolList, /*PrintSymbolObject=*/false, !PrintFileName,
                  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;
    }
  }
}

// Returns true If the binary contains a slice that matches the host
// architecture, or false otherwise.
static bool dumpMachOUniversalBinaryMatchHost(MachOUniversalBinary *UB,
                                              std::vector<NMSymbol> &SymbolList,
                                              StringRef Filename,
                                              LLVMContext *ContextPtr) {
  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, SymbolList, /*PrintSymbolObject=*/false,
                                  /*PrintObjectLabel=*/false);
      } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError()))
        error(std::move(E), Filename);
      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())) {
            ArchiveName = std::string(A->getFileName());
            dumpSymbolNamesFromObject(*O, SymbolList,
                                      /*PrintSymbolObject=*/false,
                                      !PrintFileName, 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 true;
    }
  }
  return false;
}

static void dumpMachOUniversalBinaryArchAll(MachOUniversalBinary *UB,
                                            std::vector<NMSymbol> &SymbolList,
                                            StringRef Filename,
                                            LLVMContext *ContextPtr) {
  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 (isa<MachOObjectFile>(Obj) && moreThanOneArch)
        ArchitectureName = O.getArchFlagName();
      dumpSymbolNamesFromObject(Obj, SymbolList, /*PrintSymbolObject=*/false,
                                !PrintFileName, 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())) {
          ArchiveName = std::string(A->getFileName());
          if (isa<MachOObjectFile>(F) && moreThanOneArch)
            ArchitectureName = O.getArchFlagName();
          dumpSymbolNamesFromObject(*F, SymbolList, /*PrintSymbolObject=*/false,
                                    !PrintFileName, 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");
    }
  }
}

static void dumpMachOUniversalBinary(MachOUniversalBinary *UB,
                                     std::vector<NMSymbol> &SymbolList,
                                     StringRef Filename,
                                     LLVMContext *ContextPtr) {
  // If we have a list of architecture flags specified dump only those.
  if (!ArchAll && !ArchFlags.empty()) {
    dumpMachOUniversalBinaryMatchArchFlags(UB, SymbolList, Filename,
                                           ContextPtr);
    return;
  }

  // No architecture flags were specified so if this contains a slice that
  // matches the host architecture dump only that.
  if (!ArchAll &&
      dumpMachOUniversalBinaryMatchHost(UB, SymbolList, Filename, ContextPtr))
    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.
  dumpMachOUniversalBinaryArchAll(UB, SymbolList, Filename, ContextPtr);
}

static void dumpTapiUniversal(TapiUniversal *TU,
                              std::vector<NMSymbol> &SymbolList,
                              StringRef Filename) {
  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())
      dumpSymbolNamesFromObject(
          *ObjOrErr.get(), SymbolList, /*PrintSymbolObject=*/false,
          /*PrintObjectLabel=*/true,
          /*ArchiveName=*/{}, ArchName, I.getInstallName());
    else if (Error E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
      error(std::move(E), Filename, ArchName);
    }
  }
}

static void dumpSymbolicFile(SymbolicFile *O, std::vector<NMSymbol> &SymbolList,
                             StringRef Filename) {
  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, SymbolList, /*PrintSymbolObject=*/true,
                            /*PrintObjectLabel=*/false);
}

static std::vector<NMSymbol> dumpSymbolNamesFromFile(StringRef Filename) {
  std::vector<NMSymbol> SymbolList;
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
      MemoryBuffer::getFileOrSTDIN(Filename);
  if (error(BufferOrErr.getError(), Filename))
    return SymbolList;

  // Always enable opaque pointers, to handle archives with mixed typed and
  // opaque pointer bitcode files gracefully. As we're only reading symbols,
  // the used pointer types don't matter.
  LLVMContext Context;
  Context.setOpaquePointers(true);
  LLVMContext *ContextPtr = NoLLVMBitcode ? nullptr : &Context;
  Expected<std::unique_ptr<Binary>> BinaryOrErr =
      createBinary(BufferOrErr.get()->getMemBufferRef(), ContextPtr);
  if (!BinaryOrErr) {
    error(BinaryOrErr.takeError(), Filename);
    return SymbolList;
  }
  Binary &Bin = *BinaryOrErr.get();
  if (Archive *A = dyn_cast<Archive>(&Bin))
    dumpArchive(A, SymbolList, Filename, ContextPtr);
  else if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
    dumpMachOUniversalBinary(UB, SymbolList, Filename, ContextPtr);
  else if (TapiUniversal *TU = dyn_cast<TapiUniversal>(&Bin))
    dumpTapiUniversal(TU, SymbolList, Filename);
  else if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin))
    dumpSymbolicFile(O, SymbolList, Filename);
  return SymbolList;
}

static void
exportSymbolNamesFromFiles(const std::vector<std::string> &InputFilenames) {
  std::vector<NMSymbol> SymbolList;
  for (const auto &FileName : InputFilenames) {
    std::vector<NMSymbol> FileSymList = dumpSymbolNamesFromFile(FileName);
    SymbolList.insert(SymbolList.end(), FileSymList.begin(), FileSymList.end());
  }

  // Delete symbols which should not be printed from SymolList.
  llvm::erase_if(SymbolList,
                 [](const NMSymbol &s) { return !s.shouldPrint(); });
  sortSymbolList(SymbolList);
  SymbolList.erase(std::unique(SymbolList.begin(), SymbolList.end()),
                   SymbolList.end());
  printExportSymbolList(SymbolList);
}

int llvm_nm_main(int argc, char **argv, const llvm::ToolContext &) {
  InitLLVM X(argc, argv);
  BumpPtrAllocator A;
  StringSaver Saver(A);
  NmOptTable Tbl;
  ToolName = argv[0];
  opt::InputArgList Args =
      Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
        error(Msg);
        exit(1);
      });
  if (Args.hasArg(OPT_help)) {
    Tbl.printHelp(
        outs(),
        (Twine(ToolName) + " [options] <input object files>").str().c_str(),
        "LLVM symbol table dumper");
    // TODO Replace this with OptTable API once it adds extrahelp support.
    outs() << "\nPass @FILE as argument to read options from FILE.\n";
    return 0;
  }
  if (Args.hasArg(OPT_version)) {
    // This needs to contain the word "GNU", libtool looks for that string.
    outs() << "llvm-nm, compatible with GNU nm" << '\n';
    cl::PrintVersionMessage();
    return 0;
  }

  DebugSyms = Args.hasArg(OPT_debug_syms);
  DefinedOnly = Args.hasArg(OPT_defined_only);
  Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
  DynamicSyms = Args.hasArg(OPT_dynamic);
  ExternalOnly = Args.hasArg(OPT_extern_only);
  StringRef V = Args.getLastArgValue(OPT_format_EQ, "bsd");
  if (V == "bsd")
    OutputFormat = bsd;
  else if (V == "posix")
    OutputFormat = posix;
  else if (V == "sysv")
    OutputFormat = sysv;
  else if (V == "darwin")
    OutputFormat = darwin;
  else if (V == "just-symbols")
    OutputFormat = just_symbols;
  else
    error("--format value should be one of: bsd, posix, sysv, darwin, "
          "just-symbols");
  NoLLVMBitcode = Args.hasArg(OPT_no_llvm_bc);
  NoSort = Args.hasArg(OPT_no_sort);
  NoWeakSymbols = Args.hasArg(OPT_no_weak);
  NumericSort = Args.hasArg(OPT_numeric_sort);
  ArchiveMap = Args.hasArg(OPT_print_armap);
  PrintFileName = Args.hasArg(OPT_print_file_name);
  PrintSize = Args.hasArg(OPT_print_size);
  ReverseSort = Args.hasArg(OPT_reverse_sort);
  ExportSymbols = Args.hasArg(OPT_export_symbols);
  if (ExportSymbols) {
    ExternalOnly = true;
    DefinedOnly = true;
  }

  Quiet = Args.hasArg(OPT_quiet);
  V = Args.getLastArgValue(OPT_radix_EQ, "x");
  if (V == "o")
    AddressRadix = Radix::o;
  else if (V == "d")
    AddressRadix = Radix::d;
  else if (V == "x")
    AddressRadix = Radix::x;
  else
    error("--radix value should be one of: 'o' (octal), 'd' (decimal), 'x' "
          "(hexadecimal)");
  SizeSort = Args.hasArg(OPT_size_sort);
  SpecialSyms = Args.hasArg(OPT_special_syms);
  UndefinedOnly = Args.hasArg(OPT_undefined_only);
  WithoutAliases = Args.hasArg(OPT_without_aliases);

  // Get BitMode from enviornment variable "OBJECT_MODE" for AIX OS, if
  // specified.
  Triple HostTriple(sys::getProcessTriple());
  if (HostTriple.isOSAIX()) {
    BitMode = StringSwitch<BitModeTy>(getenv("OBJECT_MODE"))
                  .Case("32", BitModeTy::Bit32)
                  .Case("64", BitModeTy::Bit64)
                  .Case("32_64", BitModeTy::Bit32_64)
                  .Case("any", BitModeTy::Any)
                  .Default(BitModeTy::Bit32);
  } else
    BitMode = BitModeTy::Any;

  if (Arg *A = Args.getLastArg(OPT_X)) {
    StringRef Mode = A->getValue();
    if (Mode == "32")
      BitMode = BitModeTy::Bit32;
    else if (Mode == "64")
      BitMode = BitModeTy::Bit64;
    else if (Mode == "32_64")
      BitMode = BitModeTy::Bit32_64;
    else if (Mode == "any")
      BitMode = BitModeTy::Any;
    else
      error("-X value should be one of: 32, 64, 32_64, (default) any");
  }

  // Mach-O specific options.
  FormatMachOasHex = Args.hasArg(OPT_x);
  AddDyldInfo = Args.hasArg(OPT_add_dyldinfo);
  AddInlinedInfo = Args.hasArg(OPT_add_inlinedinfo);
  DyldInfoOnly = Args.hasArg(OPT_dyldinfo_only);
  NoDyldInfo = Args.hasArg(OPT_no_dyldinfo);

  // XCOFF specific options.
  NoRsrc = Args.hasArg(OPT_no_rsrc);

  // 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();

  // 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;

  for (const auto *A : Args.filtered(OPT_arch_EQ)) {
    SmallVector<StringRef, 2> Values;
    llvm::SplitString(A->getValue(), Values, ",");
    for (StringRef V : Values) {
      if (V == "all")
        ArchAll = true;
      else if (MachOObjectFile::isValidArch(V))
        ArchFlags.push_back(V);
      else
        error("Unknown architecture named '" + V + "'",
              "for the --arch option");
    }
  }

  // Mach-O takes -s to accept two arguments. We emulate this by iterating over
  // both OPT_s and OPT_INPUT.
  std::vector<std::string> InputFilenames;
  int SegSectArgs = 0;
  for (opt::Arg *A : Args.filtered(OPT_s, OPT_INPUT)) {
    if (SegSectArgs > 0) {
      --SegSectArgs;
      SegSect.push_back(A->getValue());
    } else if (A->getOption().matches(OPT_s)) {
      SegSectArgs = 2;
    } else {
      InputFilenames.push_back(A->getValue());
    }
  }
  if (!SegSect.empty() && SegSect.size() != 2)
    error("bad number of arguments (must be two arguments)",
          "for the -s option");

  if (InputFilenames.empty())
    InputFilenames.push_back("a.out");
  if (InputFilenames.size() > 1)
    MultipleFiles = true;

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

  if (ExportSymbols)
    exportSymbolNamesFromFiles(InputFilenames);
  else
    llvm::for_each(InputFilenames, dumpSymbolNamesFromFile);

  if (HadError)
    return 1;
  return 0;
}
