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