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