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/raw_ostream.h" 40 #include "llvm/Support/TargetSelect.h" 41 #include <algorithm> 42 #include <cctype> 43 #include <cerrno> 44 #include <cstring> 45 #include <system_error> 46 #include <vector> 47 using namespace llvm; 48 using namespace object; 49 50 namespace { 51 enum OutputFormatTy { bsd, sysv, posix, darwin }; 52 cl::opt<OutputFormatTy> OutputFormat( 53 "format", cl::desc("Specify output format"), 54 cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"), 55 clEnumVal(posix, "POSIX.2 format"), 56 clEnumVal(darwin, "Darwin -m format"), clEnumValEnd), 57 cl::init(bsd)); 58 cl::alias OutputFormat2("f", cl::desc("Alias for --format"), 59 cl::aliasopt(OutputFormat)); 60 61 cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"), 62 cl::ZeroOrMore); 63 64 cl::opt<bool> UndefinedOnly("undefined-only", 65 cl::desc("Show only undefined symbols")); 66 cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), 67 cl::aliasopt(UndefinedOnly)); 68 69 cl::opt<bool> DynamicSyms("dynamic", 70 cl::desc("Display the dynamic symbols instead " 71 "of normal symbols.")); 72 cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"), 73 cl::aliasopt(DynamicSyms)); 74 75 cl::opt<bool> DefinedOnly("defined-only", 76 cl::desc("Show only defined symbols")); 77 cl::alias DefinedOnly2("U", cl::desc("Alias for --defined-only"), 78 cl::aliasopt(DefinedOnly)); 79 80 cl::opt<bool> ExternalOnly("extern-only", 81 cl::desc("Show only external symbols")); 82 cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"), 83 cl::aliasopt(ExternalOnly)); 84 85 cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd")); 86 cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix")); 87 cl::opt<bool> DarwinFormat("m", cl::desc("Alias for --format=darwin")); 88 89 static cl::list<std::string> 90 ArchFlags("arch", cl::desc("architecture(s) from a Mach-O file to dump"), 91 cl::ZeroOrMore); 92 bool ArchAll = false; 93 94 cl::opt<bool> PrintFileName( 95 "print-file-name", 96 cl::desc("Precede each symbol with the object file it came from")); 97 98 cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"), 99 cl::aliasopt(PrintFileName)); 100 cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"), 101 cl::aliasopt(PrintFileName)); 102 103 cl::opt<bool> DebugSyms("debug-syms", 104 cl::desc("Show all symbols, even debugger only")); 105 cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"), 106 cl::aliasopt(DebugSyms)); 107 108 cl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address")); 109 cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"), 110 cl::aliasopt(NumericSort)); 111 cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"), 112 cl::aliasopt(NumericSort)); 113 114 cl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered")); 115 cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort)); 116 117 cl::opt<bool> ReverseSort("reverse-sort", cl::desc("Sort in reverse order")); 118 cl::alias ReverseSortr("r", cl::desc("Alias for --reverse-sort"), 119 cl::aliasopt(ReverseSort)); 120 121 cl::opt<bool> PrintSize("print-size", 122 cl::desc("Show symbol size instead of address")); 123 cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"), 124 cl::aliasopt(PrintSize)); 125 126 cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size")); 127 128 cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden, 129 cl::desc("Exclude aliases from output")); 130 131 cl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map")); 132 cl::alias ArchiveMaps("M", cl::desc("Alias for --print-armap"), 133 cl::aliasopt(ArchiveMap)); 134 135 cl::opt<bool> JustSymbolName("just-symbol-name", 136 cl::desc("Print just the symbol's name")); 137 cl::alias JustSymbolNames("j", cl::desc("Alias for --just-symbol-name"), 138 cl::aliasopt(JustSymbolName)); 139 bool PrintAddress = true; 140 141 bool MultipleFiles = false; 142 143 bool HadError = false; 144 145 std::string ToolName; 146 } 147 148 static void error(Twine Message, Twine Path = Twine()) { 149 HadError = true; 150 errs() << ToolName << ": " << Path << ": " << Message << ".\n"; 151 } 152 153 static bool error(std::error_code EC, Twine Path = Twine()) { 154 if (EC) { 155 error(EC.message(), Path); 156 return true; 157 } 158 return false; 159 } 160 161 namespace { 162 struct NMSymbol { 163 uint64_t Address; 164 uint64_t Size; 165 char TypeChar; 166 StringRef Name; 167 DataRefImpl Symb; 168 }; 169 } 170 171 static bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) { 172 if (!ReverseSort) { 173 if (A.Address < B.Address) 174 return true; 175 else if (A.Address == B.Address && A.Name < B.Name) 176 return true; 177 else if (A.Address == B.Address && A.Name == B.Name && A.Size < B.Size) 178 return true; 179 else 180 return false; 181 } else { 182 if (A.Address > B.Address) 183 return true; 184 else if (A.Address == B.Address && A.Name > B.Name) 185 return true; 186 else if (A.Address == B.Address && A.Name == B.Name && A.Size > B.Size) 187 return true; 188 else 189 return false; 190 } 191 } 192 193 static bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) { 194 if (!ReverseSort) { 195 if (A.Size < B.Size) 196 return true; 197 else if (A.Size == B.Size && A.Name < B.Name) 198 return true; 199 else if (A.Size == B.Size && A.Name == B.Name && A.Address < B.Address) 200 return true; 201 else 202 return false; 203 } else { 204 if (A.Size > B.Size) 205 return true; 206 else if (A.Size == B.Size && A.Name > B.Name) 207 return true; 208 else if (A.Size == B.Size && A.Name == B.Name && A.Address > B.Address) 209 return true; 210 else 211 return false; 212 } 213 } 214 215 static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) { 216 if (!ReverseSort) { 217 if (A.Name < B.Name) 218 return true; 219 else if (A.Name == B.Name && A.Size < B.Size) 220 return true; 221 else if (A.Name == B.Name && A.Size == B.Size && A.Address < B.Address) 222 return true; 223 else 224 return false; 225 } else { 226 if (A.Name > B.Name) 227 return true; 228 else if (A.Name == B.Name && A.Size > B.Size) 229 return true; 230 else if (A.Name == B.Name && A.Size == B.Size && A.Address > B.Address) 231 return true; 232 else 233 return false; 234 } 235 } 236 237 static char isSymbolList64Bit(SymbolicFile *Obj) { 238 if (isa<IRObjectFile>(Obj)) 239 return false; 240 else if (isa<COFFObjectFile>(Obj)) 241 return false; 242 else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj)) 243 return MachO->is64Bit(); 244 else if (isa<ELF32LEObjectFile>(Obj)) 245 return false; 246 else if (isa<ELF64LEObjectFile>(Obj)) 247 return true; 248 else if (isa<ELF32BEObjectFile>(Obj)) 249 return false; 250 else if (isa<ELF64BEObjectFile>(Obj)) 251 return true; 252 else 253 return false; 254 } 255 256 static StringRef CurrentFilename; 257 typedef std::vector<NMSymbol> SymbolListT; 258 static SymbolListT SymbolList; 259 260 // darwinPrintSymbol() is used to print a symbol from a Mach-O file when the 261 // the OutputFormat is darwin. It produces the same output as darwin's nm(1) -m 262 // output. 263 static void darwinPrintSymbol(MachOObjectFile *MachO, SymbolListT::iterator I, 264 char *SymbolAddrStr, const char *printBlanks) { 265 MachO::mach_header H; 266 MachO::mach_header_64 H_64; 267 uint32_t Filetype, Flags; 268 MachO::nlist_64 STE_64; 269 MachO::nlist STE; 270 uint8_t NType; 271 uint16_t NDesc; 272 uint64_t NValue; 273 if (MachO->is64Bit()) { 274 H_64 = MachO->MachOObjectFile::getHeader64(); 275 Filetype = H_64.filetype; 276 Flags = H_64.flags; 277 STE_64 = MachO->getSymbol64TableEntry(I->Symb); 278 NType = STE_64.n_type; 279 NDesc = STE_64.n_desc; 280 NValue = STE_64.n_value; 281 } else { 282 H = MachO->MachOObjectFile::getHeader(); 283 Filetype = H.filetype; 284 Flags = H.flags; 285 STE = MachO->getSymbolTableEntry(I->Symb); 286 NType = STE.n_type; 287 NDesc = STE.n_desc; 288 NValue = STE.n_value; 289 } 290 291 if (PrintAddress) { 292 if ((NType & MachO::N_TYPE) == MachO::N_INDR) 293 strcpy(SymbolAddrStr, printBlanks); 294 outs() << SymbolAddrStr << ' '; 295 } 296 297 switch (NType & MachO::N_TYPE) { 298 case MachO::N_UNDF: 299 if (NValue != 0) { 300 outs() << "(common) "; 301 if (MachO::GET_COMM_ALIGN(NDesc) != 0) 302 outs() << "(alignment 2^" << (int)MachO::GET_COMM_ALIGN(NDesc) << ") "; 303 } else { 304 if ((NType & MachO::N_TYPE) == MachO::N_PBUD) 305 outs() << "(prebound "; 306 else 307 outs() << "("; 308 if ((NDesc & MachO::REFERENCE_TYPE) == 309 MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 310 outs() << "undefined [lazy bound]) "; 311 else if ((NDesc & MachO::REFERENCE_TYPE) == 312 MachO::REFERENCE_FLAG_UNDEFINED_LAZY) 313 outs() << "undefined [private lazy bound]) "; 314 else if ((NDesc & MachO::REFERENCE_TYPE) == 315 MachO::REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY) 316 outs() << "undefined [private]) "; 317 else 318 outs() << "undefined) "; 319 } 320 break; 321 case MachO::N_ABS: 322 outs() << "(absolute) "; 323 break; 324 case MachO::N_INDR: 325 outs() << "(indirect) "; 326 break; 327 case MachO::N_SECT: { 328 section_iterator Sec = MachO->section_end(); 329 MachO->getSymbolSection(I->Symb, Sec); 330 DataRefImpl Ref = Sec->getRawDataRefImpl(); 331 StringRef SectionName; 332 MachO->getSectionName(Ref, SectionName); 333 StringRef SegmentName = MachO->getSectionFinalSegmentName(Ref); 334 outs() << "(" << SegmentName << "," << SectionName << ") "; 335 break; 336 } 337 default: 338 outs() << "(?) "; 339 break; 340 } 341 342 if (NType & MachO::N_EXT) { 343 if (NDesc & MachO::REFERENCED_DYNAMICALLY) 344 outs() << "[referenced dynamically] "; 345 if (NType & MachO::N_PEXT) { 346 if ((NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) 347 outs() << "weak private external "; 348 else 349 outs() << "private external "; 350 } else { 351 if ((NDesc & MachO::N_WEAK_REF) == MachO::N_WEAK_REF || 352 (NDesc & MachO::N_WEAK_DEF) == MachO::N_WEAK_DEF) { 353 if ((NDesc & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) == 354 (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) 355 outs() << "weak external automatically hidden "; 356 else 357 outs() << "weak external "; 358 } else 359 outs() << "external "; 360 } 361 } else { 362 if (NType & MachO::N_PEXT) 363 outs() << "non-external (was a private external) "; 364 else 365 outs() << "non-external "; 366 } 367 368 if (Filetype == MachO::MH_OBJECT && 369 (NDesc & MachO::N_NO_DEAD_STRIP) == MachO::N_NO_DEAD_STRIP) 370 outs() << "[no dead strip] "; 371 372 if (Filetype == MachO::MH_OBJECT && 373 ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 374 (NDesc & MachO::N_SYMBOL_RESOLVER) == MachO::N_SYMBOL_RESOLVER) 375 outs() << "[symbol resolver] "; 376 377 if (Filetype == MachO::MH_OBJECT && 378 ((NType & MachO::N_TYPE) != MachO::N_UNDF) && 379 (NDesc & MachO::N_ALT_ENTRY) == MachO::N_ALT_ENTRY) 380 outs() << "[alt entry] "; 381 382 if ((NDesc & MachO::N_ARM_THUMB_DEF) == MachO::N_ARM_THUMB_DEF) 383 outs() << "[Thumb] "; 384 385 if ((NType & MachO::N_TYPE) == MachO::N_INDR) { 386 outs() << I->Name << " (for "; 387 StringRef IndirectName; 388 if (MachO->getIndirectName(I->Symb, IndirectName)) 389 outs() << "?)"; 390 else 391 outs() << IndirectName << ")"; 392 } else 393 outs() << I->Name; 394 395 if ((Flags & MachO::MH_TWOLEVEL) == MachO::MH_TWOLEVEL && 396 (((NType & MachO::N_TYPE) == MachO::N_UNDF && NValue == 0) || 397 (NType & MachO::N_TYPE) == MachO::N_PBUD)) { 398 uint32_t LibraryOrdinal = MachO::GET_LIBRARY_ORDINAL(NDesc); 399 if (LibraryOrdinal != 0) { 400 if (LibraryOrdinal == MachO::EXECUTABLE_ORDINAL) 401 outs() << " (from executable)"; 402 else if (LibraryOrdinal == MachO::DYNAMIC_LOOKUP_ORDINAL) 403 outs() << " (dynamically looked up)"; 404 else { 405 StringRef LibraryName; 406 if (MachO->getLibraryShortNameByIndex(LibraryOrdinal - 1, LibraryName)) 407 outs() << " (from bad library ordinal " << LibraryOrdinal << ")"; 408 else 409 outs() << " (from " << LibraryName << ")"; 410 } 411 } 412 } 413 414 outs() << "\n"; 415 } 416 417 static void sortAndPrintSymbolList(SymbolicFile *Obj, bool printName) { 418 if (!NoSort) { 419 if (NumericSort) 420 std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolAddress); 421 else if (SizeSort) 422 std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolSize); 423 else 424 std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolName); 425 } 426 427 if (OutputFormat == posix && MultipleFiles && printName) { 428 outs() << '\n' << CurrentFilename << ":\n"; 429 } else if (OutputFormat == bsd && MultipleFiles && printName) { 430 outs() << "\n" << CurrentFilename << ":\n"; 431 } else if (OutputFormat == sysv) { 432 outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n" 433 << "Name Value Class Type" 434 << " Size Line Section\n"; 435 } 436 437 const char *printBlanks, *printFormat; 438 if (isSymbolList64Bit(Obj)) { 439 printBlanks = " "; 440 printFormat = "%016" PRIx64; 441 } else { 442 printBlanks = " "; 443 printFormat = "%08" PRIx64; 444 } 445 446 for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end(); 447 I != E; ++I) { 448 if ((I->TypeChar != 'U') && UndefinedOnly) 449 continue; 450 if ((I->TypeChar == 'U') && DefinedOnly) 451 continue; 452 if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize) 453 continue; 454 if (JustSymbolName) { 455 outs() << I->Name << "\n"; 456 continue; 457 } 458 459 char SymbolAddrStr[18] = ""; 460 char SymbolSizeStr[18] = ""; 461 462 if (OutputFormat == sysv || I->Address == UnknownAddressOrSize) 463 strcpy(SymbolAddrStr, printBlanks); 464 if (OutputFormat == sysv) 465 strcpy(SymbolSizeStr, printBlanks); 466 467 if (I->Address != UnknownAddressOrSize) 468 format(printFormat, I->Address) 469 .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 470 if (I->Size != UnknownAddressOrSize) 471 format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 472 473 // If OutputFormat is darwin and we have a MachOObjectFile print as darwin's 474 // nm(1) -m output, else if OutputFormat is darwin and not a Mach-O object 475 // fall back to OutputFormat bsd (see below). 476 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj); 477 if (OutputFormat == darwin && MachO) { 478 darwinPrintSymbol(MachO, I, SymbolAddrStr, printBlanks); 479 } else if (OutputFormat == posix) { 480 outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr 481 << SymbolSizeStr << "\n"; 482 } else if (OutputFormat == bsd || (OutputFormat == darwin && !MachO)) { 483 if (PrintAddress) 484 outs() << SymbolAddrStr << ' '; 485 if (PrintSize) { 486 outs() << SymbolSizeStr; 487 if (I->Size != UnknownAddressOrSize) 488 outs() << ' '; 489 } 490 outs() << I->TypeChar << " " << I->Name << "\n"; 491 } else if (OutputFormat == sysv) { 492 std::string PaddedName(I->Name); 493 while (PaddedName.length() < 20) 494 PaddedName += " "; 495 outs() << PaddedName << "|" << SymbolAddrStr << "| " << I->TypeChar 496 << " | |" << SymbolSizeStr << "| |\n"; 497 } 498 } 499 500 SymbolList.clear(); 501 } 502 503 template <class ELFT> 504 static char getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, 505 basic_symbol_iterator I) { 506 typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; 507 typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; 508 509 // OK, this is ELF 510 symbol_iterator SymI(I); 511 512 DataRefImpl Symb = I->getRawDataRefImpl(); 513 const Elf_Sym *ESym = Obj.getSymbol(Symb); 514 const ELFFile<ELFT> &EF = *Obj.getELFFile(); 515 const Elf_Shdr *ESec = EF.getSection(ESym); 516 517 if (ESec) { 518 switch (ESec->sh_type) { 519 case ELF::SHT_PROGBITS: 520 case ELF::SHT_DYNAMIC: 521 switch (ESec->sh_flags) { 522 case (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR): 523 return 't'; 524 case (ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE): 525 case (ELF::SHF_ALLOC | ELF::SHF_WRITE): 526 return 'd'; 527 case ELF::SHF_ALLOC: 528 case (ELF::SHF_ALLOC | ELF::SHF_MERGE): 529 case (ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS): 530 return 'r'; 531 } 532 break; 533 case ELF::SHT_NOBITS: 534 return 'b'; 535 } 536 } 537 538 if (ESym->getType() == ELF::STT_SECTION) { 539 StringRef Name; 540 if (error(SymI->getName(Name))) 541 return '?'; 542 return StringSwitch<char>(Name) 543 .StartsWith(".debug", 'N') 544 .StartsWith(".note", 'n') 545 .Default('?'); 546 } 547 548 return '?'; 549 } 550 551 static char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { 552 const coff_symbol *Symb = Obj.getCOFFSymbol(*I); 553 // OK, this is COFF. 554 symbol_iterator SymI(I); 555 556 StringRef Name; 557 if (error(SymI->getName(Name))) 558 return '?'; 559 560 char Ret = StringSwitch<char>(Name) 561 .StartsWith(".debug", 'N') 562 .StartsWith(".sxdata", 'N') 563 .Default('?'); 564 565 if (Ret != '?') 566 return Ret; 567 568 uint32_t Characteristics = 0; 569 if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) { 570 section_iterator SecI = Obj.section_end(); 571 if (error(SymI->getSection(SecI))) 572 return '?'; 573 const coff_section *Section = Obj.getCOFFSection(*SecI); 574 Characteristics = Section->Characteristics; 575 } 576 577 switch (Symb->SectionNumber) { 578 case COFF::IMAGE_SYM_DEBUG: 579 return 'n'; 580 default: 581 // Check section type. 582 if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 583 return 't'; 584 else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && 585 ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 586 return 'r'; 587 else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 588 return 'd'; 589 else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 590 return 'b'; 591 else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 592 return 'i'; 593 594 // Check for section symbol. 595 else if (Symb->isSectionDefinition()) 596 return 's'; 597 } 598 599 return '?'; 600 } 601 602 static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { 603 if (Obj.is64Bit()) { 604 MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 605 return STE.n_type; 606 } 607 MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 608 return STE.n_type; 609 } 610 611 static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { 612 DataRefImpl Symb = I->getRawDataRefImpl(); 613 uint8_t NType = getNType(Obj, Symb); 614 615 switch (NType & MachO::N_TYPE) { 616 case MachO::N_ABS: 617 return 's'; 618 case MachO::N_INDR: 619 return 'i'; 620 case MachO::N_SECT: { 621 section_iterator Sec = Obj.section_end(); 622 Obj.getSymbolSection(Symb, Sec); 623 DataRefImpl Ref = Sec->getRawDataRefImpl(); 624 StringRef SectionName; 625 Obj.getSectionName(Ref, SectionName); 626 StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); 627 if (SegmentName == "__TEXT" && SectionName == "__text") 628 return 't'; 629 else if (SegmentName == "__DATA" && SectionName == "__data") 630 return 'd'; 631 else if (SegmentName == "__DATA" && SectionName == "__bss") 632 return 'b'; 633 else 634 return 's'; 635 } 636 } 637 638 return '?'; 639 } 640 641 static char getSymbolNMTypeChar(const GlobalValue &GV) { 642 if (GV.getType()->getElementType()->isFunctionTy()) 643 return 't'; 644 // FIXME: should we print 'b'? At the IR level we cannot be sure if this 645 // will be in bss or not, but we could approximate. 646 return 'd'; 647 } 648 649 static char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { 650 const GlobalValue *GV = Obj.getSymbolGV(I->getRawDataRefImpl()); 651 if (!GV) 652 return 't'; 653 return getSymbolNMTypeChar(*GV); 654 } 655 656 template <class ELFT> 657 static bool isObject(ELFObjectFile<ELFT> &Obj, symbol_iterator I) { 658 typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; 659 660 DataRefImpl Symb = I->getRawDataRefImpl(); 661 const Elf_Sym *ESym = Obj.getSymbol(Symb); 662 663 return ESym->getType() == ELF::STT_OBJECT; 664 } 665 666 static bool isObject(SymbolicFile *Obj, basic_symbol_iterator I) { 667 if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj)) 668 return isObject(*ELF, I); 669 if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj)) 670 return isObject(*ELF, I); 671 if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj)) 672 return isObject(*ELF, I); 673 if (ELF64BEObjectFile *ELF = dyn_cast<ELF64BEObjectFile>(Obj)) 674 return isObject(*ELF, I); 675 return false; 676 } 677 678 static char getNMTypeChar(SymbolicFile *Obj, basic_symbol_iterator I) { 679 uint32_t Symflags = I->getFlags(); 680 if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) { 681 char Ret = isObject(Obj, I) ? 'v' : 'w'; 682 if (!(Symflags & object::SymbolRef::SF_Undefined)) 683 Ret = toupper(Ret); 684 return Ret; 685 } 686 687 if (Symflags & object::SymbolRef::SF_Undefined) 688 return 'U'; 689 690 if (Symflags & object::SymbolRef::SF_Common) 691 return 'C'; 692 693 char Ret = '?'; 694 if (Symflags & object::SymbolRef::SF_Absolute) 695 Ret = 'a'; 696 else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(Obj)) 697 Ret = getSymbolNMTypeChar(*IR, I); 698 else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(Obj)) 699 Ret = getSymbolNMTypeChar(*COFF, I); 700 else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj)) 701 Ret = getSymbolNMTypeChar(*MachO, I); 702 else if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj)) 703 Ret = getSymbolNMTypeChar(*ELF, I); 704 else if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj)) 705 Ret = getSymbolNMTypeChar(*ELF, I); 706 else if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj)) 707 Ret = getSymbolNMTypeChar(*ELF, I); 708 else 709 Ret = getSymbolNMTypeChar(*cast<ELF64BEObjectFile>(Obj), I); 710 711 if (Symflags & object::SymbolRef::SF_Global) 712 Ret = toupper(Ret); 713 714 return Ret; 715 } 716 717 static void dumpSymbolNamesFromObject(SymbolicFile *Obj, bool printName) { 718 basic_symbol_iterator IBegin = Obj->symbol_begin(); 719 basic_symbol_iterator IEnd = Obj->symbol_end(); 720 if (DynamicSyms) { 721 if (!Obj->isELF()) { 722 error("File format has no dynamic symbol table", Obj->getFileName()); 723 return; 724 } 725 std::pair<symbol_iterator, symbol_iterator> IDyn = 726 getELFDynamicSymbolIterators(Obj); 727 IBegin = IDyn.first; 728 IEnd = IDyn.second; 729 } 730 std::string NameBuffer; 731 raw_string_ostream OS(NameBuffer); 732 for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) { 733 uint32_t SymFlags = I->getFlags(); 734 if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) 735 continue; 736 if (WithoutAliases) { 737 if (IRObjectFile *IR = dyn_cast<IRObjectFile>(Obj)) { 738 const GlobalValue *GV = IR->getSymbolGV(I->getRawDataRefImpl()); 739 if (GV && isa<GlobalAlias>(GV)) 740 continue; 741 } 742 } 743 NMSymbol S; 744 S.Size = UnknownAddressOrSize; 745 S.Address = UnknownAddressOrSize; 746 if ((PrintSize || SizeSort) && isa<ObjectFile>(Obj)) { 747 symbol_iterator SymI = I; 748 if (error(SymI->getSize(S.Size))) 749 break; 750 } 751 if (PrintAddress && isa<ObjectFile>(Obj)) 752 if (error(symbol_iterator(I)->getAddress(S.Address))) 753 break; 754 S.TypeChar = getNMTypeChar(Obj, I); 755 if (error(I->printName(OS))) 756 break; 757 OS << '\0'; 758 S.Symb = I->getRawDataRefImpl(); 759 SymbolList.push_back(S); 760 } 761 762 OS.flush(); 763 const char *P = NameBuffer.c_str(); 764 for (unsigned I = 0; I < SymbolList.size(); ++I) { 765 SymbolList[I].Name = P; 766 P += strlen(P) + 1; 767 } 768 769 CurrentFilename = Obj->getFileName(); 770 sortAndPrintSymbolList(Obj, printName); 771 } 772 773 // checkMachOAndArchFlags() checks to see if the SymbolicFile is a Mach-O file 774 // and if it is and there is a list of architecture flags is specified then 775 // check to make sure this Mach-O file is one of those architectures or all 776 // architectures was specificed. If not then an error is generated and this 777 // routine returns false. Else it returns true. 778 static bool checkMachOAndArchFlags(SymbolicFile *O, std::string &Filename) { 779 if (isa<MachOObjectFile>(O) && !ArchAll && ArchFlags.size() != 0) { 780 MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O); 781 bool ArchFound = false; 782 MachO::mach_header H; 783 MachO::mach_header_64 H_64; 784 Triple T; 785 if (MachO->is64Bit()) { 786 H_64 = MachO->MachOObjectFile::getHeader64(); 787 T = MachOObjectFile::getArch(H_64.cputype, H_64.cpusubtype); 788 } else { 789 H = MachO->MachOObjectFile::getHeader(); 790 T = MachOObjectFile::getArch(H.cputype, H.cpusubtype); 791 } 792 unsigned i; 793 for (i = 0; i < ArchFlags.size(); ++i) { 794 if (ArchFlags[i] == T.getArchName()) 795 ArchFound = true; 796 break; 797 } 798 if (!ArchFound) { 799 error(ArchFlags[i], 800 "file: " + Filename + " does not contain architecture"); 801 return false; 802 } 803 } 804 return true; 805 } 806 807 static void dumpSymbolNamesFromFile(std::string &Filename) { 808 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 809 MemoryBuffer::getFileOrSTDIN(Filename); 810 if (error(BufferOrErr.getError(), Filename)) 811 return; 812 std::unique_ptr<MemoryBuffer> Buffer = std::move(BufferOrErr.get()); 813 814 LLVMContext &Context = getGlobalContext(); 815 ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer, &Context); 816 if (error(BinaryOrErr.getError(), Filename)) 817 return; 818 Buffer.release(); 819 std::unique_ptr<Binary> Bin(BinaryOrErr.get()); 820 821 if (Archive *A = dyn_cast<Archive>(Bin.get())) { 822 if (ArchiveMap) { 823 Archive::symbol_iterator I = A->symbol_begin(); 824 Archive::symbol_iterator E = A->symbol_end(); 825 if (I != E) { 826 outs() << "Archive map\n"; 827 for (; I != E; ++I) { 828 ErrorOr<Archive::child_iterator> C = I->getMember(); 829 if (error(C.getError())) 830 return; 831 ErrorOr<StringRef> FileNameOrErr = C.get()->getName(); 832 if (error(FileNameOrErr.getError())) 833 return; 834 StringRef SymName = I->getName(); 835 outs() << SymName << " in " << FileNameOrErr.get() << "\n"; 836 } 837 outs() << "\n"; 838 } 839 } 840 841 for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); 842 I != E; ++I) { 843 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = I->getAsBinary(&Context); 844 if (ChildOrErr.getError()) 845 continue; 846 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 847 if (!checkMachOAndArchFlags(O, Filename)) 848 return; 849 outs() << "\n"; 850 if (isa<MachOObjectFile>(O)) { 851 outs() << Filename << "(" << O->getFileName() << ")"; 852 } else 853 outs() << O->getFileName(); 854 outs() << ":\n"; 855 dumpSymbolNamesFromObject(O, false); 856 } 857 } 858 return; 859 } 860 if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin.get())) { 861 // If we have a list of architecture flags specified dump only those. 862 if (!ArchAll && ArchFlags.size() != 0) { 863 // Look for a slice in the universal binary that matches each ArchFlag. 864 bool ArchFound; 865 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 866 ArchFound = false; 867 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 868 E = UB->end_objects(); 869 I != E; ++I) { 870 if (ArchFlags[i] == I->getArchTypeName()) { 871 ArchFound = true; 872 ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = 873 I->getAsObjectFile(); 874 std::unique_ptr<Archive> A; 875 if (ObjOrErr) { 876 std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); 877 if (ArchFlags.size() > 1) { 878 outs() << "\n" << Obj->getFileName() << " (for architecture " 879 << I->getArchTypeName() << ")" 880 << ":\n"; 881 } 882 dumpSymbolNamesFromObject(Obj.get(), false); 883 } else if (!I->getAsArchive(A)) { 884 for (Archive::child_iterator AI = A->child_begin(), 885 AE = A->child_end(); 886 AI != AE; ++AI) { 887 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 888 AI->getAsBinary(&Context); 889 if (ChildOrErr.getError()) 890 continue; 891 if (SymbolicFile *O = 892 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 893 outs() << "\n" << A->getFileName(); 894 outs() << "(" << O->getFileName() << ")"; 895 if (ArchFlags.size() > 1) { 896 outs() << " (for architecture " << I->getArchTypeName() 897 << ")"; 898 } 899 outs() << ":\n"; 900 dumpSymbolNamesFromObject(O, false); 901 } 902 } 903 } 904 } 905 } 906 if (!ArchFound) { 907 error(ArchFlags[i], 908 "file: " + Filename + " does not contain architecture"); 909 return; 910 } 911 } 912 return; 913 } 914 // No architecture flags were specified so if this contains a slice that 915 // matches the host architecture dump only that. 916 if (!ArchAll) { 917 StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); 918 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 919 E = UB->end_objects(); 920 I != E; ++I) { 921 if (HostArchName == I->getArchTypeName()) { 922 ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 923 std::unique_ptr<Archive> A; 924 if (ObjOrErr) { 925 std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); 926 dumpSymbolNamesFromObject(Obj.get(), false); 927 } else if (!I->getAsArchive(A)) { 928 for (Archive::child_iterator AI = A->child_begin(), 929 AE = A->child_end(); 930 AI != AE; ++AI) { 931 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 932 AI->getAsBinary(&Context); 933 if (ChildOrErr.getError()) 934 continue; 935 if (SymbolicFile *O = 936 dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 937 outs() << "\n" << A->getFileName() << "(" << O->getFileName() 938 << ")" 939 << ":\n"; 940 dumpSymbolNamesFromObject(O, false); 941 } 942 } 943 } 944 return; 945 } 946 } 947 } 948 // Either all architectures have been specified or none have been specified 949 // and this does not contain the host architecture so dump all the slices. 950 bool moreThanOneArch = UB->getNumberOfObjects() > 1; 951 for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 952 E = UB->end_objects(); 953 I != E; ++I) { 954 ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); 955 std::unique_ptr<Archive> A; 956 if (ObjOrErr) { 957 std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get()); 958 if (moreThanOneArch) 959 outs() << "\n"; 960 outs() << Obj->getFileName(); 961 if (isa<MachOObjectFile>(Obj.get()) && moreThanOneArch) 962 outs() << " (for architecture " << I->getArchTypeName() << ")"; 963 outs() << ":\n"; 964 dumpSymbolNamesFromObject(Obj.get(), false); 965 } else if (!I->getAsArchive(A)) { 966 for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); 967 AI != AE; ++AI) { 968 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = 969 AI->getAsBinary(&Context); 970 if (ChildOrErr.getError()) 971 continue; 972 if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { 973 outs() << "\n" << A->getFileName(); 974 if (isa<MachOObjectFile>(O)) { 975 outs() << "(" << O->getFileName() << ")"; 976 if (moreThanOneArch) 977 outs() << " (for architecture " << I->getArchTypeName() << ")"; 978 } else 979 outs() << ":" << O->getFileName(); 980 outs() << ":\n"; 981 dumpSymbolNamesFromObject(O, false); 982 } 983 } 984 } 985 } 986 return; 987 } 988 if (SymbolicFile *O = dyn_cast<SymbolicFile>(Bin.get())) { 989 if (!checkMachOAndArchFlags(O, Filename)) 990 return; 991 dumpSymbolNamesFromObject(O, true); 992 return; 993 } 994 error("unrecognizable file type", Filename); 995 return; 996 } 997 998 int main(int argc, char **argv) { 999 // Print a stack trace if we signal out. 1000 sys::PrintStackTraceOnErrorSignal(); 1001 PrettyStackTraceProgram X(argc, argv); 1002 1003 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 1004 cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 1005 1006 // llvm-nm only reads binary files. 1007 if (error(sys::ChangeStdinToBinary())) 1008 return 1; 1009 1010 llvm::InitializeAllTargetInfos(); 1011 llvm::InitializeAllTargetMCs(); 1012 llvm::InitializeAllAsmParsers(); 1013 1014 ToolName = argv[0]; 1015 if (BSDFormat) 1016 OutputFormat = bsd; 1017 if (POSIXFormat) 1018 OutputFormat = posix; 1019 if (DarwinFormat) 1020 OutputFormat = darwin; 1021 1022 // The relative order of these is important. If you pass --size-sort it should 1023 // only print out the size. However, if you pass -S --size-sort, it should 1024 // print out both the size and address. 1025 if (SizeSort && !PrintSize) 1026 PrintAddress = false; 1027 if (OutputFormat == sysv || SizeSort) 1028 PrintSize = true; 1029 1030 switch (InputFilenames.size()) { 1031 case 0: 1032 InputFilenames.push_back("a.out"); 1033 case 1: 1034 break; 1035 default: 1036 MultipleFiles = true; 1037 } 1038 1039 for (unsigned i = 0; i < ArchFlags.size(); ++i) { 1040 if (ArchFlags[i] == "all") { 1041 ArchAll = true; 1042 } else { 1043 Triple T = MachOObjectFile::getArch(ArchFlags[i]); 1044 if (T.getArch() == Triple::UnknownArch) 1045 error("Unknown architecture named '" + ArchFlags[i] + "'", 1046 "for the -arch option"); 1047 } 1048 } 1049 1050 std::for_each(InputFilenames.begin(), InputFilenames.end(), 1051 dumpSymbolNamesFromFile); 1052 1053 if (HadError) 1054 return 1; 1055 1056 return 0; 1057 } 1058