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