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