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