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