llvm-nm.cpp revision bc884fd9f7bdb64d250be639edc8dc85a20a1975
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
190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
20f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Bitcode/ReaderWriter.h"
210b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
229142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer#include "llvm/Object/Archive.h"
23bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola#include "llvm/Object/COFF.h"
24bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola#include "llvm/Object/ELFObjectFile.h"
25bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola#include "llvm/Object/MachO.h"
269c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov#include "llvm/Object/MachOUniversal.h"
2720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include "llvm/Object/ObjectFile.h"
28551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h"
2920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include "llvm/Support/FileSystem.h"
30f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/Format.h"
31c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h"
324d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner#include "llvm/Support/MemoryBuffer.h"
33cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
34a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer#include "llvm/Support/Program.h"
351f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Signals.h"
36f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/raw_ostream.h"
37333fb04506233255f10d8095c9e2de5e5f0fdc6fMichael J. Spencer#include "llvm/Support/system_error.h"
38ca5183d445954a9b2a570d6bbba1bc2b00ad6442Jeff Cohen#include <algorithm>
39972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke#include <cctype>
4009233fb86e237715d138db5dc5b72ada386089f2Alkis Evlogimenos#include <cerrno>
4108d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke#include <cstring>
4220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer#include <vector>
43d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
4420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencerusing namespace object;
45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
46972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekenamespace {
47972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  enum OutputFormatTy { bsd, sysv, posix };
48972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<OutputFormatTy>
49972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  OutputFormat("format",
50972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke       cl::desc("Specify output format"),
51972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke         cl::values(clEnumVal(bsd,   "BSD format"),
52972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                    clEnumVal(sysv,  "System V format"),
533da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman                    clEnumVal(posix, "POSIX.2 format"),
544d143ee01988e1b52e106ffccbb313937ca5e886Chris Lattner                    clEnumValEnd), cl::init(bsd));
55972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::alias OutputFormat2("f", cl::desc("Alias for --format"),
56972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                          cl::aliasopt(OutputFormat));
57972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
583da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman  cl::list<std::string>
59a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif  InputFilenames(cl::Positional, cl::desc("<input bitcode files>"),
60fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner                 cl::ZeroOrMore);
61972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
62972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> UndefinedOnly("undefined-only",
63972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                              cl::desc("Show only undefined symbols"));
64972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"),
65972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                           cl::aliasopt(UndefinedOnly));
66972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
67dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  cl::opt<bool> DynamicSyms("dynamic",
68dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer                             cl::desc("Display the dynamic symbols instead "
69dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer                                      "of normal symbols."));
70dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"),
71dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer                         cl::aliasopt(DynamicSyms));
72dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer
73972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> DefinedOnly("defined-only",
74972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                            cl::desc("Show only defined symbols"));
75972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
76972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> ExternalOnly("extern-only",
77972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                             cl::desc("Show only external symbols"));
78972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::alias ExternalOnly2("g", cl::desc("Alias for --extern-only"),
79972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke                          cl::aliasopt(ExternalOnly));
80972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
81972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> BSDFormat("B", cl::desc("Alias for --format=bsd"));
82972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  cl::opt<bool> POSIXFormat("P", cl::desc("Alias for --format=posix"));
83972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
8420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::opt<bool> PrintFileName("print-file-name",
8520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    cl::desc("Precede each symbol with the object file it came from"));
8620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
8720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::alias PrintFileNameA("A", cl::desc("Alias for --print-file-name"),
8820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                                cl::aliasopt(PrintFileName));
8920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::alias PrintFileNameo("o", cl::desc("Alias for --print-file-name"),
9020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                                cl::aliasopt(PrintFileName));
9120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
9220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::opt<bool> DebugSyms("debug-syms",
9320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    cl::desc("Show all symbols, even debugger only"));
9420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::alias DebugSymsa("a", cl::desc("Alias for --debug-syms"),
9520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                            cl::aliasopt(DebugSyms));
9620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
9720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::opt<bool> NumericSort("numeric-sort",
9820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    cl::desc("Sort symbols by address"));
9920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::alias NumericSortn("n", cl::desc("Alias for --numeric-sort"),
10020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                              cl::aliasopt(NumericSort));
10120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::alias NumericSortv("v", cl::desc("Alias for --numeric-sort"),
10220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                              cl::aliasopt(NumericSort));
10320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
10420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::opt<bool> NoSort("no-sort",
10520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    cl::desc("Show symbols in order encountered"));
10620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::alias NoSortp("p", cl::desc("Alias for --no-sort"),
10720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                         cl::aliasopt(NoSort));
10820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
10920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::opt<bool> PrintSize("print-size",
11020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    cl::desc("Show symbol size instead of address"));
11120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::alias PrintSizeS("S", cl::desc("Alias for --print-size"),
11220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                            cl::aliasopt(PrintSize));
11320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
11420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size"));
11520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
11618505b352212a5e9eac07a8555ded232b5ece894Jan Sjödin  cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden,
11718505b352212a5e9eac07a8555ded232b5ece894Jan Sjödin                               cl::desc("Exclude aliases from output"));
11818505b352212a5e9eac07a8555ded232b5ece894Jan Sjödin
119206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran  cl::opt<bool> ArchiveMap("print-armap",
120206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran    cl::desc("Print the archive map"));
121206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran  cl::alias ArchiveMaps("s", cl::desc("Alias for --print-armap"),
122206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran                                 cl::aliasopt(ArchiveMap));
12320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  bool PrintAddress = true;
12420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
125972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  bool MultipleFiles = false;
126972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
12740d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola  bool HadError = false;
12840d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola
129972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  std::string ToolName;
130d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner}
131972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
132a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
133a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencerstatic void error(Twine message, Twine path = Twine()) {
134a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  errs() << ToolName << ": " << path << ": " << message << ".\n";
135a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer}
136a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
137a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencerstatic bool error(error_code ec, Twine path = Twine()) {
138a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  if (ec) {
139a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    error(ec.message(), path);
14040d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola    HadError = true;
141a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    return true;
142a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  }
143a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  return false;
144a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer}
145a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
14620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencernamespace {
14720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  struct NMSymbol {
14820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    uint64_t  Address;
14920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    uint64_t  Size;
15020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    char      TypeChar;
15120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    StringRef Name;
15220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  };
15320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
15420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  static bool CompareSymbolAddress(const NMSymbol &a, const NMSymbol &b) {
15520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (a.Address < b.Address)
15620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      return true;
15720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    else if (a.Address == b.Address && a.Name < b.Name)
15820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      return true;
159ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar    else if (a.Address == b.Address && a.Name == b.Name && a.Size < b.Size)
160ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar      return true;
16120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    else
16220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      return false;
16320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
16420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  }
16520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
16620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  static bool CompareSymbolSize(const NMSymbol &a, const NMSymbol &b) {
16720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (a.Size < b.Size)
16820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      return true;
16920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    else if (a.Size == b.Size && a.Name < b.Name)
17020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      return true;
171ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar    else if (a.Size == b.Size && a.Name == b.Name && a.Address < b.Address)
172ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar      return true;
17320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    else
17420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      return false;
17520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  }
17620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
17720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  static bool CompareSymbolName(const NMSymbol &a, const NMSymbol &b) {
178ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar    if (a.Name < b.Name)
179ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar      return true;
180ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar    else if (a.Name == b.Name && a.Size < b.Size)
181ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar      return true;
182ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar    else if (a.Name == b.Name && a.Size == b.Size && a.Address < b.Address)
183ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar      return true;
184ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar    else
185ed074e9a1b69a55e91d9f8976cdced3a06d6058aDaniel Dunbar      return false;
18620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  }
18720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
18820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  StringRef CurrentFilename;
18920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  typedef std::vector<NMSymbol> SymbolListT;
19020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  SymbolListT SymbolList;
19120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer}
19220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
19320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencerstatic void SortAndPrintSymbolList() {
19420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  if (!NoSort) {
19520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (NumericSort)
19620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolAddress);
19720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    else if (SizeSort)
19820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolSize);
19920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    else
20020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      std::sort(SymbolList.begin(), SymbolList.end(), CompareSymbolName);
20120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  }
20220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
20320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  if (OutputFormat == posix && MultipleFiles) {
20420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    outs() << '\n' << CurrentFilename << ":\n";
20520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  } else if (OutputFormat == bsd && MultipleFiles) {
20620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    outs() << "\n" << CurrentFilename << ":\n";
20720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  } else if (OutputFormat == sysv) {
20820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    outs() << "\n\nSymbols from " << CurrentFilename << ":\n\n"
20920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer           << "Name                  Value   Class        Type"
21020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer           << "         Size   Line  Section\n";
21120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  }
21220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
21320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  for (SymbolListT::iterator i = SymbolList.begin(),
21420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer                             e = SymbolList.end(); i != e; ++i) {
21520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if ((i->TypeChar != 'U') && UndefinedOnly)
21620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      continue;
21720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if ((i->TypeChar == 'U') && DefinedOnly)
21820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      continue;
21920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (SizeSort && !PrintAddress && i->Size == UnknownAddressOrSize)
22020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      continue;
22120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
22220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    char SymbolAddrStr[10] = "";
22320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    char SymbolSizeStr[10] = "";
22420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
22520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (OutputFormat == sysv || i->Address == object::UnknownAddressOrSize)
22620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      strcpy(SymbolAddrStr, "        ");
22720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (OutputFormat == sysv)
22820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      strcpy(SymbolSizeStr, "        ");
22920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
23020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (i->Address != object::UnknownAddressOrSize)
23151cf8661637c114e4b4f178bd2677a6bb246be0dBenjamin Kramer      format("%08" PRIx64, i->Address).print(SymbolAddrStr,
23251cf8661637c114e4b4f178bd2677a6bb246be0dBenjamin Kramer                                             sizeof(SymbolAddrStr));
23320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (i->Size != object::UnknownAddressOrSize)
23451cf8661637c114e4b4f178bd2677a6bb246be0dBenjamin Kramer      format("%08" PRIx64, i->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
23520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
23620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (OutputFormat == posix) {
23720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      outs() << i->Name << " " << i->TypeChar << " "
23820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer             << SymbolAddrStr << SymbolSizeStr << "\n";
23920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    } else if (OutputFormat == bsd) {
24020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      if (PrintAddress)
24120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer        outs() << SymbolAddrStr << ' ';
24220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      if (PrintSize) {
24320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer        outs() << SymbolSizeStr;
24420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer        if (i->Size != object::UnknownAddressOrSize)
24520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer          outs() << ' ';
24620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      }
24720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      outs() << i->TypeChar << " " << i->Name  << "\n";
24820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    } else if (OutputFormat == sysv) {
24920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      std::string PaddedName (i->Name);
25020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      while (PaddedName.length () < 20)
25120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer        PaddedName += " ";
25220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      outs() << PaddedName << "|" << SymbolAddrStr << "|   "
25320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer             << i->TypeChar
25420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer             << "  |                  |" << SymbolSizeStr << "|     |\n";
25520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    }
25620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  }
25720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
25820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  SymbolList.clear();
25920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer}
26020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
261c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic char TypeCharForSymbol(GlobalValue &GV) {
2624a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio  if (GV.isDeclaration())                                  return 'U';
263c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner  if (GV.hasLinkOnceLinkage())                             return 'C';
2647d5633e9074db9eaf796e677451f6642c0174facDale Johannesen  if (GV.hasCommonLinkage())                               return 'C';
265c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner  if (GV.hasWeakLinkage())                                 return 'W';
2664a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio  if (isa<Function>(GV) && GV.hasInternalLinkage())        return 't';
267c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner  if (isa<Function>(GV))                                   return 'T';
2684a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio  if (isa<GlobalVariable>(GV) && GV.hasInternalLinkage())  return 'd';
269c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner  if (isa<GlobalVariable>(GV))                             return 'D';
2704a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio  if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) {
2714a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio    const GlobalValue *AliasedGV = GA->getAliasedGlobal();
2724a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio    if (isa<Function>(AliasedGV))                          return 'T';
2734a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio    if (isa<GlobalVariable>(AliasedGV))                    return 'D';
2744a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio  }
2754a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio                                                           return '?';
276972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
277972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
278c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic void DumpSymbolNameForGlobalValue(GlobalValue &GV) {
279266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner  // Private linkage and available_externally linkage don't exist in symtab.
2804e34d502727df36cc2caa59307953444b1ee9914Bill Wendling  if (GV.hasPrivateLinkage() ||
2814e34d502727df36cc2caa59307953444b1ee9914Bill Wendling      GV.hasLinkerPrivateLinkage() ||
2824e34d502727df36cc2caa59307953444b1ee9914Bill Wendling      GV.hasLinkerPrivateWeakLinkage() ||
2834e34d502727df36cc2caa59307953444b1ee9914Bill Wendling      GV.hasAvailableExternallyLinkage())
2845e721d768254a920b78b9129d79a84c0163cb3f4Bill Wendling    return;
285266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner  char TypeChar = TypeCharForSymbol(GV);
286bb46f52027416598a662dc1c58f48d9d56b1a65bRafael Espindola  if (GV.hasLocalLinkage () && ExternalOnly)
287972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke    return;
28820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
28920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  NMSymbol s;
29020d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  s.Address = object::UnknownAddressOrSize;
29120d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  s.Size = object::UnknownAddressOrSize;
29220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  s.TypeChar = TypeChar;
29320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  s.Name     = GV.getName();
29420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  SymbolList.push_back(s);
295972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
296972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
297c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic void DumpSymbolNamesFromModule(Module *M) {
29820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  CurrentFilename = M->getModuleIdentifier();
299266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner  std::for_each (M->begin(), M->end(), DumpSymbolNameForGlobalValue);
300266c7bbbbcc4b326dea82e577de1a415d6acc23eChris Lattner  std::for_each (M->global_begin(), M->global_end(),
3014a828eeed33a6f11698b625190bc7eafceee3100Lauro Ramos Venancio                 DumpSymbolNameForGlobalValue);
30218505b352212a5e9eac07a8555ded232b5ece894Jan Sjödin  if (!WithoutAliases)
30318505b352212a5e9eac07a8555ded232b5ece894Jan Sjödin    std::for_each (M->alias_begin(), M->alias_end(),
30418505b352212a5e9eac07a8555ded232b5ece894Jan Sjödin		   DumpSymbolNameForGlobalValue);
30520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
30620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  SortAndPrintSymbolList();
30720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer}
30820d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
309bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolatemplate <class ELFT>
310bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolaerror_code getSymbolNMTypeChar(ELFObjectFile<ELFT> &Obj, symbol_iterator I,
311bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                               char &Result) {
312bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
313bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
314bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
315bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  DataRefImpl Symb = I->getRawDataRefImpl();
316bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  const Elf_Sym *ESym = Obj.getSymbol(Symb);
317bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  const ELFFile<ELFT> &EF = *Obj.getELFFile();
318bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  const Elf_Shdr *ESec = EF.getSection(ESym);
319bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
320bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  char ret = '?';
321bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
322bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (ESec) {
323bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    switch (ESec->sh_type) {
324bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    case ELF::SHT_PROGBITS:
325bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    case ELF::SHT_DYNAMIC:
326bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      switch (ESec->sh_flags) {
327bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      case(ELF::SHF_ALLOC | ELF::SHF_EXECINSTR) :
328bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola        ret = 't';
329bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola        break;
330bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      case(ELF::SHF_ALLOC | ELF::SHF_WRITE) :
331bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola        ret = 'd';
332bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola        break;
333bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      case ELF::SHF_ALLOC:
334bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      case(ELF::SHF_ALLOC | ELF::SHF_MERGE) :
335bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      case(ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS) :
336bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola        ret = 'r';
337bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola        break;
338bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      }
339bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      break;
340bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    case ELF::SHT_NOBITS:
341bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'b';
342bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    }
343bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
344bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
345bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  switch (EF.getSymbolTableIndex(ESym)) {
346bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case ELF::SHN_UNDEF:
347bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    if (ret == '?')
348bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'U';
349bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
350bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case ELF::SHN_ABS:
351bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    ret = 'a';
352bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
353bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case ELF::SHN_COMMON:
354bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    ret = 'c';
355bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
356bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
357bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
358bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  switch (ESym->getBinding()) {
359bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case ELF::STB_GLOBAL:
360bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    ret = ::toupper(ret);
361bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
362bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case ELF::STB_WEAK:
363bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF)
364bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'w';
365bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else if (ESym->getType() == ELF::STT_OBJECT)
366bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'V';
367bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else
368bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'W';
369bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
370bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
371bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (ret == '?' && ESym->getType() == ELF::STT_SECTION) {
372bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    StringRef Name;
373bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    error_code EC = I->getName(Name);
374bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    if (EC)
375bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      return EC;
376bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Result = StringSwitch<char>(Name)
377bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                 .StartsWith(".debug", 'N')
378bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                 .StartsWith(".note", 'n')
379bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                 .Default('?');
380bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return object_error::success;
381bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
382bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
383bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  Result = ret;
384bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  return object_error::success;
385bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola}
386bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
387bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolastatic error_code getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I,
388bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                                      char &Result) {
389bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  const coff_symbol *symb = Obj.getCOFFSymbol(I);
390bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  StringRef name;
391bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (error_code ec = I->getName(name))
392bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return ec;
393bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  char ret = StringSwitch<char>(name)
394bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                 .StartsWith(".debug", 'N')
395bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                 .StartsWith(".sxdata", 'N')
396bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                 .Default('?');
397bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
398bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (ret != '?') {
399bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Result = ret;
400bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return object_error::success;
401bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
402bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
403bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  uint32_t Characteristics = 0;
404bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (symb->SectionNumber > 0) {
405bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    section_iterator SecI = Obj.end_sections();
406bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    if (error_code ec = I->getSection(SecI))
407bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      return ec;
408bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    const coff_section *Section = Obj.getCOFFSection(SecI);
409bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Characteristics = Section->Characteristics;
410bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
411bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
412bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  switch (symb->SectionNumber) {
413bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case COFF::IMAGE_SYM_UNDEFINED:
414bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    // Check storage classes.
415bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) {
416bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      Result = 'w';
417bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      return object_error::success; // Don't do ::toupper.
418bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    } else if (symb->Value != 0)    // Check for common symbols.
419bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'c';
420bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else
421bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'u';
422bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
423bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case COFF::IMAGE_SYM_ABSOLUTE:
424bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    ret = 'a';
425bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
426bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case COFF::IMAGE_SYM_DEBUG:
427bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    ret = 'n';
428bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
429bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  default:
430bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    // Check section type.
431bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    if (Characteristics & COFF::IMAGE_SCN_CNT_CODE)
432bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 't';
433bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else if (Characteristics & COFF::IMAGE_SCN_MEM_READ &&
434bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola             ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only.
435bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'r';
436bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
437bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'd';
438bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
439bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'b';
440bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO)
441bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 'i';
442bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
443bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    // Check for section symbol.
444bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC &&
445bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola             symb->Value == 0)
446bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      ret = 's';
447bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
448bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
449bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL)
450bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    ret = ::toupper(static_cast<unsigned char>(ret));
451bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
452bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  Result = ret;
453bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  return object_error::success;
454bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola}
455bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
456bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolastatic uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) {
457bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (Obj.is64Bit()) {
458bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb);
459bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return STE.n_type;
460bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
461bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  MachO::nlist STE = Obj.getSymbolTableEntry(Symb);
462bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  return STE.n_type;
463bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola}
464bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
465bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolastatic error_code getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I,
466bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola                                      char &Res) {
467bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  DataRefImpl Symb = I->getRawDataRefImpl();
468bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  uint8_t NType = getNType(Obj, Symb);
469bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
470bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  char Char;
471bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  switch (NType & MachO::N_TYPE) {
472bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case MachO::N_UNDF:
473bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Char = 'u';
474bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
475bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case MachO::N_ABS:
476bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Char = 's';
477bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
478bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  case MachO::N_SECT: {
479bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    section_iterator Sec = Obj.end_sections();
480bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Obj.getSymbolSection(Symb, Sec);
481bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    DataRefImpl Ref = Sec->getRawDataRefImpl();
482bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    StringRef SectionName;
483bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Obj.getSectionName(Ref, SectionName);
484bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref);
485bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    if (SegmentName == "__TEXT" && SectionName == "__text")
486bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      Char = 't';
487bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    else
488bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola      Char = 's';
489bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  } break;
490bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  default:
491bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Char = '?';
492bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    break;
493bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
494bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
495bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (NType & (MachO::N_EXT | MachO::N_PEXT))
496bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    Char = toupper(static_cast<unsigned char>(Char));
497bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  Res = Char;
498bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  return object_error::success;
499bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola}
500bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
501bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindolastatic char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) {
502bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  char Res = '?';
503bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (COFFObjectFile *COFF = dyn_cast<COFFObjectFile>(Obj)) {
504bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    error(getSymbolNMTypeChar(*COFF, I, Res));
505bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return Res;
506bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
507bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj)) {
508bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    error(getSymbolNMTypeChar(*MachO, I, Res));
509bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return Res;
510bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
511bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
512bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (ELF32LEObjectFile *ELF = dyn_cast<ELF32LEObjectFile>(Obj)) {
513bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    error(getSymbolNMTypeChar(*ELF, I, Res));
514bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return Res;
515bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
516bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (ELF64LEObjectFile *ELF = dyn_cast<ELF64LEObjectFile>(Obj)) {
517bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    error(getSymbolNMTypeChar(*ELF, I, Res));
518bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return Res;
519bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
520bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  if (ELF32BEObjectFile *ELF = dyn_cast<ELF32BEObjectFile>(Obj)) {
521bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    error(getSymbolNMTypeChar(*ELF, I, Res));
522bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    return Res;
523bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  }
524bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  ELF64BEObjectFile *ELF = cast<ELF64BEObjectFile>(Obj);
525bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  error(getSymbolNMTypeChar(*ELF, I, Res));
526bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola  return Res;
527bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola}
528bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola
52920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencerstatic void DumpSymbolNamesFromObject(ObjectFile *obj) {
53025b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer  error_code ec;
531dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  symbol_iterator ibegin = obj->begin_symbols();
532dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  symbol_iterator iend = obj->end_symbols();
533dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  if (DynamicSyms) {
534dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer    ibegin = obj->begin_dynamic_symbols();
535dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer    iend = obj->end_dynamic_symbols();
536dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  }
537dfa1896b6b61e708f002b814794890ff308172eeMichael J. Spencer  for (symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
53825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error(ec)) break;
539c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    uint32_t symflags;
540c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    if (error(i->getFlags(symflags))) break;
541c46255a32ec92c427e621b6d7eabd887962ce4a4David Meyer    if (!DebugSyms && (symflags & SymbolRef::SF_FormatSpecific))
54220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      continue;
54320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    NMSymbol s;
54420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    s.Size = object::UnknownAddressOrSize;
54520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    s.Address = object::UnknownAddressOrSize;
54625b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (PrintSize || SizeSort) {
54725b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer      if (error(i->getSize(s.Size))) break;
54825b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    }
54920d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    if (PrintAddress)
550b0436a73054fe676b216a0cf872d1fc433125c62Danil Malyshev      if (error(i->getAddress(s.Address))) break;
551bc884fd9f7bdb64d250be639edc8dc85a20a1975Rafael Espindola    s.TypeChar = getNMTypeChar(obj, i);
55225b15777df42d5d608810f6881b6c98107481d69Michael J. Spencer    if (error(i->getName(s.Name))) break;
55320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer    SymbolList.push_back(s);
55420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  }
55520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
556001c9205fca2220480589ec355cb6ec701a37e08Michael J. Spencer  CurrentFilename = obj->getFileName();
55720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  SortAndPrintSymbolList();
558972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
559972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
560c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattnerstatic void DumpSymbolNamesFromFile(std::string &Filename) {
561a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  if (Filename != "-" && !sys::fs::exists(Filename)) {
562a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    errs() << ToolName << ": '" << Filename << "': " << "No such file\n";
563a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    return;
564a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  }
565a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
566a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  OwningPtr<MemoryBuffer> Buffer;
567a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename))
568a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    return;
569a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
570a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());
571a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
5720d7c695c74ae6d5f68cc07378c17491915e607d3Owen Anderson  LLVMContext &Context = getGlobalContext();
573972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  std::string ErrorMessage;
574a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  if (magic == sys::fs::file_magic::bitcode) {
5754d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner    Module *Result = 0;
576a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
5778018f5d5a4134f8b2ceb315095996a552a80ee25Nuno Lopes    if (Result) {
5784d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner      DumpSymbolNamesFromModule(Result);
5798018f5d5a4134f8b2ceb315095996a552a80ee25Nuno Lopes      delete Result;
580a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    } else {
581a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer      error(ErrorMessage, Filename);
58208d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke      return;
58308d03c79a238dba0ea7b59b38304c431bd392432Brian Gaeke    }
584a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  } else if (magic == sys::fs::file_magic::archive) {
585a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    OwningPtr<Binary> arch;
586a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    if (error(object::createBinary(Buffer.take(), arch), Filename))
587a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer      return;
588a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
5899142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer    if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
590206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran      if (ArchiveMap) {
5915159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola        object::Archive::symbol_iterator I = a->begin_symbols();
5925159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola        object::Archive::symbol_iterator E = a->end_symbols();
5935159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola        if (I !=E) {
5945159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola          outs() << "Archive map" << "\n";
5955159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola          for (; I != E; ++I) {
5965159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola            object::Archive::child_iterator c;
5975159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola            StringRef symname;
5985159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola            StringRef filename;
5995159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola            if (error(I->getMember(c)))
600206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran              return;
6015159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola            if (error(I->getName(symname)))
602206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran              return;
6035159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola            if (error(c->getName(filename)))
604206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran              return;
6055159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola            outs() << symname << " in " << filename << "\n";
6065159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola          }
6075159718095bd8a18c1661889e93af3aca8eaa5aaRafael Espindola          outs() << "\n";
608206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran        }
609206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran      }
610206252cc9f5509b27aa0761c677fdee8daff001cShankar Easwaran
6119142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer      for (object::Archive::child_iterator i = a->begin_children(),
6129142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer                                           e = a->end_children(); i != e; ++i) {
6139142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer        OwningPtr<Binary> child;
614aba65b05fc5dd8649725431e38359b7fa1ab59e8Rafael Espindola        if (i->getAsBinary(child)) {
6159142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          // Try opening it as a bitcode file.
6160f76e648d800d7641b4e6e6decb90949cd680b03Michael J. Spencer          OwningPtr<MemoryBuffer> buff;
6170f76e648d800d7641b4e6e6decb90949cd680b03Michael J. Spencer          if (error(i->getMemoryBuffer(buff)))
6180f76e648d800d7641b4e6e6decb90949cd680b03Michael J. Spencer            return;
6199142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          Module *Result = 0;
6209142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          if (buff)
6211a9908daebd5c416d71ff7fe9c8250074d817733Benjamin Kramer            Result = ParseBitcodeFile(buff.get(), Context, &ErrorMessage);
6229142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer
6239142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          if (Result) {
6249142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer            DumpSymbolNamesFromModule(Result);
6259142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer            delete Result;
6269142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          }
6279142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          continue;
6289142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer        }
6299142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer        if (object::ObjectFile *o = dyn_cast<ObjectFile>(child.get())) {
6309142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          outs() << o->getFileName() << ":\n";
6319142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer          DumpSymbolNamesFromObject(o);
6329142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer        }
6339142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer      }
6349142ae2cf802dbcd1c622154ac9b5305fb26c38fMichael J. Spencer    }
6359c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov  } else if (magic == sys::fs::file_magic::macho_universal_binary) {
6369c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov    OwningPtr<Binary> Bin;
6379c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov    if (error(object::createBinary(Buffer.take(), Bin), Filename))
6389c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov      return;
6399c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov
6409c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov    object::MachOUniversalBinary *UB =
6419c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov        cast<object::MachOUniversalBinary>(Bin.get());
6429c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov    for (object::MachOUniversalBinary::object_iterator
6439c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov             I = UB->begin_objects(),
6449c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov             E = UB->end_objects();
6459c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov         I != E; ++I) {
6469c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov      OwningPtr<ObjectFile> Obj;
6479c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov      if (!I->getAsObjectFile(Obj)) {
6489c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov        outs() << Obj->getFileName() << ":\n";
6499c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov        DumpSymbolNamesFromObject(Obj.get());
6509c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov      }
6519c22f87b1374b06dc6c07f6e8047890e390bbe2dAlexey Samsonov    }
652a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  } else if (magic.is_object()) {
65376fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer    OwningPtr<Binary> obj;
654a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    if (error(object::createBinary(Buffer.take(), obj), Filename))
65520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer      return;
65676fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer    if (object::ObjectFile *o = dyn_cast<ObjectFile>(obj.get()))
65776fb9b0e5f553f03321777ff634eb245dd8a821eMichael J. Spencer      DumpSymbolNamesFromObject(o);
658820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke  } else {
65965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    errs() << ToolName << ": " << Filename << ": "
66065f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman           << "unrecognizable file type\n";
66140d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola    HadError = true;
662820428711f651a6ae6b9caf78ae170a4434d1670Brian Gaeke    return;
663972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke  }
664972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
665972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke
666972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaekeint main(int argc, char **argv) {
667cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  // Print a stack trace if we signal out.
6684d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  sys::PrintStackTraceOnErrorSignal();
669cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  PrettyStackTraceProgram X(argc, argv);
6704a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
671cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
672cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n");
673fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner
674a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer  // llvm-nm only reads binary files.
6759f1d9fd1964d82f3e801efb71518144492cdf290Rafael Espindola  if (error(sys::ChangeStdinToBinary()))
676a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer    return 1;
677a740e19e7e4ef29a7404fac3ac7e513beacf1bf7Michael J. Spencer
6784d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  ToolName = argv[0];
6794d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  if (BSDFormat) OutputFormat = bsd;
6804d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  if (POSIXFormat) OutputFormat = posix;
6814d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner
68220d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  // The relative order of these is important. If you pass --size-sort it should
68320d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  // only print out the size. However, if you pass -S --size-sort, it should
68420d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  // print out both the size and address.
68520d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  if (SizeSort && !PrintSize) PrintAddress = false;
68620d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer  if (OutputFormat == sysv || SizeSort) PrintSize = true;
68720d335aa04e31fe9a16004982e2a333914c1ee82Michael J. Spencer
6884d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  switch (InputFilenames.size()) {
6894d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  case 0: InputFilenames.push_back("-");
6904d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  case 1: break;
6914d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  default: MultipleFiles = true;
692fc046d52e442324fe238e572c314f86dbc894f92Chris Lattner  }
6934d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner
6944d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  std::for_each(InputFilenames.begin(), InputFilenames.end(),
6954d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner                DumpSymbolNamesFromFile);
69640d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola
69740d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola  if (HadError)
69840d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola    return 1;
69940d40dd44edbac3c20a4f3305f208ab48c2c219aRafael Espindola
7004d5aad2d99233fdee38cbbf844f65b7a74073954Chris Lattner  return 0;
701972d3d7fff89c50612e86dfc8222da51bb23f387Brian Gaeke}
702