1//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This program is a utility that works like traditional Unix "nm", that is, it
11// prints out the names of symbols in a bitcode or object file, along with some
12// information about each symbol.
13//
14// This "nm" supports many of the features of GNU "nm", including its different
15// output formats.
16//
17//===----------------------------------------------------------------------===//
18
19#include "llvm/IR/Function.h"
20#include "llvm/IR/GlobalAlias.h"
21#include "llvm/IR/GlobalVariable.h"
22#include "llvm/IR/LLVMContext.h"
23#include "llvm/IR/Module.h"
24#include "llvm/Object/Archive.h"
25#include "llvm/Object/COFF.h"
26#include "llvm/Object/ELFObjectFile.h"
27#include "llvm/Object/IRObjectFile.h"
28#include "llvm/Object/MachO.h"
29#include "llvm/Object/MachOUniversal.h"
30#include "llvm/Object/ObjectFile.h"
31#include "llvm/Support/COFF.h"
32#include "llvm/Support/CommandLine.h"
33#include "llvm/Support/FileSystem.h"
34#include "llvm/Support/Format.h"
35#include "llvm/Support/ManagedStatic.h"
36#include "llvm/Support/MemoryBuffer.h"
37#include "llvm/Support/PrettyStackTrace.h"
38#include "llvm/Support/Program.h"
39#include "llvm/Support/Signals.h"
40#include "llvm/Support/TargetSelect.h"
41#include "llvm/Support/raw_ostream.h"
42#include <algorithm>
43#include <cctype>
44#include <cerrno>
45#include <cstring>
46#include <system_error>
47#include <vector>
48
49using namespace llvm;
50using namespace object;
51
52namespace {
53enum OutputFormatTy { bsd, sysv, posix, darwin };
54cl::opt<OutputFormatTy> OutputFormat(
55    "format", cl::desc("Specify output format"),
56    cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"),
57               clEnumVal(posix, "POSIX.2 format"),
58               clEnumVal(darwin, "Darwin -m format"), clEnumValEnd),
59    cl::init(bsd));
60cl::alias OutputFormat2("f", cl::desc("Alias for --format"),
61                        cl::aliasopt(OutputFormat));
62
63cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
64                                     cl::ZeroOrMore);
65
66cl::opt<bool> UndefinedOnly("undefined-only",
67                            cl::desc("Show only undefined symbols"));
68cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"),
69                         cl::aliasopt(UndefinedOnly), cl::Grouping);
70
71cl::opt<bool> DynamicSyms("dynamic",
72                          cl::desc("Display the dynamic symbols instead "
73                                   "of normal symbols."));
74cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"),
75                       cl::aliasopt(DynamicSyms), cl::Grouping);
76
77cl::opt<bool> DefinedOnly("defined-only",
78                          cl::desc("Show only defined symbols"));
79cl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"),
80                       cl::aliasopt(DefinedOnly), cl::Grouping);
81
82cl::opt<bool> ExternalOnly("extern-only",
83                           cl::desc("Show only external symbols"));
84cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"),
85                        cl::aliasopt(ExternalOnly), cl::Grouping);
86
87cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"),
88                        cl::Grouping);
89cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"),
90                          cl::Grouping);
91cl::opt<bool> DarwinFormat("m", cl::desc("Alias for --format=darwin"),
92                           cl::Grouping);
93
94static cl::list<std::string>
95    ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"),
96              cl::ZeroOrMore);
97bool ArchAll = false;
98
99cl::opt<bool> PrintFileName(
100    "print-file-name",
101    cl::desc("Precede each symbol with the object file it came from"));
102
103cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"),
104                         cl::aliasopt(PrintFileName), cl::Grouping);
105cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"),
106                         cl::aliasopt(PrintFileName), cl::Grouping);
107
108cl::opt<bool> DebugSyms("debug-syms",
109                        cl::desc("Show all symbols, even debugger only"));
110cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"),
111                     cl::aliasopt(DebugSyms), cl::Grouping);
112
113cl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address"));
114cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"),
115                       cl::aliasopt(NumericSort), cl::Grouping);
116cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"),
117                       cl::aliasopt(NumericSort), cl::Grouping);
118
119cl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered"));
120cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort),
121                  cl::Grouping);
122
123cl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order"));
124cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"),
125                       cl::aliasopt(ReverseSort), cl::Grouping);
126
127cl::opt<bool> PrintSize("print-size",
128                        cl::desc("Show symbol size instead of address"));
129cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"),
130                     cl::aliasopt(PrintSize), cl::Grouping);
131
132cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size"));
133
134cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden,
135                             cl::desc("Exclude aliases from output"));
136
137cl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map"));
138cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"),
139                      cl::aliasopt(ArchiveMap), cl::Grouping);
140
141cl::opt<bool> JustSymbolName("just-symbol-name",
142                             cl::desc("Print just the symbol's name"));
143cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"),
144                          cl::aliasopt(JustSymbolName), cl::Grouping);
145
146// FIXME: This option takes exactly two strings and should be allowed anywhere
147// on the command line.  Such that "llvm-nm -s __TEXT __text foo.o" would work.
148// But that does not as the CommandLine Library does not have a way to make
149// this work.  For now the "-s __TEXT __text" has to be last on the command
150// line.
151cl::list<std::string> SegSect("s", cl::Positional, cl::ZeroOrMore,
152                              cl::desc("Dump only symbols from this segment "
153                                       "and section name, Mach-O only"));
154
155cl::opt<bool> FormatMachOasHex("x", cl::desc("Print symbol entry in hex, "
156                                             "Mach-O only"), cl::Grouping);
157
158cl::opt<bool> NoLLVMBitcode("no-llvm-bc",
159                            cl::desc("Disable LLVM bitcode reader"));
160
161bool PrintAddress = true;
162
163bool MultipleFiles = false;
164
165bool HadError = false;
166
167std::string ToolName;
168} // anonymous namespace
169
170static void error(Twine Message, Twine Path = Twine()) {
171  HadError = true;
172  errs() << ToolName << ": " << Path << ": " << Message << ".\n";
173}
174
175static bool error(std::error_code EC, Twine Path = Twine()) {
176  if (EC) {
177    error(EC.message(), Path);
178    return true;
179  }
180  return false;
181}
182
183namespace {
184struct NMSymbol {
185  uint64_t Address;
186  uint64_t Size;
187  char TypeChar;
188  StringRef Name;
189  BasicSymbolRef Sym;
190};
191} // anonymous namespace
192
193static bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) {
194  bool ADefined = !(A.Sym.getFlags() & SymbolRef::SF_Undefined);
195  bool BDefined = !(B.Sym.getFlags() & SymbolRef::SF_Undefined);
196  return std::make_tuple(ADefined, A.Address, A.Name, A.Size) <
197         std::make_tuple(BDefined, B.Address, B.Name, B.Size);
198}
199
200static bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) {
201  return std::make_tuple(A.Size, A.Name, A.Address) <
202         std::make_tuple(B.Size, B.Name, B.Address);
203}
204
205static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) {
206  return std::make_tuple(A.Name, A.Size, A.Address) <
207         std::make_tuple(B.Name, B.Size, B.Address);
208}
209
210static char isSymbolList64Bit(SymbolicFile &Obj) {
211  if (isa<IRObjectFile>(Obj)) {
212    IRObjectFile *IRobj = dyn_cast<IRObjectFile>(&Obj);
213    Module &M = IRobj->getModule();
214    if (M.getTargetTriple().empty())
215      return false;
216    Triple T(M.getTargetTriple());
217    return T.isArch64Bit();
218  }
219  if (isa<COFFObjectFile>(Obj))
220    return false;
221  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
222    return MachO->is64Bit();
223  return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8;
224}
225
226static StringRef CurrentFilename;
227typedef std::vector<NMSymbol> SymbolListT;
228static SymbolListT SymbolList;
229
230static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I);
231
232// darwinPrintSymbol() is used to print a symbol from a Mach-O file when the
233// the OutputFormat is darwin or we are printing Mach-O symbols in hex.  For
234// the darwin format it produces the same output as darwin's nm(1) -m output
235// and when printing Mach-O symbols in hex it produces the same output as
236// darwin's nm(1) -x format.
237static void darwinPrintSymbol(SymbolicFile &Obj, SymbolListT::iterator I,
238                              char *SymbolAddrStr, const char *printBlanks,
239                              const char *printDashes, const char *printFormat) {
240  MachO::mach_header H;
241  MachO::mach_header_64 H_64;
242  uint32_t Filetype = MachO::MH_OBJECT;
243  uint32_t Flags = 0;
244  uint8_t NType = 0;
245  uint8_t NSect = 0;
246  uint16_t NDesc = 0;
247  uint32_t NStrx = 0;
248  uint64_t NValue = 0;
249  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
250  if (Obj.isIR()) {
251    uint32_t SymFlags = I->Sym.getFlags();
252    if (SymFlags & SymbolRef::SF_Global)
253      NType |= MachO::N_EXT;
254    if (SymFlags & SymbolRef::SF_Hidden)
255      NType |= MachO::N_PEXT;
256    if (SymFlags & SymbolRef::SF_Undefined)
257      NType |= MachO::N_EXT | MachO::N_UNDF;
258    else {
259      // Here we have a symbol definition.  So to fake out a section name we
260      // use 1, 2 and 3 for section numbers.  See below where they are used to
261      // print out fake section names.
262      NType |= MachO::N_SECT;
263      if(SymFlags & SymbolRef::SF_Const)
264        NSect = 3;
265      else {
266        IRObjectFile *IRobj = dyn_cast<IRObjectFile>(&Obj);
267        char c = getSymbolNMTypeChar(*IRobj, I->Sym);
268        if (c == 't')
269          NSect = 1;
270        else
271          NSect = 2;
272      }
273    }
274    if (SymFlags & SymbolRef::SF_Weak)
275      NDesc |= MachO::N_WEAK_DEF;
276  } else {
277    DataRefImpl SymDRI = I->Sym.getRawDataRefImpl();
278    if (MachO->is64Bit()) {
279      H_64 = MachO->MachOObjectFile::getHeader64();
280      Filetype = H_64.filetype;
281      Flags = H_64.flags;
282      MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(SymDRI);
283      NType = STE_64.n_type;
284      NSect = STE_64.n_sect;
285      NDesc = STE_64.n_desc;
286      NStrx = STE_64.n_strx;
287      NValue = STE_64.n_value;
288    } else {
289      H = MachO->MachOObjectFile::getHeader();
290      Filetype = H.filetype;
291      Flags = H.flags;
292      MachO::nlist STE = MachO->getSymbolTableEntry(SymDRI);
293      NType = STE.n_type;
294      NSect = STE.n_sect;
295      NDesc = STE.n_desc;
296      NStrx = STE.n_strx;
297      NValue = STE.n_value;
298    }
299  }
300
301  // If we are printing Mach-O symbols in hex do that and return.
302  if (FormatMachOasHex) {
303    char Str[18] = "";
304    format(printFormat, NValue).print(Str, sizeof(Str));
305    outs() << Str << ' ';
306    format("%02x", NType).print(Str, sizeof(Str));
307    outs() << Str << ' ';
308    format("%02x", NSect).print(Str, sizeof(Str));
309    outs() << Str << ' ';
310    format("%04x", NDesc).print(Str, sizeof(Str));
311    outs() << Str << ' ';
312    format("%08x", NStrx).print(Str, sizeof(Str));
313    outs() << Str << ' ';
314    outs() << I->Name << "\n";
315    return;
316  }
317
318  if (PrintAddress) {
319    if ((NType & MachO::N_TYPE) == MachO::N_INDR)
320      strcpy(SymbolAddrStr, printBlanks);
321    if (Obj.isIR() && (NType & MachO::N_TYPE) == MachO::N_TYPE)
322      strcpy(SymbolAddrStr, printDashes);
323    outs() << SymbolAddrStr << ' ';
324  }
325
326  switch (NType & MachO::N_TYPE) {
327  case MachO::N_UNDF:
328    if (NValue != 0) {
329      outs() << "(common) ";
330      if (MachO::GET_COMM_ALIGN(NDesc) != 0)
331        outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") ";
332    } else {
333      if ((NType & MachO::N_TYPE) == MachO::N_PBUD)
334        outs() << "(prebound ";
335      else
336        outs() << "(";
337      if ((NDesc & MachO::REFERENCE_TYPE) ==
338          MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
339        outs() << "undefined [lazy bound]) ";
340      else if ((NDesc & MachO::REFERENCE_TYPE) ==
341               MachO::REFERENCE_FLAG_UNDEFINED_LAZY)
342        outs() << "undefined [private lazy bound]) ";
343      else if ((NDesc & MachO::REFERENCE_TYPE) ==
344               MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY)
345        outs() << "undefined [private]) ";
346      else
347        outs() << "undefined) ";
348    }
349    break;
350  case MachO::N_ABS:
351    outs() << "(absolute) ";
352    break;
353  case MachO::N_INDR:
354    outs() << "(indirect) ";
355    break;
356  case MachO::N_SECT: {
357    if (Obj.isIR()) {
358      // For llvm bitcode files print out a fake section name using the values
359      // use 1, 2 and 3 for section numbers as set above.
360      if (NSect == 1)
361        outs() << "(LTO,CODE) ";
362      else if (NSect == 2)
363        outs() << "(LTO,DATA) ";
364      else if (NSect == 3)
365        outs() << "(LTO,RODATA) ";
366      else
367        outs() << "(?,?) ";
368      break;
369    }
370    section_iterator Sec = *MachO->getSymbolSection(I->Sym.getRawDataRefImpl());
371    DataRefImpl Ref = Sec->getRawDataRefImpl();
372    StringRef SectionName;
373    MachO->getSectionName(Ref, SectionName);
374    StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref);
375    outs() << "(" << SegmentName << "," << SectionName << ") ";
376    break;
377  }
378  default:
379    outs() << "(?) ";
380    break;
381  }
382
383  if (NType & MachO::N_EXT) {
384    if (NDesc & MachO::REFERENCED_DYNAMICALLY)
385      outs() << "[referenced dynamically] ";
386    if (NType & MachO::N_PEXT) {
387      if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF)
388        outs() << "weak private external ";
389      else
390        outs() << "private external ";
391    } else {
392      if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF ||
393          (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) {
394        if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) ==
395            (MachO::N_WEAK_REF | MachO::N_WEAK_DEF))
396          outs() << "weak external automatically hidden ";
397        else
398          outs() << "weak external ";
399      } else
400        outs() << "external ";
401    }
402  } else {
403    if (NType & MachO::N_PEXT)
404      outs() << "non-external (was a private external) ";
405    else
406      outs() << "non-external ";
407  }
408
409  if (Filetype == MachO::MH_OBJECT &&
410      (NDesc & MachO::N_NO_DEAD_STRIP) == MachO::N_NO_DEAD_STRIP)
411    outs() << "[no dead strip] ";
412
413  if (Filetype == MachO::MH_OBJECT &&
414      ((NType & MachO::N_TYPE) != MachO::N_UNDF) &&
415      (NDesc & MachO::N_SYMBOL_RESOLVER) == MachO::N_SYMBOL_RESOLVER)
416    outs() << "[symbol resolver] ";
417
418  if (Filetype == MachO::MH_OBJECT &&
419      ((NType & MachO::N_TYPE) != MachO::N_UNDF) &&
420      (NDesc & MachO::N_ALT_ENTRY) == MachO::N_ALT_ENTRY)
421    outs() << "[alt entry] ";
422
423  if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF)
424    outs() << "[Thumb] ";
425
426  if ((NType & MachO::N_TYPE) == MachO::N_INDR) {
427    outs() << I->Name << " (for ";
428    StringRef IndirectName;
429    if (!MachO ||
430        MachO->getIndirectName(I->Sym.getRawDataRefImpl(), IndirectName))
431      outs() << "?)";
432    else
433      outs() << IndirectName << ")";
434  } else
435    outs() << I->Name;
436
437  if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL &&
438      (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) ||
439       (NType & MachO::N_TYPE) == MachO::N_PBUD)) {
440    uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc);
441    if (LibraryOrdinal != 0) {
442      if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL)
443        outs() << " (from executable)";
444      else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL)
445        outs() << " (dynamically looked up)";
446      else {
447        StringRef LibraryName;
448        if (!MachO ||
449            MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName))
450          outs() << " (from bad library ordinal " << LibraryOrdinal << ")";
451        else
452          outs() << " (from " << LibraryName << ")";
453      }
454    }
455  }
456
457  outs() << "\n";
458}
459
460// Table that maps Darwin's Mach-O stab constants to strings to allow printing.
461struct DarwinStabName {
462  uint8_t NType;
463  const char *Name;
464};
465static const struct DarwinStabName DarwinStabNames[] = {
466    {MachO::N_GSYM, "GSYM"},
467    {MachO::N_FNAME, "FNAME"},
468    {MachO::N_FUN, "FUN"},
469    {MachO::N_STSYM, "STSYM"},
470    {MachO::N_LCSYM, "LCSYM"},
471    {MachO::N_BNSYM, "BNSYM"},
472    {MachO::N_PC, "PC"},
473    {MachO::N_AST, "AST"},
474    {MachO::N_OPT, "OPT"},
475    {MachO::N_RSYM, "RSYM"},
476    {MachO::N_SLINE, "SLINE"},
477    {MachO::N_ENSYM, "ENSYM"},
478    {MachO::N_SSYM, "SSYM"},
479    {MachO::N_SO, "SO"},
480    {MachO::N_OSO, "OSO"},
481    {MachO::N_LSYM, "LSYM"},
482    {MachO::N_BINCL, "BINCL"},
483    {MachO::N_SOL, "SOL"},
484    {MachO::N_PARAMS, "PARAM"},
485    {MachO::N_VERSION, "VERS"},
486    {MachO::N_OLEVEL, "OLEV"},
487    {MachO::N_PSYM, "PSYM"},
488    {MachO::N_EINCL, "EINCL"},
489    {MachO::N_ENTRY, "ENTRY"},
490    {MachO::N_LBRAC, "LBRAC"},
491    {MachO::N_EXCL, "EXCL"},
492    {MachO::N_RBRAC, "RBRAC"},
493    {MachO::N_BCOMM, "BCOMM"},
494    {MachO::N_ECOMM, "ECOMM"},
495    {MachO::N_ECOML, "ECOML"},
496    {MachO::N_LENG, "LENG"},
497    {0, nullptr}};
498
499static const char *getDarwinStabString(uint8_t NType) {
500  for (unsigned i = 0; DarwinStabNames[i].Name; i++) {
501    if (DarwinStabNames[i].NType == NType)
502      return DarwinStabNames[i].Name;
503  }
504  return nullptr;
505}
506
507// darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of
508// a stab n_type value in a Mach-O file.
509static void darwinPrintStab(MachOObjectFile *MachO, SymbolListT::iterator I) {
510  MachO::nlist_64 STE_64;
511  MachO::nlist STE;
512  uint8_t NType;
513  uint8_t NSect;
514  uint16_t NDesc;
515  DataRefImpl SymDRI = I->Sym.getRawDataRefImpl();
516  if (MachO->is64Bit()) {
517    STE_64 = MachO->getSymbol64TableEntry(SymDRI);
518    NType = STE_64.n_type;
519    NSect = STE_64.n_sect;
520    NDesc = STE_64.n_desc;
521  } else {
522    STE = MachO->getSymbolTableEntry(SymDRI);
523    NType = STE.n_type;
524    NSect = STE.n_sect;
525    NDesc = STE.n_desc;
526  }
527
528  char Str[18] = "";
529  format("%02x", NSect).print(Str, sizeof(Str));
530  outs() << ' ' << Str << ' ';
531  format("%04x", NDesc).print(Str, sizeof(Str));
532  outs() << Str << ' ';
533  if (const char *stabString = getDarwinStabString(NType))
534    format("%5.5s", stabString).print(Str, sizeof(Str));
535  else
536    format("   %02x", NType).print(Str, sizeof(Str));
537  outs() << Str;
538}
539
540static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName,
541                                   std::string ArchiveName,
542                                   std::string ArchitectureName) {
543  if (!NoSort) {
544    std::function<bool(const NMSymbol &, const NMSymbol &)> Cmp;
545    if (NumericSort)
546      Cmp = compareSymbolAddress;
547    else if (SizeSort)
548      Cmp = compareSymbolSize;
549    else
550      Cmp = compareSymbolName;
551
552    if (ReverseSort)
553      Cmp = [=](const NMSymbol &A, const NMSymbol &B) { return Cmp(B, A); };
554    std::sort(SymbolList.begin(), SymbolList.end(), Cmp);
555  }
556
557  if (!PrintFileName) {
558    if (OutputFormat == posix && MultipleFiles && printName) {
559      outs() << '\n' << CurrentFilename << ":\n";
560    } else if (OutputFormat == bsd && MultipleFiles && printName) {
561      outs() << "\n" << CurrentFilename << ":\n";
562    } else if (OutputFormat == sysv) {
563      outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n"
564             << "Name                  Value   Class        Type"
565             << "         Size   Line  Section\n";
566    }
567  }
568
569  const char *printBlanks, *printDashes, *printFormat;
570  if (isSymbolList64Bit(Obj)) {
571    printBlanks = "                ";
572    printDashes = "----------------";
573    printFormat = "%016" PRIx64;
574  } else {
575    printBlanks = "        ";
576    printDashes = "--------";
577    printFormat = "%08" PRIx64;
578  }
579
580  for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();
581       I != E; ++I) {
582    uint32_t SymFlags = I->Sym.getFlags();
583    bool Undefined = SymFlags & SymbolRef::SF_Undefined;
584    if (!Undefined && UndefinedOnly)
585      continue;
586    if (Undefined && DefinedOnly)
587      continue;
588    bool Global = SymFlags & SymbolRef::SF_Global;
589    if (!Global && ExternalOnly)
590      continue;
591    if (SizeSort && !PrintAddress)
592      continue;
593    if (PrintFileName) {
594      if (!ArchitectureName.empty())
595        outs() << "(for architecture " << ArchitectureName << "):";
596      if (!ArchiveName.empty())
597        outs() << ArchiveName << ":";
598      outs() << CurrentFilename << ": ";
599    }
600    if ((JustSymbolName || (UndefinedOnly && isa<MachOObjectFile>(Obj) &&
601                            OutputFormat != darwin)) && OutputFormat != posix) {
602      outs() << I->Name << "\n";
603      continue;
604    }
605
606    char SymbolAddrStr[18] = "";
607    char SymbolSizeStr[18] = "";
608
609    if (OutputFormat == sysv || I->TypeChar == 'U')
610      strcpy(SymbolAddrStr, printBlanks);
611    if (OutputFormat == sysv)
612      strcpy(SymbolSizeStr, printBlanks);
613
614    if (I->TypeChar != 'U') {
615      if (Obj.isIR())
616        strcpy(SymbolAddrStr, printDashes);
617      else
618        format(printFormat, I->Address)
619          .print(SymbolAddrStr, sizeof(SymbolAddrStr));
620    }
621    format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
622
623    // If OutputFormat is darwin or we are printing Mach-O symbols in hex and
624    // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's
625    // nm(1) -m output or hex, else if OutputFormat is darwin or we are
626    // printing Mach-O symbols in hex and not a Mach-O object fall back to
627    // OutputFormat bsd (see below).
628    MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
629    if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) {
630      darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes,
631                        printFormat);
632    } else if (OutputFormat == posix) {
633      outs() << I->Name << " " << I->TypeChar << " ";
634      if (MachO)
635        outs() << I->Address << " " << "0" /* SymbolSizeStr */ << "\n";
636      else
637        outs() << SymbolAddrStr << SymbolSizeStr << "\n";
638    } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) {
639      if (PrintAddress)
640        outs() << SymbolAddrStr << ' ';
641      if (PrintSize) {
642        outs() << SymbolSizeStr;
643        outs() << ' ';
644      }
645      outs() << I->TypeChar;
646      if (I->TypeChar == '-' && MachO)
647        darwinPrintStab(MachO, I);
648      outs() << " " << I->Name << "\n";
649    } else if (OutputFormat == sysv) {
650      std::string PaddedName(I->Name);
651      while (PaddedName.length() < 20)
652        PaddedName += " ";
653      outs() << PaddedName << "|" << SymbolAddrStr << "|   " << I->TypeChar
654             << "  |                  |" << SymbolSizeStr << "|     |\n";
655    }
656  }
657
658  SymbolList.clear();
659}
660
661static char getSymbolNMTypeChar(ELFObjectFileBase &Obj,
662                                basic_symbol_iterator I) {
663  // OK, this is ELF
664  elf_symbol_iterator SymI(I);
665
666  ErrorOr<elf_section_iterator> SecIOrErr = SymI->getSection();
667  if (error(SecIOrErr.getError()))
668    return '?';
669
670  elf_section_iterator SecI = *SecIOrErr;
671  if (SecI != Obj.section_end()) {
672    switch (SecI->getType()) {
673    case ELF::SHT_PROGBITS:
674    case ELF::SHT_DYNAMIC:
675      switch (SecI->getFlags()) {
676      case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR):
677        return 't';
678      case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE):
679      case (ELF::SHF_ALLOC | ELF::SHF_WRITE):
680        return 'd';
681      case ELF::SHF_ALLOC:
682      case (ELF::SHF_ALLOC | ELF::SHF_MERGE):
683      case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS):
684        return 'r';
685      }
686      break;
687    case ELF::SHT_NOBITS:
688      return 'b';
689    }
690  }
691
692  if (SymI->getELFType() == ELF::STT_SECTION) {
693    ErrorOr<StringRef> Name = SymI->getName();
694    if (error(Name.getError()))
695      return '?';
696    return StringSwitch<char>(*Name)
697        .StartsWith(".debug", 'N')
698        .StartsWith(".note", 'n')
699        .Default('?');
700  }
701
702  return 'n';
703}
704
705static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) {
706  COFFSymbolRef Symb = Obj.getCOFFSymbol(*I);
707  // OK, this is COFF.
708  symbol_iterator SymI(I);
709
710  ErrorOr<StringRef> Name = SymI->getName();
711  if (error(Name.getError()))
712    return '?';
713
714  char Ret = StringSwitch<char>(*Name)
715                 .StartsWith(".debug", 'N')
716                 .StartsWith(".sxdata", 'N')
717                 .Default('?');
718
719  if (Ret != '?')
720    return Ret;
721
722  uint32_t Characteristics = 0;
723  if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) {
724    ErrorOr<section_iterator> SecIOrErr = SymI->getSection();
725    if (error(SecIOrErr.getError()))
726      return '?';
727    section_iterator SecI = *SecIOrErr;
728    const coff_section *Section = Obj.getCOFFSection(*SecI);
729    Characteristics = Section->Characteristics;
730  }
731
732  switch (Symb.getSectionNumber()) {
733  case COFF::IMAGE_SYM_DEBUG:
734    return 'n';
735  default:
736    // Check section type.
737    if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
738      return 't';
739    if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
740      return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r';
741    if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
742      return 'b';
743    if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
744      return 'i';
745    // Check for section symbol.
746    if (Symb.isSectionDefinition())
747      return 's';
748  }
749
750  return '?';
751}
752
753static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) {
754  if (Obj.is64Bit()) {
755    MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
756    return STE.n_type;
757  }
758  MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
759  return STE.n_type;
760}
761
762static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
763  DataRefImpl Symb = I->getRawDataRefImpl();
764  uint8_t NType = getNType(Obj, Symb);
765
766  if (NType & MachO::N_STAB)
767    return '-';
768
769  switch (NType & MachO::N_TYPE) {
770  case MachO::N_ABS:
771    return 's';
772  case MachO::N_INDR:
773    return 'i';
774  case MachO::N_SECT: {
775    section_iterator Sec = *Obj.getSymbolSection(Symb);
776    DataRefImpl Ref = Sec->getRawDataRefImpl();
777    StringRef SectionName;
778    Obj.getSectionName(Ref, SectionName);
779    StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref);
780    if (SegmentName == "__TEXT" && SectionName == "__text")
781      return 't';
782    else if (SegmentName == "__DATA" && SectionName == "__data")
783      return 'd';
784    else if (SegmentName == "__DATA" && SectionName == "__bss")
785      return 'b';
786    else
787      return 's';
788  }
789  }
790
791  return '?';
792}
793
794static char getSymbolNMTypeChar(const GlobalValue &GV) {
795  if (GV.getType()->getElementType()->isFunctionTy())
796    return 't';
797  // FIXME: should we print 'b'? At the IR level we cannot be sure if this
798  // will be in bss or not, but we could approximate.
799  return 'd';
800}
801
802static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) {
803  const GlobalValue *GV = Obj.getSymbolGV(I->getRawDataRefImpl());
804  if (!GV)
805    return 't';
806  return getSymbolNMTypeChar(*GV);
807}
808
809static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) {
810  auto *ELF = dyn_cast<ELFObjectFileBase>(&Obj);
811  if (!ELF)
812    return false;
813
814  return elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT;
815}
816
817static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) {
818  uint32_t Symflags = I->getFlags();
819  if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) {
820    char Ret = isObject(Obj, I) ? 'v' : 'w';
821    if (!(Symflags & object::SymbolRef::SF_Undefined))
822      Ret = toupper(Ret);
823    return Ret;
824  }
825
826  if (Symflags & object::SymbolRef::SF_Undefined)
827    return 'U';
828
829  if (Symflags & object::SymbolRef::SF_Common)
830    return 'C';
831
832  char Ret = '?';
833  if (Symflags & object::SymbolRef::SF_Absolute)
834    Ret = 'a';
835  else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) {
836    Ret = getSymbolNMTypeChar(*IR, I);
837    Triple Host(sys::getDefaultTargetTriple());
838    if (Ret == 'd' && Host.isOSDarwin()) {
839      if(Symflags & SymbolRef::SF_Const)
840        Ret = 's';
841    }
842  }
843  else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj))
844    Ret = getSymbolNMTypeChar(*COFF, I);
845  else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
846    Ret = getSymbolNMTypeChar(*MachO, I);
847  else
848    Ret = getSymbolNMTypeChar(cast<ELFObjectFileBase>(Obj), I);
849
850  if (Symflags & object::SymbolRef::SF_Global)
851    Ret = toupper(Ret);
852
853  return Ret;
854}
855
856// getNsectForSegSect() is used to implement the Mach-O "-s segname sectname"
857// option to dump only those symbols from that section in a Mach-O file.
858// It is called once for each Mach-O file from dumpSymbolNamesFromObject()
859// to get the section number for that named section from the command line
860// arguments. It returns the section number for that section in the Mach-O
861// file or zero it is not present.
862static unsigned getNsectForSegSect(MachOObjectFile *Obj) {
863  unsigned Nsect = 1;
864  for (section_iterator I = Obj->section_begin(), E = Obj->section_end();
865       I != E; ++I) {
866    DataRefImpl Ref = I->getRawDataRefImpl();
867    StringRef SectionName;
868    Obj->getSectionName(Ref, SectionName);
869    StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref);
870    if (SegmentName == SegSect[0] && SectionName == SegSect[1])
871      return Nsect;
872    Nsect++;
873  }
874  return 0;
875}
876
877// getNsectInMachO() is used to implement the Mach-O "-s segname sectname"
878// option to dump only those symbols from that section in a Mach-O file.
879// It is called once for each symbol in a Mach-O file from
880// dumpSymbolNamesFromObject() and returns the section number for that symbol
881// if it is in a section, else it returns 0.
882static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) {
883  DataRefImpl Symb = Sym.getRawDataRefImpl();
884  if (Obj.is64Bit()) {
885    MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
886    if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT)
887      return STE.n_sect;
888    return 0;
889  }
890  MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
891  if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT)
892    return STE.n_sect;
893  return 0;
894}
895
896static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
897                                      std::string ArchiveName = std::string(),
898                                      std::string ArchitectureName =
899                                        std::string()) {
900  auto Symbols = Obj.symbols();
901  if (DynamicSyms) {
902    const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
903    if (!E) {
904      error("File format has no dynamic symbol table", Obj.getFileName());
905      return;
906    }
907    auto DynSymbols = E->getDynamicSymbolIterators();
908    Symbols =
909        make_range<basic_symbol_iterator>(DynSymbols.begin(), DynSymbols.end());
910  }
911  std::string NameBuffer;
912  raw_string_ostream OS(NameBuffer);
913  // If a "-s segname sectname" option was specified and this is a Mach-O
914  // file get the section number for that section in this object file.
915  unsigned int Nsect = 0;
916  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
917  if (SegSect.size() != 0 && MachO) {
918    Nsect = getNsectForSegSect(MachO);
919    // If this section is not in the object file no symbols are printed.
920    if (Nsect == 0)
921      return;
922  }
923  for (BasicSymbolRef Sym : Symbols) {
924    uint32_t SymFlags = Sym.getFlags();
925    if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific))
926      continue;
927    if (WithoutAliases) {
928      if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) {
929        const GlobalValue *GV = IR->getSymbolGV(Sym.getRawDataRefImpl());
930        if (GV && isa<GlobalAlias>(GV))
931          continue;
932      }
933    }
934    // If a "-s segname sectname" option was specified and this is a Mach-O
935    // file and this section appears in this file, Nsect will be non-zero then
936    // see if this symbol is a symbol from that section and if not skip it.
937    if (Nsect && Nsect != getNsectInMachO(*MachO, Sym))
938      continue;
939    NMSymbol S;
940    S.Size = 0;
941    S.Address = 0;
942    if (PrintSize) {
943      if (isa<ELFObjectFileBase>(&Obj))
944        S.Size = ELFSymbolRef(Sym).getSize();
945    }
946    if (PrintAddress && isa<ObjectFile>(Obj)) {
947      SymbolRef SymRef(Sym);
948      ErrorOr<uint64_t> AddressOrErr = SymRef.getAddress();
949      if (error(AddressOrErr.getError()))
950        break;
951      S.Address = *AddressOrErr;
952    }
953    S.TypeChar = getNMTypeChar(Obj, Sym);
954    if (error(Sym.printName(OS)))
955      break;
956    OS << '\0';
957    S.Sym = Sym;
958    SymbolList.push_back(S);
959  }
960
961  OS.flush();
962  const char *P = NameBuffer.c_str();
963  for (unsigned I = 0; I < SymbolList.size(); ++I) {
964    SymbolList[I].Name = P;
965    P += strlen(P) + 1;
966  }
967
968  CurrentFilename = Obj.getFileName();
969  sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName);
970}
971
972// checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file
973// and if it is and there is a list of architecture flags is specified then
974// check to make sure this Mach-O file is one of those architectures or all
975// architectures was specificed.  If not then an error is generated and this
976// routine returns false.  Else it returns true.
977static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) {
978  MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O);
979
980  if (!MachO || ArchAll || ArchFlags.size() == 0)
981    return true;
982
983  MachO::mach_header H;
984  MachO::mach_header_64 H_64;
985  Triple T;
986  if (MachO->is64Bit()) {
987    H_64 = MachO->MachOObjectFile::getHeader64();
988    T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype);
989  } else {
990    H = MachO->MachOObjectFile::getHeader();
991    T = MachOObjectFile::getArch(H.cputype, H.cpusubtype);
992  }
993  if (std::none_of(
994          ArchFlags.begin(), ArchFlags.end(),
995          [&](const std::string &Name) { return Name == T.getArchName(); })) {
996    error("No architecture specified", Filename);
997    return false;
998  }
999  return true;
1000}
1001
1002static void dumpSymbolNamesFromFile(std::string &Filename) {
1003  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
1004      MemoryBuffer::getFileOrSTDIN(Filename);
1005  if (error(BufferOrErr.getError(), Filename))
1006    return;
1007
1008  LLVMContext &Context = getGlobalContext();
1009  ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary(
1010      BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context);
1011  if (error(BinaryOrErr.getError(), Filename))
1012    return;
1013  Binary &Bin = *BinaryOrErr.get();
1014
1015  if (Archive *A = dyn_cast<Archive>(&Bin)) {
1016    if (ArchiveMap) {
1017      Archive::symbol_iterator I = A->symbol_begin();
1018      Archive::symbol_iterator E = A->symbol_end();
1019      if (I != E) {
1020        outs() << "Archive map\n";
1021        for (; I != E; ++I) {
1022          ErrorOr<Archive::Child> C = I->getMember();
1023          if (error(C.getError()))
1024            return;
1025          ErrorOr<StringRef> FileNameOrErr = C->getName();
1026          if (error(FileNameOrErr.getError()))
1027            return;
1028          StringRef SymName = I->getName();
1029          outs() << SymName << " in " << FileNameOrErr.get() << "\n";
1030        }
1031        outs() << "\n";
1032      }
1033    }
1034
1035    for (Archive::child_iterator I = A->child_begin(), E = A->child_end();
1036         I != E; ++I) {
1037      if (error(I->getError()))
1038        return;
1039      auto &C = I->get();
1040      ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
1041      if (ChildOrErr.getError())
1042        continue;
1043      if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
1044        if (!checkMachOAndArchFlags(O, Filename))
1045          return;
1046        if (!PrintFileName) {
1047          outs() << "\n";
1048          if (isa<MachOObjectFile>(O)) {
1049            outs() << Filename << "(" << O->getFileName() << ")";
1050          } else
1051            outs() << O->getFileName();
1052          outs() << ":\n";
1053        }
1054        dumpSymbolNamesFromObject(*O, false, Filename);
1055      }
1056    }
1057    return;
1058  }
1059  if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
1060    // If we have a list of architecture flags specified dump only those.
1061    if (!ArchAll && ArchFlags.size() != 0) {
1062      // Look for a slice in the universal binary that matches each ArchFlag.
1063      bool ArchFound;
1064      for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1065        ArchFound = false;
1066        for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1067                                                   E = UB->end_objects();
1068             I != E; ++I) {
1069          if (ArchFlags[i] == I->getArchTypeName()) {
1070            ArchFound = true;
1071            ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr =
1072                I->getAsObjectFile();
1073            std::string ArchiveName;
1074            std::string ArchitectureName;
1075            ArchiveName.clear();
1076            ArchitectureName.clear();
1077            if (ObjOrErr) {
1078              ObjectFile &Obj = *ObjOrErr.get();
1079              if (ArchFlags.size() > 1) {
1080                if (PrintFileName)
1081                  ArchitectureName = I->getArchTypeName();
1082                else
1083                  outs() << "\n" << Obj.getFileName() << " (for architecture "
1084                         << I->getArchTypeName() << ")"
1085                         << ":\n";
1086              }
1087              dumpSymbolNamesFromObject(Obj, false, ArchiveName,
1088                                        ArchitectureName);
1089            } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
1090                           I->getAsArchive()) {
1091              std::unique_ptr<Archive> &A = *AOrErr;
1092              for (Archive::child_iterator AI = A->child_begin(),
1093                                           AE = A->child_end();
1094                   AI != AE; ++AI) {
1095                if (error(AI->getError()))
1096                  return;
1097                auto &C = AI->get();
1098                ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
1099                    C.getAsBinary(&Context);
1100                if (ChildOrErr.getError())
1101                  continue;
1102                if (SymbolicFile *O =
1103                        dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
1104                  if (PrintFileName) {
1105                    ArchiveName = A->getFileName();
1106                    if (ArchFlags.size() > 1)
1107                      ArchitectureName = I->getArchTypeName();
1108                  } else {
1109                    outs() << "\n" << A->getFileName();
1110                    outs() << "(" << O->getFileName() << ")";
1111                    if (ArchFlags.size() > 1) {
1112                      outs() << " (for architecture " << I->getArchTypeName()
1113                             << ")";
1114                    }
1115                    outs() << ":\n";
1116                  }
1117                  dumpSymbolNamesFromObject(*O, false, ArchiveName,
1118                                            ArchitectureName);
1119                }
1120              }
1121            }
1122          }
1123        }
1124        if (!ArchFound) {
1125          error(ArchFlags[i],
1126                "file: " + Filename + " does not contain architecture");
1127          return;
1128        }
1129      }
1130      return;
1131    }
1132    // No architecture flags were specified so if this contains a slice that
1133    // matches the host architecture dump only that.
1134    if (!ArchAll) {
1135      StringRef HostArchName = MachOObjectFile::getHostArch().getArchName();
1136      for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1137                                                 E = UB->end_objects();
1138           I != E; ++I) {
1139        if (HostArchName == I->getArchTypeName()) {
1140          ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1141          std::string ArchiveName;
1142          ArchiveName.clear();
1143          if (ObjOrErr) {
1144            ObjectFile &Obj = *ObjOrErr.get();
1145            dumpSymbolNamesFromObject(Obj, false);
1146          } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr =
1147                         I->getAsArchive()) {
1148            std::unique_ptr<Archive> &A = *AOrErr;
1149            for (Archive::child_iterator AI = A->child_begin(),
1150                                         AE = A->child_end();
1151                 AI != AE; ++AI) {
1152              if (error(AI->getError()))
1153                return;
1154              auto &C = AI->get();
1155              ErrorOr<std::unique_ptr<Binary>> ChildOrErr =
1156                  C.getAsBinary(&Context);
1157              if (ChildOrErr.getError())
1158                continue;
1159              if (SymbolicFile *O =
1160                      dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
1161                if (PrintFileName)
1162                  ArchiveName = A->getFileName();
1163                else
1164                  outs() << "\n" << A->getFileName() << "(" << O->getFileName()
1165                         << ")"
1166                         << ":\n";
1167                dumpSymbolNamesFromObject(*O, false, ArchiveName);
1168              }
1169            }
1170          }
1171          return;
1172        }
1173      }
1174    }
1175    // Either all architectures have been specified or none have been specified
1176    // and this does not contain the host architecture so dump all the slices.
1177    bool moreThanOneArch = UB->getNumberOfObjects() > 1;
1178    for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1179                                               E = UB->end_objects();
1180         I != E; ++I) {
1181      ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
1182      std::string ArchiveName;
1183      std::string ArchitectureName;
1184      ArchiveName.clear();
1185      ArchitectureName.clear();
1186      if (ObjOrErr) {
1187        ObjectFile &Obj = *ObjOrErr.get();
1188        if (PrintFileName) {
1189          if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
1190            ArchitectureName = I->getArchTypeName();
1191        } else {
1192          if (moreThanOneArch)
1193            outs() << "\n";
1194          outs() << Obj.getFileName();
1195          if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
1196            outs() << " (for architecture " << I->getArchTypeName() << ")";
1197          outs() << ":\n";
1198        }
1199        dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName);
1200      } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) {
1201        std::unique_ptr<Archive> &A = *AOrErr;
1202        for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
1203             AI != AE; ++AI) {
1204          if (error(AI->getError()))
1205            return;
1206          auto &C = AI->get();
1207          ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context);
1208          if (ChildOrErr.getError())
1209            continue;
1210          if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
1211            if (PrintFileName) {
1212              ArchiveName = A->getFileName();
1213              if (isa<MachOObjectFile>(O) && moreThanOneArch)
1214                ArchitectureName = I->getArchTypeName();
1215            } else {
1216              outs() << "\n" << A->getFileName();
1217              if (isa<MachOObjectFile>(O)) {
1218                outs() << "(" << O->getFileName() << ")";
1219                if (moreThanOneArch)
1220                  outs() << " (for architecture " << I->getArchTypeName()
1221                         << ")";
1222              } else
1223                outs() << ":" << O->getFileName();
1224              outs() << ":\n";
1225            }
1226            dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName);
1227          }
1228        }
1229      }
1230    }
1231    return;
1232  }
1233  if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) {
1234    if (!checkMachOAndArchFlags(O, Filename))
1235      return;
1236    dumpSymbolNamesFromObject(*O, true);
1237    return;
1238  }
1239  error("unrecognizable file type", Filename);
1240}
1241
1242int main(int argc, char **argv) {
1243  // Print a stack trace if we signal out.
1244  sys::PrintStackTraceOnErrorSignal();
1245  PrettyStackTraceProgram X(argc, argv);
1246
1247  llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
1248  cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n");
1249
1250  // llvm-nm only reads binary files.
1251  if (error(sys::ChangeStdinToBinary()))
1252    return 1;
1253
1254  llvm::InitializeAllTargetInfos();
1255  llvm::InitializeAllTargetMCs();
1256  llvm::InitializeAllAsmParsers();
1257
1258  ToolName = argv[0];
1259  if (BSDFormat)
1260    OutputFormat = bsd;
1261  if (POSIXFormat)
1262    OutputFormat = posix;
1263  if (DarwinFormat)
1264    OutputFormat = darwin;
1265
1266  // The relative order of these is important. If you pass --size-sort it should
1267  // only print out the size. However, if you pass -S --size-sort, it should
1268  // print out both the size and address.
1269  if (SizeSort && !PrintSize)
1270    PrintAddress = false;
1271  if (OutputFormat == sysv || SizeSort)
1272    PrintSize = true;
1273
1274  switch (InputFilenames.size()) {
1275  case 0:
1276    InputFilenames.push_back("a.out");
1277  case 1:
1278    break;
1279  default:
1280    MultipleFiles = true;
1281  }
1282
1283  for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1284    if (ArchFlags[i] == "all") {
1285      ArchAll = true;
1286    } else {
1287      if (!MachOObjectFile::isValidArch(ArchFlags[i]))
1288        error("Unknown architecture named '" + ArchFlags[i] + "'",
1289              "for the -arch option");
1290    }
1291  }
1292
1293  if (SegSect.size() != 0 && SegSect.size() != 2)
1294    error("bad number of arguments (must be two arguments)",
1295          "for the -s option");
1296
1297  std::for_each(InputFilenames.begin(), InputFilenames.end(),
1298                dumpSymbolNamesFromFile);
1299
1300  if (HadError)
1301    return 1;
1302
1303  return 0;
1304}
1305