llvm-nm.cpp revision 820428711f651a6ae6b9caf78ae170a4434d1670
1972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke//===-- llvm-nm.cpp - Symbol table dumping utility for llvm ---------------===//
27c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//                     The LLVM Compiler Infrastructure
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
57c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// This file was developed by the LLVM research group and is distributed under
67c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details.
77c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===//
9972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke//
10972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// This program is a utility that works like traditional Unix "nm",
11972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// that is, it prints out the names of symbols in a bytecode file,
12972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke// along with some information about each symbol.
13972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke//
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
19972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke#include "llvm/Module.h"
2008020c13d026c6b61ca68e3f9da127a4d8be36baChris Lattner#include "llvm/Bytecode/Reader.h"
2108020c13d026c6b61ca68e3f9da127a4d8be36baChris Lattner#include "Support/CommandLine.h"
221c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke#include "Support/FileUtilities.h"
23972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke#include <cctype>
2408d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke#include <cstring>
25972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
27d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
28972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekenamespace {
29972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  enum OutputFormatTy { bsd, sysv, posix };
30972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<OutputFormatTy>
31972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  OutputFormat("format",
32972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke       cl::desc("Specify output format"),
33972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke         cl::values(clEnumVal(bsd,   "BSD format"),
34972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                    clEnumVal(sysv,  "System V format"),
35972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                    clEnumVal(posix, "POSIX.2 format"), 0), cl::init(bsd));
36972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::alias OutputFormat2("f", cl::desc("Alias for --format"),
37972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                          cl::aliasopt(OutputFormat));
38972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
39972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::list<std::string>
40972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  InputFilenames(cl::Positional, cl::desc("<input bytecode files>"),
41fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner                 cl::ZeroOrMore);
42972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
43972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> UndefinedOnly("undefined-only",
44972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                              cl::desc("Show only undefined symbols"));
45972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"),
46972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                           cl::aliasopt(UndefinedOnly));
47972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
48972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> DefinedOnly("defined-only",
49972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                            cl::desc("Show only defined symbols"));
50972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
51972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> ExternalOnly("extern-only",
52972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                             cl::desc("Show only external symbols"));
53972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"),
54972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                          cl::aliasopt(ExternalOnly));
55972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
56972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"));
57972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"));
58972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
59972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  bool MultipleFiles = false;
60972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
61972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  std::string ToolName;
62972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke};
63972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
64972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekechar TypeCharForSymbol (GlobalValue &GV) {
65972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (GV.isExternal ())                                     return 'U';
66972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (GV.hasLinkOnceLinkage ())                             return 'C';
67972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (GV.hasWeakLinkage ())                                 return 'W';
68972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (isa<Function> (GV) && GV.hasInternalLinkage ())       return 't';
69972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (isa<Function> (GV))                                   return 'T';
70972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (isa<GlobalVariable> (GV) && GV.hasInternalLinkage ()) return 'd';
71972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (isa<GlobalVariable> (GV))                             return 'D';
72972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                                                            return '?';
73972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
74972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
75972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekevoid DumpSymbolNameForGlobalValue (GlobalValue &GV) {
76972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  const std::string SymbolAddrStr = "        "; // Not used yet...
77972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  char TypeChar = TypeCharForSymbol (GV);
78972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if ((TypeChar != 'U') && UndefinedOnly)
79972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    return;
80972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if ((TypeChar == 'U') && DefinedOnly)
81972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    return;
82972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (GV.hasInternalLinkage () && ExternalOnly)
83972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    return;
84972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (OutputFormat == posix) {
85972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    std::cout << GV.getName () << " " << TypeCharForSymbol (GV) << " "
86972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke              << SymbolAddrStr << "\n";
87972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  } else if (OutputFormat == bsd) {
88972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    std::cout << SymbolAddrStr << " " << TypeCharForSymbol (GV) << " "
89972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke              << GV.getName () << "\n";
90972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  } else if (OutputFormat == sysv) {
91972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    std::string PaddedName (GV.getName ());
92972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    while (PaddedName.length () < 20)
93972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke      PaddedName += " ";
94972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    std::cout << PaddedName << "|" << SymbolAddrStr << "|   "
95972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke              << TypeCharForSymbol (GV)
96972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke              << "  |                  |      |     |\n";
97972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  }
98972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
99972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
100972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekevoid DumpSymbolNamesFromModule (Module *M) {
1011c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke  const std::string &Filename = M->getModuleIdentifier ();
1021c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke  if (OutputFormat == posix && MultipleFiles) {
1031c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    std::cout << Filename << ":\n";
1041c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke  } else if (OutputFormat == bsd && MultipleFiles) {
1051c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    std::cout << "\n" << Filename << ":\n";
1061c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke  } else if (OutputFormat == sysv) {
1071c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    std::cout << "\n\nSymbols from " << Filename << ":\n\n"
1081c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke              << "Name                  Value   Class        Type"
1091c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke              << "         Size   Line  Section\n";
1101c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke  }
111972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  std::for_each (M->begin (), M->end (), DumpSymbolNameForGlobalValue);
112972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  std::for_each (M->gbegin (), M->gend (), DumpSymbolNameForGlobalValue);
113972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
114972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
115972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekevoid DumpSymbolNamesFromFile (std::string &Filename) {
116972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  std::string ErrorMessage;
11708d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke  if (!FileOpenable (Filename)) {
11808d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke    std::cerr << ToolName << ": " << Filename << ": " << strerror (errno)
11908d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke              << "\n";
12008d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke    return;
12108d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke  }
1221c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke  if (IsBytecode (Filename)) {
1231c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    Module *Result = ParseBytecodeFile(Filename, &ErrorMessage);
1241c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    if (Result) {
1251c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke      DumpSymbolNamesFromModule (Result);
1261c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    } else {
1271c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke      std::cerr << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
12808d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke      return;
129972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    }
1301c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke  } else if (IsArchive (Filename)) {
1311c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    std::vector<Module *> Modules;
13208d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke    if (ReadArchiveFile (Filename, Modules, &ErrorMessage)) {
1331c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke      std::cerr << ToolName << ": " << Filename << ": "
1341c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke                << ErrorMessage << "\n";
13508d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke      return;
13608d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke    }
1371c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    MultipleFiles = true;
1381c0b6982d28c910e7555d2c7a98f745f5d701827Brian Gaeke    std::for_each (Modules.begin (), Modules.end (), DumpSymbolNamesFromModule);
139820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke  } else {
140820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke    std::cerr << ToolName << ": " << Filename << ": "
141820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke              << "unrecognizable file type\n";
142820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke    return;
143972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  }
144972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
145972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
146972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekeint main(int argc, char **argv) {
147972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::ParseCommandLineOptions(argc, argv, " llvm symbol table dumper\n");
148972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  ToolName = argv[0];
149972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (BSDFormat) OutputFormat = bsd;
150972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  if (POSIXFormat) OutputFormat = posix;
151fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner
152fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner  switch (InputFilenames.size()) {
153fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner  case 0: InputFilenames.push_back("-");
154fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner  case 1: break;
155fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner  default: MultipleFiles = true;
156fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner  }
157972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
158972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  std::for_each (InputFilenames.begin (), InputFilenames.end (),
159972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                 DumpSymbolNamesFromFile);
160972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  return 0;
161972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
162