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