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