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