1219820Sjeff//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===//
2219820Sjeff//
3219820Sjeff// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4219820Sjeff// See https://llvm.org/LICENSE.txt for license information.
5219820Sjeff// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6219820Sjeff//
7219820Sjeff//===----------------------------------------------------------------------===//
8219820Sjeff//
9219820Sjeff// This program is a utility that works like traditional Unix "nm", that is, it
10219820Sjeff// prints out the names of symbols in a bitcode or object file, along with some
11219820Sjeff// information about each symbol.
12219820Sjeff//
13219820Sjeff// This "nm" supports many of the features of GNU "nm", including its different
14219820Sjeff// output formats.
15219820Sjeff//
16219820Sjeff//===----------------------------------------------------------------------===//
17219820Sjeff
18219820Sjeff#include "llvm/ADT/StringSwitch.h"
19219820Sjeff#include "llvm/ADT/Triple.h"
20219820Sjeff#include "llvm/BinaryFormat/COFF.h"
21219820Sjeff#include "llvm/BinaryFormat/XCOFF.h"
22219820Sjeff#include "llvm/Demangle/Demangle.h"
23219820Sjeff#include "llvm/IR/Function.h"
24219820Sjeff#include "llvm/IR/LLVMContext.h"
25219820Sjeff#include "llvm/Object/Archive.h"
26219820Sjeff#include "llvm/Object/COFF.h"
27219820Sjeff#include "llvm/Object/COFFImportFile.h"
28219820Sjeff#include "llvm/Object/ELFObjectFile.h"
29219820Sjeff#include "llvm/Object/IRObjectFile.h"
30219820Sjeff#include "llvm/Object/MachO.h"
31219820Sjeff#include "llvm/Object/MachOUniversal.h"
32219820Sjeff#include "llvm/Object/ObjectFile.h"
33219820Sjeff#include "llvm/Object/TapiFile.h"
34#include "llvm/Object/TapiUniversal.h"
35#include "llvm/Object/Wasm.h"
36#include "llvm/Object/XCOFFObjectFile.h"
37#include "llvm/Option/Arg.h"
38#include "llvm/Option/ArgList.h"
39#include "llvm/Option/Option.h"
40#include "llvm/Support/CommandLine.h"
41#include "llvm/Support/FileSystem.h"
42#include "llvm/Support/Format.h"
43#include "llvm/Support/Host.h"
44#include "llvm/Support/InitLLVM.h"
45#include "llvm/Support/MemoryBuffer.h"
46#include "llvm/Support/Program.h"
47#include "llvm/Support/Signals.h"
48#include "llvm/Support/TargetSelect.h"
49#include "llvm/Support/WithColor.h"
50#include "llvm/Support/raw_ostream.h"
51#include <vector>
52
53using namespace llvm;
54using namespace object;
55
56namespace {
57using namespace llvm::opt; // for HelpHidden in Opts.inc
58enum ID {
59  OPT_INVALID = 0, // This is not an option ID.
60#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
61               HELPTEXT, METAVAR, VALUES)                                      \
62  OPT_##ID,
63#include "Opts.inc"
64#undef OPTION
65};
66
67#define PREFIX(NAME, VALUE)                                                    \
68  static constexpr StringLiteral NAME##_init[] = VALUE;                        \
69  static constexpr ArrayRef<StringLiteral> NAME(NAME##_init,                   \
70                                                std::size(NAME##_init) - 1);
71#include "Opts.inc"
72#undef PREFIX
73
74static constexpr opt::OptTable::Info InfoTable[] = {
75#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
76               HELPTEXT, METAVAR, VALUES)                                      \
77  {                                                                            \
78      PREFIX,      NAME,      HELPTEXT,                                        \
79      METAVAR,     OPT_##ID,  opt::Option::KIND##Class,                        \
80      PARAM,       FLAGS,     OPT_##GROUP,                                     \
81      OPT_##ALIAS, ALIASARGS, VALUES},
82#include "Opts.inc"
83#undef OPTION
84};
85
86class NmOptTable : public opt::GenericOptTable {
87public:
88  NmOptTable() : opt::GenericOptTable(InfoTable) {
89    setGroupedShortOptions(true);
90  }
91};
92
93enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols };
94enum class BitModeTy { Bit32, Bit64, Bit32_64, Any };
95} // namespace
96
97static bool ArchiveMap;
98static BitModeTy BitMode;
99static bool DebugSyms;
100static bool DefinedOnly;
101static bool Demangle;
102static bool DynamicSyms;
103static bool ExportSymbols;
104static bool ExternalOnly;
105static OutputFormatTy OutputFormat;
106static bool NoLLVMBitcode;
107static bool NoSort;
108static bool NoWeakSymbols;
109static bool NumericSort;
110static bool PrintFileName;
111static bool PrintSize;
112static bool Quiet;
113static bool ReverseSort;
114static bool SpecialSyms;
115static bool SizeSort;
116static bool UndefinedOnly;
117static bool WithoutAliases;
118
119// XCOFF-specific options.
120static bool NoRsrc;
121
122namespace {
123enum Radix { d, o, x };
124} // namespace
125static Radix AddressRadix;
126
127// Mach-O specific options.
128static bool ArchAll = false;
129static std::vector<StringRef> ArchFlags;
130static bool AddDyldInfo;
131static bool AddInlinedInfo;
132static bool DyldInfoOnly;
133static bool FormatMachOasHex;
134static bool NoDyldInfo;
135static std::vector<StringRef> SegSect;
136static bool MachOPrintSizeWarning = false;
137
138// Miscellaneous states.
139static bool PrintAddress = true;
140static bool MultipleFiles = false;
141static bool HadError = false;
142
143static StringRef ToolName;
144
145static void warn(Error Err, Twine FileName, Twine Context = Twine(),
146                 Twine Archive = Twine()) {
147  assert(Err);
148
149  // Flush the standard output so that the warning isn't interleaved with other
150  // output if stdout and stderr are writing to the same place.
151  outs().flush();
152
153  handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
154    WithColor::warning(errs(), ToolName)
155        << (Archive.str().empty() ? FileName : Archive + "(" + FileName + ")")
156        << ": " << (Context.str().empty() ? "" : Context + ": ") << EI.message()
157        << "\n";
158  });
159}
160
161static void error(Twine Message, Twine Path = Twine()) {
162  HadError = true;
163  WithColor::error(errs(), ToolName) << Path << ": " << Message << "\n";
164}
165
166static bool error(std::error_code EC, Twine Path = Twine()) {
167  if (EC) {
168    error(EC.message(), Path);
169    return true;
170  }
171  return false;
172}
173
174// This version of error() prints the archive name and member name, for example:
175// "libx.a(foo.o)" after the ToolName before the error message.  It sets
176// HadError but returns allowing the code to move on to other archive members.
177static void error(llvm::Error E, StringRef FileName, const Archive::Child &C,
178                  StringRef ArchitectureName = StringRef()) {
179  HadError = true;
180  WithColor::error(errs(), ToolName) << FileName;
181
182  Expected<StringRef> NameOrErr = C.getName();
183  // TODO: if we have a error getting the name then it would be nice to print
184  // the index of which archive member this is and or its offset in the
185  // archive instead of "???" as the name.
186  if (!NameOrErr) {
187    consumeError(NameOrErr.takeError());
188    errs() << "(" << "???" << ")";
189  } else
190    errs() << "(" << NameOrErr.get() << ")";
191
192  if (!ArchitectureName.empty())
193    errs() << " (for architecture " << ArchitectureName << ")";
194
195  std::string Buf;
196  raw_string_ostream OS(Buf);
197  logAllUnhandledErrors(std::move(E), OS);
198  OS.flush();
199  errs() << ": " << Buf << "\n";
200}
201
202// This version of error() prints the file name and which architecture slice it
203// is from, for example: "foo.o (for architecture i386)" after the ToolName
204// before the error message.  It sets HadError but returns allowing the code to
205// move on to other architecture slices.
206static void error(llvm::Error E, StringRef FileName,
207                  StringRef ArchitectureName = StringRef()) {
208  HadError = true;
209  WithColor::error(errs(), ToolName) << FileName;
210
211  if (!ArchitectureName.empty())
212    errs() << " (for architecture " << ArchitectureName << ")";
213
214  std::string Buf;
215  raw_string_ostream OS(Buf);
216  logAllUnhandledErrors(std::move(E), OS);
217  OS.flush();
218  errs() << ": " << Buf << "\n";
219}
220
221namespace {
222struct NMSymbol {
223  uint64_t Address;
224  uint64_t Size;
225  char TypeChar;
226  std::string Name;
227  StringRef SectionName;
228  StringRef TypeName;
229  BasicSymbolRef Sym;
230  StringRef Visibility;
231
232  // The Sym field above points to the native symbol in the object file,
233  // for Mach-O when we are creating symbols from the dyld info the above
234  // pointer is null as there is no native symbol.  In these cases the fields
235  // below are filled in to represent what would have been a Mach-O nlist
236  // native symbol.
237  uint32_t SymFlags;
238  SectionRef Section;
239  uint8_t NType;
240  uint8_t NSect;
241  uint16_t NDesc;
242  std::string IndirectName;
243
244  bool isDefined() const {
245    if (Sym.getRawDataRefImpl().p) {
246      uint32_t Flags = cantFail(Sym.getFlags());
247      return !(Flags & SymbolRef::SF_Undefined);
248    }
249    return TypeChar != 'U';
250  }
251
252  bool initializeFlags(const SymbolicFile &Obj) {
253    Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
254    if (!SymFlagsOrErr) {
255      // TODO: Test this error.
256      error(SymFlagsOrErr.takeError(), Obj.getFileName());
257      return false;
258    }
259    SymFlags = *SymFlagsOrErr;
260    return true;
261  }
262
263  bool shouldPrint() const {
264    bool Undefined = SymFlags & SymbolRef::SF_Undefined;
265    bool Global = SymFlags & SymbolRef::SF_Global;
266    bool Weak = SymFlags & SymbolRef::SF_Weak;
267    bool FormatSpecific = SymFlags & SymbolRef::SF_FormatSpecific;
268    if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) ||
269        (!Global && ExternalOnly) || (Weak && NoWeakSymbols) ||
270        (FormatSpecific && !(SpecialSyms || DebugSyms)))
271      return false;
272    return true;
273  }
274};
275
276bool operator<(const NMSymbol &A, const NMSymbol &B) {
277  if (NumericSort)
278    return std::make_tuple(A.isDefined(), A.Address, A.Name, A.Size) <
279           std::make_tuple(B.isDefined(), B.Address, B.Name, B.Size);
280  if (SizeSort)
281    return std::make_tuple(A.Size, A.Name, A.Address) <
282           std::make_tuple(B.Size, B.Name, B.Address);
283  if (ExportSymbols)
284    return std::make_tuple(A.Name, A.Visibility) <
285           std::make_tuple(B.Name, B.Visibility);
286  return std::make_tuple(A.Name, A.Size, A.Address) <
287         std::make_tuple(B.Name, B.Size, B.Address);
288}
289
290bool operator>(const NMSymbol &A, const NMSymbol &B) { return B < A; }
291bool operator==(const NMSymbol &A, const NMSymbol &B) {
292  return !(A < B) && !(B < A);
293}
294} // anonymous namespace
295
296static char isSymbolList64Bit(SymbolicFile &Obj) {
297  if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj))
298    return Triple(IRObj->getTargetTriple()).isArch64Bit();
299  if (isa<COFFObjectFile>(Obj) || isa<COFFImportFile>(Obj))
300    return false;
301  if (XCOFFObjectFile *XCOFFObj = dyn_cast<XCOFFObjectFile>(&Obj))
302    return XCOFFObj->is64Bit();
303  if (isa<WasmObjectFile>(Obj))
304    return false;
305  if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
306    return Tapi->is64Bit();
307  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
308    return MachO->is64Bit();
309  return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8;
310}
311
312static StringRef CurrentFilename;
313
314static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I);
315
316// darwinPrintSymbol() is used to print a symbol from a Mach-O file when the
317// the OutputFormat is darwin or we are printing Mach-O symbols in hex.  For
318// the darwin format it produces the same output as darwin's nm(1) -m output
319// and when printing Mach-O symbols in hex it produces the same output as
320// darwin's nm(1) -x format.
321static void darwinPrintSymbol(SymbolicFile &Obj, const NMSymbol &S,
322                              char *SymbolAddrStr, const char *printBlanks,
323                              const char *printDashes,
324                              const char *printFormat) {
325  MachO::mach_header H;
326  MachO::mach_header_64 H_64;
327  uint32_t Filetype = MachO::MH_OBJECT;
328  uint32_t Flags = 0;
329  uint8_t NType = 0;
330  uint8_t NSect = 0;
331  uint16_t NDesc = 0;
332  uint32_t NStrx = 0;
333  uint64_t NValue = 0;
334  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
335  if (Obj.isIR()) {
336    uint32_t SymFlags = cantFail(S.Sym.getFlags());
337    if (SymFlags & SymbolRef::SF_Global)
338      NType |= MachO::N_EXT;
339    if (SymFlags & SymbolRef::SF_Hidden)
340      NType |= MachO::N_PEXT;
341    if (SymFlags & SymbolRef::SF_Undefined)
342      NType |= MachO::N_EXT | MachO::N_UNDF;
343    else {
344      // Here we have a symbol definition.  So to fake out a section name we
345      // use 1, 2 and 3 for section numbers.  See below where they are used to
346      // print out fake section names.
347      NType |= MachO::N_SECT;
348      if (SymFlags & SymbolRef::SF_Const)
349        NSect = 3;
350      else if (SymFlags & SymbolRef::SF_Executable)
351        NSect = 1;
352      else
353        NSect = 2;
354    }
355    if (SymFlags & SymbolRef::SF_Weak)
356      NDesc |= MachO::N_WEAK_DEF;
357  } else {
358    DataRefImpl SymDRI = S.Sym.getRawDataRefImpl();
359    if (MachO->is64Bit()) {
360      H_64 = MachO->MachOObjectFile::getHeader64();
361      Filetype = H_64.filetype;
362      Flags = H_64.flags;
363      if (SymDRI.p){
364        MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(SymDRI);
365        NType = STE_64.n_type;
366        NSect = STE_64.n_sect;
367        NDesc = STE_64.n_desc;
368        NStrx = STE_64.n_strx;
369        NValue = STE_64.n_value;
370      } else {
371        NType = S.NType;
372        NSect = S.NSect;
373        NDesc = S.NDesc;
374        NStrx = 0;
375        NValue = S.Address;
376      }
377    } else {
378      H = MachO->MachOObjectFile::getHeader();
379      Filetype = H.filetype;
380      Flags = H.flags;
381      if (SymDRI.p){
382        MachO::nlist STE = MachO->getSymbolTableEntry(SymDRI);
383        NType = STE.n_type;
384        NSect = STE.n_sect;
385        NDesc = STE.n_desc;
386        NStrx = STE.n_strx;
387        NValue = STE.n_value;
388      } else {
389        NType = S.NType;
390        NSect = S.NSect;
391        NDesc = S.NDesc;
392        NStrx = 0;
393        NValue = S.Address;
394      }
395    }
396  }
397
398  // If we are printing Mach-O symbols in hex do that and return.
399  if (FormatMachOasHex) {
400    outs() << format(printFormat, NValue) << ' '
401           << format("%02x %02x %04x %08x", NType, NSect, NDesc, NStrx) << ' '
402           << S.Name;
403    if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
404      outs() << " (indirect for ";
405      outs() << format(printFormat, NValue) << ' ';
406      StringRef IndirectName;
407      if (S.Sym.getRawDataRefImpl().p) {
408        if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName))
409          outs() << "?)";
410        else
411          outs() << IndirectName << ")";
412      } else
413        outs() << S.IndirectName << ")";
414    }
415    outs() << "\n";
416    return;
417  }
418
419  if (PrintAddress) {
420    if ((NType & MachO::N_TYPE) == MachO::N_INDR)
421      strcpy(SymbolAddrStr, printBlanks);
422    if (Obj.isIR() && (NType & MachO::N_TYPE) == MachO::N_TYPE)
423      strcpy(SymbolAddrStr, printDashes);
424    outs() << SymbolAddrStr << ' ';
425  }
426
427  switch (NType & MachO::N_TYPE) {
428  case MachO::N_UNDF:
429    if (NValue != 0) {
430      outs() << "(common) ";
431      if (MachO::GET_COMM_ALIGN(NDesc) != 0)
432        outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") ";
433    } else {
434      if ((NType & MachO::N_TYPE) == MachO::N_PBUD)
435        outs() << "(prebound ";
436      else
437        outs() << "(";
438      if ((NDesc & MachO::REFERENCE_TYPE) ==
439          MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
440        outs() << "undefined [lazy bound]) ";
441      else if ((NDesc & MachO::REFERENCE_TYPE) ==
442               MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY)
443        outs() << "undefined [private lazy bound]) ";
444      else if ((NDesc & MachO::REFERENCE_TYPE) ==
445               MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)
446        outs() << "undefined [private]) ";
447      else
448        outs() << "undefined) ";
449    }
450    break;
451  case MachO::N_ABS:
452    outs() << "(absolute) ";
453    break;
454  case MachO::N_INDR:
455    outs() << "(indirect) ";
456    break;
457  case MachO::N_SECT: {
458    if (Obj.isIR()) {
459      // For llvm bitcode files print out a fake section name using the values
460      // use 1, 2 and 3 for section numbers as set above.
461      if (NSect == 1)
462        outs() << "(LTO,CODE) ";
463      else if (NSect == 2)
464        outs() << "(LTO,DATA) ";
465      else if (NSect == 3)
466        outs() << "(LTO,RODATA) ";
467      else
468        outs() << "(?,?) ";
469      break;
470    }
471    section_iterator Sec = SectionRef();
472    if (S.Sym.getRawDataRefImpl().p) {
473      Expected<section_iterator> SecOrErr =
474          MachO->getSymbolSection(S.Sym.getRawDataRefImpl());
475      if (!SecOrErr) {
476        consumeError(SecOrErr.takeError());
477        outs() << "(?,?) ";
478        break;
479      }
480      Sec = *SecOrErr;
481      if (Sec == MachO->section_end()) {
482        outs() << "(?,?) ";
483        break;
484      }
485    } else {
486      Sec = S.Section;
487    }
488    DataRefImpl Ref = Sec->getRawDataRefImpl();
489    StringRef SectionName;
490    if (Expected<StringRef> NameOrErr = MachO->getSectionName(Ref))
491      SectionName = *NameOrErr;
492    StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref);
493    outs() << "(" << SegmentName << "," << SectionName << ") ";
494    break;
495  }
496  default:
497    outs() << "(?) ";
498    break;
499  }
500
501  if (NType & MachO::N_EXT) {
502    if (NDesc & MachO::REFERENCED_DYNAMICALLY)
503      outs() << "[referenced dynamically] ";
504    if (NType & MachO::N_PEXT) {
505      if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF)
506        outs() << "weak private external ";
507      else
508        outs() << "private external ";
509    } else {
510      if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF ||
511          (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) {
512        if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) ==
513            (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
514          outs() << "weak external automatically hidden ";
515        else
516          outs() << "weak external ";
517      } else
518        outs() << "external ";
519    }
520  } else {
521    if (NType & MachO::N_PEXT)
522      outs() << "non-external (was a private external) ";
523    else
524      outs() << "non-external ";
525  }
526
527  if (Filetype == MachO::MH_OBJECT) {
528    if (NDesc & MachO::N_NO_DEAD_STRIP)
529      outs() << "[no dead strip] ";
530    if ((NType & MachO::N_TYPE) != MachO::N_UNDF &&
531        NDesc & MachO::N_SYMBOL_RESOLVER)
532      outs() << "[symbol resolver] ";
533    if ((NType & MachO::N_TYPE) != MachO::N_UNDF && NDesc & MachO::N_ALT_ENTRY)
534      outs() << "[alt entry] ";
535    if ((NType & MachO::N_TYPE) != MachO::N_UNDF && NDesc & MachO::N_COLD_FUNC)
536      outs() << "[cold func] ";
537  }
538
539  if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF)
540    outs() << "[Thumb] ";
541
542  if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
543    outs() << S.Name << " (for ";
544    StringRef IndirectName;
545    if (MachO) {
546      if (S.Sym.getRawDataRefImpl().p) {
547        if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName))
548          outs() << "?)";
549        else
550          outs() << IndirectName << ")";
551      } else
552        outs() << S.IndirectName << ")";
553    } else
554      outs() << "?)";
555  } else
556    outs() << S.Name;
557
558  if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
559      (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
560       (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
561    uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
562    if (LibraryOrdinal != 0) {
563      if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL)
564        outs() << " (from executable)";
565      else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL)
566        outs() << " (dynamically looked up)";
567      else {
568        StringRef LibraryName;
569        if (!MachO ||
570            MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName))
571          outs() << " (from bad library ordinal " << LibraryOrdinal << ")";
572        else
573          outs() << " (from " << LibraryName << ")";
574      }
575    }
576  }
577
578  outs() << "\n";
579}
580
581// Table that maps Darwin's Mach-O stab constants to strings to allow printing.
582struct DarwinStabName {
583  uint8_t NType;
584  const char *Name;
585};
586const struct DarwinStabName DarwinStabNames[] = {
587    {MachO::N_GSYM, "GSYM"},
588    {MachO::N_FNAME, "FNAME"},
589    {MachO::N_FUN, "FUN"},
590    {MachO::N_STSYM, "STSYM"},
591    {MachO::N_LCSYM, "LCSYM"},
592    {MachO::N_BNSYM, "BNSYM"},
593    {MachO::N_PC, "PC"},
594    {MachO::N_AST, "AST"},
595    {MachO::N_OPT, "OPT"},
596    {MachO::N_RSYM, "RSYM"},
597    {MachO::N_SLINE, "SLINE"},
598    {MachO::N_ENSYM, "ENSYM"},
599    {MachO::N_SSYM, "SSYM"},
600    {MachO::N_SO, "SO"},
601    {MachO::N_OSO, "OSO"},
602    {MachO::N_LSYM, "LSYM"},
603    {MachO::N_BINCL, "BINCL"},
604    {MachO::N_SOL, "SOL"},
605    {MachO::N_PARAMS, "PARAM"},
606    {MachO::N_VERSION, "VERS"},
607    {MachO::N_OLEVEL, "OLEV"},
608    {MachO::N_PSYM, "PSYM"},
609    {MachO::N_EINCL, "EINCL"},
610    {MachO::N_ENTRY, "ENTRY"},
611    {MachO::N_LBRAC, "LBRAC"},
612    {MachO::N_EXCL, "EXCL"},
613    {MachO::N_RBRAC, "RBRAC"},
614    {MachO::N_BCOMM, "BCOMM"},
615    {MachO::N_ECOMM, "ECOMM"},
616    {MachO::N_ECOML, "ECOML"},
617    {MachO::N_LENG, "LENG"},
618};
619
620static const char *getDarwinStabString(uint8_t NType) {
621  for (auto I : ArrayRef(DarwinStabNames))
622    if (I.NType == NType)
623      return I.Name;
624  return nullptr;
625}
626
627// darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of
628// a stab n_type value in a Mach-O file.
629static void darwinPrintStab(MachOObjectFile *MachO, const NMSymbol &S) {
630  MachO::nlist_64 STE_64;
631  MachO::nlist STE;
632  uint8_t NType;
633  uint8_t NSect;
634  uint16_t NDesc;
635  DataRefImpl SymDRI = S.Sym.getRawDataRefImpl();
636  if (MachO->is64Bit()) {
637    STE_64 = MachO->getSymbol64TableEntry(SymDRI);
638    NType = STE_64.n_type;
639    NSect = STE_64.n_sect;
640    NDesc = STE_64.n_desc;
641  } else {
642    STE = MachO->getSymbolTableEntry(SymDRI);
643    NType = STE.n_type;
644    NSect = STE.n_sect;
645    NDesc = STE.n_desc;
646  }
647
648  outs() << format(" %02x %04x ", NSect, NDesc);
649  if (const char *stabString = getDarwinStabString(NType))
650    outs() << format("%5.5s", stabString);
651  else
652    outs() << format("   %02x", NType);
653}
654
655static std::optional<std::string> demangle(StringRef Name) {
656  std::string Demangled;
657  if (nonMicrosoftDemangle(Name.str().c_str(), Demangled))
658    return Demangled;
659  return std::nullopt;
660}
661
662static std::optional<std::string> demangleXCOFF(StringRef Name) {
663  if (Name.empty() || Name[0] != '.')
664    return demangle(Name);
665
666  Name = Name.drop_front();
667  std::optional<std::string> DemangledName = demangle(Name);
668  if (DemangledName)
669    return "." + *DemangledName;
670  return std::nullopt;
671}
672
673static std::optional<std::string> demangleMachO(StringRef Name) {
674  if (!Name.empty() && Name[0] == '_')
675    Name = Name.drop_front();
676  return demangle(Name);
677}
678
679static bool symbolIsDefined(const NMSymbol &Sym) {
680  return Sym.TypeChar != 'U' && Sym.TypeChar != 'w' && Sym.TypeChar != 'v';
681}
682
683static void writeFileName(raw_ostream &S, StringRef ArchiveName,
684                          StringRef ArchitectureName) {
685  if (!ArchitectureName.empty())
686    S << "(for architecture " << ArchitectureName << "):";
687  if (OutputFormat == posix && !ArchiveName.empty())
688    S << ArchiveName << "[" << CurrentFilename << "]: ";
689  else {
690    if (!ArchiveName.empty())
691      S << ArchiveName << ":";
692    S << CurrentFilename << ": ";
693  }
694}
695
696static void sortSymbolList(std::vector<NMSymbol> &SymbolList) {
697  if (NoSort)
698    return;
699
700  if (ReverseSort)
701    llvm::sort(SymbolList, std::greater<>());
702  else
703    llvm::sort(SymbolList);
704}
705
706static void printExportSymbolList(const std::vector<NMSymbol> &SymbolList) {
707  for (const NMSymbol &Sym : SymbolList) {
708    outs() << Sym.Name;
709    if (!Sym.Visibility.empty())
710      outs() << ' ' << Sym.Visibility;
711    outs() << '\n';
712  }
713}
714
715static void printSymbolList(SymbolicFile &Obj,
716                            std::vector<NMSymbol> &SymbolList, bool printName,
717                            StringRef ArchiveName, StringRef ArchitectureName) {
718  if (!PrintFileName) {
719    if ((OutputFormat == bsd || OutputFormat == posix ||
720         OutputFormat == just_symbols) &&
721        MultipleFiles && printName) {
722      outs() << '\n' << CurrentFilename << ":\n";
723    } else if (OutputFormat == sysv) {
724      outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n";
725      if (isSymbolList64Bit(Obj))
726        outs() << "Name                  Value           Class        Type"
727               << "         Size             Line  Section\n";
728      else
729        outs() << "Name                  Value   Class        Type"
730               << "         Size     Line  Section\n";
731    }
732  }
733
734  const char *printBlanks, *printDashes, *printFormat;
735  if (isSymbolList64Bit(Obj)) {
736    printBlanks = "                ";
737    printDashes = "----------------";
738    switch (AddressRadix) {
739    case Radix::o:
740      printFormat = OutputFormat == posix ? "%" PRIo64 : "%016" PRIo64;
741      break;
742    case Radix::x:
743      printFormat = OutputFormat == posix ? "%" PRIx64 : "%016" PRIx64;
744      break;
745    default:
746      printFormat = OutputFormat == posix ? "%" PRId64 : "%016" PRId64;
747    }
748  } else {
749    printBlanks = "        ";
750    printDashes = "--------";
751    switch (AddressRadix) {
752    case Radix::o:
753      printFormat = OutputFormat == posix ? "%" PRIo64 : "%08" PRIo64;
754      break;
755    case Radix::x:
756      printFormat = OutputFormat == posix ? "%" PRIx64 : "%08" PRIx64;
757      break;
758    default:
759      printFormat = OutputFormat == posix ? "%" PRId64 : "%08" PRId64;
760    }
761  }
762
763  for (const NMSymbol &S : SymbolList) {
764    if (!S.shouldPrint())
765      continue;
766
767    std::string Name = S.Name;
768    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
769    if (Demangle) {
770      function_ref<std::optional<std::string>(StringRef)> Fn = ::demangle;
771      if (Obj.isXCOFF())
772        Fn = demangleXCOFF;
773      if (Obj.isMachO())
774        Fn = demangleMachO;
775      if (std::optional<std::string> Opt = Fn(S.Name))
776        Name = *Opt;
777    }
778
779    if (PrintFileName)
780      writeFileName(outs(), ArchiveName, ArchitectureName);
781    if ((OutputFormat == just_symbols ||
782         (UndefinedOnly && MachO && OutputFormat != darwin)) &&
783        OutputFormat != posix) {
784      outs() << Name << "\n";
785      continue;
786    }
787
788    char SymbolAddrStr[23], SymbolSizeStr[23];
789
790    // If the format is SysV or the symbol isn't defined, then print spaces.
791    if (OutputFormat == sysv || !symbolIsDefined(S)) {
792      if (OutputFormat == posix) {
793        format(printFormat, S.Address)
794            .print(SymbolAddrStr, sizeof(SymbolAddrStr));
795        format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
796      } else {
797        strcpy(SymbolAddrStr, printBlanks);
798        strcpy(SymbolSizeStr, printBlanks);
799      }
800    }
801
802    if (symbolIsDefined(S)) {
803      // Otherwise, print the symbol address and size.
804      if (Obj.isIR())
805        strcpy(SymbolAddrStr, printDashes);
806      else if (MachO && S.TypeChar == 'I')
807        strcpy(SymbolAddrStr, printBlanks);
808      else
809        format(printFormat, S.Address)
810            .print(SymbolAddrStr, sizeof(SymbolAddrStr));
811      format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
812    }
813
814    // If OutputFormat is darwin or we are printing Mach-O symbols in hex and
815    // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's
816    // nm(1) -m output or hex, else if OutputFormat is darwin or we are
817    // printing Mach-O symbols in hex and not a Mach-O object fall back to
818    // OutputFormat bsd (see below).
819    if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) {
820      darwinPrintSymbol(Obj, S, SymbolAddrStr, printBlanks, printDashes,
821                        printFormat);
822    } else if (OutputFormat == posix) {
823      outs() << Name << " " << S.TypeChar << " " << SymbolAddrStr << " "
824             << (MachO ? "0" : SymbolSizeStr) << "\n";
825    } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) {
826      if (PrintAddress)
827        outs() << SymbolAddrStr << ' ';
828      if (PrintSize)
829        outs() << SymbolSizeStr << ' ';
830      outs() << S.TypeChar;
831      if (S.TypeChar == '-' && MachO)
832        darwinPrintStab(MachO, S);
833      outs() << " " << Name;
834      if (S.TypeChar == 'I' && MachO) {
835        outs() << " (indirect for ";
836        if (S.Sym.getRawDataRefImpl().p) {
837          StringRef IndirectName;
838          if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName))
839            outs() << "?)";
840          else
841            outs() << IndirectName << ")";
842        } else
843          outs() << S.IndirectName << ")";
844      }
845      outs() << "\n";
846    } else if (OutputFormat == sysv) {
847      outs() << left_justify(Name, 20) << "|" << SymbolAddrStr << "|   "
848             << S.TypeChar << "  |" << right_justify(S.TypeName, 18) << "|"
849             << SymbolSizeStr << "|     |" << S.SectionName << "\n";
850    }
851  }
852
853  SymbolList.clear();
854}
855
856static char getSymbolNMTypeChar(ELFObjectFileBase &Obj,
857                                basic_symbol_iterator I) {
858  // OK, this is ELF
859  elf_symbol_iterator SymI(I);
860
861  Expected<elf_section_iterator> SecIOrErr = SymI->getSection();
862  if (!SecIOrErr) {
863    consumeError(SecIOrErr.takeError());
864    return '?';
865  }
866
867  uint8_t Binding = SymI->getBinding();
868  if (Binding == ELF::STB_GNU_UNIQUE)
869    return 'u';
870
871  assert(Binding != ELF::STB_WEAK && "STB_WEAK not tested in calling function");
872  if (Binding != ELF::STB_GLOBAL && Binding != ELF::STB_LOCAL)
873    return '?';
874
875  elf_section_iterator SecI = *SecIOrErr;
876  if (SecI != Obj.section_end()) {
877    uint32_t Type = SecI->getType();
878    uint64_t Flags = SecI->getFlags();
879    if (Flags & ELF::SHF_EXECINSTR)
880      return 't';
881    if (Type == ELF::SHT_NOBITS)
882      return 'b';
883    if (Flags & ELF::SHF_ALLOC)
884      return Flags & ELF::SHF_WRITE ? 'd' : 'r';
885
886    auto NameOrErr = SecI->getName();
887    if (!NameOrErr) {
888      consumeError(NameOrErr.takeError());
889      return '?';
890    }
891    if ((*NameOrErr).startswith(".debug"))
892      return 'N';
893    if (!(Flags & ELF::SHF_WRITE))
894      return 'n';
895  }
896
897  return '?';
898}
899
900static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
901  COFFSymbolRef Symb = Obj.getCOFFSymbol(*I);
902  // OK, this is COFF.
903  symbol_iterator SymI(I);
904
905  Expected<StringRef> Name = SymI->getName();
906  if (!Name) {
907    consumeError(Name.takeError());
908    return '?';
909  }
910
911  char Ret = StringSwitch<char>(*Name)
912                 .StartsWith(".debug", 'N')
913                 .StartsWith(".sxdata", 'N')
914                 .Default('?');
915
916  if (Ret != '?')
917    return Ret;
918
919  uint32_t Characteristics = 0;
920  if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
921    Expected<section_iterator> SecIOrErr = SymI->getSection();
922    if (!SecIOrErr) {
923      consumeError(SecIOrErr.takeError());
924      return '?';
925    }
926    section_iterator SecI = *SecIOrErr;
927    const coff_section *Section = Obj.getCOFFSection(*SecI);
928    Characteristics = Section->Characteristics;
929    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Section))
930      if (NameOrErr->startswith(".idata"))
931        return 'i';
932  }
933
934  switch (Symb.getSectionNumber()) {
935  case COFF::IMAGE_SYM_DEBUG:
936    return 'n';
937  default:
938    // Check section type.
939    if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
940      return 't';
941    if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
942      return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r';
943    if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
944      return 'b';
945    if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
946      return 'i';
947    // Check for section symbol.
948    if (Symb.isSectionDefinition())
949      return 's';
950  }
951
952  return '?';
953}
954
955static char getSymbolNMTypeChar(XCOFFObjectFile &Obj, symbol_iterator I) {
956  Expected<uint32_t> TypeOrErr = I->getType();
957  if (!TypeOrErr) {
958    warn(TypeOrErr.takeError(), Obj.getFileName(),
959         "for symbol with index " +
960             Twine(Obj.getSymbolIndex(I->getRawDataRefImpl().p)));
961    return '?';
962  }
963
964  uint32_t SymType = *TypeOrErr;
965
966  if (SymType == SymbolRef::ST_File)
967    return 'f';
968
969  // If the I->getSection() call would return an error, the earlier I->getType()
970  // call will already have returned the same error first.
971  section_iterator SecIter = cantFail(I->getSection());
972
973  if (SecIter == Obj.section_end())
974    return '?';
975
976  if (Obj.isDebugSection(SecIter->getRawDataRefImpl()))
977    return 'N';
978
979  if (SecIter->isText())
980    return 't';
981
982  if (SecIter->isData())
983    return 'd';
984
985  if (SecIter->isBSS())
986    return 'b';
987
988  return '?';
989}
990
991static char getSymbolNMTypeChar(COFFImportFile &Obj) {
992  switch (Obj.getCOFFImportHeader()->getType()) {
993  case COFF::IMPORT_CODE:
994    return 't';
995  case COFF::IMPORT_DATA:
996    return 'd';
997  case COFF::IMPORT_CONST:
998    return 'r';
999  }
1000  return '?';
1001}
1002
1003static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
1004  DataRefImpl Symb = I->getRawDataRefImpl();
1005  uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type
1006                                : Obj.getSymbolTableEntry(Symb).n_type;
1007
1008  if (NType & MachO::N_STAB)
1009    return '-';
1010
1011  switch (NType & MachO::N_TYPE) {
1012  case MachO::N_ABS:
1013    return 's';
1014  case MachO::N_INDR:
1015    return 'i';
1016  case MachO::N_SECT: {
1017    Expected<section_iterator> SecOrErr = Obj.getSymbolSection(Symb);
1018    if (!SecOrErr) {
1019      consumeError(SecOrErr.takeError());
1020      return 's';
1021    }
1022    section_iterator Sec = *SecOrErr;
1023    if (Sec == Obj.section_end())
1024      return 's';
1025    DataRefImpl Ref = Sec->getRawDataRefImpl();
1026    StringRef SectionName;
1027    if (Expected<StringRef> NameOrErr = Obj.getSectionName(Ref))
1028      SectionName = *NameOrErr;
1029    StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref);
1030    if (Obj.is64Bit() && Obj.getHeader64().filetype == MachO::MH_KEXT_BUNDLE &&
1031        SegmentName == "__TEXT_EXEC" && SectionName == "__text")
1032      return 't';
1033    if (SegmentName == "__TEXT" && SectionName == "__text")
1034      return 't';
1035    if (SegmentName == "__DATA" && SectionName == "__data")
1036      return 'd';
1037    if (SegmentName == "__DATA" && SectionName == "__bss")
1038      return 'b';
1039    return 's';
1040  }
1041  }
1042
1043  return '?';
1044}
1045
1046static char getSymbolNMTypeChar(TapiFile &Obj, basic_symbol_iterator I) {
1047  return 's';
1048}
1049
1050static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) {
1051  uint32_t Flags = cantFail(I->getFlags());
1052  if (Flags & SymbolRef::SF_Executable)
1053    return 't';
1054  return 'd';
1055}
1056
1057static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) {
1058  uint32_t Flags = cantFail(I->getFlags());
1059  // FIXME: should we print 'b'? At the IR level we cannot be sure if this
1060  // will be in bss or not, but we could approximate.
1061  if (Flags & SymbolRef::SF_Executable)
1062    return 't';
1063  else if (Triple(Obj.getTargetTriple()).isOSDarwin() &&
1064           (Flags & SymbolRef::SF_Const))
1065    return 's';
1066  else
1067    return 'd';
1068}
1069
1070static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) {
1071  return isa<ELFObjectFileBase>(&Obj) &&
1072         elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT;
1073}
1074
1075// For ELF object files, Set TypeName to the symbol typename, to be printed
1076// in the 'Type' column of the SYSV format output.
1077static StringRef getNMTypeName(SymbolicFile &Obj, basic_symbol_iterator I) {
1078  if (isa<ELFObjectFileBase>(&Obj)) {
1079    elf_symbol_iterator SymI(I);
1080    return SymI->getELFTypeName();
1081  }
1082  return "";
1083}
1084
1085// Return Posix nm class type tag (single letter), but also set SecName and
1086// section and name, to be used in format=sysv output.
1087static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
1088                                   StringRef &SecName) {
1089  // Symbol Flags have been checked in the caller.
1090  uint32_t Symflags = cantFail(I->getFlags());
1091  if (ELFObjectFileBase *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj)) {
1092    if (Symflags & object::SymbolRef::SF_Absolute)
1093      SecName = "*ABS*";
1094    else if (Symflags & object::SymbolRef::SF_Common)
1095      SecName = "*COM*";
1096    else if (Symflags & object::SymbolRef::SF_Undefined)
1097      SecName = "*UND*";
1098    else {
1099      elf_symbol_iterator SymI(I);
1100      Expected<elf_section_iterator> SecIOrErr = SymI->getSection();
1101      if (!SecIOrErr) {
1102        consumeError(SecIOrErr.takeError());
1103        return '?';
1104      }
1105
1106      if (*SecIOrErr == ELFObj->section_end())
1107        return '?';
1108
1109      Expected<StringRef> NameOrErr = (*SecIOrErr)->getName();
1110      if (!NameOrErr) {
1111        consumeError(NameOrErr.takeError());
1112        return '?';
1113      }
1114      SecName = *NameOrErr;
1115    }
1116  }
1117
1118  if (Symflags & object::SymbolRef::SF_Undefined) {
1119    if (isa<MachOObjectFile>(Obj) || !(Symflags & object::SymbolRef::SF_Weak))
1120      return 'U';
1121    return isObject(Obj, I) ? 'v' : 'w';
1122  }
1123  if (isa<ELFObjectFileBase>(&Obj))
1124    if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
1125      return 'i';
1126  if (!isa<MachOObjectFile>(Obj) && (Symflags & object::SymbolRef::SF_Weak))
1127    return isObject(Obj, I) ? 'V' : 'W';
1128
1129  if (Symflags & object::SymbolRef::SF_Common)
1130    return 'C';
1131
1132  char Ret = '?';
1133  if (Symflags & object::SymbolRef::SF_Absolute)
1134    Ret = 'a';
1135  else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj))
1136    Ret = getSymbolNMTypeChar(*IR, I);
1137  else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj))
1138    Ret = getSymbolNMTypeChar(*COFF, I);
1139  else if (XCOFFObjectFile *XCOFF = dyn_cast<XCOFFObjectFile>(&Obj))
1140    Ret = getSymbolNMTypeChar(*XCOFF, I);
1141  else if (COFFImportFile *COFFImport = dyn_cast<COFFImportFile>(&Obj))
1142    Ret = getSymbolNMTypeChar(*COFFImport);
1143  else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
1144    Ret = getSymbolNMTypeChar(*MachO, I);
1145  else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj))
1146    Ret = getSymbolNMTypeChar(*Wasm, I);
1147  else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
1148    Ret = getSymbolNMTypeChar(*Tapi, I);
1149  else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) {
1150    Ret = getSymbolNMTypeChar(*ELF, I);
1151    if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE)
1152      return Ret;
1153  } else
1154    llvm_unreachable("unknown binary format");
1155
1156  if (!(Symflags & object::SymbolRef::SF_Global))
1157    return Ret;
1158
1159  return toupper(Ret);
1160}
1161
1162// getNsectForSegSect() is used to implement the Mach-O "-s segname sectname"
1163// option to dump only those symbols from that section in a Mach-O file.
1164// It is called once for each Mach-O file from getSymbolNamesFromObject()
1165// to get the section number for that named section from the command line
1166// arguments. It returns the section number for that section in the Mach-O
1167// file or zero it is not present.
1168static unsigned getNsectForSegSect(MachOObjectFile *Obj) {
1169  unsigned Nsect = 1;
1170  for (auto &S : Obj->sections()) {
1171    DataRefImpl Ref = S.getRawDataRefImpl();
1172    StringRef SectionName;
1173    if (Expected<StringRef> NameOrErr = Obj->getSectionName(Ref))
1174      SectionName = *NameOrErr;
1175    StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref);
1176    if (SegmentName == SegSect[0] && SectionName == SegSect[1])
1177      return Nsect;
1178    Nsect++;
1179  }
1180  return 0;
1181}
1182
1183// getNsectInMachO() is used to implement the Mach-O "-s segname sectname"
1184// option to dump only those symbols from that section in a Mach-O file.
1185// It is called once for each symbol in a Mach-O file from
1186// getSymbolNamesFromObject() and returns the section number for that symbol
1187// if it is in a section, else it returns 0.
1188static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) {
1189  DataRefImpl Symb = Sym.getRawDataRefImpl();
1190  if (Obj.is64Bit()) {
1191    MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
1192    return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
1193  }
1194  MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
1195  return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
1196}
1197
1198static void dumpSymbolsFromDLInfoMachO(MachOObjectFile &MachO,
1199                                       std::vector<NMSymbol> &SymbolList) {
1200  size_t I = SymbolList.size();
1201  std::string ExportsNameBuffer;
1202  raw_string_ostream EOS(ExportsNameBuffer);
1203  std::string BindsNameBuffer;
1204  raw_string_ostream BOS(BindsNameBuffer);
1205  std::string LazysNameBuffer;
1206  raw_string_ostream LOS(LazysNameBuffer);
1207  std::string WeaksNameBuffer;
1208  raw_string_ostream WOS(WeaksNameBuffer);
1209  std::string FunctionStartsNameBuffer;
1210  raw_string_ostream FOS(FunctionStartsNameBuffer);
1211
1212  MachO::mach_header H;
1213  MachO::mach_header_64 H_64;
1214  uint32_t HFlags = 0;
1215  if (MachO.is64Bit()) {
1216    H_64 = MachO.MachOObjectFile::getHeader64();
1217    HFlags = H_64.flags;
1218  } else {
1219    H = MachO.MachOObjectFile::getHeader();
1220    HFlags = H.flags;
1221  }
1222  uint64_t BaseSegmentAddress = 0;
1223  for (const auto &Command : MachO.load_commands()) {
1224    if (Command.C.cmd == MachO::LC_SEGMENT) {
1225      MachO::segment_command Seg = MachO.getSegmentLoadCommand(Command);
1226      if (Seg.fileoff == 0 && Seg.filesize != 0) {
1227        BaseSegmentAddress = Seg.vmaddr;
1228        break;
1229      }
1230    } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
1231      MachO::segment_command_64 Seg = MachO.getSegment64LoadCommand(Command);
1232      if (Seg.fileoff == 0 && Seg.filesize != 0) {
1233        BaseSegmentAddress = Seg.vmaddr;
1234        break;
1235      }
1236    }
1237  }
1238  if (DyldInfoOnly || AddDyldInfo ||
1239      HFlags & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) {
1240    unsigned ExportsAdded = 0;
1241    Error Err = Error::success();
1242    for (const llvm::object::ExportEntry &Entry : MachO.exports(Err)) {
1243      bool found = false;
1244      bool ReExport = false;
1245      if (!DyldInfoOnly) {
1246        for (const NMSymbol &S : SymbolList)
1247          if (S.Address == Entry.address() + BaseSegmentAddress &&
1248              S.Name == Entry.name()) {
1249            found = true;
1250            break;
1251          }
1252      }
1253      if (!found) {
1254        NMSymbol S = {};
1255        S.Address = Entry.address() + BaseSegmentAddress;
1256        S.Size = 0;
1257        S.TypeChar = '\0';
1258        S.Name = Entry.name().str();
1259        // There is no symbol in the nlist symbol table for this so we set
1260        // Sym effectivly to null and the rest of code in here must test for
1261        // it and not do things like Sym.getFlags() for it.
1262        S.Sym = BasicSymbolRef();
1263        S.SymFlags = SymbolRef::SF_Global;
1264        S.Section = SectionRef();
1265        S.NType = 0;
1266        S.NSect = 0;
1267        S.NDesc = 0;
1268
1269        uint64_t EFlags = Entry.flags();
1270        bool Abs = ((EFlags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
1271                    MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
1272        bool Resolver = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
1273        ReExport = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
1274        bool WeakDef = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
1275        if (WeakDef)
1276          S.NDesc |= MachO::N_WEAK_DEF;
1277        if (Abs) {
1278          S.NType = MachO::N_EXT | MachO::N_ABS;
1279          S.TypeChar = 'A';
1280        } else if (ReExport) {
1281          S.NType = MachO::N_EXT | MachO::N_INDR;
1282          S.TypeChar = 'I';
1283        } else {
1284          S.NType = MachO::N_EXT | MachO::N_SECT;
1285          if (Resolver) {
1286            S.Address = Entry.other() + BaseSegmentAddress;
1287            if ((S.Address & 1) != 0 && !MachO.is64Bit() &&
1288                H.cputype == MachO::CPU_TYPE_ARM) {
1289              S.Address &= ~1LL;
1290              S.NDesc |= MachO::N_ARM_THUMB_DEF;
1291            }
1292          } else {
1293            S.Address = Entry.address() + BaseSegmentAddress;
1294          }
1295          StringRef SegmentName = StringRef();
1296          StringRef SectionName = StringRef();
1297          for (const SectionRef &Section : MachO.sections()) {
1298            S.NSect++;
1299
1300            if (Expected<StringRef> NameOrErr = Section.getName())
1301              SectionName = *NameOrErr;
1302            else
1303              consumeError(NameOrErr.takeError());
1304
1305            SegmentName =
1306                MachO.getSectionFinalSegmentName(Section.getRawDataRefImpl());
1307            if (S.Address >= Section.getAddress() &&
1308                S.Address < Section.getAddress() + Section.getSize()) {
1309              S.Section = Section;
1310              break;
1311            } else if (Entry.name() == "__mh_execute_header" &&
1312                       SegmentName == "__TEXT" && SectionName == "__text") {
1313              S.Section = Section;
1314              S.NDesc |= MachO::REFERENCED_DYNAMICALLY;
1315              break;
1316            }
1317          }
1318          if (SegmentName == "__TEXT" && SectionName == "__text")
1319            S.TypeChar = 'T';
1320          else if (SegmentName == "__DATA" && SectionName == "__data")
1321            S.TypeChar = 'D';
1322          else if (SegmentName == "__DATA" && SectionName == "__bss")
1323            S.TypeChar = 'B';
1324          else
1325            S.TypeChar = 'S';
1326        }
1327        SymbolList.push_back(S);
1328
1329        EOS << Entry.name();
1330        EOS << '\0';
1331        ExportsAdded++;
1332
1333        // For ReExports there are a two more things to do, first add the
1334        // indirect name and second create the undefined symbol using the
1335        // referened dynamic library.
1336        if (ReExport) {
1337
1338          // Add the indirect name.
1339          if (Entry.otherName().empty())
1340            EOS << Entry.name();
1341          else
1342            EOS << Entry.otherName();
1343          EOS << '\0';
1344
1345          // Now create the undefined symbol using the referened dynamic
1346          // library.
1347          NMSymbol U = {};
1348          U.Address = 0;
1349          U.Size = 0;
1350          U.TypeChar = 'U';
1351          if (Entry.otherName().empty())
1352            U.Name = Entry.name().str();
1353          else
1354            U.Name = Entry.otherName().str();
1355          // Again there is no symbol in the nlist symbol table for this so
1356          // we set Sym effectivly to null and the rest of code in here must
1357          // test for it and not do things like Sym.getFlags() for it.
1358          U.Sym = BasicSymbolRef();
1359          U.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1360          U.Section = SectionRef();
1361          U.NType = MachO::N_EXT | MachO::N_UNDF;
1362          U.NSect = 0;
1363          U.NDesc = 0;
1364          // The library ordinal for this undefined symbol is in the export
1365          // trie Entry.other().
1366          MachO::SET_LIBRARY_ORDINAL(U.NDesc, Entry.other());
1367          SymbolList.push_back(U);
1368
1369          // Finally add the undefined symbol's name.
1370          if (Entry.otherName().empty())
1371            EOS << Entry.name();
1372          else
1373            EOS << Entry.otherName();
1374          EOS << '\0';
1375          ExportsAdded++;
1376        }
1377      }
1378    }
1379    if (Err)
1380      error(std::move(Err), MachO.getFileName());
1381    // Set the symbol names and indirect names for the added symbols.
1382    if (ExportsAdded) {
1383      EOS.flush();
1384      const char *Q = ExportsNameBuffer.c_str();
1385      for (unsigned K = 0; K < ExportsAdded; K++) {
1386        SymbolList[I].Name = Q;
1387        Q += strlen(Q) + 1;
1388        if (SymbolList[I].TypeChar == 'I') {
1389          SymbolList[I].IndirectName = Q;
1390          Q += strlen(Q) + 1;
1391        }
1392        I++;
1393      }
1394    }
1395
1396    // Add the undefined symbols from the bind entries.
1397    unsigned BindsAdded = 0;
1398    Error BErr = Error::success();
1399    StringRef LastSymbolName = StringRef();
1400    for (const llvm::object::MachOBindEntry &Entry : MachO.bindTable(BErr)) {
1401      bool found = false;
1402      if (LastSymbolName == Entry.symbolName())
1403        found = true;
1404      else if (!DyldInfoOnly) {
1405        for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
1406          if (SymbolList[J].Name == Entry.symbolName())
1407            found = true;
1408        }
1409      }
1410      if (!found) {
1411        LastSymbolName = Entry.symbolName();
1412        NMSymbol B = {};
1413        B.Address = 0;
1414        B.Size = 0;
1415        B.TypeChar = 'U';
1416        // There is no symbol in the nlist symbol table for this so we set
1417        // Sym effectivly to null and the rest of code in here must test for
1418        // it and not do things like Sym.getFlags() for it.
1419        B.Sym = BasicSymbolRef();
1420        B.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1421        B.NType = MachO::N_EXT | MachO::N_UNDF;
1422        B.NSect = 0;
1423        B.NDesc = 0;
1424        MachO::SET_LIBRARY_ORDINAL(B.NDesc, Entry.ordinal());
1425        B.Name = Entry.symbolName().str();
1426        SymbolList.push_back(B);
1427        BOS << Entry.symbolName();
1428        BOS << '\0';
1429        BindsAdded++;
1430      }
1431    }
1432    if (BErr)
1433      error(std::move(BErr), MachO.getFileName());
1434    // Set the symbol names and indirect names for the added symbols.
1435    if (BindsAdded) {
1436      BOS.flush();
1437      const char *Q = BindsNameBuffer.c_str();
1438      for (unsigned K = 0; K < BindsAdded; K++) {
1439        SymbolList[I].Name = Q;
1440        Q += strlen(Q) + 1;
1441        if (SymbolList[I].TypeChar == 'I') {
1442          SymbolList[I].IndirectName = Q;
1443          Q += strlen(Q) + 1;
1444        }
1445        I++;
1446      }
1447    }
1448
1449    // Add the undefined symbols from the lazy bind entries.
1450    unsigned LazysAdded = 0;
1451    Error LErr = Error::success();
1452    LastSymbolName = StringRef();
1453    for (const llvm::object::MachOBindEntry &Entry :
1454         MachO.lazyBindTable(LErr)) {
1455      bool found = false;
1456      if (LastSymbolName == Entry.symbolName())
1457        found = true;
1458      else {
1459        // Here we must check to see it this symbol is already in the
1460        // SymbolList as it might have already have been added above via a
1461        // non-lazy (bind) entry.
1462        for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
1463          if (SymbolList[J].Name == Entry.symbolName())
1464            found = true;
1465        }
1466      }
1467      if (!found) {
1468        LastSymbolName = Entry.symbolName();
1469        NMSymbol L = {};
1470        L.Name = Entry.symbolName().str();
1471        L.Address = 0;
1472        L.Size = 0;
1473        L.TypeChar = 'U';
1474        // There is no symbol in the nlist symbol table for this so we set
1475        // Sym effectivly to null and the rest of code in here must test for
1476        // it and not do things like Sym.getFlags() for it.
1477        L.Sym = BasicSymbolRef();
1478        L.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1479        L.NType = MachO::N_EXT | MachO::N_UNDF;
1480        L.NSect = 0;
1481        // The REFERENCE_FLAG_UNDEFINED_LAZY is no longer used but here it
1482        // makes sence since we are creating this from a lazy bind entry.
1483        L.NDesc = MachO::REFERENCE_FLAG_UNDEFINED_LAZY;
1484        MachO::SET_LIBRARY_ORDINAL(L.NDesc, Entry.ordinal());
1485        SymbolList.push_back(L);
1486        LOS << Entry.symbolName();
1487        LOS << '\0';
1488        LazysAdded++;
1489      }
1490    }
1491    if (LErr)
1492      error(std::move(LErr), MachO.getFileName());
1493    // Set the symbol names and indirect names for the added symbols.
1494    if (LazysAdded) {
1495      LOS.flush();
1496      const char *Q = LazysNameBuffer.c_str();
1497      for (unsigned K = 0; K < LazysAdded; K++) {
1498        SymbolList[I].Name = Q;
1499        Q += strlen(Q) + 1;
1500        if (SymbolList[I].TypeChar == 'I') {
1501          SymbolList[I].IndirectName = Q;
1502          Q += strlen(Q) + 1;
1503        }
1504        I++;
1505      }
1506    }
1507
1508    // Add the undefineds symbol from the weak bind entries which are not
1509    // strong symbols.
1510    unsigned WeaksAdded = 0;
1511    Error WErr = Error::success();
1512    LastSymbolName = StringRef();
1513    for (const llvm::object::MachOBindEntry &Entry :
1514         MachO.weakBindTable(WErr)) {
1515      bool found = false;
1516      unsigned J = 0;
1517      if (LastSymbolName == Entry.symbolName() ||
1518          Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
1519        found = true;
1520      } else {
1521        for (J = 0; J < SymbolList.size() && !found; ++J) {
1522          if (SymbolList[J].Name == Entry.symbolName()) {
1523            found = true;
1524            break;
1525          }
1526        }
1527      }
1528      if (!found) {
1529        LastSymbolName = Entry.symbolName();
1530        NMSymbol W = {};
1531        W.Name = Entry.symbolName().str();
1532        W.Address = 0;
1533        W.Size = 0;
1534        W.TypeChar = 'U';
1535        // There is no symbol in the nlist symbol table for this so we set
1536        // Sym effectivly to null and the rest of code in here must test for
1537        // it and not do things like Sym.getFlags() for it.
1538        W.Sym = BasicSymbolRef();
1539        W.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1540        W.NType = MachO::N_EXT | MachO::N_UNDF;
1541        W.NSect = 0;
1542        // Odd that we are using N_WEAK_DEF on an undefined symbol but that is
1543        // what is created in this case by the linker when there are real
1544        // symbols in the nlist structs.
1545        W.NDesc = MachO::N_WEAK_DEF;
1546        SymbolList.push_back(W);
1547        WOS << Entry.symbolName();
1548        WOS << '\0';
1549        WeaksAdded++;
1550      } else {
1551        // This is the case the symbol was previously been found and it could
1552        // have been added from a bind or lazy bind symbol.  If so and not
1553        // a definition also mark it as weak.
1554        if (SymbolList[J].TypeChar == 'U')
1555          // See comment above about N_WEAK_DEF.
1556          SymbolList[J].NDesc |= MachO::N_WEAK_DEF;
1557      }
1558    }
1559    if (WErr)
1560      error(std::move(WErr), MachO.getFileName());
1561    // Set the symbol names and indirect names for the added symbols.
1562    if (WeaksAdded) {
1563      WOS.flush();
1564      const char *Q = WeaksNameBuffer.c_str();
1565      for (unsigned K = 0; K < WeaksAdded; K++) {
1566        SymbolList[I].Name = Q;
1567        Q += strlen(Q) + 1;
1568        if (SymbolList[I].TypeChar == 'I') {
1569          SymbolList[I].IndirectName = Q;
1570          Q += strlen(Q) + 1;
1571        }
1572        I++;
1573      }
1574    }
1575
1576    // Trying adding symbol from the function starts table and LC_MAIN entry
1577    // point.
1578    SmallVector<uint64_t, 8> FoundFns;
1579    uint64_t lc_main_offset = UINT64_MAX;
1580    for (const auto &Command : MachO.load_commands()) {
1581      if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
1582        // We found a function starts segment, parse the addresses for
1583        // consumption.
1584        MachO::linkedit_data_command LLC =
1585            MachO.getLinkeditDataLoadCommand(Command);
1586
1587        MachO.ReadULEB128s(LLC.dataoff, FoundFns);
1588      } else if (Command.C.cmd == MachO::LC_MAIN) {
1589        MachO::entry_point_command LCmain = MachO.getEntryPointCommand(Command);
1590        lc_main_offset = LCmain.entryoff;
1591      }
1592    }
1593    // See if these addresses are already in the symbol table.
1594    unsigned FunctionStartsAdded = 0;
1595    for (uint64_t f = 0; f < FoundFns.size(); f++) {
1596      bool found = false;
1597      for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
1598        if (SymbolList[J].Address == FoundFns[f] + BaseSegmentAddress)
1599          found = true;
1600      }
1601      // See this address is not already in the symbol table fake up an
1602      // nlist for it.
1603      if (!found) {
1604        NMSymbol F = {};
1605        F.Name = "<redacted function X>";
1606        F.Address = FoundFns[f] + BaseSegmentAddress;
1607        F.Size = 0;
1608        // There is no symbol in the nlist symbol table for this so we set
1609        // Sym effectivly to null and the rest of code in here must test for
1610        // it and not do things like Sym.getFlags() for it.
1611        F.Sym = BasicSymbolRef();
1612        F.SymFlags = 0;
1613        F.NType = MachO::N_SECT;
1614        F.NSect = 0;
1615        StringRef SegmentName = StringRef();
1616        StringRef SectionName = StringRef();
1617        for (const SectionRef &Section : MachO.sections()) {
1618          if (Expected<StringRef> NameOrErr = Section.getName())
1619            SectionName = *NameOrErr;
1620          else
1621            consumeError(NameOrErr.takeError());
1622
1623          SegmentName =
1624              MachO.getSectionFinalSegmentName(Section.getRawDataRefImpl());
1625          F.NSect++;
1626          if (F.Address >= Section.getAddress() &&
1627              F.Address < Section.getAddress() + Section.getSize()) {
1628            F.Section = Section;
1629            break;
1630          }
1631        }
1632        if (SegmentName == "__TEXT" && SectionName == "__text")
1633          F.TypeChar = 't';
1634        else if (SegmentName == "__DATA" && SectionName == "__data")
1635          F.TypeChar = 'd';
1636        else if (SegmentName == "__DATA" && SectionName == "__bss")
1637          F.TypeChar = 'b';
1638        else
1639          F.TypeChar = 's';
1640        F.NDesc = 0;
1641        SymbolList.push_back(F);
1642        if (FoundFns[f] == lc_main_offset)
1643          FOS << "<redacted LC_MAIN>";
1644        else
1645          FOS << "<redacted function " << f << ">";
1646        FOS << '\0';
1647        FunctionStartsAdded++;
1648      }
1649    }
1650    if (FunctionStartsAdded) {
1651      FOS.flush();
1652      const char *Q = FunctionStartsNameBuffer.c_str();
1653      for (unsigned K = 0; K < FunctionStartsAdded; K++) {
1654        SymbolList[I].Name = Q;
1655        Q += strlen(Q) + 1;
1656        if (SymbolList[I].TypeChar == 'I') {
1657          SymbolList[I].IndirectName = Q;
1658          Q += strlen(Q) + 1;
1659        }
1660        I++;
1661      }
1662    }
1663  }
1664}
1665
1666static bool shouldDump(SymbolicFile &Obj) {
1667  // The -X option is currently only implemented for XCOFF, ELF, and IR object
1668  // files. The option isn't fundamentally impossible with other formats, just
1669  // isn't implemented.
1670  if (!isa<XCOFFObjectFile>(Obj) && !isa<ELFObjectFileBase>(Obj) &&
1671      !isa<IRObjectFile>(Obj))
1672    return true;
1673
1674  return isSymbolList64Bit(Obj) ? BitMode != BitModeTy::Bit32
1675                                : BitMode != BitModeTy::Bit64;
1676}
1677
1678static void getXCOFFExports(XCOFFObjectFile *XCOFFObj,
1679                            std::vector<NMSymbol> &SymbolList,
1680                            StringRef ArchiveName) {
1681  // Skip Shared object file.
1682  if (XCOFFObj->getFlags() & XCOFF::F_SHROBJ)
1683    return;
1684
1685  for (SymbolRef Sym : XCOFFObj->symbols()) {
1686    // There is no visibility in old 32 bit XCOFF object file interpret.
1687    bool HasVisibilityAttr =
1688        XCOFFObj->is64Bit() || (XCOFFObj->auxiliaryHeader32() &&
1689                                (XCOFFObj->auxiliaryHeader32()->getVersion() ==
1690                                 XCOFF::NEW_XCOFF_INTERPRET));
1691
1692    if (HasVisibilityAttr) {
1693      XCOFFSymbolRef XCOFFSym = XCOFFObj->toSymbolRef(Sym.getRawDataRefImpl());
1694      uint16_t SymType = XCOFFSym.getSymbolType();
1695      if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_INTERNAL)
1696        continue;
1697      if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_HIDDEN)
1698        continue;
1699    }
1700
1701    Expected<section_iterator> SymSecOrErr = Sym.getSection();
1702    if (!SymSecOrErr) {
1703      warn(SymSecOrErr.takeError(), XCOFFObj->getFileName(),
1704           "for symbol with index " +
1705               Twine(XCOFFObj->getSymbolIndex(Sym.getRawDataRefImpl().p)),
1706           ArchiveName);
1707      continue;
1708    }
1709    section_iterator SecIter = *SymSecOrErr;
1710    // If the symbol is not in a text or data section, it is not exported.
1711    if (SecIter == XCOFFObj->section_end())
1712      continue;
1713    if (!(SecIter->isText() || SecIter->isData() || SecIter->isBSS()))
1714      continue;
1715
1716    StringRef SymName = cantFail(Sym.getName());
1717    if (SymName.empty())
1718      continue;
1719    if (SymName.startswith("__sinit") || SymName.startswith("__sterm") ||
1720        SymName.front() == '.' || SymName.front() == '(')
1721      continue;
1722
1723    // Check the SymName regex matching with "^__[0-9]+__".
1724    if (SymName.size() > 4 && SymName.startswith("__") &&
1725        SymName.endswith("__")) {
1726      if (std::all_of(SymName.begin() + 2, SymName.end() - 2, isDigit))
1727        continue;
1728    }
1729
1730    if (SymName == "__rsrc" && NoRsrc)
1731      continue;
1732
1733    if (SymName.startswith("__tf1"))
1734      SymName = SymName.substr(6);
1735    else if (SymName.startswith("__tf9"))
1736      SymName = SymName.substr(14);
1737
1738    NMSymbol S = {};
1739    S.Name = SymName.str();
1740    S.Sym = Sym;
1741
1742    if (HasVisibilityAttr) {
1743      XCOFFSymbolRef XCOFFSym = XCOFFObj->toSymbolRef(Sym.getRawDataRefImpl());
1744      uint16_t SymType = XCOFFSym.getSymbolType();
1745      if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_PROTECTED)
1746        S.Visibility = "protected";
1747      else if ((SymType & XCOFF::VISIBILITY_MASK) == XCOFF::SYM_V_EXPORTED)
1748        S.Visibility = "export";
1749    }
1750    if (S.initializeFlags(*XCOFFObj))
1751      SymbolList.push_back(S);
1752  }
1753}
1754
1755static Expected<SymbolicFile::basic_symbol_iterator_range>
1756getDynamicSyms(SymbolicFile &Obj) {
1757  const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
1758  if (!E)
1759    return createError("File format has no dynamic symbol table");
1760  return E->getDynamicSymbolIterators();
1761}
1762
1763// Returns false if there is error found or true otherwise.
1764static bool getSymbolNamesFromObject(SymbolicFile &Obj,
1765                                     std::vector<NMSymbol> &SymbolList) {
1766  auto Symbols = Obj.symbols();
1767  std::vector<VersionEntry> SymbolVersions;
1768
1769  if (DynamicSyms) {
1770    Expected<SymbolicFile::basic_symbol_iterator_range> SymbolsOrErr =
1771        getDynamicSyms(Obj);
1772    if (!SymbolsOrErr) {
1773      error(SymbolsOrErr.takeError(), Obj.getFileName());
1774      return false;
1775    }
1776    Symbols = *SymbolsOrErr;
1777    if (const auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
1778      if (Expected<std::vector<VersionEntry>> VersionsOrErr =
1779              E->readDynsymVersions())
1780        SymbolVersions = std::move(*VersionsOrErr);
1781      else
1782        WithColor::warning(errs(), ToolName)
1783            << "unable to read symbol versions: "
1784            << toString(VersionsOrErr.takeError()) << "\n";
1785    }
1786  }
1787  // If a "-s segname sectname" option was specified and this is a Mach-O
1788  // file get the section number for that section in this object file.
1789  unsigned int Nsect = 0;
1790  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
1791  if (!SegSect.empty() && MachO) {
1792    Nsect = getNsectForSegSect(MachO);
1793    // If this section is not in the object file no symbols are printed.
1794    if (Nsect == 0)
1795      return false;
1796  }
1797
1798  if (!(MachO && DyldInfoOnly)) {
1799    size_t I = -1;
1800    for (BasicSymbolRef Sym : Symbols) {
1801      ++I;
1802      Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
1803      if (!SymFlagsOrErr) {
1804        error(SymFlagsOrErr.takeError(), Obj.getFileName());
1805        return false;
1806      }
1807
1808      // Don't drop format specifc symbols for ARM and AArch64 ELF targets, they
1809      // are used to repesent mapping symbols and needed to honor the
1810      // --special-syms option.
1811      auto *ELFObj = dyn_cast<ELFObjectFileBase>(&Obj);
1812      if ((!ELFObj || (ELFObj->getEMachine() != ELF::EM_ARM &&
1813                       ELFObj->getEMachine() != ELF::EM_AARCH64)) &&
1814          !DebugSyms && (*SymFlagsOrErr & SymbolRef::SF_FormatSpecific))
1815        continue;
1816      if (WithoutAliases && (*SymFlagsOrErr & SymbolRef::SF_Indirect))
1817        continue;
1818      // If a "-s segname sectname" option was specified and this is a Mach-O
1819      // file and this section appears in this file, Nsect will be non-zero then
1820      // see if this symbol is a symbol from that section and if not skip it.
1821      if (Nsect && Nsect != getNsectInMachO(*MachO, Sym))
1822        continue;
1823      NMSymbol S = {};
1824      S.Size = 0;
1825      S.Address = 0;
1826      if (isa<ELFObjectFileBase>(&Obj))
1827        S.Size = ELFSymbolRef(Sym).getSize();
1828
1829      if (const XCOFFObjectFile *XCOFFObj =
1830              dyn_cast<const XCOFFObjectFile>(&Obj))
1831        S.Size = XCOFFObj->getSymbolSize(Sym.getRawDataRefImpl());
1832
1833      if (PrintAddress && isa<ObjectFile>(Obj)) {
1834        SymbolRef SymRef(Sym);
1835        Expected<uint64_t> AddressOrErr = SymRef.getAddress();
1836        if (!AddressOrErr) {
1837          consumeError(AddressOrErr.takeError());
1838          break;
1839        }
1840        S.Address = *AddressOrErr;
1841      }
1842      S.TypeName = getNMTypeName(Obj, Sym);
1843      S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName);
1844
1845      raw_string_ostream OS(S.Name);
1846      if (Error E = Sym.printName(OS)) {
1847        if (MachO) {
1848          OS << "bad string index";
1849          consumeError(std::move(E));
1850        } else
1851          error(std::move(E), Obj.getFileName());
1852      }
1853      if (!SymbolVersions.empty() && !SymbolVersions[I].Name.empty())
1854        S.Name +=
1855            (SymbolVersions[I].IsVerDef ? "@@" : "@") + SymbolVersions[I].Name;
1856
1857      S.Sym = Sym;
1858      if (S.initializeFlags(Obj))
1859        SymbolList.push_back(S);
1860    }
1861  }
1862
1863  // If this is a Mach-O file where the nlist symbol table is out of sync
1864  // with the dyld export trie then look through exports and fake up symbols
1865  // for the ones that are missing (also done with the -add-dyldinfo flag).
1866  // This is needed if strip(1) -T is run on a binary containing swift
1867  // language symbols for example.  The option -only-dyldinfo will fake up
1868  // all symbols from the dyld export trie as well as the bind info.
1869  if (MachO && !NoDyldInfo)
1870    dumpSymbolsFromDLInfoMachO(*MachO, SymbolList);
1871
1872  return true;
1873}
1874
1875static void printObjectLabel(bool PrintArchiveName, StringRef ArchiveName,
1876                             StringRef ArchitectureName,
1877                             StringRef ObjectFileName) {
1878  outs() << "\n";
1879  if (ArchiveName.empty() || !PrintArchiveName)
1880    outs() << ObjectFileName;
1881  else
1882    outs() << ArchiveName << "(" << ObjectFileName << ")";
1883  if (!ArchitectureName.empty())
1884    outs() << " (for architecture " << ArchitectureName << ")";
1885  outs() << ":\n";
1886}
1887
1888static Expected<bool> hasSymbols(SymbolicFile &Obj) {
1889  if (DynamicSyms) {
1890    Expected<SymbolicFile::basic_symbol_iterator_range> DynamicSymsOrErr =
1891        getDynamicSyms(Obj);
1892    if (!DynamicSymsOrErr)
1893      return DynamicSymsOrErr.takeError();
1894    return !DynamicSymsOrErr->empty();
1895  }
1896  return !Obj.symbols().empty();
1897}
1898
1899static void dumpSymbolNamesFromObject(
1900    SymbolicFile &Obj, std::vector<NMSymbol> &SymbolList,
1901    bool PrintSymbolObject, bool PrintObjectLabel, StringRef ArchiveName = {},
1902    StringRef ArchitectureName = {}, StringRef ObjectName = {},
1903    bool PrintArchiveName = true) {
1904  if (!shouldDump(Obj))
1905    return;
1906
1907  if (ExportSymbols && Obj.isXCOFF()) {
1908    XCOFFObjectFile *XCOFFObj = cast<XCOFFObjectFile>(&Obj);
1909    getXCOFFExports(XCOFFObj, SymbolList, ArchiveName);
1910    return;
1911  }
1912
1913  if (PrintObjectLabel && !ExportSymbols)
1914    printObjectLabel(PrintArchiveName, ArchiveName, ArchitectureName,
1915                     ObjectName.empty() ? Obj.getFileName() : ObjectName);
1916  if (!getSymbolNamesFromObject(Obj, SymbolList) || ExportSymbols)
1917    return;
1918  CurrentFilename = Obj.getFileName();
1919
1920  // If there is an error in hasSymbols(), the error should be encountered in
1921  // function getSymbolNamesFromObject first.
1922  if (!cantFail(hasSymbols(Obj)) && SymbolList.empty() && !Quiet) {
1923    writeFileName(errs(), ArchiveName, ArchitectureName);
1924    errs() << "no symbols\n";
1925  }
1926
1927  sortSymbolList(SymbolList);
1928  printSymbolList(Obj, SymbolList, PrintSymbolObject, ArchiveName,
1929                  ArchitectureName);
1930}
1931
1932// checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file
1933// and if it is and there is a list of architecture flags is specified then
1934// check to make sure this Mach-O file is one of those architectures or all
1935// architectures was specificed.  If not then an error is generated and this
1936// routine returns false.  Else it returns true.
1937static bool checkMachOAndArchFlags(SymbolicFile *O, StringRef Filename) {
1938  auto *MachO = dyn_cast<MachOObjectFile>(O);
1939
1940  if (!MachO || ArchAll || ArchFlags.empty())
1941    return true;
1942
1943  MachO::mach_header H;
1944  MachO::mach_header_64 H_64;
1945  Triple T;
1946  const char *McpuDefault, *ArchFlag;
1947  if (MachO->is64Bit()) {
1948    H_64 = MachO->MachOObjectFile::getHeader64();
1949    T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype,
1950                                       &McpuDefault, &ArchFlag);
1951  } else {
1952    H = MachO->MachOObjectFile::getHeader();
1953    T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype,
1954                                       &McpuDefault, &ArchFlag);
1955  }
1956  const std::string ArchFlagName(ArchFlag);
1957  if (!llvm::is_contained(ArchFlags, ArchFlagName)) {
1958    error("No architecture specified", Filename);
1959    return false;
1960  }
1961  return true;
1962}
1963
1964static void dumpArchiveMap(Archive *A, StringRef Filename) {
1965  Archive::symbol_iterator I = A->symbol_begin();
1966  Archive::symbol_iterator E = A->symbol_end();
1967  if (I != E) {
1968    outs() << "Archive map\n";
1969    for (; I != E; ++I) {
1970      Expected<Archive::Child> C = I->getMember();
1971      if (!C) {
1972        error(C.takeError(), Filename);
1973        break;
1974      }
1975      Expected<StringRef> FileNameOrErr = C->getName();
1976      if (!FileNameOrErr) {
1977        error(FileNameOrErr.takeError(), Filename);
1978        break;
1979      }
1980      StringRef SymName = I->getName();
1981      outs() << SymName << " in " << FileNameOrErr.get() << "\n";
1982    }
1983    outs() << "\n";
1984  }
1985}
1986
1987static void dumpArchive(Archive *A, std::vector<NMSymbol> &SymbolList,
1988                        StringRef Filename, LLVMContext *ContextPtr) {
1989  if (ArchiveMap)
1990    dumpArchiveMap(A, Filename);
1991
1992  Error Err = Error::success();
1993  for (auto &C : A->children(Err)) {
1994    Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(ContextPtr);
1995    if (!ChildOrErr) {
1996      if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1997        error(std::move(E), Filename, C);
1998      continue;
1999    }
2000    if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
2001      if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) {
2002        WithColor::warning(errs(), ToolName)
2003            << "sizes with -print-size for Mach-O files are always zero.\n";
2004        MachOPrintSizeWarning = true;
2005      }
2006      if (!checkMachOAndArchFlags(O, Filename))
2007        return;
2008      dumpSymbolNamesFromObject(*O, SymbolList, /*PrintSymbolObject=*/false,
2009                                !PrintFileName, Filename,
2010                                /*ArchitectureName=*/{}, O->getFileName(),
2011                                /*PrintArchiveName=*/false);
2012    }
2013  }
2014  if (Err)
2015    error(std::move(Err), A->getFileName());
2016}
2017
2018static void dumpMachOUniversalBinaryMatchArchFlags(
2019    MachOUniversalBinary *UB, std::vector<NMSymbol> &SymbolList,
2020    StringRef Filename, LLVMContext *ContextPtr) {
2021  // Look for a slice in the universal binary that matches each ArchFlag.
2022  bool ArchFound;
2023  for (unsigned i = 0; i < ArchFlags.size(); ++i) {
2024    ArchFound = false;
2025    for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2026                                               E = UB->end_objects();
2027         I != E; ++I) {
2028      if (ArchFlags[i] == I->getArchFlagName()) {
2029        ArchFound = true;
2030        Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
2031        std::string ArchiveName;
2032        std::string ArchitectureName;
2033        ArchiveName.clear();
2034        ArchitectureName.clear();
2035        if (ObjOrErr) {
2036          ObjectFile &Obj = *ObjOrErr.get();
2037          if (ArchFlags.size() > 1)
2038            ArchitectureName = I->getArchFlagName();
2039          dumpSymbolNamesFromObject(Obj, SymbolList,
2040                                    /*PrintSymbolObject=*/false,
2041                                    (ArchFlags.size() > 1) && !PrintFileName,
2042                                    ArchiveName, ArchitectureName);
2043        } else if (auto E =
2044                       isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2045          error(std::move(E), Filename,
2046                ArchFlags.size() > 1 ? StringRef(I->getArchFlagName())
2047                                     : StringRef());
2048          continue;
2049        } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2050                       I->getAsArchive()) {
2051          std::unique_ptr<Archive> &A = *AOrErr;
2052          Error Err = Error::success();
2053          for (auto &C : A->children(Err)) {
2054            Expected<std::unique_ptr<Binary>> ChildOrErr =
2055                C.getAsBinary(ContextPtr);
2056            if (!ChildOrErr) {
2057              if (auto E =
2058                      isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) {
2059                error(std::move(E), Filename, C,
2060                      ArchFlags.size() > 1 ? StringRef(I->getArchFlagName())
2061                                           : StringRef());
2062              }
2063              continue;
2064            }
2065            if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
2066              ArchiveName = std::string(A->getFileName());
2067              if (ArchFlags.size() > 1)
2068                ArchitectureName = I->getArchFlagName();
2069              dumpSymbolNamesFromObject(
2070                  *O, SymbolList, /*PrintSymbolObject=*/false, !PrintFileName,
2071                  ArchiveName, ArchitectureName);
2072            }
2073          }
2074          if (Err)
2075            error(std::move(Err), A->getFileName());
2076        } else {
2077          consumeError(AOrErr.takeError());
2078          error(Filename + " for architecture " +
2079                    StringRef(I->getArchFlagName()) +
2080                    " is not a Mach-O file or an archive file",
2081                "Mach-O universal file");
2082        }
2083      }
2084    }
2085    if (!ArchFound) {
2086      error(ArchFlags[i],
2087            "file: " + Filename + " does not contain architecture");
2088      return;
2089    }
2090  }
2091}
2092
2093// Returns true If the binary contains a slice that matches the host
2094// architecture, or false otherwise.
2095static bool dumpMachOUniversalBinaryMatchHost(MachOUniversalBinary *UB,
2096                                              std::vector<NMSymbol> &SymbolList,
2097                                              StringRef Filename,
2098                                              LLVMContext *ContextPtr) {
2099  Triple HostTriple = MachOObjectFile::getHostArch();
2100  StringRef HostArchName = HostTriple.getArchName();
2101  for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2102                                             E = UB->end_objects();
2103       I != E; ++I) {
2104    if (HostArchName == I->getArchFlagName()) {
2105      Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
2106      std::string ArchiveName;
2107      if (ObjOrErr) {
2108        ObjectFile &Obj = *ObjOrErr.get();
2109        dumpSymbolNamesFromObject(Obj, SymbolList, /*PrintSymbolObject=*/false,
2110                                  /*PrintObjectLabel=*/false);
2111      } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError()))
2112        error(std::move(E), Filename);
2113      else if (Expected<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
2114        std::unique_ptr<Archive> &A = *AOrErr;
2115        Error Err = Error::success();
2116        for (auto &C : A->children(Err)) {
2117          Expected<std::unique_ptr<Binary>> ChildOrErr =
2118              C.getAsBinary(ContextPtr);
2119          if (!ChildOrErr) {
2120            if (auto E =
2121                    isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2122              error(std::move(E), Filename, C);
2123            continue;
2124          }
2125          if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
2126            ArchiveName = std::string(A->getFileName());
2127            dumpSymbolNamesFromObject(*O, SymbolList,
2128                                      /*PrintSymbolObject=*/false,
2129                                      !PrintFileName, ArchiveName);
2130          }
2131        }
2132        if (Err)
2133          error(std::move(Err), A->getFileName());
2134      } else {
2135        consumeError(AOrErr.takeError());
2136        error(Filename + " for architecture " +
2137                  StringRef(I->getArchFlagName()) +
2138                  " is not a Mach-O file or an archive file",
2139              "Mach-O universal file");
2140      }
2141      return true;
2142    }
2143  }
2144  return false;
2145}
2146
2147static void dumpMachOUniversalBinaryArchAll(MachOUniversalBinary *UB,
2148                                            std::vector<NMSymbol> &SymbolList,
2149                                            StringRef Filename,
2150                                            LLVMContext *ContextPtr) {
2151  bool moreThanOneArch = UB->getNumberOfObjects() > 1;
2152  for (const MachOUniversalBinary::ObjectForArch &O : UB->objects()) {
2153    Expected<std::unique_ptr<ObjectFile>> ObjOrErr = O.getAsObjectFile();
2154    std::string ArchiveName;
2155    std::string ArchitectureName;
2156    ArchiveName.clear();
2157    ArchitectureName.clear();
2158    if (ObjOrErr) {
2159      ObjectFile &Obj = *ObjOrErr.get();
2160      if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
2161        ArchitectureName = O.getArchFlagName();
2162      dumpSymbolNamesFromObject(Obj, SymbolList, /*PrintSymbolObject=*/false,
2163                                !PrintFileName, ArchiveName, ArchitectureName);
2164    } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2165      error(std::move(E), Filename,
2166            moreThanOneArch ? StringRef(O.getArchFlagName()) : StringRef());
2167      continue;
2168    } else if (Expected<std::unique_ptr<Archive>> AOrErr = O.getAsArchive()) {
2169      std::unique_ptr<Archive> &A = *AOrErr;
2170      Error Err = Error::success();
2171      for (auto &C : A->children(Err)) {
2172        Expected<std::unique_ptr<Binary>> ChildOrErr =
2173            C.getAsBinary(ContextPtr);
2174        if (!ChildOrErr) {
2175          if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2176            error(std::move(E), Filename, C,
2177                  moreThanOneArch ? StringRef(ArchitectureName) : StringRef());
2178          continue;
2179        }
2180        if (SymbolicFile *F = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
2181          ArchiveName = std::string(A->getFileName());
2182          if (isa<MachOObjectFile>(F) && moreThanOneArch)
2183            ArchitectureName = O.getArchFlagName();
2184          dumpSymbolNamesFromObject(*F, SymbolList, /*PrintSymbolObject=*/false,
2185                                    !PrintFileName, ArchiveName,
2186                                    ArchitectureName);
2187        }
2188      }
2189      if (Err)
2190        error(std::move(Err), A->getFileName());
2191    } else {
2192      consumeError(AOrErr.takeError());
2193      error(Filename + " for architecture " + StringRef(O.getArchFlagName()) +
2194                " is not a Mach-O file or an archive file",
2195            "Mach-O universal file");
2196    }
2197  }
2198}
2199
2200static void dumpMachOUniversalBinary(MachOUniversalBinary *UB,
2201                                     std::vector<NMSymbol> &SymbolList,
2202                                     StringRef Filename,
2203                                     LLVMContext *ContextPtr) {
2204  // If we have a list of architecture flags specified dump only those.
2205  if (!ArchAll && !ArchFlags.empty()) {
2206    dumpMachOUniversalBinaryMatchArchFlags(UB, SymbolList, Filename,
2207                                           ContextPtr);
2208    return;
2209  }
2210
2211  // No architecture flags were specified so if this contains a slice that
2212  // matches the host architecture dump only that.
2213  if (!ArchAll &&
2214      dumpMachOUniversalBinaryMatchHost(UB, SymbolList, Filename, ContextPtr))
2215    return;
2216
2217  // Either all architectures have been specified or none have been specified
2218  // and this does not contain the host architecture so dump all the slices.
2219  dumpMachOUniversalBinaryArchAll(UB, SymbolList, Filename, ContextPtr);
2220}
2221
2222static void dumpTapiUniversal(TapiUniversal *TU,
2223                              std::vector<NMSymbol> &SymbolList,
2224                              StringRef Filename) {
2225  for (const TapiUniversal::ObjectForArch &I : TU->objects()) {
2226    StringRef ArchName = I.getArchFlagName();
2227    const bool ShowArch =
2228        ArchFlags.empty() || llvm::is_contained(ArchFlags, ArchName);
2229    if (!ShowArch)
2230      continue;
2231    if (!AddInlinedInfo && !I.isTopLevelLib())
2232      continue;
2233    if (auto ObjOrErr = I.getAsObjectFile())
2234      dumpSymbolNamesFromObject(
2235          *ObjOrErr.get(), SymbolList, /*PrintSymbolObject=*/false,
2236          /*PrintObjectLabel=*/true,
2237          /*ArchiveName=*/{}, ArchName, I.getInstallName());
2238    else if (Error E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2239      error(std::move(E), Filename, ArchName);
2240    }
2241  }
2242}
2243
2244static void dumpSymbolicFile(SymbolicFile *O, std::vector<NMSymbol> &SymbolList,
2245                             StringRef Filename) {
2246  if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) {
2247    WithColor::warning(errs(), ToolName)
2248        << "sizes with --print-size for Mach-O files are always zero.\n";
2249    MachOPrintSizeWarning = true;
2250  }
2251  if (!checkMachOAndArchFlags(O, Filename))
2252    return;
2253  dumpSymbolNamesFromObject(*O, SymbolList, /*PrintSymbolObject=*/true,
2254                            /*PrintObjectLabel=*/false);
2255}
2256
2257static std::vector<NMSymbol> dumpSymbolNamesFromFile(StringRef Filename) {
2258  std::vector<NMSymbol> SymbolList;
2259  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
2260      MemoryBuffer::getFileOrSTDIN(Filename);
2261  if (error(BufferOrErr.getError(), Filename))
2262    return SymbolList;
2263
2264  // Always enable opaque pointers, to handle archives with mixed typed and
2265  // opaque pointer bitcode files gracefully. As we're only reading symbols,
2266  // the used pointer types don't matter.
2267  LLVMContext Context;
2268  Context.setOpaquePointers(true);
2269  LLVMContext *ContextPtr = NoLLVMBitcode ? nullptr : &Context;
2270  Expected<std::unique_ptr<Binary>> BinaryOrErr =
2271      createBinary(BufferOrErr.get()->getMemBufferRef(), ContextPtr);
2272  if (!BinaryOrErr) {
2273    error(BinaryOrErr.takeError(), Filename);
2274    return SymbolList;
2275  }
2276  Binary &Bin = *BinaryOrErr.get();
2277  if (Archive *A = dyn_cast<Archive>(&Bin))
2278    dumpArchive(A, SymbolList, Filename, ContextPtr);
2279  else if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin))
2280    dumpMachOUniversalBinary(UB, SymbolList, Filename, ContextPtr);
2281  else if (TapiUniversal *TU = dyn_cast<TapiUniversal>(&Bin))
2282    dumpTapiUniversal(TU, SymbolList, Filename);
2283  else if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin))
2284    dumpSymbolicFile(O, SymbolList, Filename);
2285  return SymbolList;
2286}
2287
2288static void
2289exportSymbolNamesFromFiles(const std::vector<std::string> &InputFilenames) {
2290  std::vector<NMSymbol> SymbolList;
2291  for (const auto &FileName : InputFilenames) {
2292    std::vector<NMSymbol> FileSymList = dumpSymbolNamesFromFile(FileName);
2293    SymbolList.insert(SymbolList.end(), FileSymList.begin(), FileSymList.end());
2294  }
2295
2296  // Delete symbols which should not be printed from SymolList.
2297  llvm::erase_if(SymbolList,
2298                 [](const NMSymbol &s) { return !s.shouldPrint(); });
2299  sortSymbolList(SymbolList);
2300  SymbolList.erase(std::unique(SymbolList.begin(), SymbolList.end()),
2301                   SymbolList.end());
2302  printExportSymbolList(SymbolList);
2303}
2304
2305int llvm_nm_main(int argc, char **argv) {
2306  InitLLVM X(argc, argv);
2307  BumpPtrAllocator A;
2308  StringSaver Saver(A);
2309  NmOptTable Tbl;
2310  ToolName = argv[0];
2311  opt::InputArgList Args =
2312      Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) {
2313        error(Msg);
2314        exit(1);
2315      });
2316  if (Args.hasArg(OPT_help)) {
2317    Tbl.printHelp(
2318        outs(),
2319        (Twine(ToolName) + " [options] <input object files>").str().c_str(),
2320        "LLVM symbol table dumper");
2321    // TODO Replace this with OptTable API once it adds extrahelp support.
2322    outs() << "\nPass @FILE as argument to read options from FILE.\n";
2323    return 0;
2324  }
2325  if (Args.hasArg(OPT_version)) {
2326    // This needs to contain the word "GNU", libtool looks for that string.
2327    outs() << "llvm-nm, compatible with GNU nm" << '\n';
2328    cl::PrintVersionMessage();
2329    return 0;
2330  }
2331
2332  DebugSyms = Args.hasArg(OPT_debug_syms);
2333  DefinedOnly = Args.hasArg(OPT_defined_only);
2334  Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false);
2335  DynamicSyms = Args.hasArg(OPT_dynamic);
2336  ExternalOnly = Args.hasArg(OPT_extern_only);
2337  StringRef V = Args.getLastArgValue(OPT_format_EQ, "bsd");
2338  if (V == "bsd")
2339    OutputFormat = bsd;
2340  else if (V == "posix")
2341    OutputFormat = posix;
2342  else if (V == "sysv")
2343    OutputFormat = sysv;
2344  else if (V == "darwin")
2345    OutputFormat = darwin;
2346  else if (V == "just-symbols")
2347    OutputFormat = just_symbols;
2348  else
2349    error("--format value should be one of: bsd, posix, sysv, darwin, "
2350          "just-symbols");
2351  NoLLVMBitcode = Args.hasArg(OPT_no_llvm_bc);
2352  NoSort = Args.hasArg(OPT_no_sort);
2353  NoWeakSymbols = Args.hasArg(OPT_no_weak);
2354  NumericSort = Args.hasArg(OPT_numeric_sort);
2355  ArchiveMap = Args.hasArg(OPT_print_armap);
2356  PrintFileName = Args.hasArg(OPT_print_file_name);
2357  PrintSize = Args.hasArg(OPT_print_size);
2358  ReverseSort = Args.hasArg(OPT_reverse_sort);
2359  ExportSymbols = Args.hasArg(OPT_export_symbols);
2360  if (ExportSymbols) {
2361    ExternalOnly = true;
2362    DefinedOnly = true;
2363  }
2364
2365  Quiet = Args.hasArg(OPT_quiet);
2366  V = Args.getLastArgValue(OPT_radix_EQ, "x");
2367  if (V == "o")
2368    AddressRadix = Radix::o;
2369  else if (V == "d")
2370    AddressRadix = Radix::d;
2371  else if (V == "x")
2372    AddressRadix = Radix::x;
2373  else
2374    error("--radix value should be one of: 'o' (octal), 'd' (decimal), 'x' "
2375          "(hexadecimal)");
2376  SizeSort = Args.hasArg(OPT_size_sort);
2377  SpecialSyms = Args.hasArg(OPT_special_syms);
2378  UndefinedOnly = Args.hasArg(OPT_undefined_only);
2379  WithoutAliases = Args.hasArg(OPT_without_aliases);
2380
2381  // Get BitMode from enviornment variable "OBJECT_MODE" for AIX OS, if
2382  // specified.
2383  Triple HostTriple(sys::getProcessTriple());
2384  if (HostTriple.isOSAIX()) {
2385    BitMode = StringSwitch<BitModeTy>(getenv("OBJECT_MODE"))
2386                  .Case("32", BitModeTy::Bit32)
2387                  .Case("64", BitModeTy::Bit64)
2388                  .Case("32_64", BitModeTy::Bit32_64)
2389                  .Case("any", BitModeTy::Any)
2390                  .Default(BitModeTy::Bit32);
2391  } else
2392    BitMode = BitModeTy::Any;
2393
2394  if (Arg *A = Args.getLastArg(OPT_X)) {
2395    StringRef Mode = A->getValue();
2396    if (Mode == "32")
2397      BitMode = BitModeTy::Bit32;
2398    else if (Mode == "64")
2399      BitMode = BitModeTy::Bit64;
2400    else if (Mode == "32_64")
2401      BitMode = BitModeTy::Bit32_64;
2402    else if (Mode == "any")
2403      BitMode = BitModeTy::Any;
2404    else
2405      error("-X value should be one of: 32, 64, 32_64, (default) any");
2406  }
2407
2408  // Mach-O specific options.
2409  FormatMachOasHex = Args.hasArg(OPT_x);
2410  AddDyldInfo = Args.hasArg(OPT_add_dyldinfo);
2411  AddInlinedInfo = Args.hasArg(OPT_add_inlinedinfo);
2412  DyldInfoOnly = Args.hasArg(OPT_dyldinfo_only);
2413  NoDyldInfo = Args.hasArg(OPT_no_dyldinfo);
2414
2415  // XCOFF specific options.
2416  NoRsrc = Args.hasArg(OPT_no_rsrc);
2417
2418  // llvm-nm only reads binary files.
2419  if (error(sys::ChangeStdinToBinary()))
2420    return 1;
2421
2422  // These calls are needed so that we can read bitcode correctly.
2423  llvm::InitializeAllTargetInfos();
2424  llvm::InitializeAllTargetMCs();
2425  llvm::InitializeAllAsmParsers();
2426
2427  // The relative order of these is important. If you pass --size-sort it should
2428  // only print out the size. However, if you pass -S --size-sort, it should
2429  // print out both the size and address.
2430  if (SizeSort && !PrintSize)
2431    PrintAddress = false;
2432  if (OutputFormat == sysv || SizeSort)
2433    PrintSize = true;
2434
2435  for (const auto *A : Args.filtered(OPT_arch_EQ)) {
2436    SmallVector<StringRef, 2> Values;
2437    llvm::SplitString(A->getValue(), Values, ",");
2438    for (StringRef V : Values) {
2439      if (V == "all")
2440        ArchAll = true;
2441      else if (MachOObjectFile::isValidArch(V))
2442        ArchFlags.push_back(V);
2443      else
2444        error("Unknown architecture named '" + V + "'",
2445              "for the --arch option");
2446    }
2447  }
2448
2449  // Mach-O takes -s to accept two arguments. We emulate this by iterating over
2450  // both OPT_s and OPT_INPUT.
2451  std::vector<std::string> InputFilenames;
2452  int SegSectArgs = 0;
2453  for (opt::Arg *A : Args.filtered(OPT_s, OPT_INPUT)) {
2454    if (SegSectArgs > 0) {
2455      --SegSectArgs;
2456      SegSect.push_back(A->getValue());
2457    } else if (A->getOption().matches(OPT_s)) {
2458      SegSectArgs = 2;
2459    } else {
2460      InputFilenames.push_back(A->getValue());
2461    }
2462  }
2463  if (!SegSect.empty() && SegSect.size() != 2)
2464    error("bad number of arguments (must be two arguments)",
2465          "for the -s option");
2466
2467  if (InputFilenames.empty())
2468    InputFilenames.push_back("a.out");
2469  if (InputFilenames.size() > 1)
2470    MultipleFiles = true;
2471
2472  if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly))
2473    error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only");
2474
2475  if (ExportSymbols)
2476    exportSymbolNamesFromFiles(InputFilenames);
2477  else
2478    llvm::for_each(InputFilenames, dumpSymbolNamesFromFile);
2479
2480  if (HadError)
2481    return 1;
2482  return 0;
2483}
2484