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