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