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_Weak) && !isa<MachOObjectFile>(Obj)) {
1146     char Ret = isObject(Obj, I) ? 'v' : 'w';
1147     return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret;
1148   }
1149 
1150   if (Symflags & object::SymbolRef::SF_Undefined)
1151     return 'U';
1152 
1153   if (Symflags & object::SymbolRef::SF_Common)
1154     return 'C';
1155 
1156   char Ret = '?';
1157   if (Symflags & object::SymbolRef::SF_Absolute)
1158     Ret = 'a';
1159   else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj))
1160     Ret = getSymbolNMTypeChar(*IR, I);
1161   else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj))
1162     Ret = getSymbolNMTypeChar(*COFF, I);
1163   else if (COFFImportFile *COFFImport = dyn_cast<COFFImportFile>(&Obj))
1164     Ret = getSymbolNMTypeChar(*COFFImport);
1165   else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
1166     Ret = getSymbolNMTypeChar(*MachO, I);
1167   else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj))
1168     Ret = getSymbolNMTypeChar(*Wasm, I);
1169   else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
1170     Ret = getSymbolNMTypeChar(*Tapi, I);
1171   else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) {
1172     if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
1173       return 'i';
1174     Ret = getSymbolNMTypeChar(*ELF, I);
1175     if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE)
1176       return Ret;
1177   } else
1178     llvm_unreachable("unknown binary format");
1179 
1180   if (!(Symflags & object::SymbolRef::SF_Global))
1181     return Ret;
1182 
1183   return toupper(Ret);
1184 }
1185 
1186 // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname"
1187 // option to dump only those symbols from that section in a Mach-O file.
1188 // It is called once for each Mach-O file from dumpSymbolNamesFromObject()
1189 // to get the section number for that named section from the command line
1190 // arguments. It returns the section number for that section in the Mach-O
1191 // file or zero it is not present.
1192 static unsigned getNsectForSegSect(MachOObjectFile *Obj) {
1193   unsigned Nsect = 1;
1194   for (auto &S : Obj->sections()) {
1195     DataRefImpl Ref = S.getRawDataRefImpl();
1196     StringRef SectionName;
1197     if (Expected<StringRef> NameOrErr = Obj->getSectionName(Ref))
1198       SectionName = *NameOrErr;
1199     StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref);
1200     if (SegmentName == SegSect[0] && SectionName == SegSect[1])
1201       return Nsect;
1202     Nsect++;
1203   }
1204   return 0;
1205 }
1206 
1207 // getNsectInMachO() is used to implement the Mach-O "-s segname sectname"
1208 // option to dump only those symbols from that section in a Mach-O file.
1209 // It is called once for each symbol in a Mach-O file from
1210 // dumpSymbolNamesFromObject() and returns the section number for that symbol
1211 // if it is in a section, else it returns 0.
1212 static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) {
1213   DataRefImpl Symb = Sym.getRawDataRefImpl();
1214   if (Obj.is64Bit()) {
1215     MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
1216     return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
1217   }
1218   MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
1219   return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0;
1220 }
1221 
1222 static void dumpSymbolsFromDLInfoMachO(MachOObjectFile &MachO) {
1223   size_t I = SymbolList.size();
1224   std::string ExportsNameBuffer;
1225   raw_string_ostream EOS(ExportsNameBuffer);
1226   std::string BindsNameBuffer;
1227   raw_string_ostream BOS(BindsNameBuffer);
1228   std::string LazysNameBuffer;
1229   raw_string_ostream LOS(LazysNameBuffer);
1230   std::string WeaksNameBuffer;
1231   raw_string_ostream WOS(WeaksNameBuffer);
1232   std::string FunctionStartsNameBuffer;
1233   raw_string_ostream FOS(FunctionStartsNameBuffer);
1234 
1235   MachO::mach_header H;
1236   MachO::mach_header_64 H_64;
1237   uint32_t HFlags = 0;
1238   if (MachO.is64Bit()) {
1239     H_64 = MachO.MachOObjectFile::getHeader64();
1240     HFlags = H_64.flags;
1241   } else {
1242     H = MachO.MachOObjectFile::getHeader();
1243     HFlags = H.flags;
1244   }
1245   uint64_t BaseSegmentAddress = 0;
1246   for (const auto &Command : MachO.load_commands()) {
1247     if (Command.C.cmd == MachO::LC_SEGMENT) {
1248       MachO::segment_command Seg = MachO.getSegmentLoadCommand(Command);
1249       if (Seg.fileoff == 0 && Seg.filesize != 0) {
1250         BaseSegmentAddress = Seg.vmaddr;
1251         break;
1252       }
1253     } else if (Command.C.cmd == MachO::LC_SEGMENT_64) {
1254       MachO::segment_command_64 Seg = MachO.getSegment64LoadCommand(Command);
1255       if (Seg.fileoff == 0 && Seg.filesize != 0) {
1256         BaseSegmentAddress = Seg.vmaddr;
1257         break;
1258       }
1259     }
1260   }
1261   if (DyldInfoOnly || AddDyldInfo ||
1262       HFlags & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) {
1263     unsigned ExportsAdded = 0;
1264     Error Err = Error::success();
1265     for (const llvm::object::ExportEntry &Entry : MachO.exports(Err)) {
1266       bool found = false;
1267       bool ReExport = false;
1268       if (!DyldInfoOnly) {
1269         for (const NMSymbol &S : SymbolList)
1270           if (S.Address == Entry.address() + BaseSegmentAddress &&
1271               S.Name == Entry.name()) {
1272             found = true;
1273             break;
1274           }
1275       }
1276       if (!found) {
1277         NMSymbol S = {};
1278         S.Address = Entry.address() + BaseSegmentAddress;
1279         S.Size = 0;
1280         S.TypeChar = '\0';
1281         S.Name = Entry.name().str();
1282         // There is no symbol in the nlist symbol table for this so we set
1283         // Sym effectivly to null and the rest of code in here must test for
1284         // it and not do things like Sym.getFlags() for it.
1285         S.Sym = BasicSymbolRef();
1286         S.SymFlags = SymbolRef::SF_Global;
1287         S.Section = SectionRef();
1288         S.NType = 0;
1289         S.NSect = 0;
1290         S.NDesc = 0;
1291 
1292         uint64_t EFlags = Entry.flags();
1293         bool Abs = ((EFlags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) ==
1294                     MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
1295         bool Resolver = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
1296         ReExport = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
1297         bool WeakDef = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
1298         if (WeakDef)
1299           S.NDesc |= MachO::N_WEAK_DEF;
1300         if (Abs) {
1301           S.NType = MachO::N_EXT | MachO::N_ABS;
1302           S.TypeChar = 'A';
1303         } else if (ReExport) {
1304           S.NType = MachO::N_EXT | MachO::N_INDR;
1305           S.TypeChar = 'I';
1306         } else {
1307           S.NType = MachO::N_EXT | MachO::N_SECT;
1308           if (Resolver) {
1309             S.Address = Entry.other() + BaseSegmentAddress;
1310             if ((S.Address & 1) != 0 && !MachO.is64Bit() &&
1311                 H.cputype == MachO::CPU_TYPE_ARM) {
1312               S.Address &= ~1LL;
1313               S.NDesc |= MachO::N_ARM_THUMB_DEF;
1314             }
1315           } else {
1316             S.Address = Entry.address() + BaseSegmentAddress;
1317           }
1318           StringRef SegmentName = StringRef();
1319           StringRef SectionName = StringRef();
1320           for (const SectionRef &Section : MachO.sections()) {
1321             S.NSect++;
1322 
1323             if (Expected<StringRef> NameOrErr = Section.getName())
1324               SectionName = *NameOrErr;
1325             else
1326               consumeError(NameOrErr.takeError());
1327 
1328             SegmentName =
1329                 MachO.getSectionFinalSegmentName(Section.getRawDataRefImpl());
1330             if (S.Address >= Section.getAddress() &&
1331                 S.Address < Section.getAddress() + Section.getSize()) {
1332               S.Section = Section;
1333               break;
1334             } else if (Entry.name() == "__mh_execute_header" &&
1335                        SegmentName == "__TEXT" && SectionName == "__text") {
1336               S.Section = Section;
1337               S.NDesc |= MachO::REFERENCED_DYNAMICALLY;
1338               break;
1339             }
1340           }
1341           if (SegmentName == "__TEXT" && SectionName == "__text")
1342             S.TypeChar = 'T';
1343           else if (SegmentName == "__DATA" && SectionName == "__data")
1344             S.TypeChar = 'D';
1345           else if (SegmentName == "__DATA" && SectionName == "__bss")
1346             S.TypeChar = 'B';
1347           else
1348             S.TypeChar = 'S';
1349         }
1350         SymbolList.push_back(S);
1351 
1352         EOS << Entry.name();
1353         EOS << '\0';
1354         ExportsAdded++;
1355 
1356         // For ReExports there are a two more things to do, first add the
1357         // indirect name and second create the undefined symbol using the
1358         // referened dynamic library.
1359         if (ReExport) {
1360 
1361           // Add the indirect name.
1362           if (Entry.otherName().empty())
1363             EOS << Entry.name();
1364           else
1365             EOS << Entry.otherName();
1366           EOS << '\0';
1367 
1368           // Now create the undefined symbol using the referened dynamic
1369           // library.
1370           NMSymbol U = {};
1371           U.Address = 0;
1372           U.Size = 0;
1373           U.TypeChar = 'U';
1374           if (Entry.otherName().empty())
1375             U.Name = Entry.name().str();
1376           else
1377             U.Name = Entry.otherName().str();
1378           // Again there is no symbol in the nlist symbol table for this so
1379           // we set Sym effectivly to null and the rest of code in here must
1380           // test for it and not do things like Sym.getFlags() for it.
1381           U.Sym = BasicSymbolRef();
1382           U.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1383           U.Section = SectionRef();
1384           U.NType = MachO::N_EXT | MachO::N_UNDF;
1385           U.NSect = 0;
1386           U.NDesc = 0;
1387           // The library ordinal for this undefined symbol is in the export
1388           // trie Entry.other().
1389           MachO::SET_LIBRARY_ORDINAL(U.NDesc, Entry.other());
1390           SymbolList.push_back(U);
1391 
1392           // Finally add the undefined symbol's name.
1393           if (Entry.otherName().empty())
1394             EOS << Entry.name();
1395           else
1396             EOS << Entry.otherName();
1397           EOS << '\0';
1398           ExportsAdded++;
1399         }
1400       }
1401     }
1402     if (Err)
1403       error(std::move(Err), MachO.getFileName());
1404     // Set the symbol names and indirect names for the added symbols.
1405     if (ExportsAdded) {
1406       EOS.flush();
1407       const char *Q = ExportsNameBuffer.c_str();
1408       for (unsigned K = 0; K < ExportsAdded; K++) {
1409         SymbolList[I].Name = Q;
1410         Q += strlen(Q) + 1;
1411         if (SymbolList[I].TypeChar == 'I') {
1412           SymbolList[I].IndirectName = Q;
1413           Q += strlen(Q) + 1;
1414         }
1415         I++;
1416       }
1417     }
1418 
1419     // Add the undefined symbols from the bind entries.
1420     unsigned BindsAdded = 0;
1421     Error BErr = Error::success();
1422     StringRef LastSymbolName = StringRef();
1423     for (const llvm::object::MachOBindEntry &Entry : MachO.bindTable(BErr)) {
1424       bool found = false;
1425       if (LastSymbolName == Entry.symbolName())
1426         found = true;
1427       else if (!DyldInfoOnly) {
1428         for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
1429           if (SymbolList[J].Name == Entry.symbolName())
1430             found = true;
1431         }
1432       }
1433       if (!found) {
1434         LastSymbolName = Entry.symbolName();
1435         NMSymbol B = {};
1436         B.Address = 0;
1437         B.Size = 0;
1438         B.TypeChar = 'U';
1439         // There is no symbol in the nlist symbol table for this so we set
1440         // Sym effectivly to null and the rest of code in here must test for
1441         // it and not do things like Sym.getFlags() for it.
1442         B.Sym = BasicSymbolRef();
1443         B.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1444         B.NType = MachO::N_EXT | MachO::N_UNDF;
1445         B.NSect = 0;
1446         B.NDesc = 0;
1447         MachO::SET_LIBRARY_ORDINAL(B.NDesc, Entry.ordinal());
1448         B.Name = Entry.symbolName().str();
1449         SymbolList.push_back(B);
1450         BOS << Entry.symbolName();
1451         BOS << '\0';
1452         BindsAdded++;
1453       }
1454     }
1455     if (BErr)
1456       error(std::move(BErr), MachO.getFileName());
1457     // Set the symbol names and indirect names for the added symbols.
1458     if (BindsAdded) {
1459       BOS.flush();
1460       const char *Q = BindsNameBuffer.c_str();
1461       for (unsigned K = 0; K < BindsAdded; K++) {
1462         SymbolList[I].Name = Q;
1463         Q += strlen(Q) + 1;
1464         if (SymbolList[I].TypeChar == 'I') {
1465           SymbolList[I].IndirectName = Q;
1466           Q += strlen(Q) + 1;
1467         }
1468         I++;
1469       }
1470     }
1471 
1472     // Add the undefined symbols from the lazy bind entries.
1473     unsigned LazysAdded = 0;
1474     Error LErr = Error::success();
1475     LastSymbolName = StringRef();
1476     for (const llvm::object::MachOBindEntry &Entry :
1477          MachO.lazyBindTable(LErr)) {
1478       bool found = false;
1479       if (LastSymbolName == Entry.symbolName())
1480         found = true;
1481       else {
1482         // Here we must check to see it this symbol is already in the
1483         // SymbolList as it might have already have been added above via a
1484         // non-lazy (bind) entry.
1485         for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
1486           if (SymbolList[J].Name == Entry.symbolName())
1487             found = true;
1488         }
1489       }
1490       if (!found) {
1491         LastSymbolName = Entry.symbolName();
1492         NMSymbol L = {};
1493         L.Name = Entry.symbolName().str();
1494         L.Address = 0;
1495         L.Size = 0;
1496         L.TypeChar = 'U';
1497         // There is no symbol in the nlist symbol table for this so we set
1498         // Sym effectivly to null and the rest of code in here must test for
1499         // it and not do things like Sym.getFlags() for it.
1500         L.Sym = BasicSymbolRef();
1501         L.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1502         L.NType = MachO::N_EXT | MachO::N_UNDF;
1503         L.NSect = 0;
1504         // The REFERENCE_FLAG_UNDEFINED_LAZY is no longer used but here it
1505         // makes sence since we are creating this from a lazy bind entry.
1506         L.NDesc = MachO::REFERENCE_FLAG_UNDEFINED_LAZY;
1507         MachO::SET_LIBRARY_ORDINAL(L.NDesc, Entry.ordinal());
1508         SymbolList.push_back(L);
1509         LOS << Entry.symbolName();
1510         LOS << '\0';
1511         LazysAdded++;
1512       }
1513     }
1514     if (LErr)
1515       error(std::move(LErr), MachO.getFileName());
1516     // Set the symbol names and indirect names for the added symbols.
1517     if (LazysAdded) {
1518       LOS.flush();
1519       const char *Q = LazysNameBuffer.c_str();
1520       for (unsigned K = 0; K < LazysAdded; K++) {
1521         SymbolList[I].Name = Q;
1522         Q += strlen(Q) + 1;
1523         if (SymbolList[I].TypeChar == 'I') {
1524           SymbolList[I].IndirectName = Q;
1525           Q += strlen(Q) + 1;
1526         }
1527         I++;
1528       }
1529     }
1530 
1531     // Add the undefineds symbol from the weak bind entries which are not
1532     // strong symbols.
1533     unsigned WeaksAdded = 0;
1534     Error WErr = Error::success();
1535     LastSymbolName = StringRef();
1536     for (const llvm::object::MachOBindEntry &Entry :
1537          MachO.weakBindTable(WErr)) {
1538       bool found = false;
1539       unsigned J = 0;
1540       if (LastSymbolName == Entry.symbolName() ||
1541           Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) {
1542         found = true;
1543       } else {
1544         for (J = 0; J < SymbolList.size() && !found; ++J) {
1545           if (SymbolList[J].Name == Entry.symbolName()) {
1546             found = true;
1547             break;
1548           }
1549         }
1550       }
1551       if (!found) {
1552         LastSymbolName = Entry.symbolName();
1553         NMSymbol W = {};
1554         W.Name = Entry.symbolName().str();
1555         W.Address = 0;
1556         W.Size = 0;
1557         W.TypeChar = 'U';
1558         // There is no symbol in the nlist symbol table for this so we set
1559         // Sym effectivly to null and the rest of code in here must test for
1560         // it and not do things like Sym.getFlags() for it.
1561         W.Sym = BasicSymbolRef();
1562         W.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined;
1563         W.NType = MachO::N_EXT | MachO::N_UNDF;
1564         W.NSect = 0;
1565         // Odd that we are using N_WEAK_DEF on an undefined symbol but that is
1566         // what is created in this case by the linker when there are real
1567         // symbols in the nlist structs.
1568         W.NDesc = MachO::N_WEAK_DEF;
1569         SymbolList.push_back(W);
1570         WOS << Entry.symbolName();
1571         WOS << '\0';
1572         WeaksAdded++;
1573       } else {
1574         // This is the case the symbol was previously been found and it could
1575         // have been added from a bind or lazy bind symbol.  If so and not
1576         // a definition also mark it as weak.
1577         if (SymbolList[J].TypeChar == 'U')
1578           // See comment above about N_WEAK_DEF.
1579           SymbolList[J].NDesc |= MachO::N_WEAK_DEF;
1580       }
1581     }
1582     if (WErr)
1583       error(std::move(WErr), MachO.getFileName());
1584     // Set the symbol names and indirect names for the added symbols.
1585     if (WeaksAdded) {
1586       WOS.flush();
1587       const char *Q = WeaksNameBuffer.c_str();
1588       for (unsigned K = 0; K < WeaksAdded; K++) {
1589         SymbolList[I].Name = Q;
1590         Q += strlen(Q) + 1;
1591         if (SymbolList[I].TypeChar == 'I') {
1592           SymbolList[I].IndirectName = Q;
1593           Q += strlen(Q) + 1;
1594         }
1595         I++;
1596       }
1597     }
1598 
1599     // Trying adding symbol from the function starts table and LC_MAIN entry
1600     // point.
1601     SmallVector<uint64_t, 8> FoundFns;
1602     uint64_t lc_main_offset = UINT64_MAX;
1603     for (const auto &Command : MachO.load_commands()) {
1604       if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) {
1605         // We found a function starts segment, parse the addresses for
1606         // consumption.
1607         MachO::linkedit_data_command LLC =
1608             MachO.getLinkeditDataLoadCommand(Command);
1609 
1610         MachO.ReadULEB128s(LLC.dataoff, FoundFns);
1611       } else if (Command.C.cmd == MachO::LC_MAIN) {
1612         MachO::entry_point_command LCmain = MachO.getEntryPointCommand(Command);
1613         lc_main_offset = LCmain.entryoff;
1614       }
1615     }
1616     // See if these addresses are already in the symbol table.
1617     unsigned FunctionStartsAdded = 0;
1618     for (uint64_t f = 0; f < FoundFns.size(); f++) {
1619       bool found = false;
1620       for (unsigned J = 0; J < SymbolList.size() && !found; ++J) {
1621         if (SymbolList[J].Address == FoundFns[f] + BaseSegmentAddress)
1622           found = true;
1623       }
1624       // See this address is not already in the symbol table fake up an
1625       // nlist for it.
1626       if (!found) {
1627         NMSymbol F = {};
1628         F.Name = "<redacted function X>";
1629         F.Address = FoundFns[f] + BaseSegmentAddress;
1630         F.Size = 0;
1631         // There is no symbol in the nlist symbol table for this so we set
1632         // Sym effectivly to null and the rest of code in here must test for
1633         // it and not do things like Sym.getFlags() for it.
1634         F.Sym = BasicSymbolRef();
1635         F.SymFlags = 0;
1636         F.NType = MachO::N_SECT;
1637         F.NSect = 0;
1638         StringRef SegmentName = StringRef();
1639         StringRef SectionName = StringRef();
1640         for (const SectionRef &Section : MachO.sections()) {
1641           if (Expected<StringRef> NameOrErr = Section.getName())
1642             SectionName = *NameOrErr;
1643           else
1644             consumeError(NameOrErr.takeError());
1645 
1646           SegmentName =
1647               MachO.getSectionFinalSegmentName(Section.getRawDataRefImpl());
1648           F.NSect++;
1649           if (F.Address >= Section.getAddress() &&
1650               F.Address < Section.getAddress() + Section.getSize()) {
1651             F.Section = Section;
1652             break;
1653           }
1654         }
1655         if (SegmentName == "__TEXT" && SectionName == "__text")
1656           F.TypeChar = 't';
1657         else if (SegmentName == "__DATA" && SectionName == "__data")
1658           F.TypeChar = 'd';
1659         else if (SegmentName == "__DATA" && SectionName == "__bss")
1660           F.TypeChar = 'b';
1661         else
1662           F.TypeChar = 's';
1663         F.NDesc = 0;
1664         SymbolList.push_back(F);
1665         if (FoundFns[f] == lc_main_offset)
1666           FOS << "<redacted LC_MAIN>";
1667         else
1668           FOS << "<redacted function " << f << ">";
1669         FOS << '\0';
1670         FunctionStartsAdded++;
1671       }
1672     }
1673     if (FunctionStartsAdded) {
1674       FOS.flush();
1675       const char *Q = FunctionStartsNameBuffer.c_str();
1676       for (unsigned K = 0; K < FunctionStartsAdded; K++) {
1677         SymbolList[I].Name = Q;
1678         Q += strlen(Q) + 1;
1679         if (SymbolList[I].TypeChar == 'I') {
1680           SymbolList[I].IndirectName = Q;
1681           Q += strlen(Q) + 1;
1682         }
1683         I++;
1684       }
1685     }
1686   }
1687 }
1688 
1689 namespace {
1690 struct SymbolVersion {
1691   std::string Name;
1692   bool IsDefault;
1693 };
1694 } // namespace
1695 
1696 template <class ELFT>
1697 static Expected<std::vector<SymbolVersion>>
1698 readSymbolVersionsELF(const ELFFile<ELFT> &Obj, StringRef FileName,
1699                       ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
1700   using Elf_Shdr = typename ELFT::Shdr;
1701 
1702   // We called sections() earlier, so can't fail here.
1703   typename ELFT::ShdrRange SectionsOrErr = cantFail(Obj.sections());
1704   const Elf_Shdr *SymVerSec = nullptr;
1705   const Elf_Shdr *SymVerNeedSec = nullptr;
1706   const Elf_Shdr *SymVerDefSec = nullptr;
1707   for (const Elf_Shdr &Sec : SectionsOrErr) {
1708     if (Sec.sh_type == ELF::SHT_GNU_versym)
1709       SymVerSec = &Sec;
1710     else if (Sec.sh_type == ELF::SHT_GNU_verdef)
1711       SymVerDefSec = &Sec;
1712     else if (Sec.sh_type == ELF::SHT_GNU_verneed)
1713       SymVerNeedSec = &Sec;
1714   }
1715 
1716   if (!SymVerSec)
1717     return std::vector<SymbolVersion>{};
1718 
1719   Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr =
1720       Obj.loadVersionMap(SymVerNeedSec, SymVerDefSec);
1721   if (!MapOrErr)
1722     return MapOrErr.takeError();
1723 
1724   std::vector<SymbolVersion> Ret;
1725   size_t I = 0;
1726   for (auto It = Symbols.begin(), E = Symbols.end(); It != E; ++It) {
1727     ++I;
1728     Expected<const typename ELFT::Versym *> VerEntryOrErr =
1729         Obj.template getEntry<typename ELFT::Versym>(*SymVerSec, I);
1730     if (!VerEntryOrErr)
1731       return createError("unable to read an entry with index " + Twine(I) +
1732                          " from " + describe(Obj, *SymVerSec) + ": " +
1733                          toString(VerEntryOrErr.takeError()));
1734 
1735     Expected<uint32_t> FlagsOrErr = It->getFlags();
1736     if (!FlagsOrErr)
1737       return createError("unable to read flags for symbol with index " +
1738                          Twine(I) + ": " + toString(FlagsOrErr.takeError()));
1739 
1740     bool IsDefault;
1741     Expected<StringRef> VerOrErr = Obj.getSymbolVersionByIndex(
1742         (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr,
1743         (*FlagsOrErr) & SymbolRef::SF_Undefined);
1744     if (!VerOrErr)
1745       return createError("unable to get a version for entry " + Twine(I) +
1746                          " of " + describe(Obj, *SymVerSec) + ": " +
1747                          toString(VerOrErr.takeError()));
1748 
1749     Ret.push_back({(*VerOrErr).str(), IsDefault});
1750   }
1751 
1752   return Ret;
1753 }
1754 
1755 static Expected<std::vector<SymbolVersion>>
1756 readSymbolVersionsELF(const ELFObjectFileBase &Obj,
1757                       ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
1758   if (const auto *ELF = dyn_cast<ELF32LEObjectFile>(&Obj))
1759     return readSymbolVersionsELF(ELF->getELFFile(), Obj.getFileName(), Symbols);
1760   else if (const auto *ELF = dyn_cast<ELF32BEObjectFile>(&Obj))
1761     return readSymbolVersionsELF(ELF->getELFFile(), Obj.getFileName(), Symbols);
1762   else if (const auto *ELF = dyn_cast<ELF64LEObjectFile>(&Obj))
1763     return readSymbolVersionsELF(ELF->getELFFile(), Obj.getFileName(), Symbols);
1764   return readSymbolVersionsELF(cast<ELF64BEObjectFile>(&Obj)->getELFFile(),
1765                                Obj.getFileName(), Symbols);
1766 }
1767 
1768 static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
1769                                       StringRef ArchiveName = {},
1770                                       StringRef ArchitectureName = {}) {
1771   auto Symbols = Obj.symbols();
1772   std::vector<SymbolVersion> SymbolVersions;
1773   if (DynamicSyms) {
1774     const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
1775     if (!E) {
1776       error("File format has no dynamic symbol table", Obj.getFileName());
1777       return;
1778     }
1779     Symbols = E->getDynamicSymbolIterators();
1780 
1781     if (Expected<std::vector<SymbolVersion>> VersionsOrErr =
1782             readSymbolVersionsELF(*E, Symbols))
1783       SymbolVersions = std::move(*VersionsOrErr);
1784     else
1785       WithColor::warning(errs(), ToolName)
1786           << "unable to read symbol versions: "
1787           << toString(VersionsOrErr.takeError()) << "\n";
1788   }
1789 
1790   // If a "-s segname sectname" option was specified and this is a Mach-O
1791   // file get the section number for that section in this object file.
1792   unsigned int Nsect = 0;
1793   MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj);
1794   if (!SegSect.empty() && MachO) {
1795     Nsect = getNsectForSegSect(MachO);
1796     // If this section is not in the object file no symbols are printed.
1797     if (Nsect == 0)
1798       return;
1799   }
1800   if (!(MachO && DyldInfoOnly)) {
1801     size_t I = -1;
1802     for (BasicSymbolRef Sym : Symbols) {
1803       ++I;
1804       Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
1805       if (!SymFlagsOrErr) {
1806         error(SymFlagsOrErr.takeError(), Obj.getFileName());
1807         return;
1808       }
1809       if (!DebugSyms && (*SymFlagsOrErr & SymbolRef::SF_FormatSpecific))
1810         continue;
1811       if (WithoutAliases && (*SymFlagsOrErr & SymbolRef::SF_Indirect))
1812         continue;
1813       // If a "-s segname sectname" option was specified and this is a Mach-O
1814       // file and this section appears in this file, Nsect will be non-zero then
1815       // see if this symbol is a symbol from that section and if not skip it.
1816       if (Nsect && Nsect != getNsectInMachO(*MachO, Sym))
1817         continue;
1818       NMSymbol S = {};
1819       S.Size = 0;
1820       S.Address = 0;
1821       if (isa<ELFObjectFileBase>(&Obj))
1822         S.Size = ELFSymbolRef(Sym).getSize();
1823       if (PrintAddress && isa<ObjectFile>(Obj)) {
1824         SymbolRef SymRef(Sym);
1825         Expected<uint64_t> AddressOrErr = SymRef.getAddress();
1826         if (!AddressOrErr) {
1827           consumeError(AddressOrErr.takeError());
1828           break;
1829         }
1830         S.Address = *AddressOrErr;
1831       }
1832       S.TypeName = getNMTypeName(Obj, Sym);
1833       S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName);
1834 
1835       raw_string_ostream OS(S.Name);
1836       if (Error E = Sym.printName(OS)) {
1837         if (MachO) {
1838           OS << "bad string index";
1839           consumeError(std::move(E));
1840         } else
1841           error(std::move(E), Obj.getFileName());
1842       }
1843       if (!SymbolVersions.empty() && !SymbolVersions[I].Name.empty())
1844         S.Name +=
1845             (SymbolVersions[I].IsDefault ? "@@" : "@") + SymbolVersions[I].Name;
1846 
1847       S.Sym = Sym;
1848       SymbolList.push_back(S);
1849     }
1850   }
1851 
1852   // If this is a Mach-O file where the nlist symbol table is out of sync
1853   // with the dyld export trie then look through exports and fake up symbols
1854   // for the ones that are missing (also done with the -add-dyldinfo flag).
1855   // This is needed if strip(1) -T is run on a binary containing swift
1856   // language symbols for example.  The option -only-dyldinfo will fake up
1857   // all symbols from the dyld export trie as well as the bind info.
1858   if (MachO && !NoDyldInfo)
1859     dumpSymbolsFromDLInfoMachO(*MachO);
1860 
1861   CurrentFilename = Obj.getFileName();
1862 
1863   if (Symbols.empty() && SymbolList.empty()) {
1864     writeFileName(errs(), ArchiveName, ArchitectureName);
1865     errs() << "no symbols\n";
1866   }
1867 
1868   sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName);
1869 }
1870 
1871 // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file
1872 // and if it is and there is a list of architecture flags is specified then
1873 // check to make sure this Mach-O file is one of those architectures or all
1874 // architectures was specificed.  If not then an error is generated and this
1875 // routine returns false.  Else it returns true.
1876 static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) {
1877   auto *MachO = dyn_cast<MachOObjectFile>(O);
1878 
1879   if (!MachO || ArchAll || ArchFlags.empty())
1880     return true;
1881 
1882   MachO::mach_header H;
1883   MachO::mach_header_64 H_64;
1884   Triple T;
1885   const char *McpuDefault, *ArchFlag;
1886   if (MachO->is64Bit()) {
1887     H_64 = MachO->MachOObjectFile::getHeader64();
1888     T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype,
1889                                        &McpuDefault, &ArchFlag);
1890   } else {
1891     H = MachO->MachOObjectFile::getHeader();
1892     T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype,
1893                                        &McpuDefault, &ArchFlag);
1894   }
1895   const std::string ArchFlagName(ArchFlag);
1896   if (!llvm::is_contained(ArchFlags, ArchFlagName)) {
1897     error("No architecture specified", Filename);
1898     return false;
1899   }
1900   return true;
1901 }
1902 
1903 static void dumpSymbolNamesFromFile(std::string &Filename) {
1904   ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
1905       MemoryBuffer::getFileOrSTDIN(Filename);
1906   if (error(BufferOrErr.getError(), Filename))
1907     return;
1908 
1909   LLVMContext Context;
1910   LLVMContext *ContextPtr = NoLLVMBitcode ? nullptr : &Context;
1911   Expected<std::unique_ptr<Binary>> BinaryOrErr =
1912       createBinary(BufferOrErr.get()->getMemBufferRef(), ContextPtr);
1913   if (!BinaryOrErr) {
1914     error(BinaryOrErr.takeError(), Filename);
1915     return;
1916   }
1917   Binary &Bin = *BinaryOrErr.get();
1918 
1919   if (Archive *A = dyn_cast<Archive>(&Bin)) {
1920     if (ArchiveMap) {
1921       Archive::symbol_iterator I = A->symbol_begin();
1922       Archive::symbol_iterator E = A->symbol_end();
1923       if (I != E) {
1924         outs() << "Archive map\n";
1925         for (; I != E; ++I) {
1926           Expected<Archive::Child> C = I->getMember();
1927           if (!C) {
1928             error(C.takeError(), Filename);
1929             break;
1930           }
1931           Expected<StringRef> FileNameOrErr = C->getName();
1932           if (!FileNameOrErr) {
1933             error(FileNameOrErr.takeError(), Filename);
1934             break;
1935           }
1936           StringRef SymName = I->getName();
1937           outs() << SymName << " in " << FileNameOrErr.get() << "\n";
1938         }
1939         outs() << "\n";
1940       }
1941     }
1942 
1943     {
1944       Error Err = Error::success();
1945       for (auto &C : A->children(Err)) {
1946         Expected<std::unique_ptr<Binary>> ChildOrErr =
1947             C.getAsBinary(ContextPtr);
1948         if (!ChildOrErr) {
1949           if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1950             error(std::move(E), Filename, C);
1951           continue;
1952         }
1953         if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
1954           if (!MachOPrintSizeWarning && PrintSize &&  isa<MachOObjectFile>(O)) {
1955             WithColor::warning(errs(), ToolName)
1956                 << "sizes with -print-size for Mach-O files are always zero.\n";
1957             MachOPrintSizeWarning = true;
1958           }
1959           if (!checkMachOAndArchFlags(O, Filename))
1960             return;
1961           if (!PrintFileName) {
1962             outs() << "\n";
1963             if (isa<MachOObjectFile>(O)) {
1964               outs() << Filename << "(" << O->getFileName() << ")";
1965             } else
1966               outs() << O->getFileName();
1967             outs() << ":\n";
1968           }
1969           dumpSymbolNamesFromObject(*O, false, Filename);
1970         }
1971       }
1972       if (Err)
1973         error(std::move(Err), A->getFileName());
1974     }
1975     return;
1976   }
1977   if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) {
1978     // If we have a list of architecture flags specified dump only those.
1979     if (!ArchAll && !ArchFlags.empty()) {
1980       // Look for a slice in the universal binary that matches each ArchFlag.
1981       bool ArchFound;
1982       for (unsigned i = 0; i < ArchFlags.size(); ++i) {
1983         ArchFound = false;
1984         for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
1985                                                    E = UB->end_objects();
1986              I != E; ++I) {
1987           if (ArchFlags[i] == I->getArchFlagName()) {
1988             ArchFound = true;
1989             Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
1990                 I->getAsObjectFile();
1991             std::string ArchiveName;
1992             std::string ArchitectureName;
1993             ArchiveName.clear();
1994             ArchitectureName.clear();
1995             if (ObjOrErr) {
1996               ObjectFile &Obj = *ObjOrErr.get();
1997               if (ArchFlags.size() > 1) {
1998                 if (PrintFileName)
1999                   ArchitectureName = I->getArchFlagName();
2000                 else
2001                   outs() << "\n" << Obj.getFileName() << " (for architecture "
2002                          << I->getArchFlagName() << ")"
2003                          << ":\n";
2004               }
2005               dumpSymbolNamesFromObject(Obj, false, ArchiveName,
2006                                         ArchitectureName);
2007             } else if (auto E = isNotObjectErrorInvalidFileType(
2008                        ObjOrErr.takeError())) {
2009               error(std::move(E), Filename, ArchFlags.size() > 1 ?
2010                     StringRef(I->getArchFlagName()) : StringRef());
2011               continue;
2012             } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2013                            I->getAsArchive()) {
2014               std::unique_ptr<Archive> &A = *AOrErr;
2015               Error Err = Error::success();
2016               for (auto &C : A->children(Err)) {
2017                 Expected<std::unique_ptr<Binary>> ChildOrErr =
2018                     C.getAsBinary(ContextPtr);
2019                 if (!ChildOrErr) {
2020                   if (auto E = isNotObjectErrorInvalidFileType(
2021                                        ChildOrErr.takeError())) {
2022                     error(std::move(E), Filename, C, ArchFlags.size() > 1 ?
2023                           StringRef(I->getArchFlagName()) : StringRef());
2024                   }
2025                   continue;
2026                 }
2027                 if (SymbolicFile *O =
2028                         dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
2029                   if (PrintFileName) {
2030                     ArchiveName = std::string(A->getFileName());
2031                     if (ArchFlags.size() > 1)
2032                       ArchitectureName = I->getArchFlagName();
2033                   } else {
2034                     outs() << "\n" << A->getFileName();
2035                     outs() << "(" << O->getFileName() << ")";
2036                     if (ArchFlags.size() > 1) {
2037                       outs() << " (for architecture " << I->getArchFlagName()
2038                              << ")";
2039                     }
2040                     outs() << ":\n";
2041                   }
2042                   dumpSymbolNamesFromObject(*O, false, ArchiveName,
2043                                             ArchitectureName);
2044                 }
2045               }
2046               if (Err)
2047                 error(std::move(Err), A->getFileName());
2048             } else {
2049               consumeError(AOrErr.takeError());
2050               error(Filename + " for architecture " +
2051                     StringRef(I->getArchFlagName()) +
2052                     " is not a Mach-O file or an archive file",
2053                     "Mach-O universal file");
2054             }
2055           }
2056         }
2057         if (!ArchFound) {
2058           error(ArchFlags[i],
2059                 "file: " + Filename + " does not contain architecture");
2060           return;
2061         }
2062       }
2063       return;
2064     }
2065     // No architecture flags were specified so if this contains a slice that
2066     // matches the host architecture dump only that.
2067     if (!ArchAll) {
2068       Triple HostTriple = MachOObjectFile::getHostArch();
2069       StringRef HostArchName = HostTriple.getArchName();
2070       for (MachOUniversalBinary::object_iterator I = UB->begin_objects(),
2071                                                  E = UB->end_objects();
2072            I != E; ++I) {
2073         if (HostArchName == I->getArchFlagName()) {
2074           Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile();
2075           std::string ArchiveName;
2076           if (ObjOrErr) {
2077             ObjectFile &Obj = *ObjOrErr.get();
2078             dumpSymbolNamesFromObject(Obj, false);
2079           } else if (auto E = isNotObjectErrorInvalidFileType(
2080                      ObjOrErr.takeError())) {
2081             error(std::move(E), Filename);
2082             return;
2083           } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2084                          I->getAsArchive()) {
2085             std::unique_ptr<Archive> &A = *AOrErr;
2086             Error Err = Error::success();
2087             for (auto &C : A->children(Err)) {
2088               Expected<std::unique_ptr<Binary>> ChildOrErr =
2089                   C.getAsBinary(ContextPtr);
2090               if (!ChildOrErr) {
2091                 if (auto E = isNotObjectErrorInvalidFileType(
2092                                      ChildOrErr.takeError()))
2093                   error(std::move(E), Filename, C);
2094                 continue;
2095               }
2096               if (SymbolicFile *O =
2097                       dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
2098                 if (PrintFileName)
2099                   ArchiveName = std::string(A->getFileName());
2100                 else
2101                   outs() << "\n" << A->getFileName() << "(" << O->getFileName()
2102                          << ")"
2103                          << ":\n";
2104                 dumpSymbolNamesFromObject(*O, false, ArchiveName);
2105               }
2106             }
2107             if (Err)
2108               error(std::move(Err), A->getFileName());
2109           } else {
2110             consumeError(AOrErr.takeError());
2111             error(Filename + " for architecture " +
2112                   StringRef(I->getArchFlagName()) +
2113                   " is not a Mach-O file or an archive file",
2114                   "Mach-O universal file");
2115           }
2116           return;
2117         }
2118       }
2119     }
2120     // Either all architectures have been specified or none have been specified
2121     // and this does not contain the host architecture so dump all the slices.
2122     bool moreThanOneArch = UB->getNumberOfObjects() > 1;
2123     for (const MachOUniversalBinary::ObjectForArch &O : UB->objects()) {
2124       Expected<std::unique_ptr<ObjectFile>> ObjOrErr = O.getAsObjectFile();
2125       std::string ArchiveName;
2126       std::string ArchitectureName;
2127       ArchiveName.clear();
2128       ArchitectureName.clear();
2129       if (ObjOrErr) {
2130         ObjectFile &Obj = *ObjOrErr.get();
2131         if (PrintFileName) {
2132           if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
2133             ArchitectureName = O.getArchFlagName();
2134         } else {
2135           if (moreThanOneArch)
2136             outs() << "\n";
2137           outs() << Obj.getFileName();
2138           if (isa<MachOObjectFile>(Obj) && moreThanOneArch)
2139             outs() << " (for architecture " << O.getArchFlagName() << ")";
2140           outs() << ":\n";
2141         }
2142         dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName);
2143       } else if (auto E = isNotObjectErrorInvalidFileType(
2144                  ObjOrErr.takeError())) {
2145         error(std::move(E), Filename, moreThanOneArch ?
2146               StringRef(O.getArchFlagName()) : StringRef());
2147         continue;
2148       } else if (Expected<std::unique_ptr<Archive>> AOrErr =
2149                   O.getAsArchive()) {
2150         std::unique_ptr<Archive> &A = *AOrErr;
2151         Error Err = Error::success();
2152         for (auto &C : A->children(Err)) {
2153           Expected<std::unique_ptr<Binary>> ChildOrErr =
2154             C.getAsBinary(ContextPtr);
2155           if (!ChildOrErr) {
2156             if (auto E = isNotObjectErrorInvalidFileType(
2157                                  ChildOrErr.takeError()))
2158               error(std::move(E), Filename, C, moreThanOneArch ?
2159                     StringRef(ArchitectureName) : StringRef());
2160             continue;
2161           }
2162           if (SymbolicFile *F = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) {
2163             if (PrintFileName) {
2164               ArchiveName = std::string(A->getFileName());
2165               if (isa<MachOObjectFile>(F) && moreThanOneArch)
2166                 ArchitectureName = O.getArchFlagName();
2167             } else {
2168               outs() << "\n" << A->getFileName();
2169               if (isa<MachOObjectFile>(F)) {
2170                 outs() << "(" << F->getFileName() << ")";
2171                 if (moreThanOneArch)
2172                   outs() << " (for architecture " << O.getArchFlagName()
2173                          << ")";
2174               } else
2175                 outs() << ":" << F->getFileName();
2176               outs() << ":\n";
2177             }
2178             dumpSymbolNamesFromObject(*F, false, ArchiveName, ArchitectureName);
2179           }
2180         }
2181         if (Err)
2182           error(std::move(Err), A->getFileName());
2183       } else {
2184         consumeError(AOrErr.takeError());
2185         error(Filename + " for architecture " +
2186               StringRef(O.getArchFlagName()) +
2187               " is not a Mach-O file or an archive file",
2188               "Mach-O universal file");
2189       }
2190     }
2191     return;
2192   }
2193 
2194   if (TapiUniversal *TU = dyn_cast<TapiUniversal>(&Bin)) {
2195     for (const TapiUniversal::ObjectForArch &I : TU->objects()) {
2196       StringRef ArchName = I.getArchFlagName();
2197       const bool ShowArch =
2198           ArchFlags.empty() || llvm::is_contained(ArchFlags, ArchName);
2199       if (!ShowArch)
2200         continue;
2201       if (!AddInlinedInfo && !I.isTopLevelLib())
2202         continue;
2203       if (auto ObjOrErr = I.getAsObjectFile()) {
2204         outs() << "\n"
2205                << I.getInstallName() << " (for architecture " << ArchName << ")"
2206                << ":\n";
2207         dumpSymbolNamesFromObject(*ObjOrErr.get(), false, {}, ArchName);
2208       } else if (Error E =
2209                      isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
2210         error(std::move(E), Filename, ArchName);
2211       }
2212     }
2213 
2214     return;
2215   }
2216 
2217   if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) {
2218     if (!MachOPrintSizeWarning && PrintSize &&  isa<MachOObjectFile>(O)) {
2219       WithColor::warning(errs(), ToolName)
2220           << "sizes with --print-size for Mach-O files are always zero.\n";
2221       MachOPrintSizeWarning = true;
2222     }
2223     if (!checkMachOAndArchFlags(O, Filename))
2224       return;
2225     dumpSymbolNamesFromObject(*O, true);
2226   }
2227 }
2228 
2229 int main(int argc, char **argv) {
2230   InitLLVM X(argc, argv);
2231   cl::HideUnrelatedOptions(NMCat);
2232   cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n");
2233 
2234   // llvm-nm only reads binary files.
2235   if (error(sys::ChangeStdinToBinary()))
2236     return 1;
2237 
2238   // These calls are needed so that we can read bitcode correctly.
2239   llvm::InitializeAllTargetInfos();
2240   llvm::InitializeAllTargetMCs();
2241   llvm::InitializeAllAsmParsers();
2242 
2243   ToolName = argv[0];
2244   if (BSDFormat)
2245     OutputFormat = bsd;
2246   if (POSIXFormat)
2247     OutputFormat = posix;
2248   if (DarwinFormat)
2249     OutputFormat = darwin;
2250 
2251   // The relative order of these is important. If you pass --size-sort it should
2252   // only print out the size. However, if you pass -S --size-sort, it should
2253   // print out both the size and address.
2254   if (SizeSort && !PrintSize)
2255     PrintAddress = false;
2256   if (OutputFormat == sysv || SizeSort)
2257     PrintSize = true;
2258   if (InputFilenames.empty())
2259     InputFilenames.push_back("a.out");
2260   if (InputFilenames.size() > 1)
2261     MultipleFiles = true;
2262 
2263   // If both --demangle and --no-demangle are specified then pick the last one.
2264   if (NoDemangle.getPosition() > Demangle.getPosition())
2265     Demangle = !NoDemangle;
2266 
2267   for (unsigned i = 0; i < ArchFlags.size(); ++i) {
2268     if (ArchFlags[i] == "all") {
2269       ArchAll = true;
2270     } else {
2271       if (!MachOObjectFile::isValidArch(ArchFlags[i]))
2272         error("Unknown architecture named '" + ArchFlags[i] + "'",
2273               "for the --arch option");
2274     }
2275   }
2276 
2277   if (!SegSect.empty() && SegSect.size() != 2)
2278     error("bad number of arguments (must be two arguments)",
2279           "for the -s option");
2280 
2281   if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly))
2282     error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only");
2283 
2284   llvm::for_each(InputFilenames, dumpSymbolNamesFromFile);
2285 
2286   if (HadError)
2287     return 1;
2288 }
2289