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