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