llvm-nm.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// The LLVM Compiler Infrastructure 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source 621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===// 9972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// 104d616646966b9effa05472ff3575fc3ce4df2b29Michael J. Spencer// This program is a utility that works like traditional Unix "nm", that is, it 114d616646966b9effa05472ff3575fc3ce4df2b29Michael J. Spencer// prints out the names of symbols in a bitcode or object file, along with some 124d616646966b9effa05472ff3575fc3ce4df2b29Michael J. Spencer// information about each symbol. 133da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 144d616646966b9effa05472ff3575fc3ce4df2b29Michael J. Spencer// This "nm" supports many of the features of GNU "nm", including its different 154d616646966b9effa05472ff3575fc3ce4df2b29Michael J. Spencer// output formats. 16972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// 17972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke//===----------------------------------------------------------------------===// 18972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Function.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/GlobalAlias.h" 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/GlobalVariable.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 239142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer#include "llvm/Object/Archive.h" 24bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola#include "llvm/Object/COFF.h" 25bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola#include "llvm/Object/ELFObjectFile.h" 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Object/IRObjectFile.h" 27bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola#include "llvm/Object/MachO.h" 289c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#include "llvm/Object/MachOUniversal.h" 2920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include "llvm/Object/ObjectFile.h" 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/COFF.h" 31551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 3220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include "llvm/Support/FileSystem.h" 33f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/Format.h" 34c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h" 354d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner#include "llvm/Support/MemoryBuffer.h" 36cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 37a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer#include "llvm/Support/Program.h" 381f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Signals.h" 39f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/raw_ostream.h" 40333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer#include "llvm/Support/system_error.h" 41ca5183d445954a9b2a570d6bbba1bc2b00ad6442Jeff Cohen#include <algorithm> 42972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke#include <cctype> 4309233fb86e237715d138db5dc5b72ada386089f2Alkis Evlogimenos#include <cerrno> 4408d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke#include <cstring> 4520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include <vector> 46d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm; 4720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencerusing namespace object; 48d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 49972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekenamespace { 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesenum OutputFormatTy { bsd, sysv, posix }; 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<OutputFormatTy> OutputFormat( 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "format", cl::desc("Specify output format"), 5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::values(clEnumVal(bsd, "BSD format"), clEnumVal(sysv, "System V format"), 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines clEnumVal(posix, "POSIX.2 format"), clEnumValEnd), 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::init(bsd)); 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias OutputFormat2("f", cl::desc("Alias for --format"), 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(OutputFormat)); 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"), 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::ZeroOrMore); 6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> UndefinedOnly("undefined-only", 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Show only undefined symbols")); 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(UndefinedOnly)); 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> DynamicSyms("dynamic", 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Display the dynamic symbols instead " 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "of normal symbols.")); 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"), 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(DynamicSyms)); 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> DefinedOnly("defined-only", 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Show only defined symbols")); 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> ExternalOnly("extern-only", 7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Show only external symbols")); 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"), 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(ExternalOnly)); 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd")); 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix")); 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> PrintFileName( 8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "print-file-name", 8620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::desc("Precede each symbol with the object file it came from")); 8720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"), 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(PrintFileName)); 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"), 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(PrintFileName)); 9220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> DebugSyms("debug-syms", 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Show all symbols, even debugger only")); 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"), 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(DebugSyms)); 9720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> NumericSort("numeric-sort", cl::desc("Sort symbols by address")); 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"), 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(NumericSort)); 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"), 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(NumericSort)); 10320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> NoSort("no-sort", cl::desc("Show symbols in order encountered")); 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias NoSortp("p", cl::desc("Alias for --no-sort"), cl::aliasopt(NoSort)); 10620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> PrintSize("print-size", 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Show symbol size instead of address")); 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias PrintSizeS("S", cl::desc("Alias for --print-size"), 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(PrintSize)); 11120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size")); 11320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> WithoutAliases("without-aliases", cl::Hidden, 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::desc("Exclude aliases from output")); 11618505b352212a5e9eac07a8555ded232b5ece894Jan Sjödin 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::opt<bool> ArchiveMap("print-armap", cl::desc("Print the archive map")); 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinescl::alias ArchiveMaps("s", cl::desc("Alias for --print-armap"), 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines cl::aliasopt(ArchiveMap)); 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool PrintAddress = true; 12120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MultipleFiles = false; 123972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool HadError = false; 12540d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstd::string ToolName; 127d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner} 128972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void error(Twine Message, Twine Path = Twine()) { 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines HadError = true; 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines errs() << ToolName << ": " << Path << ": " << Message << ".\n"; 132a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer} 133a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool error(error_code EC, Twine Path = Twine()) { 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (EC) { 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines error(EC.message(), Path); 137a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer return true; 138a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer } 139a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer return false; 140a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer} 141a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer 14220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencernamespace { 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstruct NMSymbol { 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Address; 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Size; 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char TypeChar; 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Name; 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 15020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool compareSymbolAddress(const NMSymbol &A, const NMSymbol &B) { 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (A.Address < B.Address) 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (A.Address == B.Address && A.Name < B.Name) 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (A.Address == B.Address && A.Name == B.Name && A.Size < B.Size) 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 16120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool compareSymbolSize(const NMSymbol &A, const NMSymbol &B) { 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (A.Size < B.Size) 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (A.Size == B.Size && A.Name < B.Name) 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (A.Size == B.Size && A.Name == B.Name && A.Address < B.Address) 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 17220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) { 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (A.Name < B.Name) 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (A.Name == B.Name && A.Size < B.Size) 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (A.Name == B.Name && A.Size == B.Size && A.Address < B.Address) 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 18220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer} 18320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic char isSymbolList64Bit(SymbolicFile *Obj) { 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isa<IRObjectFile>(Obj)) 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (isa<COFFObjectFile>(Obj)) 188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj)) 190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return MachO->is64Bit(); 191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (isa<ELF32LEObjectFile>(Obj)) 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (isa<ELF64LEObjectFile>(Obj)) 194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (isa<ELF32BEObjectFile>(Obj)) 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if(isa<ELF64BEObjectFile>(Obj)) 198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else 200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic StringRef CurrentFilename; 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestypedef std::vector<NMSymbol> SymbolListT; 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic SymbolListT SymbolList; 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic void sortAndPrintSymbolList(SymbolicFile *Obj) { 20820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (!NoSort) { 20920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (NumericSort) 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolAddress); 21120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else if (SizeSort) 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolSize); 21320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolName); 21520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 21620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 21720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == posix && MultipleFiles) { 21820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << '\n' << CurrentFilename << ":\n"; 21920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == bsd && MultipleFiles) { 22020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << "\n" << CurrentFilename << ":\n"; 22120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == sysv) { 22220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n" 22320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << "Name Value Class Type" 22420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << " Size Line Section\n"; 22520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 22620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 227dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *printBlanks, *printFormat; 228dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (isSymbolList64Bit(Obj)) { 229dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines printBlanks = " "; 230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines printFormat = "%016" PRIx64; 231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } else { 232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines printBlanks = " "; 233dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines printFormat = "%08" PRIx64; 234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 235dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end(); 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I != E; ++I) { 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((I->TypeChar != 'U') && UndefinedOnly) 23920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((I->TypeChar == 'U') && DefinedOnly) 24120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize) 24320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 24420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines char SymbolAddrStr[18] = ""; 246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines char SymbolSizeStr[18] = ""; 24720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (OutputFormat == sysv || I->Address == UnknownAddressOrSize) 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines strcpy(SymbolAddrStr, printBlanks); 25020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == sysv) 251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines strcpy(SymbolSizeStr, printBlanks); 25220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I->Address != UnknownAddressOrSize) 254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines format(printFormat, I->Address) 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .print(SymbolAddrStr, sizeof(SymbolAddrStr)); 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I->Size != UnknownAddressOrSize) 257dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 25820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 25920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == posix) { 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines << SymbolSizeStr << "\n"; 26220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == bsd) { 26320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (PrintAddress) 26420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << SymbolAddrStr << ' '; 26520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (PrintSize) { 26620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << SymbolSizeStr; 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I->Size != UnknownAddressOrSize) 26820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << ' '; 26920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << I->TypeChar << " " << I->Name << "\n"; 27120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == sysv) { 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string PaddedName(I->Name); 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (PaddedName.length() < 20) 27420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer PaddedName += " "; 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << PaddedName << "|" << SymbolAddrStr << "| " << I->TypeChar 27620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << " | |" << SymbolSizeStr << "| |\n"; 27720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 27820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 27920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 28020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer SymbolList.clear(); 28120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer} 28220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 283bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolatemplate <class ELFT> 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic char getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines basic_symbol_iterator I) { 286bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; 287bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr; 288bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // OK, this is ELF 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines symbol_iterator SymI(I); 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 292bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola DataRefImpl Symb = I->getRawDataRefImpl(); 293bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola const Elf_Sym *ESym = Obj.getSymbol(Symb); 294bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola const ELFFile<ELFT> &EF = *Obj.getELFFile(); 295bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola const Elf_Shdr *ESec = EF.getSection(ESym); 296bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 297bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola if (ESec) { 298bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola switch (ESec->sh_type) { 299bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case ELF::SHT_PROGBITS: 300bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case ELF::SHT_DYNAMIC: 301bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola switch (ESec->sh_flags) { 302bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case(ELF::SHF_ALLOC | ELF::SHF_EXECINSTR) : 30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 't'; 30436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case(ELF::SHF_TLS | ELF::SHF_ALLOC | ELF::SHF_WRITE) : 305bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case(ELF::SHF_ALLOC | ELF::SHF_WRITE) : 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'd'; 307bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case ELF::SHF_ALLOC: 308bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case(ELF::SHF_ALLOC | ELF::SHF_MERGE) : 309bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case(ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS) : 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'r'; 311bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 312bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola break; 313bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case ELF::SHT_NOBITS: 31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'b'; 315bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 316bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 317bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ESym->getType() == ELF::STT_SECTION) { 319bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola StringRef Name; 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(SymI->getName(Name))) 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return '?'; 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return StringSwitch<char>(Name) 32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .StartsWith(".debug", 'N') 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .StartsWith(".note", 'n') 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .Default('?'); 326bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 327bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return '?'; 329bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola} 330bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic char getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I) { 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_symbol *Symb = Obj.getCOFFSymbol(*I); 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // OK, this is COFF. 33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines symbol_iterator SymI(I); 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef Name; 33736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(SymI->getName(Name))) 33836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return '?'; 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char Ret = StringSwitch<char>(Name) 341bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola .StartsWith(".debug", 'N') 342bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola .StartsWith(".sxdata", 'N') 343bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola .Default('?'); 344bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Ret != '?') 34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Ret; 347bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 348bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola uint32_t Characteristics = 0; 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) { 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator SecI = Obj.section_end(); 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(SymI->getSection(SecI))) 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return '?'; 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const coff_section *Section = Obj.getCOFFSection(*SecI); 354bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola Characteristics = Section->Characteristics; 355bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 356bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Symb->SectionNumber) { 358bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case COFF::IMAGE_SYM_DEBUG: 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'n'; 360bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola default: 361bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola // Check section type. 362bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 't'; 364bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && 365bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'r'; 367bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'd'; 369bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'b'; 371bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'i'; 373bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 374bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola // Check for section symbol. 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (Symb->isSectionDefinition()) 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 's'; 377bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 378bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return '?'; 380bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola} 381bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 382bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolastatic uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { 383bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola if (Obj.is64Bit()) { 384bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); 385bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola return STE.n_type; 386bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 387bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola MachO::nlist STE = Obj.getSymbolTableEntry(Symb); 388bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola return STE.n_type; 389bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola} 390bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { 392bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola DataRefImpl Symb = I->getRawDataRefImpl(); 393bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola uint8_t NType = getNType(Obj, Symb); 394bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 395bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola switch (NType & MachO::N_TYPE) { 396bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case MachO::N_ABS: 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 's'; 398bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola case MachO::N_SECT: { 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines section_iterator Sec = Obj.section_end(); 400bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola Obj.getSymbolSection(Symb, Sec); 401bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola DataRefImpl Ref = Sec->getRawDataRefImpl(); 402bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola StringRef SectionName; 403bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola Obj.getSectionName(Ref, SectionName); 404bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); 405bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola if (SegmentName == "__TEXT" && SectionName == "__text") 40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 't'; 407bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola else 40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 's'; 40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 410bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 411bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return '?'; 413bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola} 414bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic char getSymbolNMTypeChar(const GlobalValue &GV) { 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isa<Function>(GV)) 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 't'; 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // FIXME: should we print 'b'? At the IR level we cannot be sure if this 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // will be in bss or not, but we could approximate. 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (isa<GlobalVariable>(GV)) 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'd'; 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const GlobalAlias *GA = cast<GlobalAlias>(&GV); 423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const GlobalValue *AliasedGV = GA->getAliasee(); 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getSymbolNMTypeChar(*AliasedGV); 42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 426bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic char getSymbolNMTypeChar(IRObjectFile &Obj, basic_symbol_iterator I) { 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const GlobalValue &GV = Obj.getSymbolGV(I->getRawDataRefImpl()); 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getSymbolNMTypeChar(GV); 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class ELFT> 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isObject(ELFObjectFile<ELFT> &Obj, symbol_iterator I) { 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym; 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataRefImpl Symb = I->getRawDataRefImpl(); 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const Elf_Sym *ESym = Obj.getSymbol(Symb); 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ESym->getType() == ELF::STT_OBJECT; 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic bool isObject(SymbolicFile *Obj, basic_symbol_iterator I) { 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj)) 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isObject(*ELF, I); 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj)) 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isObject(*ELF, I); 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj)) 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isObject(*ELF, I); 44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ELF64BEObjectFile *ELF = dyn_cast<ELF64BEObjectFile>(Obj)) 45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return isObject(*ELF, I); 45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic char getNMTypeChar(SymbolicFile *Obj, basic_symbol_iterator I) { 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t Symflags = I->getFlags(); 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Symflags & object::SymbolRef::SF_Weak) && !isa<MachOObjectFile>(Obj)) { 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char Ret = isObject(Obj, I) ? 'v' : 'w'; 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!(Symflags & object::SymbolRef::SF_Undefined)) 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = toupper(Ret); 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Ret; 461bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola } 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symflags & object::SymbolRef::SF_Undefined) 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'U'; 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symflags & object::SymbolRef::SF_Common) 46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 'C'; 46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines char Ret = '?'; 47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symflags & object::SymbolRef::SF_Absolute) 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = 'a'; 47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (IRObjectFile *IR = dyn_cast<IRObjectFile>(Obj)) 47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = getSymbolNMTypeChar(*IR, I); 47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(Obj)) 47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = getSymbolNMTypeChar(*COFF, I); 47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj)) 47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = getSymbolNMTypeChar(*MachO, I); 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj)) 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = getSymbolNMTypeChar(*ELF, I); 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj)) 48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = getSymbolNMTypeChar(*ELF, I); 48236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj)) 48336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = getSymbolNMTypeChar(*ELF, I); 48436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 48536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = getSymbolNMTypeChar(*cast<ELF64BEObjectFile>(Obj), I); 48636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symflags & object::SymbolRef::SF_Global) 48836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ret = toupper(Ret); 48936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Ret; 491bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola} 492bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void dumpSymbolNamesFromObject(SymbolicFile *Obj) { 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines basic_symbol_iterator IBegin = Obj->symbol_begin(); 49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines basic_symbol_iterator IEnd = Obj->symbol_end(); 496dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer if (DynamicSyms) { 49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Obj->isELF()) { 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines error("File format has no dynamic symbol table", Obj->getFileName()); 49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::pair<symbol_iterator, symbol_iterator> IDyn = 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getELFDynamicSymbolIterators(Obj); 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IBegin = IDyn.first; 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IEnd = IDyn.second; 505dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer } 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string NameBuffer; 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines raw_string_ostream OS(NameBuffer); 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (basic_symbol_iterator I = IBegin; I != IEnd; ++I) { 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t SymFlags = I->getFlags(); 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!DebugSyms && (SymFlags & SymbolRef::SF_FormatSpecific)) 51120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (WithoutAliases) { 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (IRObjectFile *IR = dyn_cast<IRObjectFile>(Obj)) { 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const GlobalValue &GV = IR->getSymbolGV(I->getRawDataRefImpl()); 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if(isa<GlobalAlias>(GV)) 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 51825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NMSymbol S; 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines S.Size = UnknownAddressOrSize; 52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines S.Address = UnknownAddressOrSize; 52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((PrintSize || SizeSort) && isa<ObjectFile>(Obj)) { 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines symbol_iterator SymI = I; 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(SymI->getSize(S.Size))) 52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (PrintAddress && isa<ObjectFile>(Obj)) 52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(symbol_iterator(I)->getAddress(S.Address))) 52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines S.TypeChar = getNMTypeChar(Obj, I); 53136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(I->printName(OS))) 53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS << '\0'; 53436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolList.push_back(S); 53520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 53620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 53736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OS.flush(); 53836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *P = NameBuffer.c_str(); 53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned I = 0; I < SymbolList.size(); ++I) { 54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymbolList[I].Name = P; 54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines P += strlen(P) + 1; 542a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer } 543a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer 54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CurrentFilename = Obj->getFileName(); 545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines sortAndPrintSymbolList(Obj); 54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void dumpSymbolNamesFromFile(std::string &Filename) { 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MemoryBuffer> Buffer; 550a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename)) 551a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer return; 552a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer 5530d7c695c74ae6d5f68cc07378c17491915e607d3Owen Anderson LLVMContext &Context = getGlobalContext(); 55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ErrorOr<Binary *> BinaryOrErr = createBinary(Buffer.release(), &Context); 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(BinaryOrErr.getError(), Filename)) 55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Binary> Bin(BinaryOrErr.get()); 55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Archive *A = dyn_cast<Archive>(Bin.get())) { 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ArchiveMap) { 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Archive::symbol_iterator I = A->symbol_begin(); 56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Archive::symbol_iterator E = A->symbol_end(); 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I != E) { 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << "Archive map\n"; 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (; I != E; ++I) { 56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Archive::child_iterator C; 56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SymName; 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef FileName; 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(I->getMember(C))) 5700f76e648d800d7641b4e6e6decb90949cd680b03Michael J. Spencer return; 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(I->getName(SymName))) 57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (error(C->getName(FileName))) 57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 57536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << SymName << " in " << FileName << "\n"; 5769142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer } 57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << "\n"; 5789142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer } 5799142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer } 5809c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov 58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); 58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I != E; ++I) { 58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Binary> Child; 58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (I->getAsBinary(Child, &Context)) 58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) { 58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines outs() << O->getFileName() << ":\n"; 58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dumpSymbolNamesFromObject(O); 58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin.get())) { 59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), 59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines E = UB->end_objects(); 5969c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov I != E; ++I) { 59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ObjectFile> Obj; 598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<Archive> A; 5999c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov if (!I->getAsObjectFile(Obj)) { 6009c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov outs() << Obj->getFileName() << ":\n"; 60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dumpSymbolNamesFromObject(Obj.get()); 6029c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 603dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (!I->getAsArchive(A)) { 604dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); 605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines AI != AE; ++AI) { 606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<Binary> Child; 607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (AI->getAsBinary(Child, &Context)) 608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines continue; 609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) { 610dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines outs() << A->getFileName() << ":"; 611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines outs() << O->getFileName() << ":\n"; 612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines dumpSymbolNamesFromObject(O); 613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 6169c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov } 617820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke return; 618972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke } 61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SymbolicFile *O = dyn_cast<SymbolicFile>(Bin.get())) { 62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dumpSymbolNamesFromObject(O); 62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines error("unrecognizable file type", Filename); 62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 625972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke} 626972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 627972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekeint main(int argc, char **argv) { 628cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner // Print a stack trace if we signal out. 6294d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner sys::PrintStackTraceOnErrorSignal(); 630cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner PrettyStackTraceProgram X(argc, argv); 6314a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer 63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 633cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 634fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner 635a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer // llvm-nm only reads binary files. 6369f1d9fd1964d82f3e801efb71518144492cdf290Rafael Espindola if (error(sys::ChangeStdinToBinary())) 637a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer return 1; 638a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer 6394d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner ToolName = argv[0]; 64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (BSDFormat) 64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutputFormat = bsd; 64236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (POSIXFormat) 64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutputFormat = posix; 6444d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner 64520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer // The relative order of these is important. If you pass --size-sort it should 64620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer // only print out the size. However, if you pass -S --size-sort, it should 64720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer // print out both the size and address. 64836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SizeSort && !PrintSize) 64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintAddress = false; 65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (OutputFormat == sysv || SizeSort) 65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PrintSize = true; 65220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 6534d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner switch (InputFilenames.size()) { 65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 0: 65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines InputFilenames.push_back("-"); 65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 1: 65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 65936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MultipleFiles = true; 660fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner } 6614d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner 6624d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner std::for_each(InputFilenames.begin(), InputFilenames.end(), 66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines dumpSymbolNamesFromFile); 66440d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola 66540d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola if (HadError) 66640d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola return 1; 66740d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola 6684d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner return 0; 669972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke} 670