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