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