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 std::function<bool(const NMSymbol &, const NMSymbol &)> Cmp; 715 if (NumericSort) 716 Cmp = compareSymbolAddress; 717 else if (SizeSort) 718 Cmp = compareSymbolSize; 719 else 720 Cmp = compareSymbolName; 721 722 if (ReverseSort) 723 Cmp = [=](const NMSymbol &A, const NMSymbol &B) { return Cmp(B, A); }; 724 llvm::sort(SymbolList, Cmp); 725 } 726 727 if (!PrintFileName) { 728 if (OutputFormat == posix && MultipleFiles && printName) { 729 outs() << '\n' << CurrentFilename << ":\n"; 730 } else if (OutputFormat == bsd && MultipleFiles && printName) { 731 outs() << "\n" << CurrentFilename << ":\n"; 732 } else if (OutputFormat == sysv) { 733 outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n"; 734 if (isSymbolList64Bit(Obj)) 735 outs() << "Name Value Class Type" 736 << " Size Line Section\n"; 737 else 738 outs() << "Name Value Class Type" 739 << " Size Line Section\n"; 740 } 741 } 742 743 const char *printBlanks, *printDashes, *printFormat; 744 if (isSymbolList64Bit(Obj)) { 745 printBlanks = " "; 746 printDashes = "----------------"; 747 switch (AddressRadix) { 748 case Radix::o: 749 printFormat = OutputFormat == posix ? "%" PRIo64 : "%016" PRIo64; 750 break; 751 case Radix::x: 752 printFormat = OutputFormat == posix ? "%" PRIx64 : "%016" PRIx64; 753 break; 754 default: 755 printFormat = OutputFormat == posix ? "%" PRId64 : "%016" PRId64; 756 } 757 } else { 758 printBlanks = " "; 759 printDashes = "--------"; 760 switch (AddressRadix) { 761 case Radix::o: 762 printFormat = OutputFormat == posix ? "%" PRIo64 : "%08" PRIo64; 763 break; 764 case Radix::x: 765 printFormat = OutputFormat == posix ? "%" PRIx64 : "%08" PRIx64; 766 break; 767 default: 768 printFormat = OutputFormat == posix ? "%" PRId64 : "%08" PRId64; 769 } 770 } 771 772 auto writeFileName = [&](raw_ostream &S) { 773 if (!ArchitectureName.empty()) 774 S << "(for architecture " << ArchitectureName << "):"; 775 if (OutputFormat == posix && !ArchiveName.empty()) 776 S << ArchiveName << "[" << CurrentFilename << "]: "; 777 else { 778 if (!ArchiveName.empty()) 779 S << ArchiveName << ":"; 780 S << CurrentFilename << ": "; 781 } 782 }; 783 784 if (SymbolList.empty()) { 785 if (PrintFileName) 786 writeFileName(errs()); 787 errs() << "no symbols\n"; 788 } 789 790 for (const NMSymbol &S : SymbolList) { 791 uint32_t SymFlags; 792 std::string Name = S.Name.str(); 793 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 794 if (Demangle) { 795 if (Optional<std::string> Opt = demangle(S.Name, MachO)) 796 Name = *Opt; 797 } 798 if (S.Sym.getRawDataRefImpl().p) 799 SymFlags = S.Sym.getFlags(); 800 else 801 SymFlags = S.SymFlags; 802 803 bool Undefined = SymFlags & SymbolRef::SF_Undefined; 804 bool Global = SymFlags & SymbolRef::SF_Global; 805 bool Weak = SymFlags & SymbolRef::SF_Weak; 806 if ((!Undefined && UndefinedOnly) || (Undefined && DefinedOnly) || 807 (!Global && ExternalOnly) || (Weak && NoWeakSymbols)) 808 continue; 809 if (PrintFileName) 810 writeFileName(outs()); 811 if ((JustSymbolName || 812 (UndefinedOnly && MachO && OutputFormat != darwin)) && 813 OutputFormat != posix) { 814 outs() << Name << "\n"; 815 continue; 816 } 817 818 char SymbolAddrStr[23], SymbolSizeStr[23]; 819 820 // If the format is SysV or the symbol isn't defined, then print spaces. 821 if (OutputFormat == sysv || !symbolIsDefined(S)) { 822 if (OutputFormat == posix) { 823 format(printFormat, S.Address) 824 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 825 format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 826 } else { 827 strcpy(SymbolAddrStr, printBlanks); 828 strcpy(SymbolSizeStr, printBlanks); 829 } 830 } 831 832 if (symbolIsDefined(S)) { 833 // Otherwise, print the symbol address and size. 834 if (Obj.isIR()) 835 strcpy(SymbolAddrStr, printDashes); 836 else if (MachO && S.TypeChar == 'I') 837 strcpy(SymbolAddrStr, printBlanks); 838 else 839 format(printFormat, S.Address) 840 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 841 format(printFormat, S.Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 842 } 843 844 // If OutputFormat is darwin or we are printing Mach-O symbols in hex and 845 // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's 846 // nm(1) -m output or hex, else if OutputFormat is darwin or we are 847 // printing Mach-O symbols in hex and not a Mach-O object fall back to 848 // OutputFormat bsd (see below). 849 if ((OutputFormat == darwin || FormatMachOasHex) && (MachO || Obj.isIR())) { 850 darwinPrintSymbol(Obj, S, SymbolAddrStr, printBlanks, printDashes, 851 printFormat); 852 } else if (OutputFormat == posix) { 853 outs() << Name << " " << S.TypeChar << " " << SymbolAddrStr << " " 854 << (MachO ? "0" : SymbolSizeStr) << "\n"; 855 } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) { 856 if (PrintAddress) 857 outs() << SymbolAddrStr << ' '; 858 if (PrintSize) 859 outs() << SymbolSizeStr << ' '; 860 outs() << S.TypeChar; 861 if (S.TypeChar == '-' && MachO) 862 darwinPrintStab(MachO, S); 863 outs() << " " << Name; 864 if (S.TypeChar == 'I' && MachO) { 865 outs() << " (indirect for "; 866 if (S.Sym.getRawDataRefImpl().p) { 867 StringRef IndirectName; 868 if (MachO->getIndirectName(S.Sym.getRawDataRefImpl(), IndirectName)) 869 outs() << "?)"; 870 else 871 outs() << IndirectName << ")"; 872 } else 873 outs() << S.IndirectName << ")"; 874 } 875 outs() << "\n"; 876 } else if (OutputFormat == sysv) { 877 outs() << left_justify(Name, 20) << "|" << SymbolAddrStr << "| " 878 << S.TypeChar << " |" << right_justify(S.TypeName, 18) << "|" 879 << SymbolSizeStr << "| |" << S.SectionName << "\n"; 880 } 881 } 882 883 SymbolList.clear(); 884 } 885 886 static char getSymbolNMTypeChar(ELFObjectFileBase &Obj, 887 basic_symbol_iterator I) { 888 // OK, this is ELF 889 elf_symbol_iterator SymI(I); 890 891 Expected<elf_section_iterator> SecIOrErr = SymI->getSection(); 892 if (!SecIOrErr) { 893 consumeError(SecIOrErr.takeError()); 894 return '?'; 895 } 896 897 uint8_t Binding = SymI->getBinding(); 898 if (Binding == ELF::STB_GNU_UNIQUE) 899 return 'u'; 900 901 assert(Binding != ELF::STB_WEAK && "STB_WEAK not tested in calling function"); 902 if (Binding != ELF::STB_GLOBAL && Binding != ELF::STB_LOCAL) 903 return '?'; 904 905 elf_section_iterator SecI = *SecIOrErr; 906 if (SecI != Obj.section_end()) { 907 uint32_t Type = SecI->getType(); 908 uint64_t Flags = SecI->getFlags(); 909 if (Flags & ELF::SHF_EXECINSTR) 910 return 't'; 911 if (Type == ELF::SHT_NOBITS) 912 return 'b'; 913 if (Flags & ELF::SHF_ALLOC) 914 return Flags & ELF::SHF_WRITE ? 'd' : 'r'; 915 916 StringRef SecName; 917 if (SecI->getName(SecName)) 918 return '?'; 919 if (SecName.startswith(".debug")) 920 return 'N'; 921 if (!(Flags & ELF::SHF_WRITE)) 922 return 'n'; 923 } 924 925 return '?'; 926 } 927 928 static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { 929 COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); 930 // OK, this is COFF. 931 symbol_iterator SymI(I); 932 933 Expected<StringRef> Name = SymI->getName(); 934 if (!Name) { 935 consumeError(Name.takeError()); 936 return '?'; 937 } 938 939 char Ret = StringSwitch<char>(*Name) 940 .StartsWith(".debug", 'N') 941 .StartsWith(".sxdata", 'N') 942 .Default('?'); 943 944 if (Ret != '?') 945 return Ret; 946 947 uint32_t Characteristics = 0; 948 if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 949 Expected<section_iterator> SecIOrErr = SymI->getSection(); 950 if (!SecIOrErr) { 951 consumeError(SecIOrErr.takeError()); 952 return '?'; 953 } 954 section_iterator SecI = *SecIOrErr; 955 const coff_section *Section = Obj.getCOFFSection(*SecI); 956 Characteristics = Section->Characteristics; 957 if (Expected<StringRef> NameOrErr = Obj.getSectionName(Section)) 958 if (NameOrErr->startswith(".idata")) 959 return 'i'; 960 } 961 962 switch (Symb.getSectionNumber()) { 963 case COFF::IMAGE_SYM_DEBUG: 964 return 'n'; 965 default: 966 // Check section type. 967 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 968 return 't'; 969 if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 970 return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r'; 971 if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 972 return 'b'; 973 if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 974 return 'i'; 975 // Check for section symbol. 976 if (Symb.isSectionDefinition()) 977 return 's'; 978 } 979 980 return '?'; 981 } 982 983 static char getSymbolNMTypeChar(COFFImportFile &Obj) { 984 switch (Obj.getCOFFImportHeader()->getType()) { 985 case COFF::IMPORT_CODE: 986 return 't'; 987 case COFF::IMPORT_DATA: 988 return 'd'; 989 case COFF::IMPORT_CONST: 990 return 'r'; 991 } 992 return '?'; 993 } 994 995 static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { 996 DataRefImpl Symb = I->getRawDataRefImpl(); 997 uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type 998 : Obj.getSymbolTableEntry(Symb).n_type; 999 1000 if (NType & MachO::N_STAB) 1001 return '-'; 1002 1003 switch (NType & MachO::N_TYPE) { 1004 case MachO::N_ABS: 1005 return 's'; 1006 case MachO::N_INDR: 1007 return 'i'; 1008 case MachO::N_SECT: { 1009 Expected<section_iterator> SecOrErr = Obj.getSymbolSection(Symb); 1010 if (!SecOrErr) { 1011 consumeError(SecOrErr.takeError()); 1012 return 's'; 1013 } 1014 section_iterator Sec = *SecOrErr; 1015 if (Sec == Obj.section_end()) 1016 return 's'; 1017 DataRefImpl Ref = Sec->getRawDataRefImpl(); 1018 StringRef SectionName; 1019 if (Expected<StringRef> NameOrErr = Obj.getSectionName(Ref)) 1020 SectionName = *NameOrErr; 1021 StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); 1022 if (Obj.is64Bit() && Obj.getHeader64().filetype == MachO::MH_KEXT_BUNDLE && 1023 SegmentName == "__TEXT_EXEC" && SectionName == "__text") 1024 return 't'; 1025 if (SegmentName == "__TEXT" && SectionName == "__text") 1026 return 't'; 1027 if (SegmentName == "__DATA" && SectionName == "__data") 1028 return 'd'; 1029 if (SegmentName == "__DATA" && SectionName == "__bss") 1030 return 'b'; 1031 return 's'; 1032 } 1033 } 1034 1035 return '?'; 1036 } 1037 1038 static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) { 1039 uint32_t Flags = I->getFlags(); 1040 if (Flags & SymbolRef::SF_Executable) 1041 return 't'; 1042 return 'd'; 1043 } 1044 1045 static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { 1046 uint32_t Flags = I->getFlags(); 1047 // FIXME: should we print 'b'? At the IR level we cannot be sure if this 1048 // will be in bss or not, but we could approximate. 1049 if (Flags & SymbolRef::SF_Executable) 1050 return 't'; 1051 else if (Triple(Obj.getTargetTriple()).isOSDarwin() && 1052 (Flags & SymbolRef::SF_Const)) 1053 return 's'; 1054 else 1055 return 'd'; 1056 } 1057 1058 static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) { 1059 return !dyn_cast<ELFObjectFileBase>(&Obj) 1060 ? false 1061 : elf_symbol_iterator(I)->getELFType() == ELF::STT_OBJECT; 1062 } 1063 1064 // For ELF object files, Set TypeName to the symbol typename, to be printed 1065 // in the 'Type' column of the SYSV format output. 1066 static StringRef getNMTypeName(SymbolicFile &Obj, basic_symbol_iterator I) { 1067 if (isa<ELFObjectFileBase>(&Obj)) { 1068 elf_symbol_iterator SymI(I); 1069 return SymI->getELFTypeName(); 1070 } 1071 return ""; 1072 } 1073 1074 // Return Posix nm class type tag (single letter), but also set SecName and 1075 // section and name, to be used in format=sysv output. 1076 static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I, 1077 StringRef &SecName) { 1078 uint32_t Symflags = I->getFlags(); 1079 if (isa<ELFObjectFileBase>(&Obj)) { 1080 if (Symflags & object::SymbolRef::SF_Absolute) 1081 SecName = "*ABS*"; 1082 else if (Symflags & object::SymbolRef::SF_Common) 1083 SecName = "*COM*"; 1084 else if (Symflags & object::SymbolRef::SF_Undefined) 1085 SecName = "*UND*"; 1086 else { 1087 elf_symbol_iterator SymI(I); 1088 Expected<elf_section_iterator> SecIOrErr = SymI->getSection(); 1089 if (!SecIOrErr) { 1090 consumeError(SecIOrErr.takeError()); 1091 return '?'; 1092 } 1093 elf_section_iterator secT = *SecIOrErr; 1094 secT->getName(SecName); 1095 } 1096 } 1097 1098 if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) { 1099 char Ret = isObject(Obj, I) ? 'v' : 'w'; 1100 return (!(Symflags & object::SymbolRef::SF_Undefined)) ? toupper(Ret) : Ret; 1101 } 1102 1103 if (Symflags & object::SymbolRef::SF_Undefined) 1104 return 'U'; 1105 1106 if (Symflags & object::SymbolRef::SF_Common) 1107 return 'C'; 1108 1109 char Ret = '?'; 1110 if (Symflags & object::SymbolRef::SF_Absolute) 1111 Ret = 'a'; 1112 else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) 1113 Ret = getSymbolNMTypeChar(*IR, I); 1114 else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj)) 1115 Ret = getSymbolNMTypeChar(*COFF, I); 1116 else if (COFFImportFile *COFFImport = dyn_cast<COFFImportFile>(&Obj)) 1117 Ret = getSymbolNMTypeChar(*COFFImport); 1118 else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) 1119 Ret = getSymbolNMTypeChar(*MachO, I); 1120 else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj)) 1121 Ret = getSymbolNMTypeChar(*Wasm, I); 1122 else 1123 Ret = getSymbolNMTypeChar(cast<ELFObjectFileBase>(Obj), I); 1124 1125 if (!(Symflags & object::SymbolRef::SF_Global)) 1126 return Ret; 1127 1128 if (Obj.isELF() && ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) 1129 return Ret; 1130 1131 return toupper(Ret); 1132 } 1133 1134 // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname" 1135 // option to dump only those symbols from that section in a Mach-O file. 1136 // It is called once for each Mach-O file from dumpSymbolNamesFromObject() 1137 // to get the section number for that named section from the command line 1138 // arguments. It returns the section number for that section in the Mach-O 1139 // file or zero it is not present. 1140 static unsigned getNsectForSegSect(MachOObjectFile *Obj) { 1141 unsigned Nsect = 1; 1142 for (auto &S : Obj->sections()) { 1143 DataRefImpl Ref = S.getRawDataRefImpl(); 1144 StringRef SectionName; 1145 if (Expected<StringRef> NameOrErr = Obj->getSectionName(Ref)) 1146 SectionName = *NameOrErr; 1147 StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref); 1148 if (SegmentName == SegSect[0] && SectionName == SegSect[1]) 1149 return Nsect; 1150 Nsect++; 1151 } 1152 return 0; 1153 } 1154 1155 // getNsectInMachO() is used to implement the Mach-O "-s segname sectname" 1156 // option to dump only those symbols from that section in a Mach-O file. 1157 // It is called once for each symbol in a Mach-O file from 1158 // dumpSymbolNamesFromObject() and returns the section number for that symbol 1159 // if it is in a section, else it returns 0. 1160 static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { 1161 DataRefImpl Symb = Sym.getRawDataRefImpl(); 1162 if (Obj.is64Bit()) { 1163 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 1164 return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0; 1165 } 1166 MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 1167 return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0; 1168 } 1169 1170 static void 1171 dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, 1172 const std::string &ArchiveName = std::string(), 1173 const std::string &ArchitectureName = std::string()) { 1174 auto Symbols = Obj.symbols(); 1175 if (DynamicSyms) { 1176 const auto *E = dyn_cast<ELFObjectFileBase>(&Obj); 1177 if (!E) { 1178 error("File format has no dynamic symbol table", Obj.getFileName()); 1179 return; 1180 } 1181 Symbols = E->getDynamicSymbolIterators(); 1182 } 1183 std::string NameBuffer; 1184 raw_string_ostream OS(NameBuffer); 1185 // If a "-s segname sectname" option was specified and this is a Mach-O 1186 // file get the section number for that section in this object file. 1187 unsigned int Nsect = 0; 1188 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 1189 if (!SegSect.empty() && MachO) { 1190 Nsect = getNsectForSegSect(MachO); 1191 // If this section is not in the object file no symbols are printed. 1192 if (Nsect == 0) 1193 return; 1194 } 1195 if (!MachO || !DyldInfoOnly) { 1196 for (BasicSymbolRef Sym : Symbols) { 1197 uint32_t SymFlags = Sym.getFlags(); 1198 if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) 1199 continue; 1200 if (WithoutAliases && (SymFlags & SymbolRef::SF_Indirect)) 1201 continue; 1202 // If a "-s segname sectname" option was specified and this is a Mach-O 1203 // file and this section appears in this file, Nsect will be non-zero then 1204 // see if this symbol is a symbol from that section and if not skip it. 1205 if (Nsect && Nsect != getNsectInMachO(*MachO, Sym)) 1206 continue; 1207 NMSymbol S = {}; 1208 S.Size = 0; 1209 S.Address = 0; 1210 if (isa<ELFObjectFileBase>(&Obj)) 1211 S.Size = ELFSymbolRef(Sym).getSize(); 1212 if (PrintAddress && isa<ObjectFile>(Obj)) { 1213 SymbolRef SymRef(Sym); 1214 Expected<uint64_t> AddressOrErr = SymRef.getAddress(); 1215 if (!AddressOrErr) { 1216 consumeError(AddressOrErr.takeError()); 1217 break; 1218 } 1219 S.Address = *AddressOrErr; 1220 } 1221 S.TypeName = getNMTypeName(Obj, Sym); 1222 S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName); 1223 if (Error E = Sym.printName(OS)) { 1224 if (MachO) { 1225 OS << "bad string index"; 1226 consumeError(std::move(E)); 1227 } else 1228 error(std::move(E), Obj.getFileName()); 1229 } 1230 OS << '\0'; 1231 S.Sym = Sym; 1232 SymbolList.push_back(S); 1233 } 1234 } 1235 1236 OS.flush(); 1237 const char *P = NameBuffer.c_str(); 1238 unsigned I; 1239 for (I = 0; I < SymbolList.size(); ++I) { 1240 SymbolList[I].Name = P; 1241 P += strlen(P) + 1; 1242 } 1243 1244 // If this is a Mach-O file where the nlist symbol table is out of sync 1245 // with the dyld export trie then look through exports and fake up symbols 1246 // for the ones that are missing (also done with the -add-dyldinfo flag). 1247 // This is needed if strip(1) -T is run on a binary containing swift 1248 // language symbols for example. The option -only-dyldinfo will fake up 1249 // all symbols from the dyld export trie as well as the bind info. 1250 std::string ExportsNameBuffer; 1251 raw_string_ostream EOS(ExportsNameBuffer); 1252 std::string BindsNameBuffer; 1253 raw_string_ostream BOS(BindsNameBuffer); 1254 std::string LazysNameBuffer; 1255 raw_string_ostream LOS(LazysNameBuffer); 1256 std::string WeaksNameBuffer; 1257 raw_string_ostream WOS(WeaksNameBuffer); 1258 std::string FunctionStartsNameBuffer; 1259 raw_string_ostream FOS(FunctionStartsNameBuffer); 1260 if (MachO && !NoDyldInfo) { 1261 MachO::mach_header H; 1262 MachO::mach_header_64 H_64; 1263 uint32_t HFlags = 0; 1264 if (MachO->is64Bit()) { 1265 H_64 = MachO->MachOObjectFile::getHeader64(); 1266 HFlags = H_64.flags; 1267 } else { 1268 H = MachO->MachOObjectFile::getHeader(); 1269 HFlags = H.flags; 1270 } 1271 uint64_t BaseSegmentAddress = 0; 1272 for (const auto &Command : MachO->load_commands()) { 1273 if (Command.C.cmd == MachO::LC_SEGMENT) { 1274 MachO::segment_command Seg = MachO->getSegmentLoadCommand(Command); 1275 if (Seg.fileoff == 0 && Seg.filesize != 0) { 1276 BaseSegmentAddress = Seg.vmaddr; 1277 break; 1278 } 1279 } else if (Command.C.cmd == MachO::LC_SEGMENT_64) { 1280 MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Command); 1281 if (Seg.fileoff == 0 && Seg.filesize != 0) { 1282 BaseSegmentAddress = Seg.vmaddr; 1283 break; 1284 } 1285 } 1286 } 1287 if (DyldInfoOnly || AddDyldInfo || 1288 HFlags & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) { 1289 unsigned ExportsAdded = 0; 1290 Error Err = Error::success(); 1291 for (const llvm::object::ExportEntry &Entry : MachO->exports(Err)) { 1292 bool found = false; 1293 bool ReExport = false; 1294 if (!DyldInfoOnly) { 1295 for (const NMSymbol &S : SymbolList) 1296 if (S.Address == Entry.address() + BaseSegmentAddress && 1297 S.Name == Entry.name()) { 1298 found = true; 1299 break; 1300 } 1301 } 1302 if (!found) { 1303 NMSymbol S = {}; 1304 S.Address = Entry.address() + BaseSegmentAddress; 1305 S.Size = 0; 1306 S.TypeChar = '\0'; 1307 S.Name = Entry.name(); 1308 // There is no symbol in the nlist symbol table for this so we set 1309 // Sym effectivly to null and the rest of code in here must test for 1310 // it and not do things like Sym.getFlags() for it. 1311 S.Sym = BasicSymbolRef(); 1312 S.SymFlags = SymbolRef::SF_Global; 1313 S.Section = SectionRef(); 1314 S.NType = 0; 1315 S.NSect = 0; 1316 S.NDesc = 0; 1317 S.IndirectName = StringRef(); 1318 1319 uint64_t EFlags = Entry.flags(); 1320 bool Abs = ((EFlags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) == 1321 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE); 1322 bool Resolver = (EFlags & 1323 MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER); 1324 ReExport = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT); 1325 bool WeakDef = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION); 1326 if (WeakDef) 1327 S.NDesc |= MachO::N_WEAK_DEF; 1328 if (Abs) { 1329 S.NType = MachO::N_EXT | MachO::N_ABS; 1330 S.TypeChar = 'A'; 1331 } else if (ReExport) { 1332 S.NType = MachO::N_EXT | MachO::N_INDR; 1333 S.TypeChar = 'I'; 1334 } else { 1335 S.NType = MachO::N_EXT | MachO::N_SECT; 1336 if (Resolver) { 1337 S.Address = Entry.other() + BaseSegmentAddress; 1338 if ((S.Address & 1) != 0 && 1339 !MachO->is64Bit() && H.cputype == MachO::CPU_TYPE_ARM){ 1340 S.Address &= ~1LL; 1341 S.NDesc |= MachO::N_ARM_THUMB_DEF; 1342 } 1343 } else { 1344 S.Address = Entry.address() + BaseSegmentAddress; 1345 } 1346 StringRef SegmentName = StringRef(); 1347 StringRef SectionName = StringRef(); 1348 for (const SectionRef &Section : MachO->sections()) { 1349 S.NSect++; 1350 Section.getName(SectionName); 1351 SegmentName = MachO->getSectionFinalSegmentName( 1352 Section.getRawDataRefImpl()); 1353 if (S.Address >= Section.getAddress() && 1354 S.Address < Section.getAddress() + Section.getSize()) { 1355 S.Section = Section; 1356 break; 1357 } else if (Entry.name() == "__mh_execute_header" && 1358 SegmentName == "__TEXT" && SectionName == "__text") { 1359 S.Section = Section; 1360 S.NDesc |= MachO::REFERENCED_DYNAMICALLY; 1361 break; 1362 } 1363 } 1364 if (SegmentName == "__TEXT" && SectionName == "__text") 1365 S.TypeChar = 'T'; 1366 else if (SegmentName == "__DATA" && SectionName == "__data") 1367 S.TypeChar = 'D'; 1368 else if (SegmentName == "__DATA" && SectionName == "__bss") 1369 S.TypeChar = 'B'; 1370 else 1371 S.TypeChar = 'S'; 1372 } 1373 SymbolList.push_back(S); 1374 1375 EOS << Entry.name(); 1376 EOS << '\0'; 1377 ExportsAdded++; 1378 1379 // For ReExports there are a two more things to do, first add the 1380 // indirect name and second create the undefined symbol using the 1381 // referened dynamic library. 1382 if (ReExport) { 1383 1384 // Add the indirect name. 1385 if (Entry.otherName().empty()) 1386 EOS << Entry.name(); 1387 else 1388 EOS << Entry.otherName(); 1389 EOS << '\0'; 1390 1391 // Now create the undefined symbol using the referened dynamic 1392 // library. 1393 NMSymbol U = {}; 1394 U.Address = 0; 1395 U.Size = 0; 1396 U.TypeChar = 'U'; 1397 if (Entry.otherName().empty()) 1398 U.Name = Entry.name(); 1399 else 1400 U.Name = Entry.otherName(); 1401 // Again there is no symbol in the nlist symbol table for this so 1402 // we set Sym effectivly to null and the rest of code in here must 1403 // test for it and not do things like Sym.getFlags() for it. 1404 U.Sym = BasicSymbolRef(); 1405 U.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1406 U.Section = SectionRef(); 1407 U.NType = MachO::N_EXT | MachO::N_UNDF; 1408 U.NSect = 0; 1409 U.NDesc = 0; 1410 // The library ordinal for this undefined symbol is in the export 1411 // trie Entry.other(). 1412 MachO::SET_LIBRARY_ORDINAL(U.NDesc, Entry.other()); 1413 U.IndirectName = StringRef(); 1414 SymbolList.push_back(U); 1415 1416 // Finally add the undefined symbol's name. 1417 if (Entry.otherName().empty()) 1418 EOS << Entry.name(); 1419 else 1420 EOS << Entry.otherName(); 1421 EOS << '\0'; 1422 ExportsAdded++; 1423 } 1424 } 1425 } 1426 if (Err) 1427 error(std::move(Err), MachO->getFileName()); 1428 // Set the symbol names and indirect names for the added symbols. 1429 if (ExportsAdded) { 1430 EOS.flush(); 1431 const char *Q = ExportsNameBuffer.c_str(); 1432 for (unsigned K = 0; K < ExportsAdded; K++) { 1433 SymbolList[I].Name = Q; 1434 Q += strlen(Q) + 1; 1435 if (SymbolList[I].TypeChar == 'I') { 1436 SymbolList[I].IndirectName = Q; 1437 Q += strlen(Q) + 1; 1438 } 1439 I++; 1440 } 1441 } 1442 1443 // Add the undefined symbols from the bind entries. 1444 unsigned BindsAdded = 0; 1445 Error BErr = Error::success(); 1446 StringRef LastSymbolName = StringRef(); 1447 for (const llvm::object::MachOBindEntry &Entry : MachO->bindTable(BErr)) { 1448 bool found = false; 1449 if (LastSymbolName == Entry.symbolName()) 1450 found = true; 1451 else if(!DyldInfoOnly) { 1452 for (unsigned J = 0; J < SymbolList.size() && !found; ++J) { 1453 if (SymbolList[J].Name == Entry.symbolName()) 1454 found = true; 1455 } 1456 } 1457 if (!found) { 1458 LastSymbolName = Entry.symbolName(); 1459 NMSymbol B = {}; 1460 B.Address = 0; 1461 B.Size = 0; 1462 B.TypeChar = 'U'; 1463 // There is no symbol in the nlist symbol table for this so we set 1464 // Sym effectivly to null and the rest of code in here must test for 1465 // it and not do things like Sym.getFlags() for it. 1466 B.Sym = BasicSymbolRef(); 1467 B.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1468 B.NType = MachO::N_EXT | MachO::N_UNDF; 1469 B.NSect = 0; 1470 B.NDesc = 0; 1471 MachO::SET_LIBRARY_ORDINAL(B.NDesc, Entry.ordinal()); 1472 B.IndirectName = StringRef(); 1473 B.Name = Entry.symbolName(); 1474 SymbolList.push_back(B); 1475 BOS << Entry.symbolName(); 1476 BOS << '\0'; 1477 BindsAdded++; 1478 } 1479 } 1480 if (BErr) 1481 error(std::move(BErr), MachO->getFileName()); 1482 // Set the symbol names and indirect names for the added symbols. 1483 if (BindsAdded) { 1484 BOS.flush(); 1485 const char *Q = BindsNameBuffer.c_str(); 1486 for (unsigned K = 0; K < BindsAdded; K++) { 1487 SymbolList[I].Name = Q; 1488 Q += strlen(Q) + 1; 1489 if (SymbolList[I].TypeChar == 'I') { 1490 SymbolList[I].IndirectName = Q; 1491 Q += strlen(Q) + 1; 1492 } 1493 I++; 1494 } 1495 } 1496 1497 // Add the undefined symbols from the lazy bind entries. 1498 unsigned LazysAdded = 0; 1499 Error LErr = Error::success(); 1500 LastSymbolName = StringRef(); 1501 for (const llvm::object::MachOBindEntry &Entry : 1502 MachO->lazyBindTable(LErr)) { 1503 bool found = false; 1504 if (LastSymbolName == Entry.symbolName()) 1505 found = true; 1506 else { 1507 // Here we must check to see it this symbol is already in the 1508 // SymbolList as it might have already have been added above via a 1509 // non-lazy (bind) entry. 1510 for (unsigned J = 0; J < SymbolList.size() && !found; ++J) { 1511 if (SymbolList[J].Name == Entry.symbolName()) 1512 found = true; 1513 } 1514 } 1515 if (!found) { 1516 LastSymbolName = Entry.symbolName(); 1517 NMSymbol L = {}; 1518 L.Name = Entry.symbolName(); 1519 L.Address = 0; 1520 L.Size = 0; 1521 L.TypeChar = 'U'; 1522 // There is no symbol in the nlist symbol table for this so we set 1523 // Sym effectivly to null and the rest of code in here must test for 1524 // it and not do things like Sym.getFlags() for it. 1525 L.Sym = BasicSymbolRef(); 1526 L.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1527 L.NType = MachO::N_EXT | MachO::N_UNDF; 1528 L.NSect = 0; 1529 // The REFERENCE_FLAG_UNDEFINED_LAZY is no longer used but here it 1530 // makes sence since we are creating this from a lazy bind entry. 1531 L.NDesc = MachO::REFERENCE_FLAG_UNDEFINED_LAZY; 1532 MachO::SET_LIBRARY_ORDINAL(L.NDesc, Entry.ordinal()); 1533 L.IndirectName = StringRef(); 1534 SymbolList.push_back(L); 1535 LOS << Entry.symbolName(); 1536 LOS << '\0'; 1537 LazysAdded++; 1538 } 1539 } 1540 if (LErr) 1541 error(std::move(LErr), MachO->getFileName()); 1542 // Set the symbol names and indirect names for the added symbols. 1543 if (LazysAdded) { 1544 LOS.flush(); 1545 const char *Q = LazysNameBuffer.c_str(); 1546 for (unsigned K = 0; K < LazysAdded; K++) { 1547 SymbolList[I].Name = Q; 1548 Q += strlen(Q) + 1; 1549 if (SymbolList[I].TypeChar == 'I') { 1550 SymbolList[I].IndirectName = Q; 1551 Q += strlen(Q) + 1; 1552 } 1553 I++; 1554 } 1555 } 1556 1557 // Add the undefineds symbol from the weak bind entries which are not 1558 // strong symbols. 1559 unsigned WeaksAdded = 0; 1560 Error WErr = Error::success(); 1561 LastSymbolName = StringRef(); 1562 for (const llvm::object::MachOBindEntry &Entry : 1563 MachO->weakBindTable(WErr)) { 1564 bool found = false; 1565 unsigned J = 0; 1566 if (LastSymbolName == Entry.symbolName() || 1567 Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) { 1568 found = true; 1569 } else { 1570 for (J = 0; J < SymbolList.size() && !found; ++J) { 1571 if (SymbolList[J].Name == Entry.symbolName()) { 1572 found = true; 1573 break; 1574 } 1575 } 1576 } 1577 if (!found) { 1578 LastSymbolName = Entry.symbolName(); 1579 NMSymbol W; 1580 memset(&W, '\0', sizeof(NMSymbol)); 1581 W.Name = Entry.symbolName(); 1582 W.Address = 0; 1583 W.Size = 0; 1584 W.TypeChar = 'U'; 1585 // There is no symbol in the nlist symbol table for this so we set 1586 // Sym effectivly to null and the rest of code in here must test for 1587 // it and not do things like Sym.getFlags() for it. 1588 W.Sym = BasicSymbolRef(); 1589 W.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1590 W.NType = MachO::N_EXT | MachO::N_UNDF; 1591 W.NSect = 0; 1592 // Odd that we are using N_WEAK_DEF on an undefined symbol but that is 1593 // what is created in this case by the linker when there are real 1594 // symbols in the nlist structs. 1595 W.NDesc = MachO::N_WEAK_DEF; 1596 W.IndirectName = StringRef(); 1597 SymbolList.push_back(W); 1598 WOS << Entry.symbolName(); 1599 WOS << '\0'; 1600 WeaksAdded++; 1601 } else { 1602 // This is the case the symbol was previously been found and it could 1603 // have been added from a bind or lazy bind symbol. If so and not 1604 // a definition also mark it as weak. 1605 if (SymbolList[J].TypeChar == 'U') 1606 // See comment above about N_WEAK_DEF. 1607 SymbolList[J].NDesc |= MachO::N_WEAK_DEF; 1608 } 1609 } 1610 if (WErr) 1611 error(std::move(WErr), MachO->getFileName()); 1612 // Set the symbol names and indirect names for the added symbols. 1613 if (WeaksAdded) { 1614 WOS.flush(); 1615 const char *Q = WeaksNameBuffer.c_str(); 1616 for (unsigned K = 0; K < WeaksAdded; K++) { 1617 SymbolList[I].Name = Q; 1618 Q += strlen(Q) + 1; 1619 if (SymbolList[I].TypeChar == 'I') { 1620 SymbolList[I].IndirectName = Q; 1621 Q += strlen(Q) + 1; 1622 } 1623 I++; 1624 } 1625 } 1626 1627 // Trying adding symbol from the function starts table and LC_MAIN entry 1628 // point. 1629 SmallVector<uint64_t, 8> FoundFns; 1630 uint64_t lc_main_offset = UINT64_MAX; 1631 for (const auto &Command : MachO->load_commands()) { 1632 if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) { 1633 // We found a function starts segment, parse the addresses for 1634 // consumption. 1635 MachO::linkedit_data_command LLC = 1636 MachO->getLinkeditDataLoadCommand(Command); 1637 1638 MachO->ReadULEB128s(LLC.dataoff, FoundFns); 1639 } else if (Command.C.cmd == MachO::LC_MAIN) { 1640 MachO::entry_point_command LCmain = 1641 MachO->getEntryPointCommand(Command); 1642 lc_main_offset = LCmain.entryoff; 1643 } 1644 } 1645 // See if these addresses are already in the symbol table. 1646 unsigned FunctionStartsAdded = 0; 1647 for (uint64_t f = 0; f < FoundFns.size(); f++) { 1648 bool found = false; 1649 for (unsigned J = 0; J < SymbolList.size() && !found; ++J) { 1650 if (SymbolList[J].Address == FoundFns[f] + BaseSegmentAddress) 1651 found = true; 1652 } 1653 // See this address is not already in the symbol table fake up an 1654 // nlist for it. 1655 if (!found) { 1656 NMSymbol F = {}; 1657 F.Name = "<redacted function X>"; 1658 F.Address = FoundFns[f] + BaseSegmentAddress; 1659 F.Size = 0; 1660 // There is no symbol in the nlist symbol table for this so we set 1661 // Sym effectivly to null and the rest of code in here must test for 1662 // it and not do things like Sym.getFlags() for it. 1663 F.Sym = BasicSymbolRef(); 1664 F.SymFlags = 0; 1665 F.NType = MachO::N_SECT; 1666 F.NSect = 0; 1667 StringRef SegmentName = StringRef(); 1668 StringRef SectionName = StringRef(); 1669 for (const SectionRef &Section : MachO->sections()) { 1670 Section.getName(SectionName); 1671 SegmentName = MachO->getSectionFinalSegmentName( 1672 Section.getRawDataRefImpl()); 1673 F.NSect++; 1674 if (F.Address >= Section.getAddress() && 1675 F.Address < Section.getAddress() + Section.getSize()) { 1676 F.Section = Section; 1677 break; 1678 } 1679 } 1680 if (SegmentName == "__TEXT" && SectionName == "__text") 1681 F.TypeChar = 't'; 1682 else if (SegmentName == "__DATA" && SectionName == "__data") 1683 F.TypeChar = 'd'; 1684 else if (SegmentName == "__DATA" && SectionName == "__bss") 1685 F.TypeChar = 'b'; 1686 else 1687 F.TypeChar = 's'; 1688 F.NDesc = 0; 1689 F.IndirectName = StringRef(); 1690 SymbolList.push_back(F); 1691 if (FoundFns[f] == lc_main_offset) 1692 FOS << "<redacted LC_MAIN>"; 1693 else 1694 FOS << "<redacted function " << f << ">"; 1695 FOS << '\0'; 1696 FunctionStartsAdded++; 1697 } 1698 } 1699 if (FunctionStartsAdded) { 1700 FOS.flush(); 1701 const char *Q = FunctionStartsNameBuffer.c_str(); 1702 for (unsigned K = 0; K < FunctionStartsAdded; K++) { 1703 SymbolList[I].Name = Q; 1704 Q += strlen(Q) + 1; 1705 if (SymbolList[I].TypeChar == 'I') { 1706 SymbolList[I].IndirectName = Q; 1707 Q += strlen(Q) + 1; 1708 } 1709 I++; 1710 } 1711 } 1712 } 1713 } 1714 1715 CurrentFilename = Obj.getFileName(); 1716 sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName); 1717 } 1718 1719 // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file 1720 // and if it is and there is a list of architecture flags is specified then 1721 // check to make sure this Mach-O file is one of those architectures or all 1722 // architectures was specificed. If not then an error is generated and this 1723 // routine returns false. Else it returns true. 1724 static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) { 1725 auto *MachO = dyn_cast<MachOObjectFile>(O); 1726 1727 if (!MachO || ArchAll || ArchFlags.empty()) 1728 return true; 1729 1730 MachO::mach_header H; 1731 MachO::mach_header_64 H_64; 1732 Triple T; 1733 const char *McpuDefault, *ArchFlag; 1734 if (MachO->is64Bit()) { 1735 H_64 = MachO->MachOObjectFile::getHeader64(); 1736 T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype, 1737 &McpuDefault, &ArchFlag); 1738 } else { 1739 H = MachO->MachOObjectFile::getHeader(); 1740 T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype, 1741 &McpuDefault, &ArchFlag); 1742 } 1743 const std::string ArchFlagName(ArchFlag); 1744 if (none_of(ArchFlags, [&](const std::string &Name) { 1745 return Name == ArchFlagName; 1746 })) { 1747 error("No architecture specified", Filename); 1748 return false; 1749 } 1750 return true; 1751 } 1752 1753 static void dumpSymbolNamesFromFile(std::string &Filename) { 1754 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 1755 MemoryBuffer::getFileOrSTDIN(Filename); 1756 if (error(BufferOrErr.getError(), Filename)) 1757 return; 1758 1759 LLVMContext Context; 1760 LLVMContext *ContextPtr = NoLLVMBitcode ? nullptr : &Context; 1761 Expected<std::unique_ptr<Binary>> BinaryOrErr = 1762 createBinary(BufferOrErr.get()->getMemBufferRef(), ContextPtr); 1763 if (!BinaryOrErr) { 1764 error(BinaryOrErr.takeError(), Filename); 1765 return; 1766 } 1767 Binary &Bin = *BinaryOrErr.get(); 1768 1769 if (Archive *A = dyn_cast<Archive>(&Bin)) { 1770 if (ArchiveMap) { 1771 Archive::symbol_iterator I = A->symbol_begin(); 1772 Archive::symbol_iterator E = A->symbol_end(); 1773 if (I != E) { 1774 outs() << "Archive map\n"; 1775 for (; I != E; ++I) { 1776 Expected<Archive::Child> C = I->getMember(); 1777 if (!C) { 1778 error(C.takeError(), Filename); 1779 break; 1780 } 1781 Expected<StringRef> FileNameOrErr = C->getName(); 1782 if (!FileNameOrErr) { 1783 error(FileNameOrErr.takeError(), Filename); 1784 break; 1785 } 1786 StringRef SymName = I->getName(); 1787 outs() << SymName << " in " << FileNameOrErr.get() << "\n"; 1788 } 1789 outs() << "\n"; 1790 } 1791 } 1792 1793 { 1794 Error Err = Error::success(); 1795 for (auto &C : A->children(Err)) { 1796 Expected<std::unique_ptr<Binary>> ChildOrErr = 1797 C.getAsBinary(ContextPtr); 1798 if (!ChildOrErr) { 1799 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) 1800 error(std::move(E), Filename, C); 1801 continue; 1802 } 1803 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1804 if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { 1805 WithColor::warning(errs(), ToolName) 1806 << "sizes with -print-size for Mach-O files are always zero.\n"; 1807 MachOPrintSizeWarning = true; 1808 } 1809 if (!checkMachOAndArchFlags(O, Filename)) 1810 return; 1811 if (!PrintFileName) { 1812 outs() << "\n"; 1813 if (isa<MachOObjectFile>(O)) { 1814 outs() << Filename << "(" << O->getFileName() << ")"; 1815 } else 1816 outs() << O->getFileName(); 1817 outs() << ":\n"; 1818 } 1819 dumpSymbolNamesFromObject(*O, false, Filename); 1820 } 1821 } 1822 if (Err) 1823 error(std::move(Err), A->getFileName()); 1824 } 1825 return; 1826 } 1827 if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) { 1828 // If we have a list of architecture flags specified dump only those. 1829 if (!ArchAll && !ArchFlags.empty()) { 1830 // Look for a slice in the universal binary that matches each ArchFlag. 1831 bool ArchFound; 1832 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1833 ArchFound = false; 1834 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1835 E = UB->end_objects(); 1836 I != E; ++I) { 1837 if (ArchFlags[i] == I->getArchFlagName()) { 1838 ArchFound = true; 1839 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = 1840 I->getAsObjectFile(); 1841 std::string ArchiveName; 1842 std::string ArchitectureName; 1843 ArchiveName.clear(); 1844 ArchitectureName.clear(); 1845 if (ObjOrErr) { 1846 ObjectFile &Obj = *ObjOrErr.get(); 1847 if (ArchFlags.size() > 1) { 1848 if (PrintFileName) 1849 ArchitectureName = I->getArchFlagName(); 1850 else 1851 outs() << "\n" << Obj.getFileName() << " (for architecture " 1852 << I->getArchFlagName() << ")" 1853 << ":\n"; 1854 } 1855 dumpSymbolNamesFromObject(Obj, false, ArchiveName, 1856 ArchitectureName); 1857 } else if (auto E = isNotObjectErrorInvalidFileType( 1858 ObjOrErr.takeError())) { 1859 error(std::move(E), Filename, ArchFlags.size() > 1 ? 1860 StringRef(I->getArchFlagName()) : StringRef()); 1861 continue; 1862 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1863 I->getAsArchive()) { 1864 std::unique_ptr<Archive> &A = *AOrErr; 1865 Error Err = Error::success(); 1866 for (auto &C : A->children(Err)) { 1867 Expected<std::unique_ptr<Binary>> ChildOrErr = 1868 C.getAsBinary(ContextPtr); 1869 if (!ChildOrErr) { 1870 if (auto E = isNotObjectErrorInvalidFileType( 1871 ChildOrErr.takeError())) { 1872 error(std::move(E), Filename, C, ArchFlags.size() > 1 ? 1873 StringRef(I->getArchFlagName()) : StringRef()); 1874 } 1875 continue; 1876 } 1877 if (SymbolicFile *O = 1878 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1879 if (PrintFileName) { 1880 ArchiveName = A->getFileName(); 1881 if (ArchFlags.size() > 1) 1882 ArchitectureName = I->getArchFlagName(); 1883 } else { 1884 outs() << "\n" << A->getFileName(); 1885 outs() << "(" << O->getFileName() << ")"; 1886 if (ArchFlags.size() > 1) { 1887 outs() << " (for architecture " << I->getArchFlagName() 1888 << ")"; 1889 } 1890 outs() << ":\n"; 1891 } 1892 dumpSymbolNamesFromObject(*O, false, ArchiveName, 1893 ArchitectureName); 1894 } 1895 } 1896 if (Err) 1897 error(std::move(Err), A->getFileName()); 1898 } else { 1899 consumeError(AOrErr.takeError()); 1900 error(Filename + " for architecture " + 1901 StringRef(I->getArchFlagName()) + 1902 " is not a Mach-O file or an archive file", 1903 "Mach-O universal file"); 1904 } 1905 } 1906 } 1907 if (!ArchFound) { 1908 error(ArchFlags[i], 1909 "file: " + Filename + " does not contain architecture"); 1910 return; 1911 } 1912 } 1913 return; 1914 } 1915 // No architecture flags were specified so if this contains a slice that 1916 // matches the host architecture dump only that. 1917 if (!ArchAll) { 1918 Triple HostTriple = MachOObjectFile::getHostArch(); 1919 StringRef HostArchName = HostTriple.getArchName(); 1920 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1921 E = UB->end_objects(); 1922 I != E; ++I) { 1923 if (HostArchName == I->getArchFlagName()) { 1924 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1925 std::string ArchiveName; 1926 if (ObjOrErr) { 1927 ObjectFile &Obj = *ObjOrErr.get(); 1928 dumpSymbolNamesFromObject(Obj, false); 1929 } else if (auto E = isNotObjectErrorInvalidFileType( 1930 ObjOrErr.takeError())) { 1931 error(std::move(E), Filename); 1932 return; 1933 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1934 I->getAsArchive()) { 1935 std::unique_ptr<Archive> &A = *AOrErr; 1936 Error Err = Error::success(); 1937 for (auto &C : A->children(Err)) { 1938 Expected<std::unique_ptr<Binary>> ChildOrErr = 1939 C.getAsBinary(ContextPtr); 1940 if (!ChildOrErr) { 1941 if (auto E = isNotObjectErrorInvalidFileType( 1942 ChildOrErr.takeError())) 1943 error(std::move(E), Filename, C); 1944 continue; 1945 } 1946 if (SymbolicFile *O = 1947 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1948 if (PrintFileName) 1949 ArchiveName = A->getFileName(); 1950 else 1951 outs() << "\n" << A->getFileName() << "(" << O->getFileName() 1952 << ")" 1953 << ":\n"; 1954 dumpSymbolNamesFromObject(*O, false, ArchiveName); 1955 } 1956 } 1957 if (Err) 1958 error(std::move(Err), A->getFileName()); 1959 } else { 1960 consumeError(AOrErr.takeError()); 1961 error(Filename + " for architecture " + 1962 StringRef(I->getArchFlagName()) + 1963 " is not a Mach-O file or an archive file", 1964 "Mach-O universal file"); 1965 } 1966 return; 1967 } 1968 } 1969 } 1970 // Either all architectures have been specified or none have been specified 1971 // and this does not contain the host architecture so dump all the slices. 1972 bool moreThanOneArch = UB->getNumberOfObjects() > 1; 1973 for (const MachOUniversalBinary::ObjectForArch &O : UB->objects()) { 1974 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = O.getAsObjectFile(); 1975 std::string ArchiveName; 1976 std::string ArchitectureName; 1977 ArchiveName.clear(); 1978 ArchitectureName.clear(); 1979 if (ObjOrErr) { 1980 ObjectFile &Obj = *ObjOrErr.get(); 1981 if (PrintFileName) { 1982 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1983 ArchitectureName = O.getArchFlagName(); 1984 } else { 1985 if (moreThanOneArch) 1986 outs() << "\n"; 1987 outs() << Obj.getFileName(); 1988 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1989 outs() << " (for architecture " << O.getArchFlagName() << ")"; 1990 outs() << ":\n"; 1991 } 1992 dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); 1993 } else if (auto E = isNotObjectErrorInvalidFileType( 1994 ObjOrErr.takeError())) { 1995 error(std::move(E), Filename, moreThanOneArch ? 1996 StringRef(O.getArchFlagName()) : StringRef()); 1997 continue; 1998 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1999 O.getAsArchive()) { 2000 std::unique_ptr<Archive> &A = *AOrErr; 2001 Error Err = Error::success(); 2002 for (auto &C : A->children(Err)) { 2003 Expected<std::unique_ptr<Binary>> ChildOrErr = 2004 C.getAsBinary(ContextPtr); 2005 if (!ChildOrErr) { 2006 if (auto E = isNotObjectErrorInvalidFileType( 2007 ChildOrErr.takeError())) 2008 error(std::move(E), Filename, C, moreThanOneArch ? 2009 StringRef(ArchitectureName) : StringRef()); 2010 continue; 2011 } 2012 if (SymbolicFile *F = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 2013 if (PrintFileName) { 2014 ArchiveName = A->getFileName(); 2015 if (isa<MachOObjectFile>(F) && moreThanOneArch) 2016 ArchitectureName = O.getArchFlagName(); 2017 } else { 2018 outs() << "\n" << A->getFileName(); 2019 if (isa<MachOObjectFile>(F)) { 2020 outs() << "(" << F->getFileName() << ")"; 2021 if (moreThanOneArch) 2022 outs() << " (for architecture " << O.getArchFlagName() 2023 << ")"; 2024 } else 2025 outs() << ":" << F->getFileName(); 2026 outs() << ":\n"; 2027 } 2028 dumpSymbolNamesFromObject(*F, false, ArchiveName, ArchitectureName); 2029 } 2030 } 2031 if (Err) 2032 error(std::move(Err), A->getFileName()); 2033 } else { 2034 consumeError(AOrErr.takeError()); 2035 error(Filename + " for architecture " + 2036 StringRef(O.getArchFlagName()) + 2037 " is not a Mach-O file or an archive file", 2038 "Mach-O universal file"); 2039 } 2040 } 2041 return; 2042 } 2043 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { 2044 if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { 2045 WithColor::warning(errs(), ToolName) 2046 << "sizes with --print-size for Mach-O files are always zero.\n"; 2047 MachOPrintSizeWarning = true; 2048 } 2049 if (!checkMachOAndArchFlags(O, Filename)) 2050 return; 2051 dumpSymbolNamesFromObject(*O, true); 2052 } 2053 } 2054 2055 int main(int argc, char **argv) { 2056 InitLLVM X(argc, argv); 2057 cl::HideUnrelatedOptions(NMCat); 2058 cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 2059 2060 // llvm-nm only reads binary files. 2061 if (error(sys::ChangeStdinToBinary())) 2062 return 1; 2063 2064 // These calls are needed so that we can read bitcode correctly. 2065 llvm::InitializeAllTargetInfos(); 2066 llvm::InitializeAllTargetMCs(); 2067 llvm::InitializeAllAsmParsers(); 2068 2069 ToolName = argv[0]; 2070 if (BSDFormat) 2071 OutputFormat = bsd; 2072 if (POSIXFormat) 2073 OutputFormat = posix; 2074 if (DarwinFormat) 2075 OutputFormat = darwin; 2076 2077 // The relative order of these is important. If you pass --size-sort it should 2078 // only print out the size. However, if you pass -S --size-sort, it should 2079 // print out both the size and address. 2080 if (SizeSort && !PrintSize) 2081 PrintAddress = false; 2082 if (OutputFormat == sysv || SizeSort) 2083 PrintSize = true; 2084 if (InputFilenames.empty()) 2085 InputFilenames.push_back("a.out"); 2086 if (InputFilenames.size() > 1) 2087 MultipleFiles = true; 2088 2089 // If both --demangle and --no-demangle are specified then pick the last one. 2090 if (NoDemangle.getPosition() > Demangle.getPosition()) 2091 Demangle = !NoDemangle; 2092 2093 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 2094 if (ArchFlags[i] == "all") { 2095 ArchAll = true; 2096 } else { 2097 if (!MachOObjectFile::isValidArch(ArchFlags[i])) 2098 error("Unknown architecture named '" + ArchFlags[i] + "'", 2099 "for the --arch option"); 2100 } 2101 } 2102 2103 if (!SegSect.empty() && SegSect.size() != 2) 2104 error("bad number of arguments (must be two arguments)", 2105 "for the -s option"); 2106 2107 if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly)) 2108 error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only"); 2109 2110 llvm::for_each(InputFilenames, dumpSymbolNamesFromFile); 2111 2112 if (HadError) 2113 return 1; 2114 } 2115