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/LLVMDriver.h" 44 #include "llvm/Support/MemoryBuffer.h" 45 #include "llvm/Support/Program.h" 46 #include "llvm/Support/Signals.h" 47 #include "llvm/Support/TargetSelect.h" 48 #include "llvm/Support/WithColor.h" 49 #include "llvm/Support/raw_ostream.h" 50 #include "llvm/TargetParser/Host.h" 51 #include "llvm/TargetParser/Triple.h" 52 #include <vector> 53 54 using namespace llvm; 55 using namespace object; 56 57 namespace { 58 using namespace llvm::opt; // for HelpHidden in Opts.inc 59 enum ID { 60 OPT_INVALID = 0, // This is not an option ID. 61 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 62 HELPTEXT, METAVAR, VALUES) \ 63 OPT_##ID, 64 #include "Opts.inc" 65 #undef OPTION 66 }; 67 68 #define PREFIX(NAME, VALUE) \ 69 static constexpr StringLiteral NAME##_init[] = VALUE; \ 70 static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ 71 std::size(NAME##_init) - 1); 72 #include "Opts.inc" 73 #undef PREFIX 74 75 static constexpr opt::OptTable::Info InfoTable[] = { 76 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ 77 HELPTEXT, METAVAR, VALUES) \ 78 { \ 79 PREFIX, NAME, HELPTEXT, \ 80 METAVAR, OPT_##ID, opt::Option::KIND##Class, \ 81 PARAM, FLAGS, OPT_##GROUP, \ 82 OPT_##ALIAS, ALIASARGS, VALUES}, 83 #include "Opts.inc" 84 #undef OPTION 85 }; 86 87 class NmOptTable : public opt::GenericOptTable { 88 public: 89 NmOptTable() : opt::GenericOptTable(InfoTable) { 90 setGroupedShortOptions(true); 91 } 92 }; 93 94 enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols }; 95 enum class BitModeTy { Bit32, Bit64, Bit32_64, Any }; 96 } // namespace 97 98 static bool ArchiveMap; 99 static BitModeTy BitMode; 100 static bool DebugSyms; 101 static bool DefinedOnly; 102 static bool Demangle; 103 static bool DynamicSyms; 104 static bool ExportSymbols; 105 static bool ExternalOnly; 106 static OutputFormatTy OutputFormat; 107 static bool NoLLVMBitcode; 108 static bool NoSort; 109 static bool NoWeakSymbols; 110 static bool NumericSort; 111 static bool PrintFileName; 112 static bool PrintSize; 113 static bool Quiet; 114 static bool ReverseSort; 115 static bool SpecialSyms; 116 static bool SizeSort; 117 static bool UndefinedOnly; 118 static bool WithoutAliases; 119 120 // XCOFF-specific options. 121 static bool NoRsrc; 122 123 namespace { 124 enum Radix { d, o, x }; 125 } // namespace 126 static Radix AddressRadix; 127 128 // Mach-O specific options. 129 static bool ArchAll = false; 130 static std::vector<StringRef> ArchFlags; 131 static bool AddDyldInfo; 132 static bool AddInlinedInfo; 133 static bool DyldInfoOnly; 134 static bool FormatMachOasHex; 135 static bool NoDyldInfo; 136 static std::vector<StringRef> SegSect; 137 static bool MachOPrintSizeWarning = false; 138 139 // Miscellaneous states. 140 static bool PrintAddress = true; 141 static bool MultipleFiles = false; 142 static bool HadError = false; 143 144 static StringRef ToolName; 145 146 static void warn(Error Err, Twine FileName, Twine Context = Twine(), 147 Twine Archive = Twine()) { 148 assert(Err); 149 150 // Flush the standard output so that the warning isn't interleaved with other 151 // output if stdout and stderr are writing to the same place. 152 outs().flush(); 153 154 handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) { 155 WithColor::warning(errs(), ToolName) 156 << (Archive.str().empty() ? FileName : Archive + "(" + FileName + ")") 157 << ": " << (Context.str().empty() ? "" : Context + ": ") << EI.message() 158 << "\n"; 159 }); 160 } 161 162 static void error(Twine Message, Twine Path = Twine()) { 163 HadError = true; 164 WithColor::error(errs(), ToolName) << Path << ": " << Message << "\n"; 165 } 166 167 static bool error(std::error_code EC, Twine Path = Twine()) { 168 if (EC) { 169 error(EC.message(), Path); 170 return true; 171 } 172 return false; 173 } 174 175 // This version of error() prints the archive name and member name, for example: 176 // "libx.a(foo.o)" after the ToolName before the error message. It sets 177 // HadError but returns allowing the code to move on to other archive members. 178 static void error(llvm::Error E, StringRef FileName, const Archive::Child &C, 179 StringRef ArchitectureName = StringRef()) { 180 HadError = true; 181 WithColor::error(errs(), ToolName) << FileName; 182 183 Expected<StringRef> NameOrErr = C.getName(); 184 // TODO: if we have a error getting the name then it would be nice to print 185 // the index of which archive member this is and or its offset in the 186 // archive instead of "???" as the name. 187 if (!NameOrErr) { 188 consumeError(NameOrErr.takeError()); 189 errs() << "(" << "???" << ")"; 190 } else 191 errs() << "(" << NameOrErr.get() << ")"; 192 193 if (!ArchitectureName.empty()) 194 errs() << " (for architecture " << ArchitectureName << ")"; 195 196 std::string Buf; 197 raw_string_ostream OS(Buf); 198 logAllUnhandledErrors(std::move(E), OS); 199 OS.flush(); 200 errs() << ": " << Buf << "\n"; 201 } 202 203 // This version of error() prints the file name and which architecture slice it 204 // is from, for example: "foo.o (for architecture i386)" after the ToolName 205 // before the error message. It sets HadError but returns allowing the code to 206 // move on to other architecture slices. 207 static void error(llvm::Error E, StringRef FileName, 208 StringRef ArchitectureName = StringRef()) { 209 HadError = true; 210 WithColor::error(errs(), ToolName) << FileName; 211 212 if (!ArchitectureName.empty()) 213 errs() << " (for architecture " << ArchitectureName << ")"; 214 215 std::string Buf; 216 raw_string_ostream OS(Buf); 217 logAllUnhandledErrors(std::move(E), OS); 218 OS.flush(); 219 errs() << ": " << Buf << "\n"; 220 } 221 222 namespace { 223 struct NMSymbol { 224 uint64_t Address; 225 uint64_t Size; 226 char TypeChar; 227 std::string Name; 228 StringRef SectionName; 229 StringRef TypeName; 230 BasicSymbolRef Sym; 231 StringRef Visibility; 232 233 // The Sym field above points to the native symbol in the object file, 234 // for Mach-O when we are creating symbols from the dyld info the above 235 // pointer is null as there is no native symbol. In these cases the fields 236 // below are filled in to represent what would have been a Mach-O nlist 237 // native symbol. 238 uint32_t SymFlags; 239 SectionRef Section; 240 uint8_t NType; 241 uint8_t NSect; 242 uint16_t NDesc; 243 std::string IndirectName; 244 245 bool isDefined() const { 246 if (Sym.getRawDataRefImpl().p) { 247 uint32_t Flags = cantFail(Sym.getFlags()); 248 return !(Flags & SymbolRef::SF_Undefined); 249 } 250 return TypeChar != 'U'; 251 } 252 253 bool initializeFlags(const SymbolicFile &Obj) { 254 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags(); 255 if (!SymFlagsOrErr) { 256 // TODO: Test this error. 257 error(SymFlagsOrErr.takeError(), Obj.getFileName()); 258 return false; 259 } 260 SymFlags = *SymFlagsOrErr; 261 return true; 262 } 263 264 bool shouldPrint() const { 265 bool Undefined = SymFlags & SymbolRef::SF_Undefined; 266 bool Global = SymFlags & SymbolRef::SF_Global; 267 bool Weak = SymFlags & SymbolRef::SF_Weak; 268 bool FormatSpecific = SymFlags & SymbolRef::SF_FormatSpecific; 269 if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) || 270 (!Global && ExternalOnly) || (Weak && NoWeakSymbols) || 271 (FormatSpecific && !(SpecialSyms || DebugSyms))) 272 return false; 273 return true; 274 } 275 }; 276 277 bool operator<(const NMSymbol &A, const NMSymbol &B) { 278 if (NumericSort) 279 return std::make_tuple(A.isDefined(), A.Address, A.Name, A.Size) < 280 std::make_tuple(B.isDefined(), B.Address, B.Name, B.Size); 281 if (SizeSort) 282 return std::make_tuple(A.Size, A.Name, A.Address) < 283 std::make_tuple(B.Size, B.Name, B.Address); 284 if (ExportSymbols) 285 return std::make_tuple(A.Name, A.Visibility) < 286 std::make_tuple(B.Name, B.Visibility); 287 return std::make_tuple(A.Name, A.Size, A.Address) < 288 std::make_tuple(B.Name, B.Size, B.Address); 289 } 290 291 bool operator>(const NMSymbol &A, const NMSymbol &B) { return B < A; } 292 bool operator==(const NMSymbol &A, const NMSymbol &B) { 293 return !(A < B) && !(B < A); 294 } 295 } // anonymous namespace 296 297 static StringRef CurrentFilename; 298 299 static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I); 300 301 // darwinPrintSymbol() is used to print a symbol from a Mach-O file when the 302 // the OutputFormat is darwin or we are printing Mach-O symbols in hex. For 303 // the darwin format it produces the same output as darwin's nm(1) -m output 304 // and when printing Mach-O symbols in hex it produces the same output as 305 // darwin's nm(1) -x format. 306 static void darwinPrintSymbol(SymbolicFile &Obj, const NMSymbol &S, 307 char *SymbolAddrStr, const char *printBlanks, 308 const char *printDashes, 309 const char *printFormat) { 310 MachO::mach_header H; 311 MachO::mach_header_64 H_64; 312 uint32_t Filetype = MachO::MH_OBJECT; 313 uint32_t Flags = 0; 314 uint8_t NType = 0; 315 uint8_t NSect = 0; 316 uint16_t NDesc = 0; 317 uint32_t NStrx = 0; 318 uint64_t NValue = 0; 319 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 320 if (Obj.isIR()) { 321 uint32_t SymFlags = cantFail(S.Sym.getFlags()); 322 if (SymFlags & SymbolRef::SF_Global) 323 NType |= MachO::N_EXT; 324 if (SymFlags & SymbolRef::SF_Hidden) 325 NType |= MachO::N_PEXT; 326 if (SymFlags & SymbolRef::SF_Undefined) 327 NType |= MachO::N_EXT | MachO::N_UNDF; 328 else { 329 // Here we have a symbol definition. So to fake out a section name we 330 // use 1, 2 and 3 for section numbers. See below where they are used to 331 // print out fake section names. 332 NType |= MachO::N_SECT; 333 if (SymFlags & SymbolRef::SF_Const) 334 NSect = 3; 335 else if (SymFlags & SymbolRef::SF_Executable) 336 NSect = 1; 337 else 338 NSect = 2; 339 } 340 if (SymFlags & SymbolRef::SF_Weak) 341 NDesc |= MachO::N_WEAK_DEF; 342 } else { 343 DataRefImpl SymDRI = S.Sym.getRawDataRefImpl(); 344 if (MachO->is64Bit()) { 345 H_64 = MachO->MachOObjectFile::getHeader64(); 346 Filetype = H_64.filetype; 347 Flags = H_64.flags; 348 if (SymDRI.p){ 349 MachO::nlist_64 STE_64 = MachO->getSymbol64TableEntry(SymDRI); 350 NType = STE_64.n_type; 351 NSect = STE_64.n_sect; 352 NDesc = STE_64.n_desc; 353 NStrx = STE_64.n_strx; 354 NValue = STE_64.n_value; 355 } else { 356 NType = S.NType; 357 NSect = S.NSect; 358 NDesc = S.NDesc; 359 NStrx = 0; 360 NValue = S.Address; 361 } 362 } else { 363 H = MachO->MachOObjectFile::getHeader(); 364 Filetype = H.filetype; 365 Flags = H.flags; 366 if (SymDRI.p){ 367 MachO::nlist STE = MachO->getSymbolTableEntry(SymDRI); 368 NType = STE.n_type; 369 NSect = STE.n_sect; 370 NDesc = STE.n_desc; 371 NStrx = STE.n_strx; 372 NValue = STE.n_value; 373 } else { 374 NType = S.NType; 375 NSect = S.NSect; 376 NDesc = S.NDesc; 377 NStrx = 0; 378 NValue = S.Address; 379 } 380 } 381 } 382 383 // If we are printing Mach-O symbols in hex do that and return. 384 if (FormatMachOasHex) { 385 outs() << format(printFormat, NValue) << ' ' 386 << format("%02x %02x %04x %08x", NType, NSect, NDesc, NStrx) << ' ' 387 << S.Name; 388 if ((NType & MachO::N_TYPE) == MachO::N_INDR) { 389 outs() << " (indirect for "; 390 outs() << format(printFormat, NValue) << ' '; 391 StringRef IndirectName; 392 if (S.Sym.getRawDataRefImpl().p) { 393 if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName)) 394 outs() << "?)"; 395 else 396 outs() << IndirectName << ")"; 397 } else 398 outs() << S.IndirectName << ")"; 399 } 400 outs() << "\n"; 401 return; 402 } 403 404 if (PrintAddress) { 405 if ((NType & MachO::N_TYPE) == MachO::N_INDR) 406 strcpy(SymbolAddrStr, printBlanks); 407 if (Obj.isIR() && (NType & MachO::N_TYPE) == MachO::N_TYPE) 408 strcpy(SymbolAddrStr, printDashes); 409 outs() << SymbolAddrStr << ' '; 410 } 411 412 switch (NType & MachO::N_TYPE) { 413 case MachO::N_UNDF: 414 if (NValue != 0) { 415 outs() << "(common) "; 416 if (MachO::GET_COMM_ALIGN(NDesc) != 0) 417 outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") "; 418 } else { 419 if ((NType & MachO::N_TYPE) == MachO::N_PBUD) 420 outs() << "(prebound "; 421 else 422 outs() << "("; 423 if ((NDesc & MachO::REFERENCE_TYPE) == 424 MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 425 outs() << "undefined [lazy bound]) "; 426 else if ((NDesc & MachO::REFERENCE_TYPE) == 427 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY) 428 outs() << "undefined [private lazy bound]) "; 429 else if ((NDesc & MachO::REFERENCE_TYPE) == 430 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) 431 outs() << "undefined [private]) "; 432 else 433 outs() << "undefined) "; 434 } 435 break; 436 case MachO::N_ABS: 437 outs() << "(absolute) "; 438 break; 439 case MachO::N_INDR: 440 outs() << "(indirect) "; 441 break; 442 case MachO::N_SECT: { 443 if (Obj.isIR()) { 444 // For llvm bitcode files print out a fake section name using the values 445 // use 1, 2 and 3 for section numbers as set above. 446 if (NSect == 1) 447 outs() << "(LTO,CODE) "; 448 else if (NSect == 2) 449 outs() << "(LTO,DATA) "; 450 else if (NSect == 3) 451 outs() << "(LTO,RODATA) "; 452 else 453 outs() << "(?,?) "; 454 break; 455 } 456 section_iterator Sec = SectionRef(); 457 if (S.Sym.getRawDataRefImpl().p) { 458 Expected<section_iterator> SecOrErr = 459 MachO->getSymbolSection(S.Sym.getRawDataRefImpl()); 460 if (!SecOrErr) { 461 consumeError(SecOrErr.takeError()); 462 outs() << "(?,?) "; 463 break; 464 } 465 Sec = *SecOrErr; 466 if (Sec == MachO->section_end()) { 467 outs() << "(?,?) "; 468 break; 469 } 470 } else { 471 Sec = S.Section; 472 } 473 DataRefImpl Ref = Sec->getRawDataRefImpl(); 474 StringRef SectionName; 475 if (Expected<StringRef> NameOrErr = MachO->getSectionName(Ref)) 476 SectionName = *NameOrErr; 477 StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref); 478 outs() << "(" << SegmentName << "," << SectionName << ") "; 479 break; 480 } 481 default: 482 outs() << "(?) "; 483 break; 484 } 485 486 if (NType & MachO::N_EXT) { 487 if (NDesc & MachO::REFERENCED_DYNAMICALLY) 488 outs() << "[referenced dynamically] "; 489 if (NType & MachO::N_PEXT) { 490 if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) 491 outs() << "weak private external "; 492 else 493 outs() << "private external "; 494 } else { 495 if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF || 496 (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) { 497 if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) == 498 (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 499 outs() << "weak external automatically hidden "; 500 else 501 outs() << "weak external "; 502 } else 503 outs() << "external "; 504 } 505 } else { 506 if (NType & MachO::N_PEXT) 507 outs() << "non-external (was a private external) "; 508 else 509 outs() << "non-external "; 510 } 511 512 if (Filetype == MachO::MH_OBJECT) { 513 if (NDesc & MachO::N_NO_DEAD_STRIP) 514 outs() << "[no dead strip] "; 515 if ((NType & MachO::N_TYPE) != MachO::N_UNDF && 516 NDesc & MachO::N_SYMBOL_RESOLVER) 517 outs() << "[symbol resolver] "; 518 if ((NType & MachO::N_TYPE) != MachO::N_UNDF && NDesc & MachO::N_ALT_ENTRY) 519 outs() << "[alt entry] "; 520 if ((NType & MachO::N_TYPE) != MachO::N_UNDF && NDesc & MachO::N_COLD_FUNC) 521 outs() << "[cold func] "; 522 } 523 524 if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF) 525 outs() << "[Thumb] "; 526 527 if ((NType & MachO::N_TYPE) == MachO::N_INDR) { 528 outs() << S.Name << " (for "; 529 StringRef IndirectName; 530 if (MachO) { 531 if (S.Sym.getRawDataRefImpl().p) { 532 if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName)) 533 outs() << "?)"; 534 else 535 outs() << IndirectName << ")"; 536 } else 537 outs() << S.IndirectName << ")"; 538 } else 539 outs() << "?)"; 540 } else 541 outs() << S.Name; 542 543 if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL && 544 (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) || 545 (NType & MachO::N_TYPE) == MachO::N_PBUD)) { 546 uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc); 547 if (LibraryOrdinal != 0) { 548 if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL) 549 outs() << " (from executable)"; 550 else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL) 551 outs() << " (dynamically looked up)"; 552 else { 553 StringRef LibraryName; 554 if (!MachO || 555 MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName)) 556 outs() << " (from bad library ordinal " << LibraryOrdinal << ")"; 557 else 558 outs() << " (from " << LibraryName << ")"; 559 } 560 } 561 } 562 563 outs() << "\n"; 564 } 565 566 // Table that maps Darwin's Mach-O stab constants to strings to allow printing. 567 struct DarwinStabName { 568 uint8_t NType; 569 const char *Name; 570 }; 571 const struct DarwinStabName DarwinStabNames[] = { 572 {MachO::N_GSYM, "GSYM"}, 573 {MachO::N_FNAME, "FNAME"}, 574 {MachO::N_FUN, "FUN"}, 575 {MachO::N_STSYM, "STSYM"}, 576 {MachO::N_LCSYM, "LCSYM"}, 577 {MachO::N_BNSYM, "BNSYM"}, 578 {MachO::N_PC, "PC"}, 579 {MachO::N_AST, "AST"}, 580 {MachO::N_OPT, "OPT"}, 581 {MachO::N_RSYM, "RSYM"}, 582 {MachO::N_SLINE, "SLINE"}, 583 {MachO::N_ENSYM, "ENSYM"}, 584 {MachO::N_SSYM, "SSYM"}, 585 {MachO::N_SO, "SO"}, 586 {MachO::N_OSO, "OSO"}, 587 {MachO::N_LSYM, "LSYM"}, 588 {MachO::N_BINCL, "BINCL"}, 589 {MachO::N_SOL, "SOL"}, 590 {MachO::N_PARAMS, "PARAM"}, 591 {MachO::N_VERSION, "VERS"}, 592 {MachO::N_OLEVEL, "OLEV"}, 593 {MachO::N_PSYM, "PSYM"}, 594 {MachO::N_EINCL, "EINCL"}, 595 {MachO::N_ENTRY, "ENTRY"}, 596 {MachO::N_LBRAC, "LBRAC"}, 597 {MachO::N_EXCL, "EXCL"}, 598 {MachO::N_RBRAC, "RBRAC"}, 599 {MachO::N_BCOMM, "BCOMM"}, 600 {MachO::N_ECOMM, "ECOMM"}, 601 {MachO::N_ECOML, "ECOML"}, 602 {MachO::N_LENG, "LENG"}, 603 }; 604 605 static const char *getDarwinStabString(uint8_t NType) { 606 for (auto I : ArrayRef(DarwinStabNames)) 607 if (I.NType == NType) 608 return I.Name; 609 return nullptr; 610 } 611 612 // darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of 613 // a stab n_type value in a Mach-O file. 614 static void darwinPrintStab(MachOObjectFile *MachO, const NMSymbol &S) { 615 MachO::nlist_64 STE_64; 616 MachO::nlist STE; 617 uint8_t NType; 618 uint8_t NSect; 619 uint16_t NDesc; 620 DataRefImpl SymDRI = S.Sym.getRawDataRefImpl(); 621 if (MachO->is64Bit()) { 622 STE_64 = MachO->getSymbol64TableEntry(SymDRI); 623 NType = STE_64.n_type; 624 NSect = STE_64.n_sect; 625 NDesc = STE_64.n_desc; 626 } else { 627 STE = MachO->getSymbolTableEntry(SymDRI); 628 NType = STE.n_type; 629 NSect = STE.n_sect; 630 NDesc = STE.n_desc; 631 } 632 633 outs() << format(" %02x %04x ", NSect, NDesc); 634 if (const char *stabString = getDarwinStabString(NType)) 635 outs() << format("%5.5s", stabString); 636 else 637 outs() << format(" %02x", NType); 638 } 639 640 static std::optional<std::string> demangle(StringRef Name) { 641 std::string Demangled; 642 if (nonMicrosoftDemangle(Name, Demangled)) 643 return Demangled; 644 return std::nullopt; 645 } 646 647 static std::optional<std::string> demangleXCOFF(StringRef Name) { 648 if (Name.empty() || Name[0] != '.') 649 return demangle(Name); 650 651 Name = Name.drop_front(); 652 std::optional<std::string> DemangledName = demangle(Name); 653 if (DemangledName) 654 return "." + *DemangledName; 655 return std::nullopt; 656 } 657 658 static std::optional<std::string> demangleMachO(StringRef Name) { 659 if (!Name.empty() && Name[0] == '_') 660 Name = Name.drop_front(); 661 return demangle(Name); 662 } 663 664 static bool symbolIsDefined(const NMSymbol &Sym) { 665 return Sym.TypeChar != 'U' && Sym.TypeChar != 'w' && Sym.TypeChar != 'v'; 666 } 667 668 static void writeFileName(raw_ostream &S, StringRef ArchiveName, 669 StringRef ArchitectureName) { 670 if (!ArchitectureName.empty()) 671 S << "(for architecture " << ArchitectureName << "):"; 672 if (OutputFormat == posix && !ArchiveName.empty()) 673 S << ArchiveName << "[" << CurrentFilename << "]: "; 674 else { 675 if (!ArchiveName.empty()) 676 S << ArchiveName << ":"; 677 S << CurrentFilename << ": "; 678 } 679 } 680 681 static void sortSymbolList(std::vector<NMSymbol> &SymbolList) { 682 if (NoSort) 683 return; 684 685 if (ReverseSort) 686 llvm::sort(SymbolList, std::greater<>()); 687 else 688 llvm::sort(SymbolList); 689 } 690 691 static void printExportSymbolList(const std::vector<NMSymbol> &SymbolList) { 692 for (const NMSymbol &Sym : SymbolList) { 693 outs() << Sym.Name; 694 if (!Sym.Visibility.empty()) 695 outs() << ' ' << Sym.Visibility; 696 outs() << '\n'; 697 } 698 } 699 700 static void printSymbolList(SymbolicFile &Obj, 701 std::vector<NMSymbol> &SymbolList, bool printName, 702 StringRef ArchiveName, StringRef ArchitectureName) { 703 if (!PrintFileName) { 704 if ((OutputFormat == bsd || OutputFormat == posix || 705 OutputFormat == just_symbols) && 706 MultipleFiles && printName) { 707 outs() << '\n' << CurrentFilename << ":\n"; 708 } else if (OutputFormat == sysv) { 709 outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n"; 710 if (Obj.is64Bit()) 711 outs() << "Name Value Class Type" 712 << " Size Line Section\n"; 713 else 714 outs() << "Name Value Class Type" 715 << " Size Line Section\n"; 716 } 717 } 718 719 const char *printBlanks, *printDashes, *printFormat; 720 if (Obj.is64Bit()) { 721 printBlanks = " "; 722 printDashes = "----------------"; 723 switch (AddressRadix) { 724 case Radix::o: 725 printFormat = OutputFormat == posix ? "%" PRIo64 : "%016" PRIo64; 726 break; 727 case Radix::x: 728 printFormat = OutputFormat == posix ? "%" PRIx64 : "%016" PRIx64; 729 break; 730 default: 731 printFormat = OutputFormat == posix ? "%" PRId64 : "%016" PRId64; 732 } 733 } else { 734 printBlanks = " "; 735 printDashes = "--------"; 736 switch (AddressRadix) { 737 case Radix::o: 738 printFormat = OutputFormat == posix ? "%" PRIo64 : "%08" PRIo64; 739 break; 740 case Radix::x: 741 printFormat = OutputFormat == posix ? "%" PRIx64 : "%08" PRIx64; 742 break; 743 default: 744 printFormat = OutputFormat == posix ? "%" PRId64 : "%08" PRId64; 745 } 746 } 747 748 for (const NMSymbol &S : SymbolList) { 749 if (!S.shouldPrint()) 750 continue; 751 752 std::string Name = S.Name; 753 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 754 if (Demangle) { 755 function_ref<std::optional<std::string>(StringRef)> Fn = ::demangle; 756 if (Obj.isXCOFF()) 757 Fn = demangleXCOFF; 758 if (Obj.isMachO()) 759 Fn = demangleMachO; 760 if (std::optional<std::string> Opt = Fn(S.Name)) 761 Name = *Opt; 762 } 763 764 if (PrintFileName) 765 writeFileName(outs(), ArchiveName, ArchitectureName); 766 if ((OutputFormat == just_symbols || 767 (UndefinedOnly && MachO && OutputFormat != darwin)) && 768 OutputFormat != posix) { 769 outs() << Name << "\n"; 770 continue; 771 } 772 773 char SymbolAddrStr[23], SymbolSizeStr[23]; 774 775 // If the format is SysV or the symbol isn't defined, then print spaces. 776 if (OutputFormat == sysv || !symbolIsDefined(S)) { 777 if (OutputFormat == posix) { 778 format(printFormat, S.Address) 779 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 780 format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 781 } else { 782 strcpy(SymbolAddrStr, printBlanks); 783 strcpy(SymbolSizeStr, printBlanks); 784 } 785 } 786 787 if (symbolIsDefined(S)) { 788 // Otherwise, print the symbol address and size. 789 if (Obj.isIR()) 790 strcpy(SymbolAddrStr, printDashes); 791 else if (MachO && S.TypeChar == 'I') 792 strcpy(SymbolAddrStr, printBlanks); 793 else 794 format(printFormat, S.Address) 795 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 796 format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 797 } 798 799 // If OutputFormat is darwin or we are printing Mach-O symbols in hex and 800 // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's 801 // nm(1) -m output or hex, else if OutputFormat is darwin or we are 802 // printing Mach-O symbols in hex and not a Mach-O object fall back to 803 // OutputFormat bsd (see below). 804 if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) { 805 darwinPrintSymbol(Obj, S, SymbolAddrStr, printBlanks, printDashes, 806 printFormat); 807 } else if (OutputFormat == posix) { 808 outs() << Name << " " << S.TypeChar << " " << SymbolAddrStr << " " 809 << (MachO ? "0" : SymbolSizeStr) << "\n"; 810 } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) { 811 if (PrintAddress) 812 outs() << SymbolAddrStr << ' '; 813 if (PrintSize) 814 outs() << SymbolSizeStr << ' '; 815 outs() << S.TypeChar; 816 if (S.TypeChar == '-' && MachO) 817 darwinPrintStab(MachO, S); 818 outs() << " " << Name; 819 if (S.TypeChar == 'I' && MachO) { 820 outs() << " (indirect for "; 821 if (S.Sym.getRawDataRefImpl().p) { 822 StringRef IndirectName; 823 if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName)) 824 outs() << "?)"; 825 else 826 outs() << IndirectName << ")"; 827 } else 828 outs() << S.IndirectName << ")"; 829 } 830 outs() << "\n"; 831 } else if (OutputFormat == sysv) { 832 outs() << left_justify(Name, 20) << "|" << SymbolAddrStr << "| " 833 << S.TypeChar << " |" << right_justify(S.TypeName, 18) << "|" 834 << SymbolSizeStr << "| |" << S.SectionName << "\n"; 835 } 836 } 837 838 SymbolList.clear(); 839 } 840 841 static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, 842 basic_symbol_iterator I) { 843 // OK, this is ELF 844 elf_symbol_iterator SymI(I); 845 846 Expected<elf_section_iterator> SecIOrErr = SymI->getSection(); 847 if (!SecIOrErr) { 848 consumeError(SecIOrErr.takeError()); 849 return '?'; 850 } 851 852 uint8_t Binding = SymI->getBinding(); 853 if (Binding == ELF::STB_GNU_UNIQUE) 854 return 'u'; 855 856 assert(Binding != ELF::STB_WEAK && "STB_WEAK not tested in calling function"); 857 if (Binding != ELF::STB_GLOBAL && Binding != ELF::STB_LOCAL) 858 return '?'; 859 860 elf_section_iterator SecI = *SecIOrErr; 861 if (SecI != Obj.section_end()) { 862 uint32_t Type = SecI->getType(); 863 uint64_t Flags = SecI->getFlags(); 864 if (Flags & ELF::SHF_EXECINSTR) 865 return 't'; 866 if (Type == ELF::SHT_NOBITS) 867 return 'b'; 868 if (Flags & ELF::SHF_ALLOC) 869 return Flags & ELF::SHF_WRITE ? 'd' : 'r'; 870 871 auto NameOrErr = SecI->getName(); 872 if (!NameOrErr) { 873 consumeError(NameOrErr.takeError()); 874 return '?'; 875 } 876 if ((*NameOrErr).startswith(".debug")) 877 return 'N'; 878 if (!(Flags & ELF::SHF_WRITE)) 879 return 'n'; 880 } 881 882 return '?'; 883 } 884 885 static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { 886 COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); 887 // OK, this is COFF. 888 symbol_iterator SymI(I); 889 890 Expected<StringRef> Name = SymI->getName(); 891 if (!Name) { 892 consumeError(Name.takeError()); 893 return '?'; 894 } 895 896 char Ret = StringSwitch<char>(*Name) 897 .StartsWith(".debug", 'N') 898 .StartsWith(".sxdata", 'N') 899 .Default('?'); 900 901 if (Ret != '?') 902 return Ret; 903 904 uint32_t Characteristics = 0; 905 if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 906 Expected<section_iterator> SecIOrErr = SymI->getSection(); 907 if (!SecIOrErr) { 908 consumeError(SecIOrErr.takeError()); 909 return '?'; 910 } 911 section_iterator SecI = *SecIOrErr; 912 const coff_section *Section = Obj.getCOFFSection(*SecI); 913 Characteristics = Section->Characteristics; 914 if (Expected<StringRef> NameOrErr = Obj.getSectionName(Section)) 915 if (NameOrErr->startswith(".idata")) 916 return 'i'; 917 } 918 919 switch (Symb.getSectionNumber()) { 920 case COFF::IMAGE_SYM_DEBUG: 921 return 'n'; 922 default: 923 // Check section type. 924 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 925 return 't'; 926 if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 927 return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r'; 928 if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 929 return 'b'; 930 if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 931 return 'i'; 932 // Check for section symbol. 933 if (Symb.isSectionDefinition()) 934 return 's'; 935 } 936 937 return '?'; 938 } 939 940 static char getSymbolNMTypeChar(XCOFFObjectFile &Obj, symbol_iterator I) { 941 Expected<uint32_t> TypeOrErr = I->getType(); 942 if (!TypeOrErr) { 943 warn(TypeOrErr.takeError(), Obj.getFileName(), 944 "for symbol with index " + 945 Twine(Obj.getSymbolIndex(I->getRawDataRefImpl().p))); 946 return '?'; 947 } 948 949 uint32_t SymType = *TypeOrErr; 950 951 if (SymType == SymbolRef::ST_File) 952 return 'f'; 953 954 // If the I->getSection() call would return an error, the earlier I->getType() 955 // call will already have returned the same error first. 956 section_iterator SecIter = cantFail(I->getSection()); 957 958 if (SecIter == Obj.section_end()) 959 return '?'; 960 961 if (Obj.isDebugSection(SecIter->getRawDataRefImpl())) 962 return 'N'; 963 964 if (SecIter->isText()) 965 return 't'; 966 967 if (SecIter->isData()) 968 return 'd'; 969 970 if (SecIter->isBSS()) 971 return 'b'; 972 973 return '?'; 974 } 975 976 static char getSymbolNMTypeChar(COFFImportFile &Obj) { 977 switch (Obj.getCOFFImportHeader()->getType()) { 978 case COFF::IMPORT_CODE: 979 return 't'; 980 case COFF::IMPORT_DATA: 981 return 'd'; 982 case COFF::IMPORT_CONST: 983 return 'r'; 984 } 985 return '?'; 986 } 987 988 static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { 989 DataRefImpl Symb = I->getRawDataRefImpl(); 990 uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type 991 : Obj.getSymbolTableEntry(Symb).n_type; 992 993 if (NType & MachO::N_STAB) 994 return '-'; 995 996 switch (NType & MachO::N_TYPE) { 997 case MachO::N_ABS: 998 return 's'; 999 case MachO::N_INDR: 1000 return 'i'; 1001 case MachO::N_SECT: { 1002 Expected<section_iterator> SecOrErr = Obj.getSymbolSection(Symb); 1003 if (!SecOrErr) { 1004 consumeError(SecOrErr.takeError()); 1005 return 's'; 1006 } 1007 section_iterator Sec = *SecOrErr; 1008 if (Sec == Obj.section_end()) 1009 return 's'; 1010 DataRefImpl Ref = Sec->getRawDataRefImpl(); 1011 StringRef SectionName; 1012 if (Expected<StringRef> NameOrErr = Obj.getSectionName(Ref)) 1013 SectionName = *NameOrErr; 1014 StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); 1015 if (Obj.is64Bit() && Obj.getHeader64().filetype == MachO::MH_KEXT_BUNDLE && 1016 SegmentName == "__TEXT_EXEC" && SectionName == "__text") 1017 return 't'; 1018 if (SegmentName == "__TEXT" && SectionName == "__text") 1019 return 't'; 1020 if (SegmentName == "__DATA" && SectionName == "__data") 1021 return 'd'; 1022 if (SegmentName == "__DATA" && SectionName == "__bss") 1023 return 'b'; 1024 return 's'; 1025 } 1026 } 1027 1028 return '?'; 1029 } 1030 1031 static char getSymbolNMTypeChar(TapiFile &Obj, basic_symbol_iterator I) { 1032 auto Type = cantFail(Obj.getSymbolType(I->getRawDataRefImpl())); 1033 switch (Type) { 1034 case SymbolRef::ST_Data: 1035 return 'd'; 1036 case SymbolRef::ST_Function: 1037 return 't'; 1038 default: 1039 return 's'; 1040 } 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 Obj.is64Bit() ? 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 printArchiveMap(iterator_range<Archive::symbol_iterator> &map, 1958 StringRef Filename) { 1959 for (auto I : map) { 1960 Expected<Archive::Child> C = I.getMember(); 1961 if (!C) { 1962 error(C.takeError(), Filename); 1963 break; 1964 } 1965 Expected<StringRef> FileNameOrErr = C->getName(); 1966 if (!FileNameOrErr) { 1967 error(FileNameOrErr.takeError(), Filename); 1968 break; 1969 } 1970 StringRef SymName = I.getName(); 1971 outs() << SymName << " in " << FileNameOrErr.get() << "\n"; 1972 } 1973 1974 outs() << "\n"; 1975 } 1976 1977 static void dumpArchiveMap(Archive *A, StringRef Filename) { 1978 auto Map = A->symbols(); 1979 if (!Map.empty()) { 1980 outs() << "Archive map\n"; 1981 printArchiveMap(Map, Filename); 1982 } 1983 1984 auto ECMap = A->ec_symbols(); 1985 if (!ECMap) { 1986 warn(ECMap.takeError(), Filename); 1987 } else if (!ECMap->empty()) { 1988 outs() << "Archive EC map\n"; 1989 printArchiveMap(*ECMap, Filename); 1990 } 1991 } 1992 1993 static void dumpArchive(Archive *A, std::vector<NMSymbol> &SymbolList, 1994 StringRef Filename, LLVMContext *ContextPtr) { 1995 if (ArchiveMap) 1996 dumpArchiveMap(A, Filename); 1997 1998 Error Err = Error::success(); 1999 for (auto &C : A->children(Err)) { 2000 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(ContextPtr); 2001 if (!ChildOrErr) { 2002 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) 2003 error(std::move(E), Filename, C); 2004 continue; 2005 } 2006 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 2007 if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { 2008 WithColor::warning(errs(), ToolName) 2009 << "sizes with -print-size for Mach-O files are always zero.\n"; 2010 MachOPrintSizeWarning = true; 2011 } 2012 if (!checkMachOAndArchFlags(O, Filename)) 2013 return; 2014 dumpSymbolNamesFromObject(*O, SymbolList, /*PrintSymbolObject=*/false, 2015 !PrintFileName, Filename, 2016 /*ArchitectureName=*/{}, O->getFileName(), 2017 /*PrintArchiveName=*/false); 2018 } 2019 } 2020 if (Err) 2021 error(std::move(Err), A->getFileName()); 2022 } 2023 2024 static void dumpMachOUniversalBinaryMatchArchFlags( 2025 MachOUniversalBinary *UB, std::vector<NMSymbol> &SymbolList, 2026 StringRef Filename, LLVMContext *ContextPtr) { 2027 // Look for a slice in the universal binary that matches each ArchFlag. 2028 bool ArchFound; 2029 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 2030 ArchFound = false; 2031 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 2032 E = UB->end_objects(); 2033 I != E; ++I) { 2034 if (ArchFlags[i] == I->getArchFlagName()) { 2035 ArchFound = true; 2036 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 2037 std::string ArchiveName; 2038 std::string ArchitectureName; 2039 ArchiveName.clear(); 2040 ArchitectureName.clear(); 2041 if (ObjOrErr) { 2042 ObjectFile &Obj = *ObjOrErr.get(); 2043 if (ArchFlags.size() > 1) 2044 ArchitectureName = I->getArchFlagName(); 2045 dumpSymbolNamesFromObject(Obj, SymbolList, 2046 /*PrintSymbolObject=*/false, 2047 (ArchFlags.size() > 1) && !PrintFileName, 2048 ArchiveName, ArchitectureName); 2049 } else if (auto E = 2050 isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { 2051 error(std::move(E), Filename, 2052 ArchFlags.size() > 1 ? StringRef(I->getArchFlagName()) 2053 : StringRef()); 2054 continue; 2055 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 2056 I->getAsArchive()) { 2057 std::unique_ptr<Archive> &A = *AOrErr; 2058 Error Err = Error::success(); 2059 for (auto &C : A->children(Err)) { 2060 Expected<std::unique_ptr<Binary>> ChildOrErr = 2061 C.getAsBinary(ContextPtr); 2062 if (!ChildOrErr) { 2063 if (auto E = 2064 isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) { 2065 error(std::move(E), Filename, C, 2066 ArchFlags.size() > 1 ? StringRef(I->getArchFlagName()) 2067 : StringRef()); 2068 } 2069 continue; 2070 } 2071 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 2072 ArchiveName = std::string(A->getFileName()); 2073 if (ArchFlags.size() > 1) 2074 ArchitectureName = I->getArchFlagName(); 2075 dumpSymbolNamesFromObject( 2076 *O, SymbolList, /*PrintSymbolObject=*/false, !PrintFileName, 2077 ArchiveName, ArchitectureName); 2078 } 2079 } 2080 if (Err) 2081 error(std::move(Err), A->getFileName()); 2082 } else { 2083 consumeError(AOrErr.takeError()); 2084 error(Filename + " for architecture " + 2085 StringRef(I->getArchFlagName()) + 2086 " is not a Mach-O file or an archive file", 2087 "Mach-O universal file"); 2088 } 2089 } 2090 } 2091 if (!ArchFound) { 2092 error(ArchFlags[i], 2093 "file: " + Filename + " does not contain architecture"); 2094 return; 2095 } 2096 } 2097 } 2098 2099 // Returns true If the binary contains a slice that matches the host 2100 // architecture, or false otherwise. 2101 static bool dumpMachOUniversalBinaryMatchHost(MachOUniversalBinary *UB, 2102 std::vector<NMSymbol> &SymbolList, 2103 StringRef Filename, 2104 LLVMContext *ContextPtr) { 2105 Triple HostTriple = MachOObjectFile::getHostArch(); 2106 StringRef HostArchName = HostTriple.getArchName(); 2107 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 2108 E = UB->end_objects(); 2109 I != E; ++I) { 2110 if (HostArchName == I->getArchFlagName()) { 2111 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 2112 std::string ArchiveName; 2113 if (ObjOrErr) { 2114 ObjectFile &Obj = *ObjOrErr.get(); 2115 dumpSymbolNamesFromObject(Obj, SymbolList, /*PrintSymbolObject=*/false, 2116 /*PrintObjectLabel=*/false); 2117 } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) 2118 error(std::move(E), Filename); 2119 else if (Expected<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { 2120 std::unique_ptr<Archive> &A = *AOrErr; 2121 Error Err = Error::success(); 2122 for (auto &C : A->children(Err)) { 2123 Expected<std::unique_ptr<Binary>> ChildOrErr = 2124 C.getAsBinary(ContextPtr); 2125 if (!ChildOrErr) { 2126 if (auto E = 2127 isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) 2128 error(std::move(E), Filename, C); 2129 continue; 2130 } 2131 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 2132 ArchiveName = std::string(A->getFileName()); 2133 dumpSymbolNamesFromObject(*O, SymbolList, 2134 /*PrintSymbolObject=*/false, 2135 !PrintFileName, ArchiveName); 2136 } 2137 } 2138 if (Err) 2139 error(std::move(Err), A->getFileName()); 2140 } else { 2141 consumeError(AOrErr.takeError()); 2142 error(Filename + " for architecture " + 2143 StringRef(I->getArchFlagName()) + 2144 " is not a Mach-O file or an archive file", 2145 "Mach-O universal file"); 2146 } 2147 return true; 2148 } 2149 } 2150 return false; 2151 } 2152 2153 static void dumpMachOUniversalBinaryArchAll(MachOUniversalBinary *UB, 2154 std::vector<NMSymbol> &SymbolList, 2155 StringRef Filename, 2156 LLVMContext *ContextPtr) { 2157 bool moreThanOneArch = UB->getNumberOfObjects() > 1; 2158 for (const MachOUniversalBinary::ObjectForArch &O : UB->objects()) { 2159 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = O.getAsObjectFile(); 2160 std::string ArchiveName; 2161 std::string ArchitectureName; 2162 ArchiveName.clear(); 2163 ArchitectureName.clear(); 2164 if (ObjOrErr) { 2165 ObjectFile &Obj = *ObjOrErr.get(); 2166 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 2167 ArchitectureName = O.getArchFlagName(); 2168 dumpSymbolNamesFromObject(Obj, SymbolList, /*PrintSymbolObject=*/false, 2169 !PrintFileName, ArchiveName, ArchitectureName); 2170 } else if (auto E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { 2171 error(std::move(E), Filename, 2172 moreThanOneArch ? StringRef(O.getArchFlagName()) : StringRef()); 2173 continue; 2174 } else if (Expected<std::unique_ptr<Archive>> AOrErr = O.getAsArchive()) { 2175 std::unique_ptr<Archive> &A = *AOrErr; 2176 Error Err = Error::success(); 2177 for (auto &C : A->children(Err)) { 2178 Expected<std::unique_ptr<Binary>> ChildOrErr = 2179 C.getAsBinary(ContextPtr); 2180 if (!ChildOrErr) { 2181 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) 2182 error(std::move(E), Filename, C, 2183 moreThanOneArch ? StringRef(ArchitectureName) : StringRef()); 2184 continue; 2185 } 2186 if (SymbolicFile *F = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 2187 ArchiveName = std::string(A->getFileName()); 2188 if (isa<MachOObjectFile>(F) && moreThanOneArch) 2189 ArchitectureName = O.getArchFlagName(); 2190 dumpSymbolNamesFromObject(*F, SymbolList, /*PrintSymbolObject=*/false, 2191 !PrintFileName, ArchiveName, 2192 ArchitectureName); 2193 } 2194 } 2195 if (Err) 2196 error(std::move(Err), A->getFileName()); 2197 } else { 2198 consumeError(AOrErr.takeError()); 2199 error(Filename + " for architecture " + StringRef(O.getArchFlagName()) + 2200 " is not a Mach-O file or an archive file", 2201 "Mach-O universal file"); 2202 } 2203 } 2204 } 2205 2206 static void dumpMachOUniversalBinary(MachOUniversalBinary *UB, 2207 std::vector<NMSymbol> &SymbolList, 2208 StringRef Filename, 2209 LLVMContext *ContextPtr) { 2210 // If we have a list of architecture flags specified dump only those. 2211 if (!ArchAll && !ArchFlags.empty()) { 2212 dumpMachOUniversalBinaryMatchArchFlags(UB, SymbolList, Filename, 2213 ContextPtr); 2214 return; 2215 } 2216 2217 // No architecture flags were specified so if this contains a slice that 2218 // matches the host architecture dump only that. 2219 if (!ArchAll && 2220 dumpMachOUniversalBinaryMatchHost(UB, SymbolList, Filename, ContextPtr)) 2221 return; 2222 2223 // Either all architectures have been specified or none have been specified 2224 // and this does not contain the host architecture so dump all the slices. 2225 dumpMachOUniversalBinaryArchAll(UB, SymbolList, Filename, ContextPtr); 2226 } 2227 2228 static void dumpTapiUniversal(TapiUniversal *TU, 2229 std::vector<NMSymbol> &SymbolList, 2230 StringRef Filename) { 2231 for (const TapiUniversal::ObjectForArch &I : TU->objects()) { 2232 StringRef ArchName = I.getArchFlagName(); 2233 const bool ShowArch = 2234 ArchFlags.empty() || llvm::is_contained(ArchFlags, ArchName); 2235 if (!ShowArch) 2236 continue; 2237 if (!AddInlinedInfo && !I.isTopLevelLib()) 2238 continue; 2239 if (auto ObjOrErr = I.getAsObjectFile()) 2240 dumpSymbolNamesFromObject( 2241 *ObjOrErr.get(), SymbolList, /*PrintSymbolObject=*/false, 2242 /*PrintObjectLabel=*/true, 2243 /*ArchiveName=*/{}, ArchName, I.getInstallName()); 2244 else if (Error E = isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) { 2245 error(std::move(E), Filename, ArchName); 2246 } 2247 } 2248 } 2249 2250 static void dumpSymbolicFile(SymbolicFile *O, std::vector<NMSymbol> &SymbolList, 2251 StringRef Filename) { 2252 if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { 2253 WithColor::warning(errs(), ToolName) 2254 << "sizes with --print-size for Mach-O files are always zero.\n"; 2255 MachOPrintSizeWarning = true; 2256 } 2257 if (!checkMachOAndArchFlags(O, Filename)) 2258 return; 2259 dumpSymbolNamesFromObject(*O, SymbolList, /*PrintSymbolObject=*/true, 2260 /*PrintObjectLabel=*/false); 2261 } 2262 2263 static std::vector<NMSymbol> dumpSymbolNamesFromFile(StringRef Filename) { 2264 std::vector<NMSymbol> SymbolList; 2265 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 2266 MemoryBuffer::getFileOrSTDIN(Filename); 2267 if (error(BufferOrErr.getError(), Filename)) 2268 return SymbolList; 2269 2270 LLVMContext Context; 2271 LLVMContext *ContextPtr = NoLLVMBitcode ? nullptr : &Context; 2272 Expected<std::unique_ptr<Binary>> BinaryOrErr = 2273 createBinary(BufferOrErr.get()->getMemBufferRef(), ContextPtr); 2274 if (!BinaryOrErr) { 2275 error(BinaryOrErr.takeError(), Filename); 2276 return SymbolList; 2277 } 2278 Binary &Bin = *BinaryOrErr.get(); 2279 if (Archive *A = dyn_cast<Archive>(&Bin)) 2280 dumpArchive(A, SymbolList, Filename, ContextPtr); 2281 else if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) 2282 dumpMachOUniversalBinary(UB, SymbolList, Filename, ContextPtr); 2283 else if (TapiUniversal *TU = dyn_cast<TapiUniversal>(&Bin)) 2284 dumpTapiUniversal(TU, SymbolList, Filename); 2285 else if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) 2286 dumpSymbolicFile(O, SymbolList, Filename); 2287 return SymbolList; 2288 } 2289 2290 static void 2291 exportSymbolNamesFromFiles(const std::vector<std::string> &InputFilenames) { 2292 std::vector<NMSymbol> SymbolList; 2293 for (const auto &FileName : InputFilenames) { 2294 std::vector<NMSymbol> FileSymList = dumpSymbolNamesFromFile(FileName); 2295 SymbolList.insert(SymbolList.end(), FileSymList.begin(), FileSymList.end()); 2296 } 2297 2298 // Delete symbols which should not be printed from SymolList. 2299 llvm::erase_if(SymbolList, 2300 [](const NMSymbol &s) { return !s.shouldPrint(); }); 2301 sortSymbolList(SymbolList); 2302 SymbolList.erase(std::unique(SymbolList.begin(), SymbolList.end()), 2303 SymbolList.end()); 2304 printExportSymbolList(SymbolList); 2305 } 2306 2307 int llvm_nm_main(int argc, char **argv, const llvm::ToolContext &) { 2308 InitLLVM X(argc, argv); 2309 BumpPtrAllocator A; 2310 StringSaver Saver(A); 2311 NmOptTable Tbl; 2312 ToolName = argv[0]; 2313 opt::InputArgList Args = 2314 Tbl.parseArgs(argc, argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) { 2315 error(Msg); 2316 exit(1); 2317 }); 2318 if (Args.hasArg(OPT_help)) { 2319 Tbl.printHelp( 2320 outs(), 2321 (Twine(ToolName) + " [options] <input object files>").str().c_str(), 2322 "LLVM symbol table dumper"); 2323 // TODO Replace this with OptTable API once it adds extrahelp support. 2324 outs() << "\nPass @FILE as argument to read options from FILE.\n"; 2325 return 0; 2326 } 2327 if (Args.hasArg(OPT_version)) { 2328 // This needs to contain the word "GNU", libtool looks for that string. 2329 outs() << "llvm-nm, compatible with GNU nm" << '\n'; 2330 cl::PrintVersionMessage(); 2331 return 0; 2332 } 2333 2334 DebugSyms = Args.hasArg(OPT_debug_syms); 2335 DefinedOnly = Args.hasArg(OPT_defined_only); 2336 Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, false); 2337 DynamicSyms = Args.hasArg(OPT_dynamic); 2338 ExternalOnly = Args.hasArg(OPT_extern_only); 2339 StringRef V = Args.getLastArgValue(OPT_format_EQ, "bsd"); 2340 if (V == "bsd") 2341 OutputFormat = bsd; 2342 else if (V == "posix") 2343 OutputFormat = posix; 2344 else if (V == "sysv") 2345 OutputFormat = sysv; 2346 else if (V == "darwin") 2347 OutputFormat = darwin; 2348 else if (V == "just-symbols") 2349 OutputFormat = just_symbols; 2350 else 2351 error("--format value should be one of: bsd, posix, sysv, darwin, " 2352 "just-symbols"); 2353 NoLLVMBitcode = Args.hasArg(OPT_no_llvm_bc); 2354 NoSort = Args.hasArg(OPT_no_sort); 2355 NoWeakSymbols = Args.hasArg(OPT_no_weak); 2356 NumericSort = Args.hasArg(OPT_numeric_sort); 2357 ArchiveMap = Args.hasArg(OPT_print_armap); 2358 PrintFileName = Args.hasArg(OPT_print_file_name); 2359 PrintSize = Args.hasArg(OPT_print_size); 2360 ReverseSort = Args.hasArg(OPT_reverse_sort); 2361 ExportSymbols = Args.hasArg(OPT_export_symbols); 2362 if (ExportSymbols) { 2363 ExternalOnly = true; 2364 DefinedOnly = true; 2365 } 2366 2367 Quiet = Args.hasArg(OPT_quiet); 2368 V = Args.getLastArgValue(OPT_radix_EQ, "x"); 2369 if (V == "o") 2370 AddressRadix = Radix::o; 2371 else if (V == "d") 2372 AddressRadix = Radix::d; 2373 else if (V == "x") 2374 AddressRadix = Radix::x; 2375 else 2376 error("--radix value should be one of: 'o' (octal), 'd' (decimal), 'x' " 2377 "(hexadecimal)"); 2378 SizeSort = Args.hasArg(OPT_size_sort); 2379 SpecialSyms = Args.hasArg(OPT_special_syms); 2380 UndefinedOnly = Args.hasArg(OPT_undefined_only); 2381 WithoutAliases = Args.hasArg(OPT_without_aliases); 2382 2383 // Get BitMode from enviornment variable "OBJECT_MODE" for AIX OS, if 2384 // specified. 2385 Triple HostTriple(sys::getProcessTriple()); 2386 if (HostTriple.isOSAIX()) { 2387 BitMode = StringSwitch<BitModeTy>(getenv("OBJECT_MODE")) 2388 .Case("32", BitModeTy::Bit32) 2389 .Case("64", BitModeTy::Bit64) 2390 .Case("32_64", BitModeTy::Bit32_64) 2391 .Case("any", BitModeTy::Any) 2392 .Default(BitModeTy::Bit32); 2393 } else 2394 BitMode = BitModeTy::Any; 2395 2396 if (Arg *A = Args.getLastArg(OPT_X)) { 2397 StringRef Mode = A->getValue(); 2398 if (Mode == "32") 2399 BitMode = BitModeTy::Bit32; 2400 else if (Mode == "64") 2401 BitMode = BitModeTy::Bit64; 2402 else if (Mode == "32_64") 2403 BitMode = BitModeTy::Bit32_64; 2404 else if (Mode == "any") 2405 BitMode = BitModeTy::Any; 2406 else 2407 error("-X value should be one of: 32, 64, 32_64, (default) any"); 2408 } 2409 2410 // Mach-O specific options. 2411 FormatMachOasHex = Args.hasArg(OPT_x); 2412 AddDyldInfo = Args.hasArg(OPT_add_dyldinfo); 2413 AddInlinedInfo = Args.hasArg(OPT_add_inlinedinfo); 2414 DyldInfoOnly = Args.hasArg(OPT_dyldinfo_only); 2415 NoDyldInfo = Args.hasArg(OPT_no_dyldinfo); 2416 2417 // XCOFF specific options. 2418 NoRsrc = Args.hasArg(OPT_no_rsrc); 2419 2420 // llvm-nm only reads binary files. 2421 if (error(sys::ChangeStdinToBinary())) 2422 return 1; 2423 2424 // These calls are needed so that we can read bitcode correctly. 2425 llvm::InitializeAllTargetInfos(); 2426 llvm::InitializeAllTargetMCs(); 2427 llvm::InitializeAllAsmParsers(); 2428 2429 // The relative order of these is important. If you pass --size-sort it should 2430 // only print out the size. However, if you pass -S --size-sort, it should 2431 // print out both the size and address. 2432 if (SizeSort && !PrintSize) 2433 PrintAddress = false; 2434 if (OutputFormat == sysv || SizeSort) 2435 PrintSize = true; 2436 2437 for (const auto *A : Args.filtered(OPT_arch_EQ)) { 2438 SmallVector<StringRef, 2> Values; 2439 llvm::SplitString(A->getValue(), Values, ","); 2440 for (StringRef V : Values) { 2441 if (V == "all") 2442 ArchAll = true; 2443 else if (MachOObjectFile::isValidArch(V)) 2444 ArchFlags.push_back(V); 2445 else 2446 error("Unknown architecture named '" + V + "'", 2447 "for the --arch option"); 2448 } 2449 } 2450 2451 // Mach-O takes -s to accept two arguments. We emulate this by iterating over 2452 // both OPT_s and OPT_INPUT. 2453 std::vector<std::string> InputFilenames; 2454 int SegSectArgs = 0; 2455 for (opt::Arg *A : Args.filtered(OPT_s, OPT_INPUT)) { 2456 if (SegSectArgs > 0) { 2457 --SegSectArgs; 2458 SegSect.push_back(A->getValue()); 2459 } else if (A->getOption().matches(OPT_s)) { 2460 SegSectArgs = 2; 2461 } else { 2462 InputFilenames.push_back(A->getValue()); 2463 } 2464 } 2465 if (!SegSect.empty() && SegSect.size() != 2) 2466 error("bad number of arguments (must be two arguments)", 2467 "for the -s option"); 2468 2469 if (InputFilenames.empty()) 2470 InputFilenames.push_back("a.out"); 2471 if (InputFilenames.size() > 1) 2472 MultipleFiles = true; 2473 2474 if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly)) 2475 error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only"); 2476 2477 if (ExportSymbols) 2478 exportSymbolNamesFromFiles(InputFilenames); 2479 else 2480 llvm::for_each(InputFilenames, dumpSymbolNamesFromFile); 2481 2482 if (HadError) 2483 return 1; 2484 return 0; 2485 } 2486