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 if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) { 1137 if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC) 1138 return 'i'; 1139 Ret = getSymbolNMTypeChar(*ELF, I); 1140 if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) 1141 return Ret; 1142 } else 1143 llvm_unreachable("unknown binary format"); 1144 1145 if (!(Symflags & object::SymbolRef::SF_Global)) 1146 return Ret; 1147 1148 return toupper(Ret); 1149 } 1150 1151 // getNsectForSegSect() is used to implement the Mach-O "-s segname sectname" 1152 // option to dump only those symbols from that section in a Mach-O file. 1153 // It is called once for each Mach-O file from dumpSymbolNamesFromObject() 1154 // to get the section number for that named section from the command line 1155 // arguments. It returns the section number for that section in the Mach-O 1156 // file or zero it is not present. 1157 static unsigned getNsectForSegSect(MachOObjectFile *Obj) { 1158 unsigned Nsect = 1; 1159 for (auto &S : Obj->sections()) { 1160 DataRefImpl Ref = S.getRawDataRefImpl(); 1161 StringRef SectionName; 1162 if (Expected<StringRef> NameOrErr = Obj->getSectionName(Ref)) 1163 SectionName = *NameOrErr; 1164 StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref); 1165 if (SegmentName == SegSect[0] && SectionName == SegSect[1]) 1166 return Nsect; 1167 Nsect++; 1168 } 1169 return 0; 1170 } 1171 1172 // getNsectInMachO() is used to implement the Mach-O "-s segname sectname" 1173 // option to dump only those symbols from that section in a Mach-O file. 1174 // It is called once for each symbol in a Mach-O file from 1175 // dumpSymbolNamesFromObject() and returns the section number for that symbol 1176 // if it is in a section, else it returns 0. 1177 static unsigned getNsectInMachO(MachOObjectFile &Obj, BasicSymbolRef Sym) { 1178 DataRefImpl Symb = Sym.getRawDataRefImpl(); 1179 if (Obj.is64Bit()) { 1180 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 1181 return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0; 1182 } 1183 MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 1184 return (STE.n_type & MachO::N_TYPE) == MachO::N_SECT ? STE.n_sect : 0; 1185 } 1186 1187 static void 1188 dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, 1189 const std::string &ArchiveName = std::string(), 1190 const std::string &ArchitectureName = std::string()) { 1191 auto Symbols = Obj.symbols(); 1192 if (DynamicSyms) { 1193 const auto *E = dyn_cast<ELFObjectFileBase>(&Obj); 1194 if (!E) { 1195 error("File format has no dynamic symbol table", Obj.getFileName()); 1196 return; 1197 } 1198 Symbols = E->getDynamicSymbolIterators(); 1199 } 1200 std::string NameBuffer; 1201 raw_string_ostream OS(NameBuffer); 1202 // If a "-s segname sectname" option was specified and this is a Mach-O 1203 // file get the section number for that section in this object file. 1204 unsigned int Nsect = 0; 1205 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 1206 if (!SegSect.empty() && MachO) { 1207 Nsect = getNsectForSegSect(MachO); 1208 // If this section is not in the object file no symbols are printed. 1209 if (Nsect == 0) 1210 return; 1211 } 1212 if (!MachO || !DyldInfoOnly) { 1213 for (BasicSymbolRef Sym : Symbols) { 1214 uint32_t SymFlags = Sym.getFlags(); 1215 if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) 1216 continue; 1217 if (WithoutAliases && (SymFlags & SymbolRef::SF_Indirect)) 1218 continue; 1219 // If a "-s segname sectname" option was specified and this is a Mach-O 1220 // file and this section appears in this file, Nsect will be non-zero then 1221 // see if this symbol is a symbol from that section and if not skip it. 1222 if (Nsect && Nsect != getNsectInMachO(*MachO, Sym)) 1223 continue; 1224 NMSymbol S = {}; 1225 S.Size = 0; 1226 S.Address = 0; 1227 if (isa<ELFObjectFileBase>(&Obj)) 1228 S.Size = ELFSymbolRef(Sym).getSize(); 1229 if (PrintAddress && isa<ObjectFile>(Obj)) { 1230 SymbolRef SymRef(Sym); 1231 Expected<uint64_t> AddressOrErr = SymRef.getAddress(); 1232 if (!AddressOrErr) { 1233 consumeError(AddressOrErr.takeError()); 1234 break; 1235 } 1236 S.Address = *AddressOrErr; 1237 } 1238 S.TypeName = getNMTypeName(Obj, Sym); 1239 S.TypeChar = getNMSectionTagAndName(Obj, Sym, S.SectionName); 1240 if (Error E = Sym.printName(OS)) { 1241 if (MachO) { 1242 OS << "bad string index"; 1243 consumeError(std::move(E)); 1244 } else 1245 error(std::move(E), Obj.getFileName()); 1246 } 1247 OS << '\0'; 1248 S.Sym = Sym; 1249 SymbolList.push_back(S); 1250 } 1251 } 1252 1253 OS.flush(); 1254 const char *P = NameBuffer.c_str(); 1255 unsigned I; 1256 for (I = 0; I < SymbolList.size(); ++I) { 1257 SymbolList[I].Name = P; 1258 P += strlen(P) + 1; 1259 } 1260 1261 // If this is a Mach-O file where the nlist symbol table is out of sync 1262 // with the dyld export trie then look through exports and fake up symbols 1263 // for the ones that are missing (also done with the -add-dyldinfo flag). 1264 // This is needed if strip(1) -T is run on a binary containing swift 1265 // language symbols for example. The option -only-dyldinfo will fake up 1266 // all symbols from the dyld export trie as well as the bind info. 1267 std::string ExportsNameBuffer; 1268 raw_string_ostream EOS(ExportsNameBuffer); 1269 std::string BindsNameBuffer; 1270 raw_string_ostream BOS(BindsNameBuffer); 1271 std::string LazysNameBuffer; 1272 raw_string_ostream LOS(LazysNameBuffer); 1273 std::string WeaksNameBuffer; 1274 raw_string_ostream WOS(WeaksNameBuffer); 1275 std::string FunctionStartsNameBuffer; 1276 raw_string_ostream FOS(FunctionStartsNameBuffer); 1277 if (MachO && !NoDyldInfo) { 1278 MachO::mach_header H; 1279 MachO::mach_header_64 H_64; 1280 uint32_t HFlags = 0; 1281 if (MachO->is64Bit()) { 1282 H_64 = MachO->MachOObjectFile::getHeader64(); 1283 HFlags = H_64.flags; 1284 } else { 1285 H = MachO->MachOObjectFile::getHeader(); 1286 HFlags = H.flags; 1287 } 1288 uint64_t BaseSegmentAddress = 0; 1289 for (const auto &Command : MachO->load_commands()) { 1290 if (Command.C.cmd == MachO::LC_SEGMENT) { 1291 MachO::segment_command Seg = MachO->getSegmentLoadCommand(Command); 1292 if (Seg.fileoff == 0 && Seg.filesize != 0) { 1293 BaseSegmentAddress = Seg.vmaddr; 1294 break; 1295 } 1296 } else if (Command.C.cmd == MachO::LC_SEGMENT_64) { 1297 MachO::segment_command_64 Seg = MachO->getSegment64LoadCommand(Command); 1298 if (Seg.fileoff == 0 && Seg.filesize != 0) { 1299 BaseSegmentAddress = Seg.vmaddr; 1300 break; 1301 } 1302 } 1303 } 1304 if (DyldInfoOnly || AddDyldInfo || 1305 HFlags & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) { 1306 unsigned ExportsAdded = 0; 1307 Error Err = Error::success(); 1308 for (const llvm::object::ExportEntry &Entry : MachO->exports(Err)) { 1309 bool found = false; 1310 bool ReExport = false; 1311 if (!DyldInfoOnly) { 1312 for (const NMSymbol &S : SymbolList) 1313 if (S.Address == Entry.address() + BaseSegmentAddress && 1314 S.Name == Entry.name()) { 1315 found = true; 1316 break; 1317 } 1318 } 1319 if (!found) { 1320 NMSymbol S = {}; 1321 S.Address = Entry.address() + BaseSegmentAddress; 1322 S.Size = 0; 1323 S.TypeChar = '\0'; 1324 S.Name = Entry.name(); 1325 // There is no symbol in the nlist symbol table for this so we set 1326 // Sym effectivly to null and the rest of code in here must test for 1327 // it and not do things like Sym.getFlags() for it. 1328 S.Sym = BasicSymbolRef(); 1329 S.SymFlags = SymbolRef::SF_Global; 1330 S.Section = SectionRef(); 1331 S.NType = 0; 1332 S.NSect = 0; 1333 S.NDesc = 0; 1334 S.IndirectName = StringRef(); 1335 1336 uint64_t EFlags = Entry.flags(); 1337 bool Abs = ((EFlags & MachO::EXPORT_SYMBOL_FLAGS_KIND_MASK) == 1338 MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE); 1339 bool Resolver = (EFlags & 1340 MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER); 1341 ReExport = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT); 1342 bool WeakDef = (EFlags & MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION); 1343 if (WeakDef) 1344 S.NDesc |= MachO::N_WEAK_DEF; 1345 if (Abs) { 1346 S.NType = MachO::N_EXT | MachO::N_ABS; 1347 S.TypeChar = 'A'; 1348 } else if (ReExport) { 1349 S.NType = MachO::N_EXT | MachO::N_INDR; 1350 S.TypeChar = 'I'; 1351 } else { 1352 S.NType = MachO::N_EXT | MachO::N_SECT; 1353 if (Resolver) { 1354 S.Address = Entry.other() + BaseSegmentAddress; 1355 if ((S.Address & 1) != 0 && 1356 !MachO->is64Bit() && H.cputype == MachO::CPU_TYPE_ARM){ 1357 S.Address &= ~1LL; 1358 S.NDesc |= MachO::N_ARM_THUMB_DEF; 1359 } 1360 } else { 1361 S.Address = Entry.address() + BaseSegmentAddress; 1362 } 1363 StringRef SegmentName = StringRef(); 1364 StringRef SectionName = StringRef(); 1365 for (const SectionRef &Section : MachO->sections()) { 1366 S.NSect++; 1367 1368 if (Expected<StringRef> NameOrErr = Section.getName()) 1369 SectionName = *NameOrErr; 1370 else 1371 consumeError(NameOrErr.takeError()); 1372 1373 SegmentName = MachO->getSectionFinalSegmentName( 1374 Section.getRawDataRefImpl()); 1375 if (S.Address >= Section.getAddress() && 1376 S.Address < Section.getAddress() + Section.getSize()) { 1377 S.Section = Section; 1378 break; 1379 } else if (Entry.name() == "__mh_execute_header" && 1380 SegmentName == "__TEXT" && SectionName == "__text") { 1381 S.Section = Section; 1382 S.NDesc |= MachO::REFERENCED_DYNAMICALLY; 1383 break; 1384 } 1385 } 1386 if (SegmentName == "__TEXT" && SectionName == "__text") 1387 S.TypeChar = 'T'; 1388 else if (SegmentName == "__DATA" && SectionName == "__data") 1389 S.TypeChar = 'D'; 1390 else if (SegmentName == "__DATA" && SectionName == "__bss") 1391 S.TypeChar = 'B'; 1392 else 1393 S.TypeChar = 'S'; 1394 } 1395 SymbolList.push_back(S); 1396 1397 EOS << Entry.name(); 1398 EOS << '\0'; 1399 ExportsAdded++; 1400 1401 // For ReExports there are a two more things to do, first add the 1402 // indirect name and second create the undefined symbol using the 1403 // referened dynamic library. 1404 if (ReExport) { 1405 1406 // Add the indirect name. 1407 if (Entry.otherName().empty()) 1408 EOS << Entry.name(); 1409 else 1410 EOS << Entry.otherName(); 1411 EOS << '\0'; 1412 1413 // Now create the undefined symbol using the referened dynamic 1414 // library. 1415 NMSymbol U = {}; 1416 U.Address = 0; 1417 U.Size = 0; 1418 U.TypeChar = 'U'; 1419 if (Entry.otherName().empty()) 1420 U.Name = Entry.name(); 1421 else 1422 U.Name = Entry.otherName(); 1423 // Again there is no symbol in the nlist symbol table for this so 1424 // we set Sym effectivly to null and the rest of code in here must 1425 // test for it and not do things like Sym.getFlags() for it. 1426 U.Sym = BasicSymbolRef(); 1427 U.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1428 U.Section = SectionRef(); 1429 U.NType = MachO::N_EXT | MachO::N_UNDF; 1430 U.NSect = 0; 1431 U.NDesc = 0; 1432 // The library ordinal for this undefined symbol is in the export 1433 // trie Entry.other(). 1434 MachO::SET_LIBRARY_ORDINAL(U.NDesc, Entry.other()); 1435 U.IndirectName = StringRef(); 1436 SymbolList.push_back(U); 1437 1438 // Finally add the undefined symbol's name. 1439 if (Entry.otherName().empty()) 1440 EOS << Entry.name(); 1441 else 1442 EOS << Entry.otherName(); 1443 EOS << '\0'; 1444 ExportsAdded++; 1445 } 1446 } 1447 } 1448 if (Err) 1449 error(std::move(Err), MachO->getFileName()); 1450 // Set the symbol names and indirect names for the added symbols. 1451 if (ExportsAdded) { 1452 EOS.flush(); 1453 const char *Q = ExportsNameBuffer.c_str(); 1454 for (unsigned K = 0; K < ExportsAdded; K++) { 1455 SymbolList[I].Name = Q; 1456 Q += strlen(Q) + 1; 1457 if (SymbolList[I].TypeChar == 'I') { 1458 SymbolList[I].IndirectName = Q; 1459 Q += strlen(Q) + 1; 1460 } 1461 I++; 1462 } 1463 } 1464 1465 // Add the undefined symbols from the bind entries. 1466 unsigned BindsAdded = 0; 1467 Error BErr = Error::success(); 1468 StringRef LastSymbolName = StringRef(); 1469 for (const llvm::object::MachOBindEntry &Entry : MachO->bindTable(BErr)) { 1470 bool found = false; 1471 if (LastSymbolName == Entry.symbolName()) 1472 found = true; 1473 else if(!DyldInfoOnly) { 1474 for (unsigned J = 0; J < SymbolList.size() && !found; ++J) { 1475 if (SymbolList[J].Name == Entry.symbolName()) 1476 found = true; 1477 } 1478 } 1479 if (!found) { 1480 LastSymbolName = Entry.symbolName(); 1481 NMSymbol B = {}; 1482 B.Address = 0; 1483 B.Size = 0; 1484 B.TypeChar = 'U'; 1485 // There is no symbol in the nlist symbol table for this so we set 1486 // Sym effectivly to null and the rest of code in here must test for 1487 // it and not do things like Sym.getFlags() for it. 1488 B.Sym = BasicSymbolRef(); 1489 B.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1490 B.NType = MachO::N_EXT | MachO::N_UNDF; 1491 B.NSect = 0; 1492 B.NDesc = 0; 1493 MachO::SET_LIBRARY_ORDINAL(B.NDesc, Entry.ordinal()); 1494 B.IndirectName = StringRef(); 1495 B.Name = Entry.symbolName(); 1496 SymbolList.push_back(B); 1497 BOS << Entry.symbolName(); 1498 BOS << '\0'; 1499 BindsAdded++; 1500 } 1501 } 1502 if (BErr) 1503 error(std::move(BErr), MachO->getFileName()); 1504 // Set the symbol names and indirect names for the added symbols. 1505 if (BindsAdded) { 1506 BOS.flush(); 1507 const char *Q = BindsNameBuffer.c_str(); 1508 for (unsigned K = 0; K < BindsAdded; K++) { 1509 SymbolList[I].Name = Q; 1510 Q += strlen(Q) + 1; 1511 if (SymbolList[I].TypeChar == 'I') { 1512 SymbolList[I].IndirectName = Q; 1513 Q += strlen(Q) + 1; 1514 } 1515 I++; 1516 } 1517 } 1518 1519 // Add the undefined symbols from the lazy bind entries. 1520 unsigned LazysAdded = 0; 1521 Error LErr = Error::success(); 1522 LastSymbolName = StringRef(); 1523 for (const llvm::object::MachOBindEntry &Entry : 1524 MachO->lazyBindTable(LErr)) { 1525 bool found = false; 1526 if (LastSymbolName == Entry.symbolName()) 1527 found = true; 1528 else { 1529 // Here we must check to see it this symbol is already in the 1530 // SymbolList as it might have already have been added above via a 1531 // non-lazy (bind) entry. 1532 for (unsigned J = 0; J < SymbolList.size() && !found; ++J) { 1533 if (SymbolList[J].Name == Entry.symbolName()) 1534 found = true; 1535 } 1536 } 1537 if (!found) { 1538 LastSymbolName = Entry.symbolName(); 1539 NMSymbol L = {}; 1540 L.Name = Entry.symbolName(); 1541 L.Address = 0; 1542 L.Size = 0; 1543 L.TypeChar = 'U'; 1544 // There is no symbol in the nlist symbol table for this so we set 1545 // Sym effectivly to null and the rest of code in here must test for 1546 // it and not do things like Sym.getFlags() for it. 1547 L.Sym = BasicSymbolRef(); 1548 L.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1549 L.NType = MachO::N_EXT | MachO::N_UNDF; 1550 L.NSect = 0; 1551 // The REFERENCE_FLAG_UNDEFINED_LAZY is no longer used but here it 1552 // makes sence since we are creating this from a lazy bind entry. 1553 L.NDesc = MachO::REFERENCE_FLAG_UNDEFINED_LAZY; 1554 MachO::SET_LIBRARY_ORDINAL(L.NDesc, Entry.ordinal()); 1555 L.IndirectName = StringRef(); 1556 SymbolList.push_back(L); 1557 LOS << Entry.symbolName(); 1558 LOS << '\0'; 1559 LazysAdded++; 1560 } 1561 } 1562 if (LErr) 1563 error(std::move(LErr), MachO->getFileName()); 1564 // Set the symbol names and indirect names for the added symbols. 1565 if (LazysAdded) { 1566 LOS.flush(); 1567 const char *Q = LazysNameBuffer.c_str(); 1568 for (unsigned K = 0; K < LazysAdded; K++) { 1569 SymbolList[I].Name = Q; 1570 Q += strlen(Q) + 1; 1571 if (SymbolList[I].TypeChar == 'I') { 1572 SymbolList[I].IndirectName = Q; 1573 Q += strlen(Q) + 1; 1574 } 1575 I++; 1576 } 1577 } 1578 1579 // Add the undefineds symbol from the weak bind entries which are not 1580 // strong symbols. 1581 unsigned WeaksAdded = 0; 1582 Error WErr = Error::success(); 1583 LastSymbolName = StringRef(); 1584 for (const llvm::object::MachOBindEntry &Entry : 1585 MachO->weakBindTable(WErr)) { 1586 bool found = false; 1587 unsigned J = 0; 1588 if (LastSymbolName == Entry.symbolName() || 1589 Entry.flags() & MachO::BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) { 1590 found = true; 1591 } else { 1592 for (J = 0; J < SymbolList.size() && !found; ++J) { 1593 if (SymbolList[J].Name == Entry.symbolName()) { 1594 found = true; 1595 break; 1596 } 1597 } 1598 } 1599 if (!found) { 1600 LastSymbolName = Entry.symbolName(); 1601 NMSymbol W; 1602 memset(&W, '\0', sizeof(NMSymbol)); 1603 W.Name = Entry.symbolName(); 1604 W.Address = 0; 1605 W.Size = 0; 1606 W.TypeChar = 'U'; 1607 // There is no symbol in the nlist symbol table for this so we set 1608 // Sym effectivly to null and the rest of code in here must test for 1609 // it and not do things like Sym.getFlags() for it. 1610 W.Sym = BasicSymbolRef(); 1611 W.SymFlags = SymbolRef::SF_Global | SymbolRef::SF_Undefined; 1612 W.NType = MachO::N_EXT | MachO::N_UNDF; 1613 W.NSect = 0; 1614 // Odd that we are using N_WEAK_DEF on an undefined symbol but that is 1615 // what is created in this case by the linker when there are real 1616 // symbols in the nlist structs. 1617 W.NDesc = MachO::N_WEAK_DEF; 1618 W.IndirectName = StringRef(); 1619 SymbolList.push_back(W); 1620 WOS << Entry.symbolName(); 1621 WOS << '\0'; 1622 WeaksAdded++; 1623 } else { 1624 // This is the case the symbol was previously been found and it could 1625 // have been added from a bind or lazy bind symbol. If so and not 1626 // a definition also mark it as weak. 1627 if (SymbolList[J].TypeChar == 'U') 1628 // See comment above about N_WEAK_DEF. 1629 SymbolList[J].NDesc |= MachO::N_WEAK_DEF; 1630 } 1631 } 1632 if (WErr) 1633 error(std::move(WErr), MachO->getFileName()); 1634 // Set the symbol names and indirect names for the added symbols. 1635 if (WeaksAdded) { 1636 WOS.flush(); 1637 const char *Q = WeaksNameBuffer.c_str(); 1638 for (unsigned K = 0; K < WeaksAdded; K++) { 1639 SymbolList[I].Name = Q; 1640 Q += strlen(Q) + 1; 1641 if (SymbolList[I].TypeChar == 'I') { 1642 SymbolList[I].IndirectName = Q; 1643 Q += strlen(Q) + 1; 1644 } 1645 I++; 1646 } 1647 } 1648 1649 // Trying adding symbol from the function starts table and LC_MAIN entry 1650 // point. 1651 SmallVector<uint64_t, 8> FoundFns; 1652 uint64_t lc_main_offset = UINT64_MAX; 1653 for (const auto &Command : MachO->load_commands()) { 1654 if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) { 1655 // We found a function starts segment, parse the addresses for 1656 // consumption. 1657 MachO::linkedit_data_command LLC = 1658 MachO->getLinkeditDataLoadCommand(Command); 1659 1660 MachO->ReadULEB128s(LLC.dataoff, FoundFns); 1661 } else if (Command.C.cmd == MachO::LC_MAIN) { 1662 MachO::entry_point_command LCmain = 1663 MachO->getEntryPointCommand(Command); 1664 lc_main_offset = LCmain.entryoff; 1665 } 1666 } 1667 // See if these addresses are already in the symbol table. 1668 unsigned FunctionStartsAdded = 0; 1669 for (uint64_t f = 0; f < FoundFns.size(); f++) { 1670 bool found = false; 1671 for (unsigned J = 0; J < SymbolList.size() && !found; ++J) { 1672 if (SymbolList[J].Address == FoundFns[f] + BaseSegmentAddress) 1673 found = true; 1674 } 1675 // See this address is not already in the symbol table fake up an 1676 // nlist for it. 1677 if (!found) { 1678 NMSymbol F = {}; 1679 F.Name = "<redacted function X>"; 1680 F.Address = FoundFns[f] + BaseSegmentAddress; 1681 F.Size = 0; 1682 // There is no symbol in the nlist symbol table for this so we set 1683 // Sym effectivly to null and the rest of code in here must test for 1684 // it and not do things like Sym.getFlags() for it. 1685 F.Sym = BasicSymbolRef(); 1686 F.SymFlags = 0; 1687 F.NType = MachO::N_SECT; 1688 F.NSect = 0; 1689 StringRef SegmentName = StringRef(); 1690 StringRef SectionName = StringRef(); 1691 for (const SectionRef &Section : MachO->sections()) { 1692 if (Expected<StringRef> NameOrErr = Section.getName()) 1693 SectionName = *NameOrErr; 1694 else 1695 consumeError(NameOrErr.takeError()); 1696 1697 SegmentName = MachO->getSectionFinalSegmentName( 1698 Section.getRawDataRefImpl()); 1699 F.NSect++; 1700 if (F.Address >= Section.getAddress() && 1701 F.Address < Section.getAddress() + Section.getSize()) { 1702 F.Section = Section; 1703 break; 1704 } 1705 } 1706 if (SegmentName == "__TEXT" && SectionName == "__text") 1707 F.TypeChar = 't'; 1708 else if (SegmentName == "__DATA" && SectionName == "__data") 1709 F.TypeChar = 'd'; 1710 else if (SegmentName == "__DATA" && SectionName == "__bss") 1711 F.TypeChar = 'b'; 1712 else 1713 F.TypeChar = 's'; 1714 F.NDesc = 0; 1715 F.IndirectName = StringRef(); 1716 SymbolList.push_back(F); 1717 if (FoundFns[f] == lc_main_offset) 1718 FOS << "<redacted LC_MAIN>"; 1719 else 1720 FOS << "<redacted function " << f << ">"; 1721 FOS << '\0'; 1722 FunctionStartsAdded++; 1723 } 1724 } 1725 if (FunctionStartsAdded) { 1726 FOS.flush(); 1727 const char *Q = FunctionStartsNameBuffer.c_str(); 1728 for (unsigned K = 0; K < FunctionStartsAdded; K++) { 1729 SymbolList[I].Name = Q; 1730 Q += strlen(Q) + 1; 1731 if (SymbolList[I].TypeChar == 'I') { 1732 SymbolList[I].IndirectName = Q; 1733 Q += strlen(Q) + 1; 1734 } 1735 I++; 1736 } 1737 } 1738 } 1739 } 1740 1741 CurrentFilename = Obj.getFileName(); 1742 sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName); 1743 } 1744 1745 // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file 1746 // and if it is and there is a list of architecture flags is specified then 1747 // check to make sure this Mach-O file is one of those architectures or all 1748 // architectures was specificed. If not then an error is generated and this 1749 // routine returns false. Else it returns true. 1750 static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) { 1751 auto *MachO = dyn_cast<MachOObjectFile>(O); 1752 1753 if (!MachO || ArchAll || ArchFlags.empty()) 1754 return true; 1755 1756 MachO::mach_header H; 1757 MachO::mach_header_64 H_64; 1758 Triple T; 1759 const char *McpuDefault, *ArchFlag; 1760 if (MachO->is64Bit()) { 1761 H_64 = MachO->MachOObjectFile::getHeader64(); 1762 T = MachOObjectFile::getArchTriple(H_64.cputype, H_64.cpusubtype, 1763 &McpuDefault, &ArchFlag); 1764 } else { 1765 H = MachO->MachOObjectFile::getHeader(); 1766 T = MachOObjectFile::getArchTriple(H.cputype, H.cpusubtype, 1767 &McpuDefault, &ArchFlag); 1768 } 1769 const std::string ArchFlagName(ArchFlag); 1770 if (none_of(ArchFlags, [&](const std::string &Name) { 1771 return Name == ArchFlagName; 1772 })) { 1773 error("No architecture specified", Filename); 1774 return false; 1775 } 1776 return true; 1777 } 1778 1779 static void dumpSymbolNamesFromFile(std::string &Filename) { 1780 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 1781 MemoryBuffer::getFileOrSTDIN(Filename); 1782 if (error(BufferOrErr.getError(), Filename)) 1783 return; 1784 1785 LLVMContext Context; 1786 LLVMContext *ContextPtr = NoLLVMBitcode ? nullptr : &Context; 1787 Expected<std::unique_ptr<Binary>> BinaryOrErr = 1788 createBinary(BufferOrErr.get()->getMemBufferRef(), ContextPtr); 1789 if (!BinaryOrErr) { 1790 error(BinaryOrErr.takeError(), Filename); 1791 return; 1792 } 1793 Binary &Bin = *BinaryOrErr.get(); 1794 1795 if (Archive *A = dyn_cast<Archive>(&Bin)) { 1796 if (ArchiveMap) { 1797 Archive::symbol_iterator I = A->symbol_begin(); 1798 Archive::symbol_iterator E = A->symbol_end(); 1799 if (I != E) { 1800 outs() << "Archive map\n"; 1801 for (; I != E; ++I) { 1802 Expected<Archive::Child> C = I->getMember(); 1803 if (!C) { 1804 error(C.takeError(), Filename); 1805 break; 1806 } 1807 Expected<StringRef> FileNameOrErr = C->getName(); 1808 if (!FileNameOrErr) { 1809 error(FileNameOrErr.takeError(), Filename); 1810 break; 1811 } 1812 StringRef SymName = I->getName(); 1813 outs() << SymName << " in " << FileNameOrErr.get() << "\n"; 1814 } 1815 outs() << "\n"; 1816 } 1817 } 1818 1819 { 1820 Error Err = Error::success(); 1821 for (auto &C : A->children(Err)) { 1822 Expected<std::unique_ptr<Binary>> ChildOrErr = 1823 C.getAsBinary(ContextPtr); 1824 if (!ChildOrErr) { 1825 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError())) 1826 error(std::move(E), Filename, C); 1827 continue; 1828 } 1829 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1830 if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { 1831 WithColor::warning(errs(), ToolName) 1832 << "sizes with -print-size for Mach-O files are always zero.\n"; 1833 MachOPrintSizeWarning = true; 1834 } 1835 if (!checkMachOAndArchFlags(O, Filename)) 1836 return; 1837 if (!PrintFileName) { 1838 outs() << "\n"; 1839 if (isa<MachOObjectFile>(O)) { 1840 outs() << Filename << "(" << O->getFileName() << ")"; 1841 } else 1842 outs() << O->getFileName(); 1843 outs() << ":\n"; 1844 } 1845 dumpSymbolNamesFromObject(*O, false, Filename); 1846 } 1847 } 1848 if (Err) 1849 error(std::move(Err), A->getFileName()); 1850 } 1851 return; 1852 } 1853 if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) { 1854 // If we have a list of architecture flags specified dump only those. 1855 if (!ArchAll && !ArchFlags.empty()) { 1856 // Look for a slice in the universal binary that matches each ArchFlag. 1857 bool ArchFound; 1858 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1859 ArchFound = false; 1860 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1861 E = UB->end_objects(); 1862 I != E; ++I) { 1863 if (ArchFlags[i] == I->getArchFlagName()) { 1864 ArchFound = true; 1865 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = 1866 I->getAsObjectFile(); 1867 std::string ArchiveName; 1868 std::string ArchitectureName; 1869 ArchiveName.clear(); 1870 ArchitectureName.clear(); 1871 if (ObjOrErr) { 1872 ObjectFile &Obj = *ObjOrErr.get(); 1873 if (ArchFlags.size() > 1) { 1874 if (PrintFileName) 1875 ArchitectureName = I->getArchFlagName(); 1876 else 1877 outs() << "\n" << Obj.getFileName() << " (for architecture " 1878 << I->getArchFlagName() << ")" 1879 << ":\n"; 1880 } 1881 dumpSymbolNamesFromObject(Obj, false, ArchiveName, 1882 ArchitectureName); 1883 } else if (auto E = isNotObjectErrorInvalidFileType( 1884 ObjOrErr.takeError())) { 1885 error(std::move(E), Filename, ArchFlags.size() > 1 ? 1886 StringRef(I->getArchFlagName()) : StringRef()); 1887 continue; 1888 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1889 I->getAsArchive()) { 1890 std::unique_ptr<Archive> &A = *AOrErr; 1891 Error Err = Error::success(); 1892 for (auto &C : A->children(Err)) { 1893 Expected<std::unique_ptr<Binary>> ChildOrErr = 1894 C.getAsBinary(ContextPtr); 1895 if (!ChildOrErr) { 1896 if (auto E = isNotObjectErrorInvalidFileType( 1897 ChildOrErr.takeError())) { 1898 error(std::move(E), Filename, C, ArchFlags.size() > 1 ? 1899 StringRef(I->getArchFlagName()) : StringRef()); 1900 } 1901 continue; 1902 } 1903 if (SymbolicFile *O = 1904 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1905 if (PrintFileName) { 1906 ArchiveName = A->getFileName(); 1907 if (ArchFlags.size() > 1) 1908 ArchitectureName = I->getArchFlagName(); 1909 } else { 1910 outs() << "\n" << A->getFileName(); 1911 outs() << "(" << O->getFileName() << ")"; 1912 if (ArchFlags.size() > 1) { 1913 outs() << " (for architecture " << I->getArchFlagName() 1914 << ")"; 1915 } 1916 outs() << ":\n"; 1917 } 1918 dumpSymbolNamesFromObject(*O, false, ArchiveName, 1919 ArchitectureName); 1920 } 1921 } 1922 if (Err) 1923 error(std::move(Err), A->getFileName()); 1924 } else { 1925 consumeError(AOrErr.takeError()); 1926 error(Filename + " for architecture " + 1927 StringRef(I->getArchFlagName()) + 1928 " is not a Mach-O file or an archive file", 1929 "Mach-O universal file"); 1930 } 1931 } 1932 } 1933 if (!ArchFound) { 1934 error(ArchFlags[i], 1935 "file: " + Filename + " does not contain architecture"); 1936 return; 1937 } 1938 } 1939 return; 1940 } 1941 // No architecture flags were specified so if this contains a slice that 1942 // matches the host architecture dump only that. 1943 if (!ArchAll) { 1944 Triple HostTriple = MachOObjectFile::getHostArch(); 1945 StringRef HostArchName = HostTriple.getArchName(); 1946 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1947 E = UB->end_objects(); 1948 I != E; ++I) { 1949 if (HostArchName == I->getArchFlagName()) { 1950 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1951 std::string ArchiveName; 1952 if (ObjOrErr) { 1953 ObjectFile &Obj = *ObjOrErr.get(); 1954 dumpSymbolNamesFromObject(Obj, false); 1955 } else if (auto E = isNotObjectErrorInvalidFileType( 1956 ObjOrErr.takeError())) { 1957 error(std::move(E), Filename); 1958 return; 1959 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 1960 I->getAsArchive()) { 1961 std::unique_ptr<Archive> &A = *AOrErr; 1962 Error Err = Error::success(); 1963 for (auto &C : A->children(Err)) { 1964 Expected<std::unique_ptr<Binary>> ChildOrErr = 1965 C.getAsBinary(ContextPtr); 1966 if (!ChildOrErr) { 1967 if (auto E = isNotObjectErrorInvalidFileType( 1968 ChildOrErr.takeError())) 1969 error(std::move(E), Filename, C); 1970 continue; 1971 } 1972 if (SymbolicFile *O = 1973 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1974 if (PrintFileName) 1975 ArchiveName = A->getFileName(); 1976 else 1977 outs() << "\n" << A->getFileName() << "(" << O->getFileName() 1978 << ")" 1979 << ":\n"; 1980 dumpSymbolNamesFromObject(*O, false, ArchiveName); 1981 } 1982 } 1983 if (Err) 1984 error(std::move(Err), A->getFileName()); 1985 } else { 1986 consumeError(AOrErr.takeError()); 1987 error(Filename + " for architecture " + 1988 StringRef(I->getArchFlagName()) + 1989 " is not a Mach-O file or an archive file", 1990 "Mach-O universal file"); 1991 } 1992 return; 1993 } 1994 } 1995 } 1996 // Either all architectures have been specified or none have been specified 1997 // and this does not contain the host architecture so dump all the slices. 1998 bool moreThanOneArch = UB->getNumberOfObjects() > 1; 1999 for (const MachOUniversalBinary::ObjectForArch &O : UB->objects()) { 2000 Expected<std::unique_ptr<ObjectFile>> ObjOrErr = O.getAsObjectFile(); 2001 std::string ArchiveName; 2002 std::string ArchitectureName; 2003 ArchiveName.clear(); 2004 ArchitectureName.clear(); 2005 if (ObjOrErr) { 2006 ObjectFile &Obj = *ObjOrErr.get(); 2007 if (PrintFileName) { 2008 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 2009 ArchitectureName = O.getArchFlagName(); 2010 } else { 2011 if (moreThanOneArch) 2012 outs() << "\n"; 2013 outs() << Obj.getFileName(); 2014 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 2015 outs() << " (for architecture " << O.getArchFlagName() << ")"; 2016 outs() << ":\n"; 2017 } 2018 dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); 2019 } else if (auto E = isNotObjectErrorInvalidFileType( 2020 ObjOrErr.takeError())) { 2021 error(std::move(E), Filename, moreThanOneArch ? 2022 StringRef(O.getArchFlagName()) : StringRef()); 2023 continue; 2024 } else if (Expected<std::unique_ptr<Archive>> AOrErr = 2025 O.getAsArchive()) { 2026 std::unique_ptr<Archive> &A = *AOrErr; 2027 Error Err = Error::success(); 2028 for (auto &C : A->children(Err)) { 2029 Expected<std::unique_ptr<Binary>> ChildOrErr = 2030 C.getAsBinary(ContextPtr); 2031 if (!ChildOrErr) { 2032 if (auto E = isNotObjectErrorInvalidFileType( 2033 ChildOrErr.takeError())) 2034 error(std::move(E), Filename, C, moreThanOneArch ? 2035 StringRef(ArchitectureName) : StringRef()); 2036 continue; 2037 } 2038 if (SymbolicFile *F = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 2039 if (PrintFileName) { 2040 ArchiveName = A->getFileName(); 2041 if (isa<MachOObjectFile>(F) && moreThanOneArch) 2042 ArchitectureName = O.getArchFlagName(); 2043 } else { 2044 outs() << "\n" << A->getFileName(); 2045 if (isa<MachOObjectFile>(F)) { 2046 outs() << "(" << F->getFileName() << ")"; 2047 if (moreThanOneArch) 2048 outs() << " (for architecture " << O.getArchFlagName() 2049 << ")"; 2050 } else 2051 outs() << ":" << F->getFileName(); 2052 outs() << ":\n"; 2053 } 2054 dumpSymbolNamesFromObject(*F, false, ArchiveName, ArchitectureName); 2055 } 2056 } 2057 if (Err) 2058 error(std::move(Err), A->getFileName()); 2059 } else { 2060 consumeError(AOrErr.takeError()); 2061 error(Filename + " for architecture " + 2062 StringRef(O.getArchFlagName()) + 2063 " is not a Mach-O file or an archive file", 2064 "Mach-O universal file"); 2065 } 2066 } 2067 return; 2068 } 2069 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { 2070 if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) { 2071 WithColor::warning(errs(), ToolName) 2072 << "sizes with --print-size for Mach-O files are always zero.\n"; 2073 MachOPrintSizeWarning = true; 2074 } 2075 if (!checkMachOAndArchFlags(O, Filename)) 2076 return; 2077 dumpSymbolNamesFromObject(*O, true); 2078 } 2079 } 2080 2081 int main(int argc, char **argv) { 2082 InitLLVM X(argc, argv); 2083 cl::HideUnrelatedOptions(NMCat); 2084 cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 2085 2086 // llvm-nm only reads binary files. 2087 if (error(sys::ChangeStdinToBinary())) 2088 return 1; 2089 2090 // These calls are needed so that we can read bitcode correctly. 2091 llvm::InitializeAllTargetInfos(); 2092 llvm::InitializeAllTargetMCs(); 2093 llvm::InitializeAllAsmParsers(); 2094 2095 ToolName = argv[0]; 2096 if (BSDFormat) 2097 OutputFormat = bsd; 2098 if (POSIXFormat) 2099 OutputFormat = posix; 2100 if (DarwinFormat) 2101 OutputFormat = darwin; 2102 2103 // The relative order of these is important. If you pass --size-sort it should 2104 // only print out the size. However, if you pass -S --size-sort, it should 2105 // print out both the size and address. 2106 if (SizeSort && !PrintSize) 2107 PrintAddress = false; 2108 if (OutputFormat == sysv || SizeSort) 2109 PrintSize = true; 2110 if (InputFilenames.empty()) 2111 InputFilenames.push_back("a.out"); 2112 if (InputFilenames.size() > 1) 2113 MultipleFiles = true; 2114 2115 // If both --demangle and --no-demangle are specified then pick the last one. 2116 if (NoDemangle.getPosition() > Demangle.getPosition()) 2117 Demangle = !NoDemangle; 2118 2119 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 2120 if (ArchFlags[i] == "all") { 2121 ArchAll = true; 2122 } else { 2123 if (!MachOObjectFile::isValidArch(ArchFlags[i])) 2124 error("Unknown architecture named '" + ArchFlags[i] + "'", 2125 "for the --arch option"); 2126 } 2127 } 2128 2129 if (!SegSect.empty() && SegSect.size() != 2) 2130 error("bad number of arguments (must be two arguments)", 2131 "for the -s option"); 2132 2133 if (NoDyldInfo && (AddDyldInfo || DyldInfoOnly)) 2134 error("--no-dyldinfo can't be used with --add-dyldinfo or --dyldinfo-only"); 2135 2136 llvm::for_each(InputFilenames, dumpSymbolNamesFromFile); 2137 2138 if (HadError) 2139 return 1; 2140 } 2141