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