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