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