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