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