1//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This program is a utility that works like traditional Unix "nm", that is, it 11// prints out the names of symbols in a bitcode or object file, along with some 12// information about each symbol. 13// 14// This "nm" supports many of the features of GNU "nm", including its different 15// output formats. 16// 17//===----------------------------------------------------------------------===// 18 19#include "llvm/IR/Function.h" 20#include "llvm/IR/GlobalAlias.h" 21#include "llvm/IR/GlobalVariable.h" 22#include "llvm/IR/LLVMContext.h" 23#include "llvm/Object/Archive.h" 24#include "llvm/Object/COFF.h" 25#include "llvm/Object/ELFObjectFile.h" 26#include "llvm/Object/IRObjectFile.h" 27#include "llvm/Object/MachO.h" 28#include "llvm/Object/MachOUniversal.h" 29#include "llvm/Object/ObjectFile.h" 30#include "llvm/Support/COFF.h" 31#include "llvm/Support/CommandLine.h" 32#include "llvm/Support/FileSystem.h" 33#include "llvm/Support/Format.h" 34#include "llvm/Support/ManagedStatic.h" 35#include "llvm/Support/MemoryBuffer.h" 36#include "llvm/Support/PrettyStackTrace.h" 37#include "llvm/Support/Program.h" 38#include "llvm/Support/Signals.h" 39#include "llvm/Support/TargetSelect.h" 40#include "llvm/Support/raw_ostream.h" 41#include <algorithm> 42#include <cctype> 43#include <cerrno> 44#include <cstring> 45#include <system_error> 46#include <vector> 47using namespace llvm; 48using namespace object; 49 50namespace { 51enum OutputFormatTy { bsd, sysv, posix, darwin }; 52cl::opt<OutputFormatTy> OutputFormat( 53 "format", cl::desc("Specify output format"), 54 cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"), 55 clEnumVal(posix, "POSIX.2 format"), 56 clEnumVal(darwin, "Darwin -m format"), clEnumValEnd), 57 cl::init(bsd)); 58cl::alias OutputFormat2("f", cl::desc("Alias for --format"), 59 cl::aliasopt(OutputFormat)); 60 61cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"), 62 cl::ZeroOrMore); 63 64cl::opt<bool> UndefinedOnly("undefined-only", 65 cl::desc("Show only undefined symbols")); 66cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), 67 cl::aliasopt(UndefinedOnly)); 68 69cl::opt<bool> DynamicSyms("dynamic", 70 cl::desc("Display the dynamic symbols instead " 71 "of normal symbols.")); 72cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"), 73 cl::aliasopt(DynamicSyms)); 74 75cl::opt<bool> DefinedOnly("defined-only", 76 cl::desc("Show only defined symbols")); 77cl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"), 78 cl::aliasopt(DefinedOnly)); 79 80cl::opt<bool> ExternalOnly("extern-only", 81 cl::desc("Show only external symbols")); 82cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"), 83 cl::aliasopt(ExternalOnly)); 84 85cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd")); 86cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix")); 87cl::opt<bool> DarwinFormat("m", cl::desc("Alias for --format=darwin")); 88 89static cl::list<std::string> 90 ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), 91 cl::ZeroOrMore); 92bool ArchAll = false; 93 94cl::opt<bool> PrintFileName( 95 "print-file-name", 96 cl::desc("Precede each symbol with the object file it came from")); 97 98cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"), 99 cl::aliasopt(PrintFileName)); 100cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"), 101 cl::aliasopt(PrintFileName)); 102 103cl::opt<bool> DebugSyms("debug-syms", 104 cl::desc("Show all symbols, even debugger only")); 105cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"), 106 cl::aliasopt(DebugSyms)); 107 108cl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address")); 109cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"), 110 cl::aliasopt(NumericSort)); 111cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"), 112 cl::aliasopt(NumericSort)); 113 114cl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered")); 115cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort)); 116 117cl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order")); 118cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"), 119 cl::aliasopt(ReverseSort)); 120 121cl::opt<bool> PrintSize("print-size", 122 cl::desc("Show symbol size instead of address")); 123cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"), 124 cl::aliasopt(PrintSize)); 125 126cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size")); 127 128cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden, 129 cl::desc("Exclude aliases from output")); 130 131cl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map")); 132cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"), 133 cl::aliasopt(ArchiveMap)); 134 135cl::opt<bool> JustSymbolName("just-symbol-name", 136 cl::desc("Print just the symbol's name")); 137cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"), 138 cl::aliasopt(JustSymbolName)); 139 140// FIXME: This option takes exactly two strings and should be allowed anywhere 141// on the command line. Such that "llvm-nm -s __TEXT __text foo.o" would work. 142// But that does not as the CommandLine Library does not have a way to make 143// this work. For now the "-s __TEXT __text" has to be last on the command 144// line. 145cl::list<std::string> SegSect("s", cl::Positional, cl::ZeroOrMore, 146 cl::desc("Dump only symbols from this segment " 147 "and section name, Mach-O only")); 148 149cl::opt<bool> FormatMachOasHex("x", cl::desc("Print symbol entry in hex, " 150 "Mach-O only")); 151 152cl::opt<bool> NoLLVMBitcode("no-llvm-bc", 153 cl::desc("Disable LLVM bitcode reader")); 154 155bool PrintAddress = true; 156 157bool MultipleFiles = false; 158 159bool HadError = false; 160 161std::string ToolName; 162} 163 164static void error(Twine Message, Twine Path = Twine()) { 165 HadError = true; 166 errs() << ToolName << ": " << Path << ": " << Message << ".\n"; 167} 168 169static bool error(std::error_code EC, Twine Path = Twine()) { 170 if (EC) { 171 error(EC.message(), Path); 172 return true; 173 } 174 return false; 175} 176 177namespace { 178struct NMSymbol { 179 uint64_t Address; 180 uint64_t Size; 181 char TypeChar; 182 StringRef Name; 183 DataRefImpl Symb; 184}; 185} 186 187static bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) { 188 if (!ReverseSort) { 189 if (A.Address < B.Address) 190 return true; 191 if (A.Address == B.Address && A.Name < B.Name) 192 return true; 193 if (A.Address == B.Address && A.Name == B.Name && A.Size < B.Size) 194 return true; 195 return false; 196 } 197 198 if (A.Address > B.Address) 199 return true; 200 if (A.Address == B.Address && A.Name > B.Name) 201 return true; 202 if (A.Address == B.Address && A.Name == B.Name && A.Size > B.Size) 203 return true; 204 return false; 205} 206 207static bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) { 208 if (!ReverseSort) { 209 if (A.Size < B.Size) 210 return true; 211 if (A.Size == B.Size && A.Name < B.Name) 212 return true; 213 if (A.Size == B.Size && A.Name == B.Name && A.Address < B.Address) 214 return true; 215 return false; 216 } 217 218 if (A.Size > B.Size) 219 return true; 220 if (A.Size == B.Size && A.Name > B.Name) 221 return true; 222 if (A.Size == B.Size && A.Name == B.Name && A.Address > B.Address) 223 return true; 224 return false; 225} 226 227static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) { 228 if (!ReverseSort) { 229 if (A.Name < B.Name) 230 return true; 231 if (A.Name == B.Name && A.Size < B.Size) 232 return true; 233 if (A.Name == B.Name && A.Size == B.Size && A.Address < B.Address) 234 return true; 235 return false; 236 } 237 if (A.Name > B.Name) 238 return true; 239 if (A.Name == B.Name && A.Size > B.Size) 240 return true; 241 if (A.Name == B.Name && A.Size == B.Size && A.Address > B.Address) 242 return true; 243 return false; 244} 245 246static char isSymbolList64Bit(SymbolicFile &Obj) { 247 if (isa<IRObjectFile>(Obj)) 248 return false; 249 if (isa<COFFObjectFile>(Obj)) 250 return false; 251 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) 252 return MachO->is64Bit(); 253 if (isa<ELF32LEObjectFile>(Obj)) 254 return false; 255 if (isa<ELF64LEObjectFile>(Obj)) 256 return true; 257 if (isa<ELF32BEObjectFile>(Obj)) 258 return false; 259 if (isa<ELF64BEObjectFile>(Obj)) 260 return true; 261 return false; 262} 263 264static StringRef CurrentFilename; 265typedef std::vector<NMSymbol> SymbolListT; 266static SymbolListT SymbolList; 267 268// darwinPrintSymbol() is used to print a symbol from a Mach-O file when the 269// the OutputFormat is darwin or we are printing Mach-O symbols in hex. For 270// the darwin format it produces the same output as darwin's nm(1) -m output 271// and when printing Mach-O symbols in hex it produces the same output as 272// darwin's nm(1) -x format. 273static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, 274 char *SymbolAddrStr, const char *printBlanks) { 275 MachO::mach_header H; 276 MachO::mach_header_64 H_64; 277 uint32_t Filetype, Flags; 278 MachO::nlist_64 STE_64; 279 MachO::nlist STE; 280 uint8_t NType; 281 uint8_t NSect; 282 uint16_t NDesc; 283 uint32_t NStrx; 284 uint64_t NValue; 285 if (MachO->is64Bit()) { 286 H_64 = MachO->MachOObjectFile::getHeader64(); 287 Filetype = H_64.filetype; 288 Flags = H_64.flags; 289 STE_64 = MachO->getSymbol64TableEntry(I->Symb); 290 NType = STE_64.n_type; 291 NSect = STE_64.n_sect; 292 NDesc = STE_64.n_desc; 293 NStrx = STE_64.n_strx; 294 NValue = STE_64.n_value; 295 } else { 296 H = MachO->MachOObjectFile::getHeader(); 297 Filetype = H.filetype; 298 Flags = H.flags; 299 STE = MachO->getSymbolTableEntry(I->Symb); 300 NType = STE.n_type; 301 NSect = STE.n_sect; 302 NDesc = STE.n_desc; 303 NStrx = STE.n_strx; 304 NValue = STE.n_value; 305 } 306 307 // If we are printing Mach-O symbols in hex do that and return. 308 if (FormatMachOasHex) { 309 char Str[18] = ""; 310 const char *printFormat; 311 if (MachO->is64Bit()) 312 printFormat = "%016" PRIx64; 313 else 314 printFormat = "%08" PRIx64; 315 format(printFormat, NValue).print(Str, sizeof(Str)); 316 outs() << Str << ' '; 317 format("%02x", NType).print(Str, sizeof(Str)); 318 outs() << Str << ' '; 319 format("%02x", NSect).print(Str, sizeof(Str)); 320 outs() << Str << ' '; 321 format("%04x", NDesc).print(Str, sizeof(Str)); 322 outs() << Str << ' '; 323 format("%08x", NStrx).print(Str, sizeof(Str)); 324 outs() << Str << ' '; 325 outs() << I->Name << "\n"; 326 return; 327 } 328 329 if (PrintAddress) { 330 if ((NType & MachO::N_TYPE) == MachO::N_INDR) 331 strcpy(SymbolAddrStr, printBlanks); 332 outs() << SymbolAddrStr << ' '; 333 } 334 335 switch (NType & MachO::N_TYPE) { 336 case MachO::N_UNDF: 337 if (NValue != 0) { 338 outs() << "(common) "; 339 if (MachO::GET_COMM_ALIGN(NDesc) != 0) 340 outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") "; 341 } else { 342 if ((NType & MachO::N_TYPE) == MachO::N_PBUD) 343 outs() << "(prebound "; 344 else 345 outs() << "("; 346 if ((NDesc & MachO::REFERENCE_TYPE) == 347 MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 348 outs() << "undefined [lazy bound]) "; 349 else if ((NDesc & MachO::REFERENCE_TYPE) == 350 MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 351 outs() << "undefined [private lazy bound]) "; 352 else if ((NDesc & MachO::REFERENCE_TYPE) == 353 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) 354 outs() << "undefined [private]) "; 355 else 356 outs() << "undefined) "; 357 } 358 break; 359 case MachO::N_ABS: 360 outs() << "(absolute) "; 361 break; 362 case MachO::N_INDR: 363 outs() << "(indirect) "; 364 break; 365 case MachO::N_SECT: { 366 section_iterator Sec = MachO->section_end(); 367 MachO->getSymbolSection(I->Symb, Sec); 368 DataRefImpl Ref = Sec->getRawDataRefImpl(); 369 StringRef SectionName; 370 MachO->getSectionName(Ref, SectionName); 371 StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref); 372 outs() << "(" << SegmentName << "," << SectionName << ") "; 373 break; 374 } 375 default: 376 outs() << "(?) "; 377 break; 378 } 379 380 if (NType & MachO::N_EXT) { 381 if (NDesc & MachO::REFERENCED_DYNAMICALLY) 382 outs() << "[referenced dynamically] "; 383 if (NType & MachO::N_PEXT) { 384 if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) 385 outs() << "weak private external "; 386 else 387 outs() << "private external "; 388 } else { 389 if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF || 390 (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) { 391 if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) == 392 (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 393 outs() << "weak external automatically hidden "; 394 else 395 outs() << "weak external "; 396 } else 397 outs() << "external "; 398 } 399 } else { 400 if (NType & MachO::N_PEXT) 401 outs() << "non-external (was a private external) "; 402 else 403 outs() << "non-external "; 404 } 405 406 if (Filetype == MachO::MH_OBJECT && 407 (NDesc & MachO::N_NO_DEAD_STRIP) == MachO::N_NO_DEAD_STRIP) 408 outs() << "[no dead strip] "; 409 410 if (Filetype == MachO::MH_OBJECT && 411 ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 412 (NDesc & MachO::N_SYMBOL_RESOLVER) == MachO::N_SYMBOL_RESOLVER) 413 outs() << "[symbol resolver] "; 414 415 if (Filetype == MachO::MH_OBJECT && 416 ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 417 (NDesc & MachO::N_ALT_ENTRY) == MachO::N_ALT_ENTRY) 418 outs() << "[alt entry] "; 419 420 if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF) 421 outs() << "[Thumb] "; 422 423 if ((NType & MachO::N_TYPE) == MachO::N_INDR) { 424 outs() << I->Name << " (for "; 425 StringRef IndirectName; 426 if (MachO->getIndirectName(I->Symb, IndirectName)) 427 outs() << "?)"; 428 else 429 outs() << IndirectName << ")"; 430 } else 431 outs() << I->Name; 432 433 if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL && 434 (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) || 435 (NType & MachO::N_TYPE) == MachO::N_PBUD)) { 436 uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc); 437 if (LibraryOrdinal != 0) { 438 if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL) 439 outs() << " (from executable)"; 440 else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL) 441 outs() << " (dynamically looked up)"; 442 else { 443 StringRef LibraryName; 444 if (MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName)) 445 outs() << " (from bad library ordinal " << LibraryOrdinal << ")"; 446 else 447 outs() << " (from " << LibraryName << ")"; 448 } 449 } 450 } 451 452 outs() << "\n"; 453} 454 455// Table that maps Darwin's Mach-O stab constants to strings to allow printing. 456struct DarwinStabName { 457 uint8_t NType; 458 const char *Name; 459}; 460static const struct DarwinStabName DarwinStabNames[] = { 461 {MachO::N_GSYM, "GSYM"}, 462 {MachO::N_FNAME, "FNAME"}, 463 {MachO::N_FUN, "FUN"}, 464 {MachO::N_STSYM, "STSYM"}, 465 {MachO::N_LCSYM, "LCSYM"}, 466 {MachO::N_BNSYM, "BNSYM"}, 467 {MachO::N_PC, "PC"}, 468 {MachO::N_AST, "AST"}, 469 {MachO::N_OPT, "OPT"}, 470 {MachO::N_RSYM, "RSYM"}, 471 {MachO::N_SLINE, "SLINE"}, 472 {MachO::N_ENSYM, "ENSYM"}, 473 {MachO::N_SSYM, "SSYM"}, 474 {MachO::N_SO, "SO"}, 475 {MachO::N_OSO, "OSO"}, 476 {MachO::N_LSYM, "LSYM"}, 477 {MachO::N_BINCL, "BINCL"}, 478 {MachO::N_SOL, "SOL"}, 479 {MachO::N_PARAMS, "PARAM"}, 480 {MachO::N_VERSION, "VERS"}, 481 {MachO::N_OLEVEL, "OLEV"}, 482 {MachO::N_PSYM, "PSYM"}, 483 {MachO::N_EINCL, "EINCL"}, 484 {MachO::N_ENTRY, "ENTRY"}, 485 {MachO::N_LBRAC, "LBRAC"}, 486 {MachO::N_EXCL, "EXCL"}, 487 {MachO::N_RBRAC, "RBRAC"}, 488 {MachO::N_BCOMM, "BCOMM"}, 489 {MachO::N_ECOMM, "ECOMM"}, 490 {MachO::N_ECOML, "ECOML"}, 491 {MachO::N_LENG, "LENG"}, 492 {0, 0}}; 493static const char *getDarwinStabString(uint8_t NType) { 494 for (unsigned i = 0; DarwinStabNames[i].Name; i++) { 495 if (DarwinStabNames[i].NType == NType) 496 return DarwinStabNames[i].Name; 497 } 498 return 0; 499} 500 501// darwinPrintStab() prints the n_sect, n_desc along with a symbolic name of 502// a stab n_type value in a Mach-O file. 503static void darwinPrintStab(MachOObjectFile *MachO, SymbolListT::iterator I) { 504 MachO::nlist_64 STE_64; 505 MachO::nlist STE; 506 uint8_t NType; 507 uint8_t NSect; 508 uint16_t NDesc; 509 if (MachO->is64Bit()) { 510 STE_64 = MachO->getSymbol64TableEntry(I->Symb); 511 NType = STE_64.n_type; 512 NSect = STE_64.n_sect; 513 NDesc = STE_64.n_desc; 514 } else { 515 STE = MachO->getSymbolTableEntry(I->Symb); 516 NType = STE.n_type; 517 NSect = STE.n_sect; 518 NDesc = STE.n_desc; 519 } 520 521 char Str[18] = ""; 522 format("%02x", NSect).print(Str, sizeof(Str)); 523 outs() << ' ' << Str << ' '; 524 format("%04x", NDesc).print(Str, sizeof(Str)); 525 outs() << Str << ' '; 526 if (const char *stabString = getDarwinStabString(NType)) 527 format("%5.5s", stabString).print(Str, sizeof(Str)); 528 else 529 format(" %02x", NType).print(Str, sizeof(Str)); 530 outs() << Str; 531} 532 533static void sortAndPrintSymbolList(SymbolicFile &Obj, bool printName, 534 std::string ArchiveName, 535 std::string ArchitectureName) { 536 if (!NoSort) { 537 if (NumericSort) 538 std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolAddress); 539 else if (SizeSort) 540 std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolSize); 541 else 542 std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolName); 543 } 544 545 if (!PrintFileName) { 546 if (OutputFormat == posix && MultipleFiles && printName) { 547 outs() << '\n' << CurrentFilename << ":\n"; 548 } else if (OutputFormat == bsd && MultipleFiles && printName) { 549 outs() << "\n" << CurrentFilename << ":\n"; 550 } else if (OutputFormat == sysv) { 551 outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n" 552 << "Name Value Class Type" 553 << " Size Line Section\n"; 554 } 555 } 556 557 const char *printBlanks, *printFormat; 558 if (isSymbolList64Bit(Obj)) { 559 printBlanks = " "; 560 printFormat = "%016" PRIx64; 561 } else { 562 printBlanks = " "; 563 printFormat = "%08" PRIx64; 564 } 565 566 for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end(); 567 I != E; ++I) { 568 if ((I->TypeChar != 'U') && UndefinedOnly) 569 continue; 570 if ((I->TypeChar == 'U') && DefinedOnly) 571 continue; 572 if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize) 573 continue; 574 if (PrintFileName) { 575 if (!ArchitectureName.empty()) 576 outs() << "(for architecture " << ArchitectureName << "):"; 577 if (!ArchiveName.empty()) 578 outs() << ArchiveName << ":"; 579 outs() << CurrentFilename << ": "; 580 } 581 if (JustSymbolName || (UndefinedOnly && isa<MachOObjectFile>(Obj))) { 582 outs() << I->Name << "\n"; 583 continue; 584 } 585 586 char SymbolAddrStr[18] = ""; 587 char SymbolSizeStr[18] = ""; 588 589 if (OutputFormat == sysv || I->Address == UnknownAddressOrSize) 590 strcpy(SymbolAddrStr, printBlanks); 591 if (OutputFormat == sysv) 592 strcpy(SymbolSizeStr, printBlanks); 593 594 if (I->Address != UnknownAddressOrSize) 595 format(printFormat, I->Address) 596 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 597 if (I->Size != UnknownAddressOrSize) 598 format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 599 600 // If OutputFormat is darwin or we are printing Mach-O symbols in hex and 601 // we have a MachOObjectFile, call darwinPrintSymbol to print as darwin's 602 // nm(1) -m output or hex, else if OutputFormat is darwin or we are 603 // printing Mach-O symbols in hex and not a Mach-O object fall back to 604 // OutputFormat bsd (see below). 605 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 606 if ((OutputFormat == darwin || FormatMachOasHex) && MachO) { 607 darwinPrintSymbol(MachO, I, SymbolAddrStr, printBlanks); 608 } else if (OutputFormat == posix) { 609 outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr 610 << SymbolSizeStr << "\n"; 611 } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) { 612 if (PrintAddress) 613 outs() << SymbolAddrStr << ' '; 614 if (PrintSize) { 615 outs() << SymbolSizeStr; 616 if (I->Size != UnknownAddressOrSize) 617 outs() << ' '; 618 } 619 outs() << I->TypeChar; 620 if (I->TypeChar == '-' && MachO) 621 darwinPrintStab(MachO, I); 622 outs() << " " << I->Name << "\n"; 623 } else if (OutputFormat == sysv) { 624 std::string PaddedName(I->Name); 625 while (PaddedName.length() < 20) 626 PaddedName += " "; 627 outs() << PaddedName << "|" << SymbolAddrStr << "| " << I->TypeChar 628 << " | |" << SymbolSizeStr << "| |\n"; 629 } 630 } 631 632 SymbolList.clear(); 633} 634 635template <class ELFT> 636static char getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, 637 basic_symbol_iterator I) { 638 typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; 639 typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; 640 641 // OK, this is ELF 642 symbol_iterator SymI(I); 643 644 DataRefImpl Symb = I->getRawDataRefImpl(); 645 const Elf_Sym *ESym = Obj.getSymbol(Symb); 646 const ELFFile<ELFT> &EF = *Obj.getELFFile(); 647 const Elf_Shdr *ESec = EF.getSection(ESym); 648 649 if (ESec) { 650 switch (ESec->sh_type) { 651 case ELF::SHT_PROGBITS: 652 case ELF::SHT_DYNAMIC: 653 switch (ESec->sh_flags) { 654 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 655 return 't'; 656 case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): 657 case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 658 return 'd'; 659 case ELF::SHF_ALLOC: 660 case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 661 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 662 return 'r'; 663 } 664 break; 665 case ELF::SHT_NOBITS: 666 return 'b'; 667 } 668 } 669 670 if (ESym->getType() == ELF::STT_SECTION) { 671 StringRef Name; 672 if (error(SymI->getName(Name))) 673 return '?'; 674 return StringSwitch<char>(Name) 675 .StartsWith(".debug", 'N') 676 .StartsWith(".note", 'n') 677 .Default('?'); 678 } 679 680 return '?'; 681} 682 683static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { 684 COFFSymbolRef Symb = Obj.getCOFFSymbol(*I); 685 // OK, this is COFF. 686 symbol_iterator SymI(I); 687 688 StringRef Name; 689 if (error(SymI->getName(Name))) 690 return '?'; 691 692 char Ret = StringSwitch<char>(Name) 693 .StartsWith(".debug", 'N') 694 .StartsWith(".sxdata", 'N') 695 .Default('?'); 696 697 if (Ret != '?') 698 return Ret; 699 700 uint32_t Characteristics = 0; 701 if (!COFF::isReservedSectionNumber(Symb.getSectionNumber())) { 702 section_iterator SecI = Obj.section_end(); 703 if (error(SymI->getSection(SecI))) 704 return '?'; 705 const coff_section *Section = Obj.getCOFFSection(*SecI); 706 Characteristics = Section->Characteristics; 707 } 708 709 switch (Symb.getSectionNumber()) { 710 case COFF::IMAGE_SYM_DEBUG: 711 return 'n'; 712 default: 713 // Check section type. 714 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 715 return 't'; 716 if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 717 return Characteristics & COFF::IMAGE_SCN_MEM_WRITE ? 'd' : 'r'; 718 if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 719 return 'b'; 720 if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 721 return 'i'; 722 // Check for section symbol. 723 if (Symb.isSectionDefinition()) 724 return 's'; 725 } 726 727 return '?'; 728} 729 730static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { 731 if (Obj.is64Bit()) { 732 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 733 return STE.n_type; 734 } 735 MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 736 return STE.n_type; 737} 738 739static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { 740 DataRefImpl Symb = I->getRawDataRefImpl(); 741 uint8_t NType = getNType(Obj, Symb); 742 743 if (NType & MachO::N_STAB) 744 return '-'; 745 746 switch (NType & MachO::N_TYPE) { 747 case MachO::N_ABS: 748 return 's'; 749 case MachO::N_INDR: 750 return 'i'; 751 case MachO::N_SECT: { 752 section_iterator Sec = Obj.section_end(); 753 Obj.getSymbolSection(Symb, Sec); 754 DataRefImpl Ref = Sec->getRawDataRefImpl(); 755 StringRef SectionName; 756 Obj.getSectionName(Ref, SectionName); 757 StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); 758 if (SegmentName == "__TEXT" && SectionName == "__text") 759 return 't'; 760 else if (SegmentName == "__DATA" && SectionName == "__data") 761 return 'd'; 762 else if (SegmentName == "__DATA" && SectionName == "__bss") 763 return 'b'; 764 else 765 return 's'; 766 } 767 } 768 769 return '?'; 770} 771 772static char getSymbolNMTypeChar(const GlobalValue &GV) { 773 if (GV.getType()->getElementType()->isFunctionTy()) 774 return 't'; 775 // FIXME: should we print 'b'? At the IR level we cannot be sure if this 776 // will be in bss or not, but we could approximate. 777 return 'd'; 778} 779 780static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { 781 const GlobalValue *GV = Obj.getSymbolGV(I->getRawDataRefImpl()); 782 if (!GV) 783 return 't'; 784 return getSymbolNMTypeChar(*GV); 785} 786 787template <class ELFT> 788static bool isELFObject(ELFObjectFile<ELFT> &Obj, symbol_iterator I) { 789 typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; 790 791 DataRefImpl Symb = I->getRawDataRefImpl(); 792 const Elf_Sym *ESym = Obj.getSymbol(Symb); 793 794 return ESym->getType() == ELF::STT_OBJECT; 795} 796 797static bool isObject(SymbolicFile &Obj, basic_symbol_iterator I) { 798 if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(&Obj)) 799 return isELFObject(*ELF, I); 800 if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(&Obj)) 801 return isELFObject(*ELF, I); 802 if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(&Obj)) 803 return isELFObject(*ELF, I); 804 if (ELF64BEObjectFile *ELF = dyn_cast<ELF64BEObjectFile>(&Obj)) 805 return isELFObject(*ELF, I); 806 return false; 807} 808 809static char getNMTypeChar(SymbolicFile &Obj, basic_symbol_iterator I) { 810 uint32_t Symflags = I->getFlags(); 811 if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) { 812 char Ret = isObject(Obj, I) ? 'v' : 'w'; 813 if (!(Symflags & object::SymbolRef::SF_Undefined)) 814 Ret = toupper(Ret); 815 return Ret; 816 } 817 818 if (Symflags & object::SymbolRef::SF_Undefined) 819 return 'U'; 820 821 if (Symflags & object::SymbolRef::SF_Common) 822 return 'C'; 823 824 char Ret = '?'; 825 if (Symflags & object::SymbolRef::SF_Absolute) 826 Ret = 'a'; 827 else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) 828 Ret = getSymbolNMTypeChar(*IR, I); 829 else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(&Obj)) 830 Ret = getSymbolNMTypeChar(*COFF, I); 831 else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj)) 832 Ret = getSymbolNMTypeChar(*MachO, I); 833 else if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(&Obj)) 834 Ret = getSymbolNMTypeChar(*ELF, I); 835 else if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(&Obj)) 836 Ret = getSymbolNMTypeChar(*ELF, I); 837 else if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(&Obj)) 838 Ret = getSymbolNMTypeChar(*ELF, I); 839 else 840 Ret = getSymbolNMTypeChar(cast<ELF64BEObjectFile>(Obj), I); 841 842 if (Symflags & object::SymbolRef::SF_Global) 843 Ret = toupper(Ret); 844 845 return Ret; 846} 847 848// getNsectForSegSect() is used to implement the Mach-O "-s segname sectname" 849// option to dump only those symbols from that section in a Mach-O file. 850// It is called once for each Mach-O file from dumpSymbolNamesFromObject() 851// to get the section number for that named section from the command line 852// arguments. It returns the section number for that section in the Mach-O 853// file or zero it is not present. 854static unsigned getNsectForSegSect(MachOObjectFile *Obj) { 855 unsigned Nsect = 1; 856 for (section_iterator I = Obj->section_begin(), E = Obj->section_end(); 857 I != E; ++I) { 858 DataRefImpl Ref = I->getRawDataRefImpl(); 859 StringRef SectionName; 860 Obj->getSectionName(Ref, SectionName); 861 StringRef SegmentName = Obj->getSectionFinalSegmentName(Ref); 862 if (SegmentName == SegSect[0] && SectionName == SegSect[1]) 863 return Nsect; 864 Nsect++; 865 } 866 return 0; 867} 868 869// getNsectInMachO() is used to implement the Mach-O "-s segname sectname" 870// option to dump only those symbols from that section in a Mach-O file. 871// It is called once for each symbol in a Mach-O file from 872// dumpSymbolNamesFromObject() and returns the section number for that symbol 873// if it is in a section, else it returns 0. 874static unsigned getNsectInMachO(MachOObjectFile &Obj, basic_symbol_iterator I) { 875 DataRefImpl Symb = I->getRawDataRefImpl(); 876 if (Obj.is64Bit()) { 877 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 878 if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT) 879 return STE.n_sect; 880 return 0; 881 } 882 MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 883 if ((STE.n_type & MachO::N_TYPE) == MachO::N_SECT) 884 return STE.n_sect; 885 return 0; 886} 887 888static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, 889 std::string ArchiveName = std::string(), 890 std::string ArchitectureName = 891 std::string()) { 892 basic_symbol_iterator IBegin = Obj.symbol_begin(); 893 basic_symbol_iterator IEnd = Obj.symbol_end(); 894 if (DynamicSyms) { 895 if (!Obj.isELF()) { 896 error("File format has no dynamic symbol table", Obj.getFileName()); 897 return; 898 } 899 std::pair<symbol_iterator, symbol_iterator> IDyn = 900 getELFDynamicSymbolIterators(&Obj); 901 IBegin = IDyn.first; 902 IEnd = IDyn.second; 903 } 904 std::string NameBuffer; 905 raw_string_ostream OS(NameBuffer); 906 // If a "-s segname sectname" option was specified and this is a Mach-O 907 // file get the section number for that section in this object file. 908 unsigned int Nsect = 0; 909 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj); 910 if (SegSect.size() != 0 && MachO) { 911 Nsect = getNsectForSegSect(MachO); 912 // If this section is not in the object file no symbols are printed. 913 if (Nsect == 0) 914 return; 915 } 916 for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) { 917 uint32_t SymFlags = I->getFlags(); 918 if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) 919 continue; 920 if (WithoutAliases) { 921 if (IRObjectFile *IR = dyn_cast<IRObjectFile>(&Obj)) { 922 const GlobalValue *GV = IR->getSymbolGV(I->getRawDataRefImpl()); 923 if (GV && isa<GlobalAlias>(GV)) 924 continue; 925 } 926 } 927 // If a "-s segname sectname" option was specified and this is a Mach-O 928 // file and this section appears in this file, Nsect will be non-zero then 929 // see if this symbol is a symbol from that section and if not skip it. 930 if (Nsect && Nsect != getNsectInMachO(*MachO, I)) 931 continue; 932 NMSymbol S; 933 S.Size = UnknownAddressOrSize; 934 S.Address = UnknownAddressOrSize; 935 if ((PrintSize || SizeSort) && isa<ObjectFile>(Obj)) { 936 symbol_iterator SymI = I; 937 if (error(SymI->getSize(S.Size))) 938 break; 939 } 940 if (PrintAddress && isa<ObjectFile>(Obj)) 941 if (error(symbol_iterator(I)->getAddress(S.Address))) 942 break; 943 S.TypeChar = getNMTypeChar(Obj, I); 944 if (error(I->printName(OS))) 945 break; 946 OS << '\0'; 947 S.Symb = I->getRawDataRefImpl(); 948 SymbolList.push_back(S); 949 } 950 951 OS.flush(); 952 const char *P = NameBuffer.c_str(); 953 for (unsigned I = 0; I < SymbolList.size(); ++I) { 954 SymbolList[I].Name = P; 955 P += strlen(P) + 1; 956 } 957 958 CurrentFilename = Obj.getFileName(); 959 sortAndPrintSymbolList(Obj, printName, ArchiveName, ArchitectureName); 960} 961 962// checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file 963// and if it is and there is a list of architecture flags is specified then 964// check to make sure this Mach-O file is one of those architectures or all 965// architectures was specificed. If not then an error is generated and this 966// routine returns false. Else it returns true. 967static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) { 968 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O); 969 970 if (!MachO || ArchAll || ArchFlags.size() == 0) 971 return true; 972 973 MachO::mach_header H; 974 MachO::mach_header_64 H_64; 975 Triple T; 976 if (MachO->is64Bit()) { 977 H_64 = MachO->MachOObjectFile::getHeader64(); 978 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype); 979 } else { 980 H = MachO->MachOObjectFile::getHeader(); 981 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype); 982 } 983 if (std::none_of( 984 ArchFlags.begin(), ArchFlags.end(), 985 [&](const std::string &Name) { return Name == T.getArchName(); })) { 986 error("No architecture specified", Filename); 987 return false; 988 } 989 return true; 990} 991 992static void dumpSymbolNamesFromFile(std::string &Filename) { 993 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 994 MemoryBuffer::getFileOrSTDIN(Filename); 995 if (error(BufferOrErr.getError(), Filename)) 996 return; 997 998 LLVMContext &Context = getGlobalContext(); 999 ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary( 1000 BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context); 1001 if (error(BinaryOrErr.getError(), Filename)) 1002 return; 1003 Binary &Bin = *BinaryOrErr.get(); 1004 1005 if (Archive *A = dyn_cast<Archive>(&Bin)) { 1006 if (ArchiveMap) { 1007 Archive::symbol_iterator I = A->symbol_begin(); 1008 Archive::symbol_iterator E = A->symbol_end(); 1009 if (I != E) { 1010 outs() << "Archive map\n"; 1011 for (; I != E; ++I) { 1012 ErrorOr<Archive::child_iterator> C = I->getMember(); 1013 if (error(C.getError())) 1014 return; 1015 ErrorOr<StringRef> FileNameOrErr = C.get()->getName(); 1016 if (error(FileNameOrErr.getError())) 1017 return; 1018 StringRef SymName = I->getName(); 1019 outs() << SymName << " in " << FileNameOrErr.get() << "\n"; 1020 } 1021 outs() << "\n"; 1022 } 1023 } 1024 1025 for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); 1026 I != E; ++I) { 1027 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(&Context); 1028 if (ChildOrErr.getError()) 1029 continue; 1030 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1031 if (!checkMachOAndArchFlags(O, Filename)) 1032 return; 1033 if (!PrintFileName) { 1034 outs() << "\n"; 1035 if (isa<MachOObjectFile>(O)) { 1036 outs() << Filename << "(" << O->getFileName() << ")"; 1037 } else 1038 outs() << O->getFileName(); 1039 outs() << ":\n"; 1040 } 1041 dumpSymbolNamesFromObject(*O, false, Filename); 1042 } 1043 } 1044 return; 1045 } 1046 if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) { 1047 // If we have a list of architecture flags specified dump only those. 1048 if (!ArchAll && ArchFlags.size() != 0) { 1049 // Look for a slice in the universal binary that matches each ArchFlag. 1050 bool ArchFound; 1051 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1052 ArchFound = false; 1053 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1054 E = UB->end_objects(); 1055 I != E; ++I) { 1056 if (ArchFlags[i] == I->getArchTypeName()) { 1057 ArchFound = true; 1058 ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = 1059 I->getAsObjectFile(); 1060 std::string ArchiveName; 1061 std::string ArchitectureName; 1062 ArchiveName.clear(); 1063 ArchitectureName.clear(); 1064 if (ObjOrErr) { 1065 ObjectFile &Obj = *ObjOrErr.get(); 1066 if (ArchFlags.size() > 1) { 1067 if (PrintFileName) 1068 ArchitectureName = I->getArchTypeName(); 1069 else 1070 outs() << "\n" << Obj.getFileName() << " (for architecture " 1071 << I->getArchTypeName() << ")" 1072 << ":\n"; 1073 } 1074 dumpSymbolNamesFromObject(Obj, false, ArchiveName, 1075 ArchitectureName); 1076 } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = 1077 I->getAsArchive()) { 1078 std::unique_ptr<Archive> &A = *AOrErr; 1079 for (Archive::child_iterator AI = A->child_begin(), 1080 AE = A->child_end(); 1081 AI != AE; ++AI) { 1082 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 1083 AI->getAsBinary(&Context); 1084 if (ChildOrErr.getError()) 1085 continue; 1086 if (SymbolicFile *O = 1087 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1088 if (PrintFileName) { 1089 ArchiveName = A->getFileName(); 1090 if (ArchFlags.size() > 1) 1091 ArchitectureName = I->getArchTypeName(); 1092 } else { 1093 outs() << "\n" << A->getFileName(); 1094 outs() << "(" << O->getFileName() << ")"; 1095 if (ArchFlags.size() > 1) { 1096 outs() << " (for architecture " << I->getArchTypeName() 1097 << ")"; 1098 } 1099 outs() << ":\n"; 1100 } 1101 dumpSymbolNamesFromObject(*O, false, ArchiveName, 1102 ArchitectureName); 1103 } 1104 } 1105 } 1106 } 1107 } 1108 if (!ArchFound) { 1109 error(ArchFlags[i], 1110 "file: " + Filename + " does not contain architecture"); 1111 return; 1112 } 1113 } 1114 return; 1115 } 1116 // No architecture flags were specified so if this contains a slice that 1117 // matches the host architecture dump only that. 1118 if (!ArchAll) { 1119 StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); 1120 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1121 E = UB->end_objects(); 1122 I != E; ++I) { 1123 if (HostArchName == I->getArchTypeName()) { 1124 ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1125 std::string ArchiveName; 1126 ArchiveName.clear(); 1127 if (ObjOrErr) { 1128 ObjectFile &Obj = *ObjOrErr.get(); 1129 dumpSymbolNamesFromObject(Obj, false); 1130 } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = 1131 I->getAsArchive()) { 1132 std::unique_ptr<Archive> &A = *AOrErr; 1133 for (Archive::child_iterator AI = A->child_begin(), 1134 AE = A->child_end(); 1135 AI != AE; ++AI) { 1136 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 1137 AI->getAsBinary(&Context); 1138 if (ChildOrErr.getError()) 1139 continue; 1140 if (SymbolicFile *O = 1141 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1142 if (PrintFileName) 1143 ArchiveName = A->getFileName(); 1144 else 1145 outs() << "\n" << A->getFileName() << "(" << O->getFileName() 1146 << ")" 1147 << ":\n"; 1148 dumpSymbolNamesFromObject(*O, false, ArchiveName); 1149 } 1150 } 1151 } 1152 return; 1153 } 1154 } 1155 } 1156 // Either all architectures have been specified or none have been specified 1157 // and this does not contain the host architecture so dump all the slices. 1158 bool moreThanOneArch = UB->getNumberOfObjects() > 1; 1159 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 1160 E = UB->end_objects(); 1161 I != E; ++I) { 1162 ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 1163 std::string ArchiveName; 1164 std::string ArchitectureName; 1165 ArchiveName.clear(); 1166 ArchitectureName.clear(); 1167 if (ObjOrErr) { 1168 ObjectFile &Obj = *ObjOrErr.get(); 1169 if (PrintFileName) { 1170 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1171 ArchitectureName = I->getArchTypeName(); 1172 } else { 1173 if (moreThanOneArch) 1174 outs() << "\n"; 1175 outs() << Obj.getFileName(); 1176 if (isa<MachOObjectFile>(Obj) && moreThanOneArch) 1177 outs() << " (for architecture " << I->getArchTypeName() << ")"; 1178 outs() << ":\n"; 1179 } 1180 dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); 1181 } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { 1182 std::unique_ptr<Archive> &A = *AOrErr; 1183 for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); 1184 AI != AE; ++AI) { 1185 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 1186 AI->getAsBinary(&Context); 1187 if (ChildOrErr.getError()) 1188 continue; 1189 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 1190 if (PrintFileName) { 1191 ArchiveName = A->getFileName(); 1192 if (isa<MachOObjectFile>(O) && moreThanOneArch) 1193 ArchitectureName = I->getArchTypeName(); 1194 } else { 1195 outs() << "\n" << A->getFileName(); 1196 if (isa<MachOObjectFile>(O)) { 1197 outs() << "(" << O->getFileName() << ")"; 1198 if (moreThanOneArch) 1199 outs() << " (for architecture " << I->getArchTypeName() 1200 << ")"; 1201 } else 1202 outs() << ":" << O->getFileName(); 1203 outs() << ":\n"; 1204 } 1205 dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName); 1206 } 1207 } 1208 } 1209 } 1210 return; 1211 } 1212 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { 1213 if (!checkMachOAndArchFlags(O, Filename)) 1214 return; 1215 dumpSymbolNamesFromObject(*O, true); 1216 return; 1217 } 1218 error("unrecognizable file type", Filename); 1219 return; 1220} 1221 1222int main(int argc, char **argv) { 1223 // Print a stack trace if we signal out. 1224 sys::PrintStackTraceOnErrorSignal(); 1225 PrettyStackTraceProgram X(argc, argv); 1226 1227 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 1228 cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 1229 1230 // llvm-nm only reads binary files. 1231 if (error(sys::ChangeStdinToBinary())) 1232 return 1; 1233 1234 llvm::InitializeAllTargetInfos(); 1235 llvm::InitializeAllTargetMCs(); 1236 llvm::InitializeAllAsmParsers(); 1237 1238 ToolName = argv[0]; 1239 if (BSDFormat) 1240 OutputFormat = bsd; 1241 if (POSIXFormat) 1242 OutputFormat = posix; 1243 if (DarwinFormat) 1244 OutputFormat = darwin; 1245 1246 // The relative order of these is important. If you pass --size-sort it should 1247 // only print out the size. However, if you pass -S --size-sort, it should 1248 // print out both the size and address. 1249 if (SizeSort && !PrintSize) 1250 PrintAddress = false; 1251 if (OutputFormat == sysv || SizeSort) 1252 PrintSize = true; 1253 1254 switch (InputFilenames.size()) { 1255 case 0: 1256 InputFilenames.push_back("a.out"); 1257 case 1: 1258 break; 1259 default: 1260 MultipleFiles = true; 1261 } 1262 1263 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1264 if (ArchFlags[i] == "all") { 1265 ArchAll = true; 1266 } else { 1267 if (!MachOObjectFile::isValidArch(ArchFlags[i])) 1268 error("Unknown architecture named '" + ArchFlags[i] + "'", 1269 "for the -arch option"); 1270 } 1271 } 1272 1273 if (SegSect.size() != 0 && SegSect.size() != 2) 1274 error("bad number of arguments (must be two arguments)", 1275 "for the -s option"); 1276 1277 std::for_each(InputFilenames.begin(), InputFilenames.end(), 1278 dumpSymbolNamesFromFile); 1279 1280 if (HadError) 1281 return 1; 1282 1283 return 0; 1284} 1285