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