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