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. 13 // 14 // This "nm" supports many of the features of GNU "nm", including its different 15 // output formats. 16 // 17 //===----------------------------------------------------------------------===// 18 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/IR/Function.h" 21 #include "llvm/IR/GlobalAlias.h" 22 #include "llvm/IR/GlobalVariable.h" 23 #include "llvm/IR/LLVMContext.h" 24 #include "llvm/IR/Module.h" 25 #include "llvm/Object/Archive.h" 26 #include "llvm/Object/COFF.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/Support/COFF.h" 33 #include "llvm/Support/CommandLine.h" 34 #include "llvm/Support/FileSystem.h" 35 #include "llvm/Support/Format.h" 36 #include "llvm/Support/ManagedStatic.h" 37 #include "llvm/Support/MemoryBuffer.h" 38 #include "llvm/Support/PrettyStackTrace.h" 39 #include "llvm/Support/Program.h" 40 #include "llvm/Support/Signals.h" 41 #include "llvm/Support/TargetSelect.h" 42 #include "llvm/Support/raw_ostream.h" 43 #include <algorithm> 44 #include <cctype> 45 #include <cerrno> 46 #include <cstring> 47 #include <system_error> 48 #include <vector> 49 50 using namespace llvm; 51 using namespace object; 52 53 namespace { 54 enum OutputFormatTy { bsd, sysv, posix, darwin }; 55 cl::opt<OutputFormatTy> OutputFormat( 56 "format", cl::desc("Specify output format"), 57 cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"), 58 clEnumVal(posix, "POSIX.2 format"), 59 clEnumVal(darwin, "Darwin -m format")), 60 cl::init(bsd)); 61 cl::alias OutputFormat2("f", cl::desc("Alias for --format"), 62 cl::aliasopt(OutputFormat)); 63 64 cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"), 65 cl::ZeroOrMore); 66 67 cl::opt<bool> UndefinedOnly("undefined-only", 68 cl::desc("Show only undefined symbols")); 69 cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), 70 cl::aliasopt(UndefinedOnly), cl::Grouping); 71 72 cl::opt<bool> DynamicSyms("dynamic", 73 cl::desc("Display the dynamic symbols instead " 74 "of normal symbols.")); 75 cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"), 76 cl::aliasopt(DynamicSyms), cl::Grouping); 77 78 cl::opt<bool> DefinedOnly("defined-only", 79 cl::desc("Show only defined symbols")); 80 cl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"), 81 cl::aliasopt(DefinedOnly), cl::Grouping); 82 83 cl::opt<bool> ExternalOnly("extern-only", 84 cl::desc("Show only external symbols")); 85 cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"), 86 cl::aliasopt(ExternalOnly), cl::Grouping); 87 88 cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"), 89 cl::Grouping); 90 cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"), 91 cl::Grouping); 92 cl::opt<bool> DarwinFormat("m", cl::desc("Alias for --format=darwin"), 93 cl::Grouping); 94 95 static cl::list<std::string> 96 ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), 97 cl::ZeroOrMore); 98 bool ArchAll = false; 99 100 cl::opt<bool> PrintFileName( 101 "print-file-name", 102 cl::desc("Precede each symbol with the object file it came from")); 103 104 cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"), 105 cl::aliasopt(PrintFileName), cl::Grouping); 106 cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"), 107 cl::aliasopt(PrintFileName), cl::Grouping); 108 109 cl::opt<bool> DebugSyms("debug-syms", 110 cl::desc("Show all symbols, even debugger only")); 111 cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"), 112 cl::aliasopt(DebugSyms), cl::Grouping); 113 114 cl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address")); 115 cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"), 116 cl::aliasopt(NumericSort), cl::Grouping); 117 cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"), 118 cl::aliasopt(NumericSort), cl::Grouping); 119 120 cl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered")); 121 cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort), 122 cl::Grouping); 123 124 cl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order")); 125 cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"), 126 cl::aliasopt(ReverseSort), cl::Grouping); 127 128 cl::opt<bool> PrintSize("print-size", 129 cl::desc("Show symbol size instead of address")); 130 cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"), 131 cl::aliasopt(PrintSize), cl::Grouping); 132 133 cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size")); 134 135 cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden, 136 cl::desc("Exclude aliases from output")); 137 138 cl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map")); 139 cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"), 140 cl::aliasopt(ArchiveMap), cl::Grouping); 141 142 enum Radix { d, o, x }; 143 cl::opt<Radix> 144 AddressRadix("radix", cl::desc("Radix (o/d/x) for printing symbol Values"), 145 cl::values(clEnumVal(d, "decimal"), clEnumVal(o, "octal"), 146 clEnumVal(x, "hexadecimal")), 147 cl::init(x)); 148 cl::alias RadixAlias("t", cl::desc("Alias for --radix"), 149 cl::aliasopt(AddressRadix)); 150 151 cl::opt<bool> JustSymbolName("just-symbol-name", 152 cl::desc("Print just the symbol's name")); 153 cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"), 154 cl::aliasopt(JustSymbolName), cl::Grouping); 155 156 // FIXME: This option takes exactly two strings and should be allowed anywhere 157 // on the command line. Such that "llvm-nm -s __TEXT __text foo.o" would work. 158 // But that does not as the CommandLine Library does not have a way to make 159 // this work. For now the "-s __TEXT __text" has to be last on the command 160 // line. 161 cl::list<std::string> SegSect("s", cl::Positional, cl::ZeroOrMore, 162 cl::desc("Dump only symbols from this segment " 163 "and section name, Mach-O only")); 164 165 cl::opt<bool> FormatMachOasHex("x", cl::desc("Print symbol entry in hex, " 166 "Mach-O only"), cl::Grouping); 167 168 cl::opt<bool> NoLLVMBitcode("no-llvm-bc", 169 cl::desc("Disable LLVM bitcode reader")); 170 171 bool PrintAddress = true; 172 173 bool MultipleFiles = false; 174 175 bool HadError = false; 176 177 std::string ToolName; 178 } // anonymous namespace 179 180 static void error(Twine Message, Twine Path = Twine()) { 181 HadError = true; 182 errs() << ToolName << ": " << Path << ": " << Message << ".\n"; 183 } 184 185 static bool error(std::error_code EC, Twine Path = Twine()) { 186 if (EC) { 187 error(EC.message(), Path); 188 return true; 189 } 190 return false; 191 } 192 193 // This version of error() prints the archive name and member name, for example: 194 // "libx.a(foo.o)" after the ToolName before the error message. It sets 195 // HadError but returns allowing the code to move on to other archive members. 196 static void error(llvm::Error E, StringRef FileName, const Archive::Child &C, 197 StringRef ArchitectureName = StringRef()) { 198 HadError = true; 199 errs() << ToolName << ": " << FileName; 200 201 Expected<StringRef> NameOrErr = C.getName(); 202 // TODO: if we have a error getting the name then it would be nice to print 203 // the index of which archive member this is and or its offset in the 204 // archive instead of "???" as the name. 205 if (!NameOrErr) { 206 consumeError(NameOrErr.takeError()); 207 errs() << "(" << "???" << ")"; 208 } else 209 errs() << "(" << NameOrErr.get() << ")"; 210 211 if (!ArchitectureName.empty()) 212 errs() << " (for architecture " << ArchitectureName << ") "; 213 214 std::string Buf; 215 raw_string_ostream OS(Buf); 216 logAllUnhandledErrors(std::move(E), OS, ""); 217 OS.flush(); 218 errs() << " " << Buf << "\n"; 219 } 220 221 // This version of error() prints the file name and which architecture slice it 222 // is from, for example: "foo.o (for architecture i386)" after the ToolName 223 // before the error message. It sets HadError but returns allowing the code to 224 // move on to other architecture slices. 225 static void error(llvm::Error E, StringRef FileName, 226 StringRef ArchitectureName = StringRef()) { 227 HadError = true; 228 errs() << ToolName << ": " << FileName; 229 230 if (!ArchitectureName.empty()) 231 errs() << " (for architecture " << ArchitectureName << ") "; 232 233 std::string Buf; 234 raw_string_ostream OS(Buf); 235 logAllUnhandledErrors(std::move(E), OS, ""); 236 OS.flush(); 237 errs() << " " << Buf << "\n"; 238 } 239 240 namespace { 241 struct NMSymbol { 242 uint64_t Address; 243 uint64_t Size; 244 char TypeChar; 245 StringRef Name; 246 BasicSymbolRef Sym; 247 }; 248 } // anonymous namespace 249 250 static bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) { 251 bool ADefined = !(A.Sym.getFlags() & SymbolRef::SF_Undefined); 252 bool BDefined = !(B.Sym.getFlags() & SymbolRef::SF_Undefined); 253 return std::make_tuple(ADefined, A.Address, A.Name, A.Size) < 254 std::make_tuple(BDefined, B.Address, B.Name, B.Size); 255 } 256 257 static bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) { 258 return std::make_tuple(A.Size, A.Name, A.Address) < 259 std::make_tuple(B.Size, B.Name, B.Address); 260 } 261 262 static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) { 263 return std::make_tuple(A.Name, A.Size, A.Address) < 264 std::make_tuple(B.Name, B.Size, B.Address); 265 } 266 267 static char isSymbolList64Bit(SymbolicFile &Obj) { 268 if (auto *IRObj = dyn_cast<IRObjectFile>(&Obj)) 269 return Triple(IRObj->getTargetTriple()).isArch64Bit(); 270 if (isa<COFFObjectFile>(Obj)) 271 return false; 272 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) 273 return MachO->is64Bit(); 274 return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8; 275 } 276 277 static StringRef CurrentFilename; 278 typedef std::vector<NMSymbol> SymbolListT; 279 static SymbolListT SymbolList; 280 281 static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I); 282 283 // darwinPrintSymbol() is used to print a symbol from a Mach-O file when the 284 // the OutputFormat is darwin or we are printing Mach-O symbols in hex. For 285 // the darwin format it produces the same output as darwin's nm(1) -m output 286 // and when printing Mach-O symbols in hex it produces the same output as 287 // darwin's nm(1) -x format. 288 static void darwinPrintSymbol(SymbolicFile &Obj, SymbolListT::iterator I, 289 char *SymbolAddrStr, const char *printBlanks, 290 const char *printDashes, const char *printFormat) { 291 MachO::mach_header H; 292 MachO::mach_header_64 H_64; 293 uint32_t Filetype = MachO::MH_OBJECT; 294 uint32_t Flags = 0; 295 uint8_t NType = 0; 296 uint8_t NSect = 0; 297 uint16_t NDesc = 0; 298 uint32_t NStrx = 0; 299 uint64_t NValue = 0; 300 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 301 if (Obj.isIR()) { 302 uint32_t SymFlags = I->Sym.getFlags(); 303 if (SymFlags & SymbolRef::SF_Global) 304 NType |= MachO::N_EXT; 305 if (SymFlags & SymbolRef::SF_Hidden) 306 NType |= MachO::N_PEXT; 307 if (SymFlags & SymbolRef::SF_Undefined) 308 NType |= MachO::N_EXT | MachO::N_UNDF; 309 else { 310 // Here we have a symbol definition. So to fake out a section name we 311 // use 1, 2 and 3 for section numbers. See below where they are used to 312 // print out fake section names. 313 NType |= MachO::N_SECT; 314 if (SymFlags & SymbolRef::SF_Const) 315 NSect = 3; 316 else if (SymFlags & SymbolRef::SF_Executable) 317 NSect = 1; 318 else 319 NSect = 2; 320 } 321 if (SymFlags & SymbolRef::SF_Weak) 322 NDesc |= MachO::N_WEAK_DEF; 323 } else { 324 DataRefImpl SymDRI = I->Sym.getRawDataRefImpl(); 325 if (MachO->is64Bit()) { 326 H_64 = MachO->MachOObjectFile::getHeader64(); 327 Filetype = H_64.filetype; 328 Flags = H_64.flags; 329 MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(SymDRI); 330 NType = STE_64.n_type; 331 NSect = STE_64.n_sect; 332 NDesc = STE_64.n_desc; 333 NStrx = STE_64.n_strx; 334 NValue = STE_64.n_value; 335 } else { 336 H = MachO->MachOObjectFile::getHeader(); 337 Filetype = H.filetype; 338 Flags = H.flags; 339 MachO::nlist STE = MachO->getSymbolTableEntry(SymDRI); 340 NType = STE.n_type; 341 NSect = STE.n_sect; 342 NDesc = STE.n_desc; 343 NStrx = STE.n_strx; 344 NValue = STE.n_value; 345 } 346 } 347 348 // If we are printing Mach-O symbols in hex do that and return. 349 if (FormatMachOasHex) { 350 char Str[18] = ""; 351 format(printFormat, NValue).print(Str, sizeof(Str)); 352 outs() << Str << ' '; 353 format("%02x", NType).print(Str, sizeof(Str)); 354 outs() << Str << ' '; 355 format("%02x", NSect).print(Str, sizeof(Str)); 356 outs() << Str << ' '; 357 format("%04x", NDesc).print(Str, sizeof(Str)); 358 outs() << Str << ' '; 359 format("%08x", NStrx).print(Str, sizeof(Str)); 360 outs() << Str << ' '; 361 outs() << I->Name << "\n"; 362 return; 363 } 364 365 if (PrintAddress) { 366 if ((NType & MachO::N_TYPE) == MachO::N_INDR) 367 strcpy(SymbolAddrStr, printBlanks); 368 if (Obj.isIR() && (NType & MachO::N_TYPE) == MachO::N_TYPE) 369 strcpy(SymbolAddrStr, printDashes); 370 outs() << SymbolAddrStr << ' '; 371 } 372 373 switch (NType & MachO::N_TYPE) { 374 case MachO::N_UNDF: 375 if (NValue != 0) { 376 outs() << "(common) "; 377 if (MachO::GET_COMM_ALIGN(NDesc) != 0) 378 outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") "; 379 } else { 380 if ((NType & MachO::N_TYPE) == MachO::N_PBUD) 381 outs() << "(prebound "; 382 else 383 outs() << "("; 384 if ((NDesc & MachO::REFERENCE_TYPE) == 385 MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 386 outs() << "undefined [lazy bound]) "; 387 else if ((NDesc & MachO::REFERENCE_TYPE) == 388 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY) 389 outs() << "undefined [private lazy bound]) "; 390 else if ((NDesc & MachO::REFERENCE_TYPE) == 391 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) 392 outs() << "undefined [private]) "; 393 else 394 outs() << "undefined) "; 395 } 396 break; 397 case MachO::N_ABS: 398 outs() << "(absolute) "; 399 break; 400 case MachO::N_INDR: 401 outs() << "(indirect) "; 402 break; 403 case MachO::N_SECT: { 404 if (Obj.isIR()) { 405 // For llvm bitcode files print out a fake section name using the values 406 // use 1, 2 and 3 for section numbers as set above. 407 if (NSect == 1) 408 outs() << "(LTO,CODE) "; 409 else if (NSect == 2) 410 outs() << "(LTO,DATA) "; 411 else if (NSect == 3) 412 outs() << "(LTO,RODATA) "; 413 else 414 outs() << "(?,?) "; 415 break; 416 } 417 Expected<section_iterator> SecOrErr = 418 MachO->getSymbolSection(I->Sym.getRawDataRefImpl()); 419 if (!SecOrErr) { 420 consumeError(SecOrErr.takeError()); 421 outs() << "(?,?) "; 422 break; 423 } 424 section_iterator Sec = *SecOrErr; 425 DataRefImpl Ref = Sec->getRawDataRefImpl(); 426 StringRef SectionName; 427 MachO->getSectionName(Ref, SectionName); 428 StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref); 429 outs() << "(" << SegmentName << "," << SectionName << ") "; 430 break; 431 } 432 default: 433 outs() << "(?) "; 434 break; 435 } 436 437 if (NType & MachO::N_EXT) { 438 if (NDesc & MachO::REFERENCED_DYNAMICALLY) 439 outs() << "[referenced dynamically] "; 440 if (NType & MachO::N_PEXT) { 441 if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) 442 outs() << "weak private external "; 443 else 444 outs() << "private external "; 445 } else { 446 if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF || 447 (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) { 448 if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) == 449 (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 450 outs() << "weak external automatically hidden "; 451 else 452 outs() << "weak external "; 453 } else 454 outs() << "external "; 455 } 456 } else { 457 if (NType & MachO::N_PEXT) 458 outs() << "non-external (was a private external) "; 459 else 460 outs() << "non-external "; 461 } 462 463 if (Filetype == MachO::MH_OBJECT && 464 (NDesc & MachO::N_NO_DEAD_STRIP) == MachO::N_NO_DEAD_STRIP) 465 outs() << "[no dead strip] "; 466 467 if (Filetype == MachO::MH_OBJECT && 468 ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 469 (NDesc & MachO::N_SYMBOL_RESOLVER) == MachO::N_SYMBOL_RESOLVER) 470 outs() << "[symbol resolver] "; 471 472 if (Filetype == MachO::MH_OBJECT && 473 ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 474 (NDesc & MachO::N_ALT_ENTRY) == MachO::N_ALT_ENTRY) 475 outs() << "[alt entry] "; 476 477 if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF) 478 outs() << "[Thumb] "; 479 480 if ((NType & MachO::N_TYPE) == MachO::N_INDR) { 481 outs() << I->Name << " (for "; 482 StringRef IndirectName; 483 if (!MachO || 484 MachO->getIndirectName(I->Sym.getRawDataRefImpl(), IndirectName)) 485 outs() << "?)"; 486 else 487 outs() << IndirectName << ")"; 488 } else 489 outs() << I->Name; 490 491 if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL && 492 (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) || 493 (NType & MachO::N_TYPE) == MachO::N_PBUD)) { 494 uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc); 495 if (LibraryOrdinal != 0) { 496 if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL) 497 outs() << " (from executable)"; 498 else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL) 499 outs() << " (dynamically looked up)"; 500 else { 501 StringRef LibraryName; 502 if (!MachO || 503 MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName)) 504 outs() << " (from bad library ordinal " << LibraryOrdinal << ")"; 505 else 506 outs() << " (from " << LibraryName << ")"; 507 } 508 } 509 } 510 511 outs() << "\n"; 512 } 513 514 // Table that maps Darwin's Mach-O stab constants to strings to allow printing. 515 struct DarwinStabName { 516 uint8_t NType; 517 const char *Name; 518 }; 519 static const struct DarwinStabName DarwinStabNames[] = { 520 {MachO::N_GSYM, "GSYM"}, 521 {MachO::N_FNAME, "FNAME"}, 522 {MachO::N_FUN, "FUN"}, 523 {MachO::N_STSYM, "STSYM"}, 524 {MachO::N_LCSYM, "LCSYM"}, 525 {MachO::N_BNSYM, "BNSYM"}, 526 {MachO::N_PC, "PC"}, 527 {MachO::N_AST, "AST"}, 528 {MachO::N_OPT, "OPT"}, 529 {MachO::N_RSYM, "RSYM"}, 530 {MachO::N_SLINE, "SLINE"}, 531 {MachO::N_ENSYM, "ENSYM"}, 532 {MachO::N_SSYM, "SSYM"}, 533 {MachO::N_SO, "SO"}, 534 {MachO::N_OSO, "OSO"}, 535 {MachO::N_LSYM, "LSYM"}, 536 {MachO::N_BINCL, "BINCL"}, 537 {MachO::N_SOL, "SOL"}, 538 {MachO::N_PARAMS, "PARAM"}, 539 {MachO::N_VERSION, "VERS"}, 540 {MachO::N_OLEVEL, "OLEV"}, 541 {MachO::N_PSYM, "PSYM"}, 542 {MachO::N_EINCL, "EINCL"}, 543 {MachO::N_ENTRY, "ENTRY"}, 544 {MachO::N_LBRAC, "LBRAC"}, 545 {MachO::N_EXCL, "EXCL"}, 546 {MachO::N_RBRAC, "RBRAC"}, 547 {MachO::N_BCOMM, "BCOMM"}, 548 {MachO::N_ECOMM, "ECOMM"}, 549 {MachO::N_ECOML, "ECOML"}, 550 {MachO::N_LENG, "LENG"}, 551 {0, nullptr}}; 552 553 static const char *getDarwinStabString(uint8_t NType) { 554 for (unsigned i = 0; DarwinStabNames[i].Name; i++) { 555 if (DarwinStabNames[i].NType == NType) 556 return DarwinStabNames[i].Name; 557 } 558 return nullptr; 559 } 560 561 // darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of 562 // a stab n_type value in a Mach-O file. 563 static void darwinPrintStab(MachOObjectFile *MachO, SymbolListT::iterator I) { 564 MachO::nlist_64 STE_64; 565 MachO::nlist STE; 566 uint8_t NType; 567 uint8_t NSect; 568 uint16_t NDesc; 569 DataRefImpl SymDRI = I->Sym.getRawDataRefImpl(); 570 if (MachO->is64Bit()) { 571 STE_64 = MachO->getSymbol64TableEntry(SymDRI); 572 NType = STE_64.n_type; 573 NSect = STE_64.n_sect; 574 NDesc = STE_64.n_desc; 575 } else { 576 STE = MachO->getSymbolTableEntry(SymDRI); 577 NType = STE.n_type; 578 NSect = STE.n_sect; 579 NDesc = STE.n_desc; 580 } 581 582 char Str[18] = ""; 583 format("%02x", NSect).print(Str, sizeof(Str)); 584 outs() << ' ' << Str << ' '; 585 format("%04x", NDesc).print(Str, sizeof(Str)); 586 outs() << Str << ' '; 587 if (const char *stabString = getDarwinStabString(NType)) 588 format("%5.5s", stabString).print(Str, sizeof(Str)); 589 else 590 format(" %02x", NType).print(Str, sizeof(Str)); 591 outs() << Str; 592 } 593 594 static bool symbolIsDefined(const NMSymbol &Sym) { 595 return Sym.TypeChar != 'U' && Sym.TypeChar != 'w' && Sym.TypeChar != 'v'; 596 } 597 598 static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, 599 const std::string &ArchiveName, 600 const std::string &ArchitectureName) { 601 if (!NoSort) { 602 std::function<bool(const NMSymbol &, const NMSymbol &)> Cmp; 603 if (NumericSort) 604 Cmp = compareSymbolAddress; 605 else if (SizeSort) 606 Cmp = compareSymbolSize; 607 else 608 Cmp = compareSymbolName; 609 610 if (ReverseSort) 611 Cmp = [=](const NMSymbol &A, const NMSymbol &B) { return Cmp(B, A); }; 612 std::sort(SymbolList.begin(), SymbolList.end(), Cmp); 613 } 614 615 if (!PrintFileName) { 616 if (OutputFormat == posix && MultipleFiles && printName) { 617 outs() << '\n' << CurrentFilename << ":\n"; 618 } else if (OutputFormat == bsd && MultipleFiles && printName) { 619 outs() << "\n" << CurrentFilename << ":\n"; 620 } else if (OutputFormat == sysv) { 621 outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n" 622 << "Name Value Class Type" 623 << " Size Line Section\n"; 624 } 625 } 626 627 const char *printBlanks, *printDashes, *printFormat; 628 if (isSymbolList64Bit(Obj)) { 629 printBlanks = " "; 630 printDashes = "----------------"; 631 switch (AddressRadix) { 632 case Radix::o: 633 printFormat = OutputFormat == posix ? "%" PRIo64 : "%016" PRIo64; 634 break; 635 case Radix::x: 636 printFormat = OutputFormat == posix ? "%" PRIx64 : "%016" PRIx64; 637 break; 638 default: 639 printFormat = OutputFormat == posix ? "%" PRId64 : "%016" PRId64; 640 } 641 } else { 642 printBlanks = " "; 643 printDashes = "--------"; 644 switch (AddressRadix) { 645 case Radix::o: 646 printFormat = OutputFormat == posix ? "%" PRIo64 : "%08" PRIo64; 647 break; 648 case Radix::x: 649 printFormat = OutputFormat == posix ? "%" PRIx64 : "%08" PRIx64; 650 break; 651 default: 652 printFormat = OutputFormat == posix ? "%" PRId64 : "%08" PRId64; 653 } 654 } 655 656 for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end(); 657 I != E; ++I) { 658 uint32_t SymFlags = I->Sym.getFlags(); 659 bool Undefined = SymFlags & SymbolRef::SF_Undefined; 660 bool Global = SymFlags & SymbolRef::SF_Global; 661 if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) || 662 (!Global && ExternalOnly) || (SizeSort && !PrintAddress)) 663 continue; 664 if (PrintFileName) { 665 if (!ArchitectureName.empty()) 666 outs() << "(for architecture " << ArchitectureName << "):"; 667 if (OutputFormat == posix && !ArchiveName.empty()) 668 outs() << ArchiveName << "[" << CurrentFilename << "]: "; 669 else { 670 if (!ArchiveName.empty()) 671 outs() << ArchiveName << ":"; 672 outs() << CurrentFilename << ": "; 673 } 674 } 675 if ((JustSymbolName || (UndefinedOnly && isa<MachOObjectFile>(Obj) && 676 OutputFormat != darwin)) && OutputFormat != posix) { 677 outs() << I->Name << "\n"; 678 continue; 679 } 680 681 char SymbolAddrStr[18] = ""; 682 char SymbolSizeStr[18] = ""; 683 684 // If the format is SysV or the symbol isn't defined, then print spaces. 685 if (OutputFormat == sysv || !symbolIsDefined(*I)) { 686 if (OutputFormat == posix) { 687 format(printFormat, I->Address) 688 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 689 format(printFormat, I->Size) 690 .print(SymbolSizeStr, sizeof(SymbolSizeStr)); 691 } else { 692 strcpy(SymbolAddrStr, printBlanks); 693 strcpy(SymbolSizeStr, printBlanks); 694 } 695 } 696 697 // Otherwise, print the symbol address and size. 698 if (symbolIsDefined(*I)) { 699 if (Obj.isIR()) 700 strcpy(SymbolAddrStr, printDashes); 701 else 702 format(printFormat, I->Address) 703 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 704 format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 705 } 706 707 // If OutputFormat is darwin or we are printing Mach-O symbols in hex and 708 // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's 709 // nm(1) -m output or hex, else if OutputFormat is darwin or we are 710 // printing Mach-O symbols in hex and not a Mach-O object fall back to 711 // OutputFormat bsd (see below). 712 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 713 if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) { 714 darwinPrintSymbol(Obj, I, SymbolAddrStr, printBlanks, printDashes, 715 printFormat); 716 } else if (OutputFormat == posix) { 717 outs() << I->Name << " " << I->TypeChar << " "; 718 if (MachO) 719 outs() << SymbolAddrStr << " " << "0" /* SymbolSizeStr */ << "\n"; 720 else 721 outs() << SymbolAddrStr << " " << SymbolSizeStr << "\n"; 722 } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) { 723 if (PrintAddress) 724 outs() << SymbolAddrStr << ' '; 725 if (PrintSize) { 726 outs() << SymbolSizeStr; 727 outs() << ' '; 728 } 729 outs() << I->TypeChar; 730 if (I->TypeChar == '-' && MachO) 731 darwinPrintStab(MachO, I); 732 outs() << " " << I->Name << "\n"; 733 } else if (OutputFormat == sysv) { 734 std::string PaddedName(I->Name); 735 while (PaddedName.length() < 20) 736 PaddedName += " "; 737 outs() << PaddedName << "|" << SymbolAddrStr << "| " << I->TypeChar 738 << " | |" << SymbolSizeStr << "| |\n"; 739 } 740 } 741 742 SymbolList.clear(); 743 } 744 745 static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, 746 basic_symbol_iterator I) { 747 // OK, this is ELF 748 elf_symbol_iterator SymI(I); 749 750 Expected<elf_section_iterator> SecIOrErr = SymI->getSection(); 751 if (!SecIOrErr) { 752 consumeError(SecIOrErr.takeError()); 753 return '?'; 754 } 755 756 elf_section_iterator SecI = *SecIOrErr; 757 if (SecI != Obj.section_end()) { 758 switch (SecI->getType()) { 759 case ELF::SHT_PROGBITS: 760 case ELF::SHT_DYNAMIC: 761 switch (SecI->getFlags()) { 762 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 763 return 't'; 764 case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): 765 case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 766 return 'd'; 767 case ELF::SHF_ALLOC: 768 case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 769 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 770 return 'r'; 771 } 772 break; 773 case ELF::SHT_NOBITS: 774 return 'b'; 775 case ELF::SHT_INIT_ARRAY: 776 case ELF::SHT_FINI_ARRAY: 777 return 't'; 778 } 779 } 780 781 if (SymI->getELFType() == ELF::STT_SECTION) { 782 Expected<StringRef> Name = SymI->getName(); 783 if (!Name) { 784 consumeError(Name.takeError()); 785 return '?'; 786 } 787 return StringSwitch<char>(*Name) 788 .StartsWith(".debug", 'N') 789 .StartsWith(".note", 'n') 790 .Default('?'); 791 } 792 793 return 'n'; 794 } 795 796 static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { 797 COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); 798 // OK, this is COFF. 799 symbol_iterator SymI(I); 800 801 Expected<StringRef> Name = SymI->getName(); 802 if (!Name) { 803 consumeError(Name.takeError()); 804 return '?'; 805 } 806 807 char Ret = StringSwitch<char>(*Name) 808 .StartsWith(".debug", 'N') 809 .StartsWith(".sxdata", 'N') 810 .Default('?'); 811 812 if (Ret != '?') 813 return Ret; 814 815 uint32_t Characteristics = 0; 816 if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 817 Expected<section_iterator> SecIOrErr = SymI->getSection(); 818 if (!SecIOrErr) { 819 consumeError(SecIOrErr.takeError()); 820 return '?'; 821 } 822 section_iterator SecI = *SecIOrErr; 823 const coff_section *Section = Obj.getCOFFSection(*SecI); 824 Characteristics = Section->Characteristics; 825 } 826 827 switch (Symb.getSectionNumber()) { 828 case COFF::IMAGE_SYM_DEBUG: 829 return 'n'; 830 default: 831 // Check section type. 832 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 833 return 't'; 834 if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 835 return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r'; 836 if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 837 return 'b'; 838 if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 839 return 'i'; 840 // Check for section symbol. 841 if (Symb.isSectionDefinition()) 842 return 's'; 843 } 844 845 return '?'; 846 } 847 848 static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { 849 DataRefImpl Symb = I->getRawDataRefImpl(); 850 uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type 851 : Obj.getSymbolTableEntry(Symb).n_type; 852 853 if (NType & MachO::N_STAB) 854 return '-'; 855 856 switch (NType & MachO::N_TYPE) { 857 case MachO::N_ABS: 858 return 's'; 859 case MachO::N_INDR: 860 return 'i'; 861 case MachO::N_SECT: { 862 Expected<section_iterator> SecOrErr = Obj.getSymbolSection(Symb); 863 if (!SecOrErr) { 864 consumeError(SecOrErr.takeError()); 865 return 's'; 866 } 867 section_iterator Sec = *SecOrErr; 868 DataRefImpl Ref = Sec->getRawDataRefImpl(); 869 StringRef SectionName; 870 Obj.getSectionName(Ref, SectionName); 871 StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); 872 if (SegmentName == "__TEXT" && SectionName == "__text") 873 return 't'; 874 if (SegmentName == "__DATA" && SectionName == "__data") 875 return 'd'; 876 if (SegmentName == "__DATA" && SectionName == "__bss") 877 return 'b'; 878 return 's'; 879 } 880 } 881 882 return '?'; 883 } 884 885 static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { 886 uint32_t Flags = I->getFlags(); 887 // FIXME: should we print 'b'? At the IR level we cannot be sure if this 888 // will be in bss or not, but we could approximate. 889 if (Flags & SymbolRef::SF_Executable) 890 return 't'; 891 else if (Triple(Obj.getTargetTriple()).isOSDarwin() && 892 (Flags & SymbolRef::SF_Const)) 893 return 's'; 894 else 895 return 'd'; 896 } 897 898 static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) { 899 return !dyn_cast<ELFObjectFileBase>(&Obj) 900 ? false 901 : elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT; 902 } 903 904 static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) { 905 uint32_t Symflags = I->getFlags(); 906 if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) { 907 char Ret = isObject(Obj, I) ? 'v' : 'w'; 908 return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret; 909 } 910 911 if (Symflags & object::SymbolRef::SF_Undefined) 912 return 'U'; 913 914 if (Symflags & object::SymbolRef::SF_Common) 915 return 'C'; 916 917 char Ret = '?'; 918 if (Symflags & object::SymbolRef::SF_Absolute) 919 Ret = 'a'; 920 else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) 921 Ret = getSymbolNMTypeChar(*IR, I); 922 else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj)) 923 Ret = getSymbolNMTypeChar(*COFF, I); 924 else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) 925 Ret = getSymbolNMTypeChar(*MachO, I); 926 else 927 Ret = getSymbolNMTypeChar(cast<ELFObjectFileBase>(Obj), I); 928 929 if (Symflags & object::SymbolRef::SF_Global) 930 Ret = toupper(Ret); 931 932 return Ret; 933 } 934 935 // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname" 936 // option to dump only those symbols from that section in a Mach-O file. 937 // It is called once for each Mach-O file from dumpSymbolNamesFromObject() 938 // to get the section number for that named section from the command line 939 // arguments. It returns the section number for that section in the Mach-O 940 // file or zero it is not present. 941 static unsigned getNsectForSegSect(MachOObjectFile *Obj) { 942 unsigned Nsect = 1; 943 for (auto &S : Obj->sections()) { 944 DataRefImpl Ref = S.getRawDataRefImpl(); 945 StringRef SectionName; 946 Obj->getSectionName(Ref, SectionName); 947 StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref); 948 if (SegmentName == SegSect[0] && SectionName == SegSect[1]) 949 return Nsect; 950 Nsect++; 951 } 952 return 0; 953 } 954 955 // getNsectInMachO() is used to implement the Mach-O "-s segname sectname" 956 // option to dump only those symbols from that section in a Mach-O file. 957 // It is called once for each symbol in a Mach-O file from 958 // dumpSymbolNamesFromObject() and returns the section number for that symbol 959 // if it is in a section, else it returns 0. 960 static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { 961 DataRefImpl Symb = Sym.getRawDataRefImpl(); 962 if (Obj.is64Bit()) { 963 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 964 return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0; 965 } 966 MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 967 return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0; 968 } 969 970 static void 971 dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, 972 const std::string &ArchiveName = std::string(), 973 const std::string &ArchitectureName = std::string()) { 974 auto Symbols = Obj.symbols(); 975 if (DynamicSyms) { 976 const auto *E = dyn_cast<ELFObjectFileBase>(&Obj); 977 if (!E) { 978 error("File format has no dynamic symbol table", Obj.getFileName()); 979 return; 980 } 981 auto DynSymbols = E->getDynamicSymbolIterators(); 982 Symbols = 983 make_range<basic_symbol_iterator>(DynSymbols.begin(), DynSymbols.end()); 984 } 985 std::string NameBuffer; 986 raw_string_ostream OS(NameBuffer); 987 // If a "-s segname sectname" option was specified and this is a Mach-O 988 // file get the section number for that section in this object file. 989 unsigned int Nsect = 0; 990 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 991 if (SegSect.size() != 0 && MachO) { 992 Nsect = getNsectForSegSect(MachO); 993 // If this section is not in the object file no symbols are printed. 994 if (Nsect == 0) 995 return; 996 } 997 for (BasicSymbolRef Sym : Symbols) { 998 uint32_t SymFlags = Sym.getFlags(); 999 if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) 1000 continue; 1001 if (WithoutAliases && (SymFlags & SymbolRef::SF_Indirect)) 1002 continue; 1003 // If a "-s segname sectname" option was specified and this is a Mach-O 1004 // file and this section appears in this file, Nsect will be non-zero then 1005 // see if this symbol is a symbol from that section and if not skip it. 1006 if (Nsect && Nsect != getNsectInMachO(*MachO, Sym)) 1007 continue; 1008 NMSymbol S; 1009 S.Size = 0; 1010 S.Address = 0; 1011 if (PrintSize) { 1012 if (isa<ELFObjectFileBase>(&Obj)) 1013 S.Size = ELFSymbolRef(Sym).getSize(); 1014 } 1015 if (PrintAddress && isa<ObjectFile>(Obj)) { 1016 SymbolRef SymRef(Sym); 1017 Expected<uint64_t> AddressOrErr = SymRef.getAddress(); 1018 if (!AddressOrErr) { 1019 consumeError(AddressOrErr.takeError()); 1020 break; 1021 } 1022 S.Address = *AddressOrErr; 1023 } 1024 S.TypeChar = getNMTypeChar(Obj, Sym); 1025 std::error_code EC = Sym.printName(OS); 1026 if (EC && MachO) 1027 OS << "bad string index"; 1028 else 1029 error(EC); 1030 OS << '\0'; 1031 S.Sym = Sym; 1032 SymbolList.push_back(S); 1033 } 1034 1035 OS.flush(); 1036 const char *P = NameBuffer.c_str(); 1037 for (unsigned I = 0; I < SymbolList.size(); ++I) { 1038 SymbolList[I].Name = P; 1039 P += strlen(P) + 1; 1040 } 1041 1042 CurrentFilename = Obj.getFileName(); 1043 sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName); 1044 } 1045 1046 // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file 1047 // and if it is and there is a list of architecture flags is specified then 1048 // check to make sure this Mach-O file is one of those architectures or all 1049 // architectures was specificed. If not then an error is generated and this 1050 // routine returns false. Else it returns true. 1051 static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) { 1052 auto *MachO = dyn_cast<MachOObjectFile>(O); 1053 1054 if (!MachO || ArchAll || ArchFlags.empty()) 1055 return true; 1056 1057 MachO::mach_header H; 1058 MachO::mach_header_64 H_64; 1059 Triple T; 1060 if (MachO->is64Bit()) { 1061 H_64 = MachO->MachOObjectFile::getHeader64(); 1062 T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype); 1063 } else { 1064 H = MachO->MachOObjectFile::getHeader(); 1065 T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype); 1066 } 1067 if (none_of(ArchFlags, [&](const std::string &Name) { 1068 return Name == T.getArchName(); 1069 })) { 1070 error("No architecture specified", Filename); 1071 return false; 1072 } 1073 return true; 1074 } 1075 1076 static void dumpSymbolNamesFromFile(std::string &Filename) { 1077 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 1078 MemoryBuffer::getFileOrSTDIN(Filename); 1079 if (error(BufferOrErr.getError(), Filename)) 1080 return; 1081 1082 LLVMContext Context; 1083 Expected<std::unique_ptr<Binary>> BinaryOrErr = createBinary( 1084 BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context); 1085 if (!BinaryOrErr) { 1086 error(BinaryOrErr.takeError(), Filename); 1087 return; 1088 } 1089 Binary &Bin = *BinaryOrErr.get(); 1090 1091 if (Archive *A = dyn_cast<Archive>(&Bin)) { 1092 if (ArchiveMap) { 1093 Archive::symbol_iterator I = A->symbol_begin(); 1094 Archive::symbol_iterator E = A->symbol_end(); 1095 if (I != E) { 1096 outs() << "Archive map\n"; 1097 for (; I != E; ++I) { 1098 Expected<Archive::Child> C = I->getMember(); 1099 if (!C) 1100 error(C.takeError(), Filename); 1101 Expected<StringRef> FileNameOrErr = C->getName(); 1102 if (!FileNameOrErr) { 1103 error(FileNameOrErr.takeError(), Filename); 1104 return; 1105 } 1106 StringRef SymName = I->getName(); 1107 outs() << SymName << " in " << FileNameOrErr.get() << "\n"; 1108 } 1109 outs() << "\n"; 1110 } 1111 } 1112 1113 { 1114 Error Err = Error::success(); 1115 for (auto &C : A->children(Err)) { 1116 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); 1117 if (!ChildOrErr) { 1118 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) 1119 error(std::move(E), Filename, C); 1120 continue; 1121 } 1122 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1123 if (!checkMachOAndArchFlags(O, Filename)) 1124 return; 1125 if (!PrintFileName) { 1126 outs() << "\n"; 1127 if (isa<MachOObjectFile>(O)) { 1128 outs() << Filename << "(" << O->getFileName() << ")"; 1129 } else 1130 outs() << O->getFileName(); 1131 outs() << ":\n"; 1132 } 1133 dumpSymbolNamesFromObject(*O, false, Filename); 1134 } 1135 } 1136 if (Err) 1137 error(std::move(Err), A->getFileName()); 1138 } 1139 return; 1140 } 1141 if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) { 1142 // If we have a list of architecture flags specified dump only those. 1143 if (!ArchAll && ArchFlags.size() != 0) { 1144 // Look for a slice in the universal binary that matches each ArchFlag. 1145 bool ArchFound; 1146 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1147 ArchFound = false; 1148 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1149 E = UB->end_objects(); 1150 I != E; ++I) { 1151 if (ArchFlags[i] == I->getArchFlagName()) { 1152 ArchFound = true; 1153 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = 1154 I->getAsObjectFile(); 1155 std::string ArchiveName; 1156 std::string ArchitectureName; 1157 ArchiveName.clear(); 1158 ArchitectureName.clear(); 1159 if (ObjOrErr) { 1160 ObjectFile &Obj = *ObjOrErr.get(); 1161 if (ArchFlags.size() > 1) { 1162 if (PrintFileName) 1163 ArchitectureName = I->getArchFlagName(); 1164 else 1165 outs() << "\n" << Obj.getFileName() << " (for architecture " 1166 << I->getArchFlagName() << ")" 1167 << ":\n"; 1168 } 1169 dumpSymbolNamesFromObject(Obj, false, ArchiveName, 1170 ArchitectureName); 1171 } else if (auto E = isNotObjectErrorInvalidFileType( 1172 ObjOrErr.takeError())) { 1173 error(std::move(E), Filename, ArchFlags.size() > 1 ? 1174 StringRef(I->getArchFlagName()) : StringRef()); 1175 continue; 1176 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1177 I->getAsArchive()) { 1178 std::unique_ptr<Archive> &A = *AOrErr; 1179 Error Err = Error::success(); 1180 for (auto &C : A->children(Err)) { 1181 Expected<std::unique_ptr<Binary>> ChildOrErr = 1182 C.getAsBinary(&Context); 1183 if (!ChildOrErr) { 1184 if (auto E = isNotObjectErrorInvalidFileType( 1185 ChildOrErr.takeError())) { 1186 error(std::move(E), Filename, C, ArchFlags.size() > 1 ? 1187 StringRef(I->getArchFlagName()) : StringRef()); 1188 } 1189 continue; 1190 } 1191 if (SymbolicFile *O = 1192 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1193 if (PrintFileName) { 1194 ArchiveName = A->getFileName(); 1195 if (ArchFlags.size() > 1) 1196 ArchitectureName = I->getArchFlagName(); 1197 } else { 1198 outs() << "\n" << A->getFileName(); 1199 outs() << "(" << O->getFileName() << ")"; 1200 if (ArchFlags.size() > 1) { 1201 outs() << " (for architecture " << I->getArchFlagName() 1202 << ")"; 1203 } 1204 outs() << ":\n"; 1205 } 1206 dumpSymbolNamesFromObject(*O, false, ArchiveName, 1207 ArchitectureName); 1208 } 1209 } 1210 if (Err) 1211 error(std::move(Err), A->getFileName()); 1212 } else { 1213 consumeError(AOrErr.takeError()); 1214 error(Filename + " for architecture " + 1215 StringRef(I->getArchFlagName()) + 1216 " is not a Mach-O file or an archive file", 1217 "Mach-O universal file"); 1218 } 1219 } 1220 } 1221 if (!ArchFound) { 1222 error(ArchFlags[i], 1223 "file: " + Filename + " does not contain architecture"); 1224 return; 1225 } 1226 } 1227 return; 1228 } 1229 // No architecture flags were specified so if this contains a slice that 1230 // matches the host architecture dump only that. 1231 if (!ArchAll) { 1232 StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); 1233 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1234 E = UB->end_objects(); 1235 I != E; ++I) { 1236 if (HostArchName == I->getArchFlagName()) { 1237 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1238 std::string ArchiveName; 1239 ArchiveName.clear(); 1240 if (ObjOrErr) { 1241 ObjectFile &Obj = *ObjOrErr.get(); 1242 dumpSymbolNamesFromObject(Obj, false); 1243 } else if (auto E = isNotObjectErrorInvalidFileType( 1244 ObjOrErr.takeError())) { 1245 error(std::move(E), Filename); 1246 return; 1247 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1248 I->getAsArchive()) { 1249 std::unique_ptr<Archive> &A = *AOrErr; 1250 Error Err = Error::success(); 1251 for (auto &C : A->children(Err)) { 1252 Expected<std::unique_ptr<Binary>> ChildOrErr = 1253 C.getAsBinary(&Context); 1254 if (!ChildOrErr) { 1255 if (auto E = isNotObjectErrorInvalidFileType( 1256 ChildOrErr.takeError())) 1257 error(std::move(E), Filename, C); 1258 continue; 1259 } 1260 if (SymbolicFile *O = 1261 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1262 if (PrintFileName) 1263 ArchiveName = A->getFileName(); 1264 else 1265 outs() << "\n" << A->getFileName() << "(" << O->getFileName() 1266 << ")" 1267 << ":\n"; 1268 dumpSymbolNamesFromObject(*O, false, ArchiveName); 1269 } 1270 } 1271 if (Err) 1272 error(std::move(Err), A->getFileName()); 1273 } else { 1274 consumeError(AOrErr.takeError()); 1275 error(Filename + " for architecture " + 1276 StringRef(I->getArchFlagName()) + 1277 " is not a Mach-O file or an archive file", 1278 "Mach-O universal file"); 1279 } 1280 return; 1281 } 1282 } 1283 } 1284 // Either all architectures have been specified or none have been specified 1285 // and this does not contain the host architecture so dump all the slices. 1286 bool moreThanOneArch = UB->getNumberOfObjects() > 1; 1287 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1288 E = UB->end_objects(); 1289 I != E; ++I) { 1290 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1291 std::string ArchiveName; 1292 std::string ArchitectureName; 1293 ArchiveName.clear(); 1294 ArchitectureName.clear(); 1295 if (ObjOrErr) { 1296 ObjectFile &Obj = *ObjOrErr.get(); 1297 if (PrintFileName) { 1298 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1299 ArchitectureName = I->getArchFlagName(); 1300 } else { 1301 if (moreThanOneArch) 1302 outs() << "\n"; 1303 outs() << Obj.getFileName(); 1304 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1305 outs() << " (for architecture " << I->getArchFlagName() << ")"; 1306 outs() << ":\n"; 1307 } 1308 dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); 1309 } else if (auto E = isNotObjectErrorInvalidFileType( 1310 ObjOrErr.takeError())) { 1311 error(std::move(E), Filename, moreThanOneArch ? 1312 StringRef(I->getArchFlagName()) : StringRef()); 1313 continue; 1314 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1315 I->getAsArchive()) { 1316 std::unique_ptr<Archive> &A = *AOrErr; 1317 Error Err = Error::success(); 1318 for (auto &C : A->children(Err)) { 1319 Expected<std::unique_ptr<Binary>> ChildOrErr = 1320 C.getAsBinary(&Context); 1321 if (!ChildOrErr) { 1322 if (auto E = isNotObjectErrorInvalidFileType( 1323 ChildOrErr.takeError())) 1324 error(std::move(E), Filename, C, moreThanOneArch ? 1325 StringRef(ArchitectureName) : StringRef()); 1326 continue; 1327 } 1328 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1329 if (PrintFileName) { 1330 ArchiveName = A->getFileName(); 1331 if (isa<MachOObjectFile>(O) && moreThanOneArch) 1332 ArchitectureName = I->getArchFlagName(); 1333 } else { 1334 outs() << "\n" << A->getFileName(); 1335 if (isa<MachOObjectFile>(O)) { 1336 outs() << "(" << O->getFileName() << ")"; 1337 if (moreThanOneArch) 1338 outs() << " (for architecture " << I->getArchFlagName() 1339 << ")"; 1340 } else 1341 outs() << ":" << O->getFileName(); 1342 outs() << ":\n"; 1343 } 1344 dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName); 1345 } 1346 } 1347 if (Err) 1348 error(std::move(Err), A->getFileName()); 1349 } else { 1350 consumeError(AOrErr.takeError()); 1351 error(Filename + " for architecture " + 1352 StringRef(I->getArchFlagName()) + 1353 " is not a Mach-O file or an archive file", 1354 "Mach-O universal file"); 1355 } 1356 } 1357 return; 1358 } 1359 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { 1360 if (!checkMachOAndArchFlags(O, Filename)) 1361 return; 1362 dumpSymbolNamesFromObject(*O, true); 1363 } 1364 } 1365 1366 int main(int argc, char **argv) { 1367 // Print a stack trace if we signal out. 1368 sys::PrintStackTraceOnErrorSignal(argv[0]); 1369 PrettyStackTraceProgram X(argc, argv); 1370 1371 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 1372 cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 1373 1374 // llvm-nm only reads binary files. 1375 if (error(sys::ChangeStdinToBinary())) 1376 return 1; 1377 1378 // These calls are needed so that we can read bitcode correctly. 1379 llvm::InitializeAllTargetInfos(); 1380 llvm::InitializeAllTargetMCs(); 1381 llvm::InitializeAllAsmParsers(); 1382 1383 ToolName = argv[0]; 1384 if (BSDFormat) 1385 OutputFormat = bsd; 1386 if (POSIXFormat) 1387 OutputFormat = posix; 1388 if (DarwinFormat) 1389 OutputFormat = darwin; 1390 1391 // The relative order of these is important. If you pass --size-sort it should 1392 // only print out the size. However, if you pass -S --size-sort, it should 1393 // print out both the size and address. 1394 if (SizeSort && !PrintSize) 1395 PrintAddress = false; 1396 if (OutputFormat == sysv || SizeSort) 1397 PrintSize = true; 1398 if (InputFilenames.empty()) 1399 InputFilenames.push_back("a.out"); 1400 if (InputFilenames.size() > 1) 1401 MultipleFiles = true; 1402 1403 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1404 if (ArchFlags[i] == "all") { 1405 ArchAll = true; 1406 } else { 1407 if (!MachOObjectFile::isValidArch(ArchFlags[i])) 1408 error("Unknown architecture named '" + ArchFlags[i] + "'", 1409 "for the -arch option"); 1410 } 1411 } 1412 1413 if (SegSect.size() != 0 && SegSect.size() != 2) 1414 error("bad number of arguments (must be two arguments)", 1415 "for the -s option"); 1416 1417 std::for_each(InputFilenames.begin(), InputFilenames.end(), 1418 dumpSymbolNamesFromFile); 1419 1420 if (HadError) 1421 return 1; 1422 } 1423