llvm-nm.cpp revision 25b15777df42d5d608810f6881b6c98107481d69
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// 10972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// This program is a utility that works like traditional Unix "nm", 11a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif// that is, it prints out the names of symbols in a bitcode file, 12972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// along with some information about each symbol. 133da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 14972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// This "nm" does not print symbols' addresses. It supports many of 15972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// the features of GNU "nm", including its different output formats. 16972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// 17972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke//===----------------------------------------------------------------------===// 18972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 198b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson#include "llvm/LLVMContext.h" 20972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke#include "llvm/Module.h" 214d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner#include "llvm/Bitcode/ReaderWriter.h" 2244dadffe4bd58ab32961ca5fe537e8ba69c09243Chris Lattner#include "llvm/Bitcode/Archive.h" 2320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include "llvm/Object/ObjectFile.h" 24551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 2520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include "llvm/Support/FileSystem.h" 26c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h" 274d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner#include "llvm/Support/MemoryBuffer.h" 28cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 2965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman#include "llvm/Support/raw_ostream.h" 301f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Signals.h" 3120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include "llvm/Support/Format.h" 32333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer#include "llvm/Support/system_error.h" 33ca5183d445954a9b2a570d6bbba1bc2b00ad6442Jeff Cohen#include <algorithm> 34972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke#include <cctype> 3509233fb86e237715d138db5dc5b72ada386089f2Alkis Evlogimenos#include <cerrno> 3608d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke#include <cstring> 3720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include <vector> 38d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm; 3920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencerusing namespace object; 40d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 41972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekenamespace { 42972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke enum OutputFormatTy { bsd, sysv, posix }; 43972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::opt<OutputFormatTy> 44972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke OutputFormat("format", 45972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::desc("Specify output format"), 46972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::values(clEnumVal(bsd, "BSD format"), 47972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke clEnumVal(sysv, "System V format"), 483da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman clEnumVal(posix, "POSIX.2 format"), 494d143ee01988e1b52e106ffccbb313937ca5e886Chris Lattner clEnumValEnd), cl::init(bsd)); 50972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::alias OutputFormat2("f", cl::desc("Alias for --format"), 51972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::aliasopt(OutputFormat)); 52972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 533da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman cl::list<std::string> 54a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif InputFilenames(cl::Positional, cl::desc("<input bitcode files>"), 55fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner cl::ZeroOrMore); 56972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 57972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::opt<bool> UndefinedOnly("undefined-only", 58972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::desc("Show only undefined symbols")); 59972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"), 60972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::aliasopt(UndefinedOnly)); 61972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 62972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::opt<bool> DefinedOnly("defined-only", 63972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::desc("Show only defined symbols")); 64972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 65972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::opt<bool> ExternalOnly("extern-only", 66972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::desc("Show only external symbols")); 67972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"), 68972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::aliasopt(ExternalOnly)); 69972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 70972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd")); 71972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix")); 72972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 7320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::opt<bool> PrintFileName("print-file-name", 7420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::desc("Precede each symbol with the object file it came from")); 7520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 7620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"), 7720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::aliasopt(PrintFileName)); 7820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"), 7920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::aliasopt(PrintFileName)); 8020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 8120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::opt<bool> DebugSyms("debug-syms", 8220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::desc("Show all symbols, even debugger only")); 8320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"), 8420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::aliasopt(DebugSyms)); 8520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 8620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::opt<bool> NumericSort("numeric-sort", 8720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::desc("Sort symbols by address")); 8820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"), 8920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::aliasopt(NumericSort)); 9020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"), 9120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::aliasopt(NumericSort)); 9220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 9320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::opt<bool> NoSort("no-sort", 9420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::desc("Show symbols in order encountered")); 9520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::alias NoSortp("p", cl::desc("Alias for --no-sort"), 9620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::aliasopt(NoSort)); 9720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 9820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::opt<bool> PrintSize("print-size", 9920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::desc("Show symbol size instead of address")); 10020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"), 10120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::aliasopt(PrintSize)); 10220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 10320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size")); 10420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 10520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer bool PrintAddress = true; 10620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 107972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke bool MultipleFiles = false; 108972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 109972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke std::string ToolName; 110d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner} 111972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 11220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencernamespace { 11320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer struct NMSymbol { 11420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer uint64_t Address; 11520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer uint64_t Size; 11620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer char TypeChar; 11720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer StringRef Name; 11820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer }; 11920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 12020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer static bool CompareSymbolAddress(const NMSymbol &a, const NMSymbol &b) { 12120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (a.Address < b.Address) 12220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return true; 12320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else if (a.Address == b.Address && a.Name < b.Name) 12420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return true; 12520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else 12620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return false; 12720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 12820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 12920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 13020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer static bool CompareSymbolSize(const NMSymbol &a, const NMSymbol &b) { 13120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (a.Size < b.Size) 13220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return true; 13320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else if (a.Size == b.Size && a.Name < b.Name) 13420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return true; 13520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else 13620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return false; 13720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 13820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 13920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer static bool CompareSymbolName(const NMSymbol &a, const NMSymbol &b) { 14020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return a.Name < b.Name; 14120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 14220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 14320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer StringRef CurrentFilename; 14420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer typedef std::vector<NMSymbol> SymbolListT; 14520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer SymbolListT SymbolList; 14625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 14725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer bool error(error_code ec) { 14825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!ec) return false; 14925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer 15025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer outs() << ToolName << ": error reading file: " << ec.message() << ".\n"; 15125b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer outs().flush(); 15225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer return true; 15325b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 15420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer} 15520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 15620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencerstatic void SortAndPrintSymbolList() { 15720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (!NoSort) { 15820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (NumericSort) 15920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolAddress); 16020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else if (SizeSort) 16120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolSize); 16220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer else 16320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolName); 16420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 16520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 16620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == posix && MultipleFiles) { 16720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << '\n' << CurrentFilename << ":\n"; 16820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == bsd && MultipleFiles) { 16920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << "\n" << CurrentFilename << ":\n"; 17020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == sysv) { 17120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n" 17220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << "Name Value Class Type" 17320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << " Size Line Section\n"; 17420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 17520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 17620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer for (SymbolListT::iterator i = SymbolList.begin(), 17720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer e = SymbolList.end(); i != e; ++i) { 17820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if ((i->TypeChar != 'U') && UndefinedOnly) 17920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 18020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if ((i->TypeChar == 'U') && DefinedOnly) 18120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 18220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (SizeSort && !PrintAddress && i->Size == UnknownAddressOrSize) 18320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 18420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 18520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer char SymbolAddrStr[10] = ""; 18620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer char SymbolSizeStr[10] = ""; 18720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 18820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == sysv || i->Address == object::UnknownAddressOrSize) 18920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer strcpy(SymbolAddrStr, " "); 19020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == sysv) 19120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer strcpy(SymbolSizeStr, " "); 19220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 19320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (i->Address != object::UnknownAddressOrSize) 19420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer format("%08x", i->Address).print(SymbolAddrStr, sizeof(SymbolAddrStr)); 19520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (i->Size != object::UnknownAddressOrSize) 19620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer format("%08x", i->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr)); 19720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 19820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == posix) { 19920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << i->Name << " " << i->TypeChar << " " 20020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << SymbolAddrStr << SymbolSizeStr << "\n"; 20120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == bsd) { 20220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (PrintAddress) 20320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << SymbolAddrStr << ' '; 20420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (PrintSize) { 20520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << SymbolSizeStr; 20620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (i->Size != object::UnknownAddressOrSize) 20720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << ' '; 20820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 20920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << i->TypeChar << " " << i->Name << "\n"; 21020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (OutputFormat == sysv) { 21120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer std::string PaddedName (i->Name); 21220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer while (PaddedName.length () < 20) 21320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer PaddedName += " "; 21420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer outs() << PaddedName << "|" << SymbolAddrStr << "| " 21520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << i->TypeChar 21620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer << " | |" << SymbolSizeStr << "| |\n"; 21720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 21820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 21920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 22020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer SymbolList.clear(); 22120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer} 22220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 223c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic char TypeCharForSymbol(GlobalValue &GV) { 2244a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio if (GV.isDeclaration()) return 'U'; 225c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner if (GV.hasLinkOnceLinkage()) return 'C'; 2267d5633e9074db9eaf796e677451f6642c0174facDale Johannesen if (GV.hasCommonLinkage()) return 'C'; 227c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner if (GV.hasWeakLinkage()) return 'W'; 2284a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio if (isa<Function>(GV) && GV.hasInternalLinkage()) return 't'; 229c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner if (isa<Function>(GV)) return 'T'; 2304a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio if (isa<GlobalVariable>(GV) && GV.hasInternalLinkage()) return 'd'; 231c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner if (isa<GlobalVariable>(GV)) return 'D'; 2324a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) { 2334a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio const GlobalValue *AliasedGV = GA->getAliasedGlobal(); 2344a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio if (isa<Function>(AliasedGV)) return 'T'; 2354a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio if (isa<GlobalVariable>(AliasedGV)) return 'D'; 2364a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio } 2374a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio return '?'; 238972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke} 239972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 240c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic void DumpSymbolNameForGlobalValue(GlobalValue &GV) { 241266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner // Private linkage and available_externally linkage don't exist in symtab. 2424e34d502727df36cc2caa59307953444b1ee9914Bill Wendling if (GV.hasPrivateLinkage() || 2434e34d502727df36cc2caa59307953444b1ee9914Bill Wendling GV.hasLinkerPrivateLinkage() || 2444e34d502727df36cc2caa59307953444b1ee9914Bill Wendling GV.hasLinkerPrivateWeakLinkage() || 2454e34d502727df36cc2caa59307953444b1ee9914Bill Wendling GV.hasLinkerPrivateWeakDefAutoLinkage() || 2464e34d502727df36cc2caa59307953444b1ee9914Bill Wendling GV.hasAvailableExternallyLinkage()) 2475e721d768254a920b78b9129d79a84c0163cb3f4Bill Wendling return; 248266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner char TypeChar = TypeCharForSymbol(GV); 249bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola if (GV.hasLocalLinkage () && ExternalOnly) 250972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke return; 25120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 25220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer NMSymbol s; 25320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer s.Address = object::UnknownAddressOrSize; 25420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer s.Size = object::UnknownAddressOrSize; 25520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer s.TypeChar = TypeChar; 25620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer s.Name = GV.getName(); 25720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer SymbolList.push_back(s); 258972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke} 259972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 260c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic void DumpSymbolNamesFromModule(Module *M) { 26120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer CurrentFilename = M->getModuleIdentifier(); 262266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner std::for_each (M->begin(), M->end(), DumpSymbolNameForGlobalValue); 263266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner std::for_each (M->global_begin(), M->global_end(), 2644a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio DumpSymbolNameForGlobalValue); 265266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner std::for_each (M->alias_begin(), M->alias_end(), 2664a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio DumpSymbolNameForGlobalValue); 26720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 26820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer SortAndPrintSymbolList(); 26920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer} 27020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 27120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencerstatic void DumpSymbolNamesFromObject(ObjectFile *obj) { 27225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer error_code ec; 27320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer for (ObjectFile::symbol_iterator i = obj->begin_symbols(), 27425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer e = obj->end_symbols(); 27525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer i != e; i.increment(ec)) { 27625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error(ec)) break; 27725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer bool internal; 27825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error(i->isInternal(internal))) break; 27925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (!DebugSyms && internal) 28020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer continue; 28120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer NMSymbol s; 28220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer s.Size = object::UnknownAddressOrSize; 28320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer s.Address = object::UnknownAddressOrSize; 28425b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (PrintSize || SizeSort) { 28525b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error(i->getSize(s.Size))) break; 28625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer } 28720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (PrintAddress) 28825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error(i->getAddress(s.Address))) break; 28925b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error(i->getNMTypeChar(s.TypeChar))) break; 29025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer if (error(i->getName(s.Name))) break; 29120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer SymbolList.push_back(s); 29220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 29320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 294001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer CurrentFilename = obj->getFileName(); 29520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer SortAndPrintSymbolList(); 296972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke} 297972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 298c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic void DumpSymbolNamesFromFile(std::string &Filename) { 2990d7c695c74ae6d5f68cc07378c17491915e607d3Owen Anderson LLVMContext &Context = getGlobalContext(); 300972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke std::string ErrorMessage; 30111db4b8084270cb91446485b9534864ce52a95efReid Spencer sys::Path aPath(Filename); 30220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer bool exists; 30320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (sys::fs::exists(aPath.str(), exists) || !exists) 30420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer errs() << ToolName << ": '" << Filename << "': " << "No such file\n"; 3058b1daa3e71109b8ae6a057a1def35ae0ab87ce37Brian Gaeke // Note: Currently we do not support reading an archive from stdin. 30644dadffe4bd58ab32961ca5fe537e8ba69c09243Chris Lattner if (Filename == "-" || aPath.isBitcodeFile()) { 3073ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer OwningPtr<MemoryBuffer> Buffer; 3083ff9563c3e391954b2e224afcf8b2b0fcc3888aaMichael J. Spencer if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buffer)) 309333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer ErrorMessage = ec.message(); 3104d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner Module *Result = 0; 3114d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner if (Buffer.get()) 31231895e73591d3c9ceae731a1274c8f56194b9616Owen Anderson Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage); 3134a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer 3148018f5d5a4134f8b2ceb315095996a552a80ee25Nuno Lopes if (Result) { 3154d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner DumpSymbolNamesFromModule(Result); 3168018f5d5a4134f8b2ceb315095996a552a80ee25Nuno Lopes delete Result; 3178018f5d5a4134f8b2ceb315095996a552a80ee25Nuno Lopes } else 31865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; 3194a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer 32011db4b8084270cb91446485b9534864ce52a95efReid Spencer } else if (aPath.isArchive()) { 3218d8a7ffe580c622e7e43f1426bca64e517de0d06Reid Spencer std::string ErrMsg; 32231895e73591d3c9ceae731a1274c8f56194b9616Owen Anderson Archive* archive = Archive::OpenAndLoad(sys::Path(Filename), Context, 3238b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson &ErrorMessage); 32463efb7798051f2634167eee1e807f0dc7c3f13cfReid Spencer if (!archive) 32565f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; 3261c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke std::vector<Module *> Modules; 327c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner if (archive->getAllModules(Modules, &ErrorMessage)) { 32865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n"; 32908d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke return; 33008d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke } 3311c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke MultipleFiles = true; 332c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner std::for_each (Modules.begin(), Modules.end(), DumpSymbolNamesFromModule); 33320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } else if (aPath.isObjectFile()) { 33476fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer OwningPtr<Binary> obj; 33576fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer if (error_code ec = object::createBinary(aPath.str(), obj)) { 33676fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer errs() << ToolName << ": " << Filename << ": " << ec.message() << ".\n"; 33720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer return; 33820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer } 33976fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer if (object::ObjectFile *o = dyn_cast<ObjectFile>(obj.get())) 34076fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer DumpSymbolNamesFromObject(o); 341820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke } else { 34265f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman errs() << ToolName << ": " << Filename << ": " 34365f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman << "unrecognizable file type\n"; 344820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke return; 345972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke } 346972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke} 347972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke 348972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekeint main(int argc, char **argv) { 349cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner // Print a stack trace if we signal out. 3504d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner sys::PrintStackTraceOnErrorSignal(); 351cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner PrettyStackTraceProgram X(argc, argv); 3524a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer 353cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 354cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); 355fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner 3564d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner ToolName = argv[0]; 3574d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner if (BSDFormat) OutputFormat = bsd; 3584d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner if (POSIXFormat) OutputFormat = posix; 3594d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner 36020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer // The relative order of these is important. If you pass --size-sort it should 36120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer // only print out the size. However, if you pass -S --size-sort, it should 36220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer // print out both the size and address. 36320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (SizeSort && !PrintSize) PrintAddress = false; 36420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer if (OutputFormat == sysv || SizeSort) PrintSize = true; 36520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer 3664d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner switch (InputFilenames.size()) { 3674d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner case 0: InputFilenames.push_back("-"); 3684d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner case 1: break; 3694d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner default: MultipleFiles = true; 370fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner } 3714d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner 3724d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner std::for_each(InputFilenames.begin(), InputFilenames.end(), 3734d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner DumpSymbolNamesFromFile); 3744d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner return 0; 375972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke} 376