1*9880d681SAndroid Build Coastguard Worker //===-- llvm-objdump.cpp - Object file 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 binutils "objdump", that is, it
11*9880d681SAndroid Build Coastguard Worker // dumps out a plethora of information about an object file depending on the
12*9880d681SAndroid Build Coastguard Worker // flags.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // The flags and output of this program should be near identical to those of
15*9880d681SAndroid Build Coastguard Worker // binutils objdump.
16*9880d681SAndroid Build Coastguard Worker //
17*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker #include "llvm-objdump.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Optional.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/FaultMaps.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/DWARF/DWARFContext.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCDisassembler/MCDisassembler.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstPrinter.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrAnalysis.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectFileInfo.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/Archive.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/COFF.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ELFObjectFile.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/MachO.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Casting.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Errc.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/GraphWriter.h"
49*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Host.h"
50*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
51*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
52*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/PrettyStackTrace.h"
53*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Signals.h"
54*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SourceMgr.h"
55*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
56*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetSelect.h"
57*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
58*9880d681SAndroid Build Coastguard Worker #include <algorithm>
59*9880d681SAndroid Build Coastguard Worker #include <cctype>
60*9880d681SAndroid Build Coastguard Worker #include <cstring>
61*9880d681SAndroid Build Coastguard Worker #include <system_error>
62*9880d681SAndroid Build Coastguard Worker #include <utility>
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker using namespace llvm;
65*9880d681SAndroid Build Coastguard Worker using namespace object;
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker static cl::list<std::string>
68*9880d681SAndroid Build Coastguard Worker InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
71*9880d681SAndroid Build Coastguard Worker llvm::Disassemble("disassemble",
72*9880d681SAndroid Build Coastguard Worker cl::desc("Display assembler mnemonics for the machine instructions"));
73*9880d681SAndroid Build Coastguard Worker static cl::alias
74*9880d681SAndroid Build Coastguard Worker Disassembled("d", cl::desc("Alias for --disassemble"),
75*9880d681SAndroid Build Coastguard Worker cl::aliasopt(Disassemble));
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
78*9880d681SAndroid Build Coastguard Worker llvm::DisassembleAll("disassemble-all",
79*9880d681SAndroid Build Coastguard Worker cl::desc("Display assembler mnemonics for the machine instructions"));
80*9880d681SAndroid Build Coastguard Worker static cl::alias
81*9880d681SAndroid Build Coastguard Worker DisassembleAlld("D", cl::desc("Alias for --disassemble-all"),
82*9880d681SAndroid Build Coastguard Worker cl::aliasopt(DisassembleAll));
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
85*9880d681SAndroid Build Coastguard Worker llvm::Relocations("r", cl::desc("Display the relocation entries in the file"));
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
88*9880d681SAndroid Build Coastguard Worker llvm::SectionContents("s", cl::desc("Display the content of each section"));
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
91*9880d681SAndroid Build Coastguard Worker llvm::SymbolTable("t", cl::desc("Display the symbol table"));
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
94*9880d681SAndroid Build Coastguard Worker llvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
97*9880d681SAndroid Build Coastguard Worker llvm::Rebase("rebase", cl::desc("Display mach-o rebasing info"));
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
100*9880d681SAndroid Build Coastguard Worker llvm::Bind("bind", cl::desc("Display mach-o binding info"));
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
103*9880d681SAndroid Build Coastguard Worker llvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
106*9880d681SAndroid Build Coastguard Worker llvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
109*9880d681SAndroid Build Coastguard Worker llvm::RawClangAST("raw-clang-ast",
110*9880d681SAndroid Build Coastguard Worker cl::desc("Dump the raw binary contents of the clang AST section"));
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker static cl::opt<bool>
113*9880d681SAndroid Build Coastguard Worker MachOOpt("macho", cl::desc("Use MachO specific object file parser"));
114*9880d681SAndroid Build Coastguard Worker static cl::alias
115*9880d681SAndroid Build Coastguard Worker MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt));
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
118*9880d681SAndroid Build Coastguard Worker llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
119*9880d681SAndroid Build Coastguard Worker "see -version for available targets"));
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
122*9880d681SAndroid Build Coastguard Worker llvm::MCPU("mcpu",
123*9880d681SAndroid Build Coastguard Worker cl::desc("Target a specific cpu type (-mcpu=help for details)"),
124*9880d681SAndroid Build Coastguard Worker cl::value_desc("cpu-name"),
125*9880d681SAndroid Build Coastguard Worker cl::init(""));
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
128*9880d681SAndroid Build Coastguard Worker llvm::ArchName("arch-name", cl::desc("Target arch to disassemble for, "
129*9880d681SAndroid Build Coastguard Worker "see -version for available targets"));
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
132*9880d681SAndroid Build Coastguard Worker llvm::SectionHeaders("section-headers", cl::desc("Display summaries of the "
133*9880d681SAndroid Build Coastguard Worker "headers for each section."));
134*9880d681SAndroid Build Coastguard Worker static cl::alias
135*9880d681SAndroid Build Coastguard Worker SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
136*9880d681SAndroid Build Coastguard Worker cl::aliasopt(SectionHeaders));
137*9880d681SAndroid Build Coastguard Worker static cl::alias
138*9880d681SAndroid Build Coastguard Worker SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
139*9880d681SAndroid Build Coastguard Worker cl::aliasopt(SectionHeaders));
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
142*9880d681SAndroid Build Coastguard Worker llvm::FilterSections("section", cl::desc("Operate on the specified sections only. "
143*9880d681SAndroid Build Coastguard Worker "With -macho dump segment,section"));
144*9880d681SAndroid Build Coastguard Worker cl::alias
145*9880d681SAndroid Build Coastguard Worker static FilterSectionsj("j", cl::desc("Alias for --section"),
146*9880d681SAndroid Build Coastguard Worker cl::aliasopt(llvm::FilterSections));
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
149*9880d681SAndroid Build Coastguard Worker llvm::MAttrs("mattr",
150*9880d681SAndroid Build Coastguard Worker cl::CommaSeparated,
151*9880d681SAndroid Build Coastguard Worker cl::desc("Target specific attributes"),
152*9880d681SAndroid Build Coastguard Worker cl::value_desc("a1,+a2,-a3,..."));
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
155*9880d681SAndroid Build Coastguard Worker llvm::NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling "
156*9880d681SAndroid Build Coastguard Worker "instructions, do not print "
157*9880d681SAndroid Build Coastguard Worker "the instruction bytes."));
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
160*9880d681SAndroid Build Coastguard Worker llvm::UnwindInfo("unwind-info", cl::desc("Display unwind information"));
161*9880d681SAndroid Build Coastguard Worker
162*9880d681SAndroid Build Coastguard Worker static cl::alias
163*9880d681SAndroid Build Coastguard Worker UnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
164*9880d681SAndroid Build Coastguard Worker cl::aliasopt(UnwindInfo));
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
167*9880d681SAndroid Build Coastguard Worker llvm::PrivateHeaders("private-headers",
168*9880d681SAndroid Build Coastguard Worker cl::desc("Display format specific file headers"));
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
171*9880d681SAndroid Build Coastguard Worker llvm::FirstPrivateHeader("private-header",
172*9880d681SAndroid Build Coastguard Worker cl::desc("Display only the first format specific file "
173*9880d681SAndroid Build Coastguard Worker "header"));
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker static cl::alias
176*9880d681SAndroid Build Coastguard Worker PrivateHeadersShort("p", cl::desc("Alias for --private-headers"),
177*9880d681SAndroid Build Coastguard Worker cl::aliasopt(PrivateHeaders));
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
180*9880d681SAndroid Build Coastguard Worker llvm::PrintImmHex("print-imm-hex",
181*9880d681SAndroid Build Coastguard Worker cl::desc("Use hex format for immediate values"));
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker cl::opt<bool> PrintFaultMaps("fault-map-section",
184*9880d681SAndroid Build Coastguard Worker cl::desc("Display contents of faultmap section"));
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker cl::opt<DIDumpType> llvm::DwarfDumpType(
187*9880d681SAndroid Build Coastguard Worker "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
188*9880d681SAndroid Build Coastguard Worker cl::values(clEnumValN(DIDT_Frames, "frames", ".debug_frame"),
189*9880d681SAndroid Build Coastguard Worker clEnumValEnd));
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker static StringRef ToolName;
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker namespace {
194*9880d681SAndroid Build Coastguard Worker typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate;
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker class SectionFilterIterator {
197*9880d681SAndroid Build Coastguard Worker public:
SectionFilterIterator(FilterPredicate P,llvm::object::section_iterator const & I,llvm::object::section_iterator const & E)198*9880d681SAndroid Build Coastguard Worker SectionFilterIterator(FilterPredicate P,
199*9880d681SAndroid Build Coastguard Worker llvm::object::section_iterator const &I,
200*9880d681SAndroid Build Coastguard Worker llvm::object::section_iterator const &E)
201*9880d681SAndroid Build Coastguard Worker : Predicate(std::move(P)), Iterator(I), End(E) {
202*9880d681SAndroid Build Coastguard Worker ScanPredicate();
203*9880d681SAndroid Build Coastguard Worker }
operator *() const204*9880d681SAndroid Build Coastguard Worker const llvm::object::SectionRef &operator*() const { return *Iterator; }
operator ++()205*9880d681SAndroid Build Coastguard Worker SectionFilterIterator &operator++() {
206*9880d681SAndroid Build Coastguard Worker ++Iterator;
207*9880d681SAndroid Build Coastguard Worker ScanPredicate();
208*9880d681SAndroid Build Coastguard Worker return *this;
209*9880d681SAndroid Build Coastguard Worker }
operator !=(SectionFilterIterator const & Other) const210*9880d681SAndroid Build Coastguard Worker bool operator!=(SectionFilterIterator const &Other) const {
211*9880d681SAndroid Build Coastguard Worker return Iterator != Other.Iterator;
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker private:
ScanPredicate()215*9880d681SAndroid Build Coastguard Worker void ScanPredicate() {
216*9880d681SAndroid Build Coastguard Worker while (Iterator != End && !Predicate(*Iterator)) {
217*9880d681SAndroid Build Coastguard Worker ++Iterator;
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker }
220*9880d681SAndroid Build Coastguard Worker FilterPredicate Predicate;
221*9880d681SAndroid Build Coastguard Worker llvm::object::section_iterator Iterator;
222*9880d681SAndroid Build Coastguard Worker llvm::object::section_iterator End;
223*9880d681SAndroid Build Coastguard Worker };
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker class SectionFilter {
226*9880d681SAndroid Build Coastguard Worker public:
SectionFilter(FilterPredicate P,llvm::object::ObjectFile const & O)227*9880d681SAndroid Build Coastguard Worker SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O)
228*9880d681SAndroid Build Coastguard Worker : Predicate(std::move(P)), Object(O) {}
begin()229*9880d681SAndroid Build Coastguard Worker SectionFilterIterator begin() {
230*9880d681SAndroid Build Coastguard Worker return SectionFilterIterator(Predicate, Object.section_begin(),
231*9880d681SAndroid Build Coastguard Worker Object.section_end());
232*9880d681SAndroid Build Coastguard Worker }
end()233*9880d681SAndroid Build Coastguard Worker SectionFilterIterator end() {
234*9880d681SAndroid Build Coastguard Worker return SectionFilterIterator(Predicate, Object.section_end(),
235*9880d681SAndroid Build Coastguard Worker Object.section_end());
236*9880d681SAndroid Build Coastguard Worker }
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker private:
239*9880d681SAndroid Build Coastguard Worker FilterPredicate Predicate;
240*9880d681SAndroid Build Coastguard Worker llvm::object::ObjectFile const &Object;
241*9880d681SAndroid Build Coastguard Worker };
ToolSectionFilter(llvm::object::ObjectFile const & O)242*9880d681SAndroid Build Coastguard Worker SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O) {
243*9880d681SAndroid Build Coastguard Worker return SectionFilter([](llvm::object::SectionRef const &S) {
244*9880d681SAndroid Build Coastguard Worker if(FilterSections.empty())
245*9880d681SAndroid Build Coastguard Worker return true;
246*9880d681SAndroid Build Coastguard Worker llvm::StringRef String;
247*9880d681SAndroid Build Coastguard Worker std::error_code error = S.getName(String);
248*9880d681SAndroid Build Coastguard Worker if (error)
249*9880d681SAndroid Build Coastguard Worker return false;
250*9880d681SAndroid Build Coastguard Worker return std::find(FilterSections.begin(),
251*9880d681SAndroid Build Coastguard Worker FilterSections.end(),
252*9880d681SAndroid Build Coastguard Worker String) != FilterSections.end();
253*9880d681SAndroid Build Coastguard Worker },
254*9880d681SAndroid Build Coastguard Worker O);
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker }
257*9880d681SAndroid Build Coastguard Worker
error(std::error_code EC)258*9880d681SAndroid Build Coastguard Worker void llvm::error(std::error_code EC) {
259*9880d681SAndroid Build Coastguard Worker if (!EC)
260*9880d681SAndroid Build Coastguard Worker return;
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": error reading file: " << EC.message() << ".\n";
263*9880d681SAndroid Build Coastguard Worker errs().flush();
264*9880d681SAndroid Build Coastguard Worker exit(1);
265*9880d681SAndroid Build Coastguard Worker }
266*9880d681SAndroid Build Coastguard Worker
error(Twine Message)267*9880d681SAndroid Build Coastguard Worker LLVM_ATTRIBUTE_NORETURN void llvm::error(Twine Message) {
268*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": " << Message << ".\n";
269*9880d681SAndroid Build Coastguard Worker errs().flush();
270*9880d681SAndroid Build Coastguard Worker exit(1);
271*9880d681SAndroid Build Coastguard Worker }
272*9880d681SAndroid Build Coastguard Worker
report_error(StringRef File,std::error_code EC)273*9880d681SAndroid Build Coastguard Worker LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
274*9880d681SAndroid Build Coastguard Worker std::error_code EC) {
275*9880d681SAndroid Build Coastguard Worker assert(EC);
276*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": '" << File << "': " << EC.message() << ".\n";
277*9880d681SAndroid Build Coastguard Worker exit(1);
278*9880d681SAndroid Build Coastguard Worker }
279*9880d681SAndroid Build Coastguard Worker
report_error(StringRef File,llvm::Error E)280*9880d681SAndroid Build Coastguard Worker LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
281*9880d681SAndroid Build Coastguard Worker llvm::Error E) {
282*9880d681SAndroid Build Coastguard Worker assert(E);
283*9880d681SAndroid Build Coastguard Worker std::string Buf;
284*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
285*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(std::move(E), OS, "");
286*9880d681SAndroid Build Coastguard Worker OS.flush();
287*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": '" << File << "': " << Buf;
288*9880d681SAndroid Build Coastguard Worker exit(1);
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker
report_error(StringRef ArchiveName,StringRef FileName,llvm::Error E,StringRef ArchitectureName)291*9880d681SAndroid Build Coastguard Worker LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
292*9880d681SAndroid Build Coastguard Worker StringRef FileName,
293*9880d681SAndroid Build Coastguard Worker llvm::Error E,
294*9880d681SAndroid Build Coastguard Worker StringRef ArchitectureName) {
295*9880d681SAndroid Build Coastguard Worker assert(E);
296*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": ";
297*9880d681SAndroid Build Coastguard Worker if (ArchiveName != "")
298*9880d681SAndroid Build Coastguard Worker errs() << ArchiveName << "(" << FileName << ")";
299*9880d681SAndroid Build Coastguard Worker else
300*9880d681SAndroid Build Coastguard Worker errs() << FileName;
301*9880d681SAndroid Build Coastguard Worker if (!ArchitectureName.empty())
302*9880d681SAndroid Build Coastguard Worker errs() << " (for architecture " << ArchitectureName << ")";
303*9880d681SAndroid Build Coastguard Worker std::string Buf;
304*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
305*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(std::move(E), OS, "");
306*9880d681SAndroid Build Coastguard Worker OS.flush();
307*9880d681SAndroid Build Coastguard Worker errs() << " " << Buf;
308*9880d681SAndroid Build Coastguard Worker exit(1);
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker
report_error(StringRef ArchiveName,const object::Archive::Child & C,llvm::Error E,StringRef ArchitectureName)311*9880d681SAndroid Build Coastguard Worker LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
312*9880d681SAndroid Build Coastguard Worker const object::Archive::Child &C,
313*9880d681SAndroid Build Coastguard Worker llvm::Error E,
314*9880d681SAndroid Build Coastguard Worker StringRef ArchitectureName) {
315*9880d681SAndroid Build Coastguard Worker ErrorOr<StringRef> NameOrErr = C.getName();
316*9880d681SAndroid Build Coastguard Worker // TODO: if we have a error getting the name then it would be nice to print
317*9880d681SAndroid Build Coastguard Worker // the index of which archive member this is and or its offset in the
318*9880d681SAndroid Build Coastguard Worker // archive instead of "???" as the name.
319*9880d681SAndroid Build Coastguard Worker if (NameOrErr.getError())
320*9880d681SAndroid Build Coastguard Worker llvm::report_error(ArchiveName, "???", std::move(E), ArchitectureName);
321*9880d681SAndroid Build Coastguard Worker else
322*9880d681SAndroid Build Coastguard Worker llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E),
323*9880d681SAndroid Build Coastguard Worker ArchitectureName);
324*9880d681SAndroid Build Coastguard Worker }
325*9880d681SAndroid Build Coastguard Worker
getTarget(const ObjectFile * Obj=nullptr)326*9880d681SAndroid Build Coastguard Worker static const Target *getTarget(const ObjectFile *Obj = nullptr) {
327*9880d681SAndroid Build Coastguard Worker // Figure out the target triple.
328*9880d681SAndroid Build Coastguard Worker llvm::Triple TheTriple("unknown-unknown-unknown");
329*9880d681SAndroid Build Coastguard Worker if (TripleName.empty()) {
330*9880d681SAndroid Build Coastguard Worker if (Obj) {
331*9880d681SAndroid Build Coastguard Worker TheTriple.setArch(Triple::ArchType(Obj->getArch()));
332*9880d681SAndroid Build Coastguard Worker // TheTriple defaults to ELF, and COFF doesn't have an environment:
333*9880d681SAndroid Build Coastguard Worker // the best we can do here is indicate that it is mach-o.
334*9880d681SAndroid Build Coastguard Worker if (Obj->isMachO())
335*9880d681SAndroid Build Coastguard Worker TheTriple.setObjectFormat(Triple::MachO);
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker if (Obj->isCOFF()) {
338*9880d681SAndroid Build Coastguard Worker const auto COFFObj = dyn_cast<COFFObjectFile>(Obj);
339*9880d681SAndroid Build Coastguard Worker if (COFFObj->getArch() == Triple::thumb)
340*9880d681SAndroid Build Coastguard Worker TheTriple.setTriple("thumbv7-windows");
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker }
343*9880d681SAndroid Build Coastguard Worker } else
344*9880d681SAndroid Build Coastguard Worker TheTriple.setTriple(Triple::normalize(TripleName));
345*9880d681SAndroid Build Coastguard Worker
346*9880d681SAndroid Build Coastguard Worker // Get the target specific parser.
347*9880d681SAndroid Build Coastguard Worker std::string Error;
348*9880d681SAndroid Build Coastguard Worker const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
349*9880d681SAndroid Build Coastguard Worker Error);
350*9880d681SAndroid Build Coastguard Worker if (!TheTarget)
351*9880d681SAndroid Build Coastguard Worker report_fatal_error("can't find target: " + Error);
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker // Update the triple name and return the found target.
354*9880d681SAndroid Build Coastguard Worker TripleName = TheTriple.getTriple();
355*9880d681SAndroid Build Coastguard Worker return TheTarget;
356*9880d681SAndroid Build Coastguard Worker }
357*9880d681SAndroid Build Coastguard Worker
RelocAddressLess(RelocationRef a,RelocationRef b)358*9880d681SAndroid Build Coastguard Worker bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
359*9880d681SAndroid Build Coastguard Worker return a.getOffset() < b.getOffset();
360*9880d681SAndroid Build Coastguard Worker }
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker namespace {
363*9880d681SAndroid Build Coastguard Worker class PrettyPrinter {
364*9880d681SAndroid Build Coastguard Worker public:
~PrettyPrinter()365*9880d681SAndroid Build Coastguard Worker virtual ~PrettyPrinter(){}
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI)366*9880d681SAndroid Build Coastguard Worker virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
367*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes, uint64_t Address,
368*9880d681SAndroid Build Coastguard Worker raw_ostream &OS, StringRef Annot,
369*9880d681SAndroid Build Coastguard Worker MCSubtargetInfo const &STI) {
370*9880d681SAndroid Build Coastguard Worker OS << format("%8" PRIx64 ":", Address);
371*9880d681SAndroid Build Coastguard Worker if (!NoShowRawInsn) {
372*9880d681SAndroid Build Coastguard Worker OS << "\t";
373*9880d681SAndroid Build Coastguard Worker dumpBytes(Bytes, OS);
374*9880d681SAndroid Build Coastguard Worker }
375*9880d681SAndroid Build Coastguard Worker if (MI)
376*9880d681SAndroid Build Coastguard Worker IP.printInst(MI, OS, "", STI);
377*9880d681SAndroid Build Coastguard Worker else
378*9880d681SAndroid Build Coastguard Worker OS << " <unknown>";
379*9880d681SAndroid Build Coastguard Worker }
380*9880d681SAndroid Build Coastguard Worker };
381*9880d681SAndroid Build Coastguard Worker PrettyPrinter PrettyPrinterInst;
382*9880d681SAndroid Build Coastguard Worker class HexagonPrettyPrinter : public PrettyPrinter {
383*9880d681SAndroid Build Coastguard Worker public:
printLead(ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS)384*9880d681SAndroid Build Coastguard Worker void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
385*9880d681SAndroid Build Coastguard Worker raw_ostream &OS) {
386*9880d681SAndroid Build Coastguard Worker uint32_t opcode =
387*9880d681SAndroid Build Coastguard Worker (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
388*9880d681SAndroid Build Coastguard Worker OS << format("%8" PRIx64 ":", Address);
389*9880d681SAndroid Build Coastguard Worker if (!NoShowRawInsn) {
390*9880d681SAndroid Build Coastguard Worker OS << "\t";
391*9880d681SAndroid Build Coastguard Worker dumpBytes(Bytes.slice(0, 4), OS);
392*9880d681SAndroid Build Coastguard Worker OS << format("%08" PRIx32, opcode);
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker }
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI)395*9880d681SAndroid Build Coastguard Worker void printInst(MCInstPrinter &IP, const MCInst *MI,
396*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes, uint64_t Address,
397*9880d681SAndroid Build Coastguard Worker raw_ostream &OS, StringRef Annot,
398*9880d681SAndroid Build Coastguard Worker MCSubtargetInfo const &STI) override {
399*9880d681SAndroid Build Coastguard Worker if (!MI) {
400*9880d681SAndroid Build Coastguard Worker printLead(Bytes, Address, OS);
401*9880d681SAndroid Build Coastguard Worker OS << " <unknown>";
402*9880d681SAndroid Build Coastguard Worker return;
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker std::string Buffer;
405*9880d681SAndroid Build Coastguard Worker {
406*9880d681SAndroid Build Coastguard Worker raw_string_ostream TempStream(Buffer);
407*9880d681SAndroid Build Coastguard Worker IP.printInst(MI, TempStream, "", STI);
408*9880d681SAndroid Build Coastguard Worker }
409*9880d681SAndroid Build Coastguard Worker StringRef Contents(Buffer);
410*9880d681SAndroid Build Coastguard Worker // Split off bundle attributes
411*9880d681SAndroid Build Coastguard Worker auto PacketBundle = Contents.rsplit('\n');
412*9880d681SAndroid Build Coastguard Worker // Split off first instruction from the rest
413*9880d681SAndroid Build Coastguard Worker auto HeadTail = PacketBundle.first.split('\n');
414*9880d681SAndroid Build Coastguard Worker auto Preamble = " { ";
415*9880d681SAndroid Build Coastguard Worker auto Separator = "";
416*9880d681SAndroid Build Coastguard Worker while(!HeadTail.first.empty()) {
417*9880d681SAndroid Build Coastguard Worker OS << Separator;
418*9880d681SAndroid Build Coastguard Worker Separator = "\n";
419*9880d681SAndroid Build Coastguard Worker printLead(Bytes, Address, OS);
420*9880d681SAndroid Build Coastguard Worker OS << Preamble;
421*9880d681SAndroid Build Coastguard Worker Preamble = " ";
422*9880d681SAndroid Build Coastguard Worker StringRef Inst;
423*9880d681SAndroid Build Coastguard Worker auto Duplex = HeadTail.first.split('\v');
424*9880d681SAndroid Build Coastguard Worker if(!Duplex.second.empty()){
425*9880d681SAndroid Build Coastguard Worker OS << Duplex.first;
426*9880d681SAndroid Build Coastguard Worker OS << "; ";
427*9880d681SAndroid Build Coastguard Worker Inst = Duplex.second;
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker else
430*9880d681SAndroid Build Coastguard Worker Inst = HeadTail.first;
431*9880d681SAndroid Build Coastguard Worker OS << Inst;
432*9880d681SAndroid Build Coastguard Worker Bytes = Bytes.slice(4);
433*9880d681SAndroid Build Coastguard Worker Address += 4;
434*9880d681SAndroid Build Coastguard Worker HeadTail = HeadTail.second.split('\n');
435*9880d681SAndroid Build Coastguard Worker }
436*9880d681SAndroid Build Coastguard Worker OS << " } " << PacketBundle.second;
437*9880d681SAndroid Build Coastguard Worker }
438*9880d681SAndroid Build Coastguard Worker };
439*9880d681SAndroid Build Coastguard Worker HexagonPrettyPrinter HexagonPrettyPrinterInst;
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker class AMDGCNPrettyPrinter : public PrettyPrinter {
442*9880d681SAndroid Build Coastguard Worker public:
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI)443*9880d681SAndroid Build Coastguard Worker void printInst(MCInstPrinter &IP,
444*9880d681SAndroid Build Coastguard Worker const MCInst *MI,
445*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes,
446*9880d681SAndroid Build Coastguard Worker uint64_t Address,
447*9880d681SAndroid Build Coastguard Worker raw_ostream &OS,
448*9880d681SAndroid Build Coastguard Worker StringRef Annot,
449*9880d681SAndroid Build Coastguard Worker MCSubtargetInfo const &STI) override {
450*9880d681SAndroid Build Coastguard Worker if (!MI) {
451*9880d681SAndroid Build Coastguard Worker OS << " <unknown>";
452*9880d681SAndroid Build Coastguard Worker return;
453*9880d681SAndroid Build Coastguard Worker }
454*9880d681SAndroid Build Coastguard Worker
455*9880d681SAndroid Build Coastguard Worker SmallString<40> InstStr;
456*9880d681SAndroid Build Coastguard Worker raw_svector_ostream IS(InstStr);
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker IP.printInst(MI, IS, "", STI);
459*9880d681SAndroid Build Coastguard Worker
460*9880d681SAndroid Build Coastguard Worker OS << left_justify(IS.str(), 60) << format("// %012" PRIX64 ": ", Address);
461*9880d681SAndroid Build Coastguard Worker typedef support::ulittle32_t U32;
462*9880d681SAndroid Build Coastguard Worker for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
463*9880d681SAndroid Build Coastguard Worker Bytes.size() / sizeof(U32)))
464*9880d681SAndroid Build Coastguard Worker // D should be explicitly casted to uint32_t here as it is passed
465*9880d681SAndroid Build Coastguard Worker // by format to snprintf as vararg.
466*9880d681SAndroid Build Coastguard Worker OS << format("%08" PRIX32 " ", static_cast<uint32_t>(D));
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker if (!Annot.empty())
469*9880d681SAndroid Build Coastguard Worker OS << "// " << Annot;
470*9880d681SAndroid Build Coastguard Worker }
471*9880d681SAndroid Build Coastguard Worker };
472*9880d681SAndroid Build Coastguard Worker AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
473*9880d681SAndroid Build Coastguard Worker
selectPrettyPrinter(Triple const & Triple)474*9880d681SAndroid Build Coastguard Worker PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
475*9880d681SAndroid Build Coastguard Worker switch(Triple.getArch()) {
476*9880d681SAndroid Build Coastguard Worker default:
477*9880d681SAndroid Build Coastguard Worker return PrettyPrinterInst;
478*9880d681SAndroid Build Coastguard Worker case Triple::hexagon:
479*9880d681SAndroid Build Coastguard Worker return HexagonPrettyPrinterInst;
480*9880d681SAndroid Build Coastguard Worker case Triple::amdgcn:
481*9880d681SAndroid Build Coastguard Worker return AMDGCNPrettyPrinterInst;
482*9880d681SAndroid Build Coastguard Worker }
483*9880d681SAndroid Build Coastguard Worker }
484*9880d681SAndroid Build Coastguard Worker }
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker template <class ELFT>
getRelocationValueString(const ELFObjectFile<ELFT> * Obj,const RelocationRef & RelRef,SmallVectorImpl<char> & Result)487*9880d681SAndroid Build Coastguard Worker static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
488*9880d681SAndroid Build Coastguard Worker const RelocationRef &RelRef,
489*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<char> &Result) {
490*9880d681SAndroid Build Coastguard Worker DataRefImpl Rel = RelRef.getRawDataRefImpl();
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Worker typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
493*9880d681SAndroid Build Coastguard Worker typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
494*9880d681SAndroid Build Coastguard Worker typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
495*9880d681SAndroid Build Coastguard Worker
496*9880d681SAndroid Build Coastguard Worker const ELFFile<ELFT> &EF = *Obj->getELFFile();
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Worker ErrorOr<const Elf_Shdr *> SecOrErr = EF.getSection(Rel.d.a);
499*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = SecOrErr.getError())
500*9880d681SAndroid Build Coastguard Worker return EC;
501*9880d681SAndroid Build Coastguard Worker const Elf_Shdr *Sec = *SecOrErr;
502*9880d681SAndroid Build Coastguard Worker ErrorOr<const Elf_Shdr *> SymTabOrErr = EF.getSection(Sec->sh_link);
503*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = SymTabOrErr.getError())
504*9880d681SAndroid Build Coastguard Worker return EC;
505*9880d681SAndroid Build Coastguard Worker const Elf_Shdr *SymTab = *SymTabOrErr;
506*9880d681SAndroid Build Coastguard Worker assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
507*9880d681SAndroid Build Coastguard Worker SymTab->sh_type == ELF::SHT_DYNSYM);
508*9880d681SAndroid Build Coastguard Worker ErrorOr<const Elf_Shdr *> StrTabSec = EF.getSection(SymTab->sh_link);
509*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = StrTabSec.getError())
510*9880d681SAndroid Build Coastguard Worker return EC;
511*9880d681SAndroid Build Coastguard Worker ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(*StrTabSec);
512*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = StrTabOrErr.getError())
513*9880d681SAndroid Build Coastguard Worker return EC;
514*9880d681SAndroid Build Coastguard Worker StringRef StrTab = *StrTabOrErr;
515*9880d681SAndroid Build Coastguard Worker uint8_t type = RelRef.getType();
516*9880d681SAndroid Build Coastguard Worker StringRef res;
517*9880d681SAndroid Build Coastguard Worker int64_t addend = 0;
518*9880d681SAndroid Build Coastguard Worker switch (Sec->sh_type) {
519*9880d681SAndroid Build Coastguard Worker default:
520*9880d681SAndroid Build Coastguard Worker return object_error::parse_failed;
521*9880d681SAndroid Build Coastguard Worker case ELF::SHT_REL: {
522*9880d681SAndroid Build Coastguard Worker // TODO: Read implicit addend from section data.
523*9880d681SAndroid Build Coastguard Worker break;
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker case ELF::SHT_RELA: {
526*9880d681SAndroid Build Coastguard Worker const Elf_Rela *ERela = Obj->getRela(Rel);
527*9880d681SAndroid Build Coastguard Worker addend = ERela->r_addend;
528*9880d681SAndroid Build Coastguard Worker break;
529*9880d681SAndroid Build Coastguard Worker }
530*9880d681SAndroid Build Coastguard Worker }
531*9880d681SAndroid Build Coastguard Worker symbol_iterator SI = RelRef.getSymbol();
532*9880d681SAndroid Build Coastguard Worker const Elf_Sym *symb = Obj->getSymbol(SI->getRawDataRefImpl());
533*9880d681SAndroid Build Coastguard Worker StringRef Target;
534*9880d681SAndroid Build Coastguard Worker if (symb->getType() == ELF::STT_SECTION) {
535*9880d681SAndroid Build Coastguard Worker Expected<section_iterator> SymSI = SI->getSection();
536*9880d681SAndroid Build Coastguard Worker if (!SymSI)
537*9880d681SAndroid Build Coastguard Worker return errorToErrorCode(SymSI.takeError());
538*9880d681SAndroid Build Coastguard Worker const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
539*9880d681SAndroid Build Coastguard Worker ErrorOr<StringRef> SecName = EF.getSectionName(SymSec);
540*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = SecName.getError())
541*9880d681SAndroid Build Coastguard Worker return EC;
542*9880d681SAndroid Build Coastguard Worker Target = *SecName;
543*9880d681SAndroid Build Coastguard Worker } else {
544*9880d681SAndroid Build Coastguard Worker Expected<StringRef> SymName = symb->getName(StrTab);
545*9880d681SAndroid Build Coastguard Worker if (!SymName)
546*9880d681SAndroid Build Coastguard Worker return errorToErrorCode(SymName.takeError());
547*9880d681SAndroid Build Coastguard Worker Target = *SymName;
548*9880d681SAndroid Build Coastguard Worker }
549*9880d681SAndroid Build Coastguard Worker switch (EF.getHeader()->e_machine) {
550*9880d681SAndroid Build Coastguard Worker case ELF::EM_X86_64:
551*9880d681SAndroid Build Coastguard Worker switch (type) {
552*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_PC8:
553*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_PC16:
554*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_PC32: {
555*9880d681SAndroid Build Coastguard Worker std::string fmtbuf;
556*9880d681SAndroid Build Coastguard Worker raw_string_ostream fmt(fmtbuf);
557*9880d681SAndroid Build Coastguard Worker fmt << Target << (addend < 0 ? "" : "+") << addend << "-P";
558*9880d681SAndroid Build Coastguard Worker fmt.flush();
559*9880d681SAndroid Build Coastguard Worker Result.append(fmtbuf.begin(), fmtbuf.end());
560*9880d681SAndroid Build Coastguard Worker } break;
561*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_8:
562*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_16:
563*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_32:
564*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_32S:
565*9880d681SAndroid Build Coastguard Worker case ELF::R_X86_64_64: {
566*9880d681SAndroid Build Coastguard Worker std::string fmtbuf;
567*9880d681SAndroid Build Coastguard Worker raw_string_ostream fmt(fmtbuf);
568*9880d681SAndroid Build Coastguard Worker fmt << Target << (addend < 0 ? "" : "+") << addend;
569*9880d681SAndroid Build Coastguard Worker fmt.flush();
570*9880d681SAndroid Build Coastguard Worker Result.append(fmtbuf.begin(), fmtbuf.end());
571*9880d681SAndroid Build Coastguard Worker } break;
572*9880d681SAndroid Build Coastguard Worker default:
573*9880d681SAndroid Build Coastguard Worker res = "Unknown";
574*9880d681SAndroid Build Coastguard Worker }
575*9880d681SAndroid Build Coastguard Worker break;
576*9880d681SAndroid Build Coastguard Worker case ELF::EM_LANAI:
577*9880d681SAndroid Build Coastguard Worker case ELF::EM_AARCH64: {
578*9880d681SAndroid Build Coastguard Worker std::string fmtbuf;
579*9880d681SAndroid Build Coastguard Worker raw_string_ostream fmt(fmtbuf);
580*9880d681SAndroid Build Coastguard Worker fmt << Target;
581*9880d681SAndroid Build Coastguard Worker if (addend != 0)
582*9880d681SAndroid Build Coastguard Worker fmt << (addend < 0 ? "" : "+") << addend;
583*9880d681SAndroid Build Coastguard Worker fmt.flush();
584*9880d681SAndroid Build Coastguard Worker Result.append(fmtbuf.begin(), fmtbuf.end());
585*9880d681SAndroid Build Coastguard Worker break;
586*9880d681SAndroid Build Coastguard Worker }
587*9880d681SAndroid Build Coastguard Worker case ELF::EM_386:
588*9880d681SAndroid Build Coastguard Worker case ELF::EM_IAMCU:
589*9880d681SAndroid Build Coastguard Worker case ELF::EM_ARM:
590*9880d681SAndroid Build Coastguard Worker case ELF::EM_HEXAGON:
591*9880d681SAndroid Build Coastguard Worker case ELF::EM_MIPS:
592*9880d681SAndroid Build Coastguard Worker res = Target;
593*9880d681SAndroid Build Coastguard Worker break;
594*9880d681SAndroid Build Coastguard Worker case ELF::EM_WEBASSEMBLY:
595*9880d681SAndroid Build Coastguard Worker switch (type) {
596*9880d681SAndroid Build Coastguard Worker case ELF::R_WEBASSEMBLY_DATA: {
597*9880d681SAndroid Build Coastguard Worker std::string fmtbuf;
598*9880d681SAndroid Build Coastguard Worker raw_string_ostream fmt(fmtbuf);
599*9880d681SAndroid Build Coastguard Worker fmt << Target << (addend < 0 ? "" : "+") << addend;
600*9880d681SAndroid Build Coastguard Worker fmt.flush();
601*9880d681SAndroid Build Coastguard Worker Result.append(fmtbuf.begin(), fmtbuf.end());
602*9880d681SAndroid Build Coastguard Worker break;
603*9880d681SAndroid Build Coastguard Worker }
604*9880d681SAndroid Build Coastguard Worker case ELF::R_WEBASSEMBLY_FUNCTION:
605*9880d681SAndroid Build Coastguard Worker res = Target;
606*9880d681SAndroid Build Coastguard Worker break;
607*9880d681SAndroid Build Coastguard Worker default:
608*9880d681SAndroid Build Coastguard Worker res = "Unknown";
609*9880d681SAndroid Build Coastguard Worker }
610*9880d681SAndroid Build Coastguard Worker break;
611*9880d681SAndroid Build Coastguard Worker default:
612*9880d681SAndroid Build Coastguard Worker res = "Unknown";
613*9880d681SAndroid Build Coastguard Worker }
614*9880d681SAndroid Build Coastguard Worker if (Result.empty())
615*9880d681SAndroid Build Coastguard Worker Result.append(res.begin(), res.end());
616*9880d681SAndroid Build Coastguard Worker return std::error_code();
617*9880d681SAndroid Build Coastguard Worker }
618*9880d681SAndroid Build Coastguard Worker
getRelocationValueString(const ELFObjectFileBase * Obj,const RelocationRef & Rel,SmallVectorImpl<char> & Result)619*9880d681SAndroid Build Coastguard Worker static std::error_code getRelocationValueString(const ELFObjectFileBase *Obj,
620*9880d681SAndroid Build Coastguard Worker const RelocationRef &Rel,
621*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<char> &Result) {
622*9880d681SAndroid Build Coastguard Worker if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
623*9880d681SAndroid Build Coastguard Worker return getRelocationValueString(ELF32LE, Rel, Result);
624*9880d681SAndroid Build Coastguard Worker if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
625*9880d681SAndroid Build Coastguard Worker return getRelocationValueString(ELF64LE, Rel, Result);
626*9880d681SAndroid Build Coastguard Worker if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
627*9880d681SAndroid Build Coastguard Worker return getRelocationValueString(ELF32BE, Rel, Result);
628*9880d681SAndroid Build Coastguard Worker auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
629*9880d681SAndroid Build Coastguard Worker return getRelocationValueString(ELF64BE, Rel, Result);
630*9880d681SAndroid Build Coastguard Worker }
631*9880d681SAndroid Build Coastguard Worker
getRelocationValueString(const COFFObjectFile * Obj,const RelocationRef & Rel,SmallVectorImpl<char> & Result)632*9880d681SAndroid Build Coastguard Worker static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
633*9880d681SAndroid Build Coastguard Worker const RelocationRef &Rel,
634*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<char> &Result) {
635*9880d681SAndroid Build Coastguard Worker symbol_iterator SymI = Rel.getSymbol();
636*9880d681SAndroid Build Coastguard Worker Expected<StringRef> SymNameOrErr = SymI->getName();
637*9880d681SAndroid Build Coastguard Worker if (!SymNameOrErr)
638*9880d681SAndroid Build Coastguard Worker return errorToErrorCode(SymNameOrErr.takeError());
639*9880d681SAndroid Build Coastguard Worker StringRef SymName = *SymNameOrErr;
640*9880d681SAndroid Build Coastguard Worker Result.append(SymName.begin(), SymName.end());
641*9880d681SAndroid Build Coastguard Worker return std::error_code();
642*9880d681SAndroid Build Coastguard Worker }
643*9880d681SAndroid Build Coastguard Worker
printRelocationTargetName(const MachOObjectFile * O,const MachO::any_relocation_info & RE,raw_string_ostream & fmt)644*9880d681SAndroid Build Coastguard Worker static void printRelocationTargetName(const MachOObjectFile *O,
645*9880d681SAndroid Build Coastguard Worker const MachO::any_relocation_info &RE,
646*9880d681SAndroid Build Coastguard Worker raw_string_ostream &fmt) {
647*9880d681SAndroid Build Coastguard Worker bool IsScattered = O->isRelocationScattered(RE);
648*9880d681SAndroid Build Coastguard Worker
649*9880d681SAndroid Build Coastguard Worker // Target of a scattered relocation is an address. In the interest of
650*9880d681SAndroid Build Coastguard Worker // generating pretty output, scan through the symbol table looking for a
651*9880d681SAndroid Build Coastguard Worker // symbol that aligns with that address. If we find one, print it.
652*9880d681SAndroid Build Coastguard Worker // Otherwise, we just print the hex address of the target.
653*9880d681SAndroid Build Coastguard Worker if (IsScattered) {
654*9880d681SAndroid Build Coastguard Worker uint32_t Val = O->getPlainRelocationSymbolNum(RE);
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker for (const SymbolRef &Symbol : O->symbols()) {
657*9880d681SAndroid Build Coastguard Worker std::error_code ec;
658*9880d681SAndroid Build Coastguard Worker Expected<uint64_t> Addr = Symbol.getAddress();
659*9880d681SAndroid Build Coastguard Worker if (!Addr) {
660*9880d681SAndroid Build Coastguard Worker std::string Buf;
661*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
662*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(Addr.takeError(), OS, "");
663*9880d681SAndroid Build Coastguard Worker OS.flush();
664*9880d681SAndroid Build Coastguard Worker report_fatal_error(Buf);
665*9880d681SAndroid Build Coastguard Worker }
666*9880d681SAndroid Build Coastguard Worker if (*Addr != Val)
667*9880d681SAndroid Build Coastguard Worker continue;
668*9880d681SAndroid Build Coastguard Worker Expected<StringRef> Name = Symbol.getName();
669*9880d681SAndroid Build Coastguard Worker if (!Name) {
670*9880d681SAndroid Build Coastguard Worker std::string Buf;
671*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Buf);
672*9880d681SAndroid Build Coastguard Worker logAllUnhandledErrors(Name.takeError(), OS, "");
673*9880d681SAndroid Build Coastguard Worker OS.flush();
674*9880d681SAndroid Build Coastguard Worker report_fatal_error(Buf);
675*9880d681SAndroid Build Coastguard Worker }
676*9880d681SAndroid Build Coastguard Worker fmt << *Name;
677*9880d681SAndroid Build Coastguard Worker return;
678*9880d681SAndroid Build Coastguard Worker }
679*9880d681SAndroid Build Coastguard Worker
680*9880d681SAndroid Build Coastguard Worker // If we couldn't find a symbol that this relocation refers to, try
681*9880d681SAndroid Build Coastguard Worker // to find a section beginning instead.
682*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : ToolSectionFilter(*O)) {
683*9880d681SAndroid Build Coastguard Worker std::error_code ec;
684*9880d681SAndroid Build Coastguard Worker
685*9880d681SAndroid Build Coastguard Worker StringRef Name;
686*9880d681SAndroid Build Coastguard Worker uint64_t Addr = Section.getAddress();
687*9880d681SAndroid Build Coastguard Worker if (Addr != Val)
688*9880d681SAndroid Build Coastguard Worker continue;
689*9880d681SAndroid Build Coastguard Worker if ((ec = Section.getName(Name)))
690*9880d681SAndroid Build Coastguard Worker report_fatal_error(ec.message());
691*9880d681SAndroid Build Coastguard Worker fmt << Name;
692*9880d681SAndroid Build Coastguard Worker return;
693*9880d681SAndroid Build Coastguard Worker }
694*9880d681SAndroid Build Coastguard Worker
695*9880d681SAndroid Build Coastguard Worker fmt << format("0x%x", Val);
696*9880d681SAndroid Build Coastguard Worker return;
697*9880d681SAndroid Build Coastguard Worker }
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker StringRef S;
700*9880d681SAndroid Build Coastguard Worker bool isExtern = O->getPlainRelocationExternal(RE);
701*9880d681SAndroid Build Coastguard Worker uint64_t Val = O->getPlainRelocationSymbolNum(RE);
702*9880d681SAndroid Build Coastguard Worker
703*9880d681SAndroid Build Coastguard Worker if (isExtern) {
704*9880d681SAndroid Build Coastguard Worker symbol_iterator SI = O->symbol_begin();
705*9880d681SAndroid Build Coastguard Worker advance(SI, Val);
706*9880d681SAndroid Build Coastguard Worker Expected<StringRef> SOrErr = SI->getName();
707*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(SOrErr.takeError()));
708*9880d681SAndroid Build Coastguard Worker S = *SOrErr;
709*9880d681SAndroid Build Coastguard Worker } else {
710*9880d681SAndroid Build Coastguard Worker section_iterator SI = O->section_begin();
711*9880d681SAndroid Build Coastguard Worker // Adjust for the fact that sections are 1-indexed.
712*9880d681SAndroid Build Coastguard Worker advance(SI, Val - 1);
713*9880d681SAndroid Build Coastguard Worker SI->getName(S);
714*9880d681SAndroid Build Coastguard Worker }
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker fmt << S;
717*9880d681SAndroid Build Coastguard Worker }
718*9880d681SAndroid Build Coastguard Worker
getRelocationValueString(const MachOObjectFile * Obj,const RelocationRef & RelRef,SmallVectorImpl<char> & Result)719*9880d681SAndroid Build Coastguard Worker static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
720*9880d681SAndroid Build Coastguard Worker const RelocationRef &RelRef,
721*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<char> &Result) {
722*9880d681SAndroid Build Coastguard Worker DataRefImpl Rel = RelRef.getRawDataRefImpl();
723*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RE = Obj->getRelocation(Rel);
724*9880d681SAndroid Build Coastguard Worker
725*9880d681SAndroid Build Coastguard Worker unsigned Arch = Obj->getArch();
726*9880d681SAndroid Build Coastguard Worker
727*9880d681SAndroid Build Coastguard Worker std::string fmtbuf;
728*9880d681SAndroid Build Coastguard Worker raw_string_ostream fmt(fmtbuf);
729*9880d681SAndroid Build Coastguard Worker unsigned Type = Obj->getAnyRelocationType(RE);
730*9880d681SAndroid Build Coastguard Worker bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
731*9880d681SAndroid Build Coastguard Worker
732*9880d681SAndroid Build Coastguard Worker // Determine any addends that should be displayed with the relocation.
733*9880d681SAndroid Build Coastguard Worker // These require decoding the relocation type, which is triple-specific.
734*9880d681SAndroid Build Coastguard Worker
735*9880d681SAndroid Build Coastguard Worker // X86_64 has entirely custom relocation types.
736*9880d681SAndroid Build Coastguard Worker if (Arch == Triple::x86_64) {
737*9880d681SAndroid Build Coastguard Worker bool isPCRel = Obj->getAnyRelocationPCRel(RE);
738*9880d681SAndroid Build Coastguard Worker
739*9880d681SAndroid Build Coastguard Worker switch (Type) {
740*9880d681SAndroid Build Coastguard Worker case MachO::X86_64_RELOC_GOT_LOAD:
741*9880d681SAndroid Build Coastguard Worker case MachO::X86_64_RELOC_GOT: {
742*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
743*9880d681SAndroid Build Coastguard Worker fmt << "@GOT";
744*9880d681SAndroid Build Coastguard Worker if (isPCRel)
745*9880d681SAndroid Build Coastguard Worker fmt << "PCREL";
746*9880d681SAndroid Build Coastguard Worker break;
747*9880d681SAndroid Build Coastguard Worker }
748*9880d681SAndroid Build Coastguard Worker case MachO::X86_64_RELOC_SUBTRACTOR: {
749*9880d681SAndroid Build Coastguard Worker DataRefImpl RelNext = Rel;
750*9880d681SAndroid Build Coastguard Worker Obj->moveRelocationNext(RelNext);
751*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
752*9880d681SAndroid Build Coastguard Worker
753*9880d681SAndroid Build Coastguard Worker // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
754*9880d681SAndroid Build Coastguard Worker // X86_64_RELOC_UNSIGNED.
755*9880d681SAndroid Build Coastguard Worker // NOTE: Scattered relocations don't exist on x86_64.
756*9880d681SAndroid Build Coastguard Worker unsigned RType = Obj->getAnyRelocationType(RENext);
757*9880d681SAndroid Build Coastguard Worker if (RType != MachO::X86_64_RELOC_UNSIGNED)
758*9880d681SAndroid Build Coastguard Worker report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
759*9880d681SAndroid Build Coastguard Worker "X86_64_RELOC_SUBTRACTOR.");
760*9880d681SAndroid Build Coastguard Worker
761*9880d681SAndroid Build Coastguard Worker // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
762*9880d681SAndroid Build Coastguard Worker // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
763*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RENext, fmt);
764*9880d681SAndroid Build Coastguard Worker fmt << "-";
765*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
766*9880d681SAndroid Build Coastguard Worker break;
767*9880d681SAndroid Build Coastguard Worker }
768*9880d681SAndroid Build Coastguard Worker case MachO::X86_64_RELOC_TLV:
769*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
770*9880d681SAndroid Build Coastguard Worker fmt << "@TLV";
771*9880d681SAndroid Build Coastguard Worker if (isPCRel)
772*9880d681SAndroid Build Coastguard Worker fmt << "P";
773*9880d681SAndroid Build Coastguard Worker break;
774*9880d681SAndroid Build Coastguard Worker case MachO::X86_64_RELOC_SIGNED_1:
775*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
776*9880d681SAndroid Build Coastguard Worker fmt << "-1";
777*9880d681SAndroid Build Coastguard Worker break;
778*9880d681SAndroid Build Coastguard Worker case MachO::X86_64_RELOC_SIGNED_2:
779*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
780*9880d681SAndroid Build Coastguard Worker fmt << "-2";
781*9880d681SAndroid Build Coastguard Worker break;
782*9880d681SAndroid Build Coastguard Worker case MachO::X86_64_RELOC_SIGNED_4:
783*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
784*9880d681SAndroid Build Coastguard Worker fmt << "-4";
785*9880d681SAndroid Build Coastguard Worker break;
786*9880d681SAndroid Build Coastguard Worker default:
787*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
788*9880d681SAndroid Build Coastguard Worker break;
789*9880d681SAndroid Build Coastguard Worker }
790*9880d681SAndroid Build Coastguard Worker // X86 and ARM share some relocation types in common.
791*9880d681SAndroid Build Coastguard Worker } else if (Arch == Triple::x86 || Arch == Triple::arm ||
792*9880d681SAndroid Build Coastguard Worker Arch == Triple::ppc) {
793*9880d681SAndroid Build Coastguard Worker // Generic relocation types...
794*9880d681SAndroid Build Coastguard Worker switch (Type) {
795*9880d681SAndroid Build Coastguard Worker case MachO::GENERIC_RELOC_PAIR: // prints no info
796*9880d681SAndroid Build Coastguard Worker return std::error_code();
797*9880d681SAndroid Build Coastguard Worker case MachO::GENERIC_RELOC_SECTDIFF: {
798*9880d681SAndroid Build Coastguard Worker DataRefImpl RelNext = Rel;
799*9880d681SAndroid Build Coastguard Worker Obj->moveRelocationNext(RelNext);
800*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
801*9880d681SAndroid Build Coastguard Worker
802*9880d681SAndroid Build Coastguard Worker // X86 sect diff's must be followed by a relocation of type
803*9880d681SAndroid Build Coastguard Worker // GENERIC_RELOC_PAIR.
804*9880d681SAndroid Build Coastguard Worker unsigned RType = Obj->getAnyRelocationType(RENext);
805*9880d681SAndroid Build Coastguard Worker
806*9880d681SAndroid Build Coastguard Worker if (RType != MachO::GENERIC_RELOC_PAIR)
807*9880d681SAndroid Build Coastguard Worker report_fatal_error("Expected GENERIC_RELOC_PAIR after "
808*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_SECTDIFF.");
809*9880d681SAndroid Build Coastguard Worker
810*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
811*9880d681SAndroid Build Coastguard Worker fmt << "-";
812*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RENext, fmt);
813*9880d681SAndroid Build Coastguard Worker break;
814*9880d681SAndroid Build Coastguard Worker }
815*9880d681SAndroid Build Coastguard Worker }
816*9880d681SAndroid Build Coastguard Worker
817*9880d681SAndroid Build Coastguard Worker if (Arch == Triple::x86 || Arch == Triple::ppc) {
818*9880d681SAndroid Build Coastguard Worker switch (Type) {
819*9880d681SAndroid Build Coastguard Worker case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
820*9880d681SAndroid Build Coastguard Worker DataRefImpl RelNext = Rel;
821*9880d681SAndroid Build Coastguard Worker Obj->moveRelocationNext(RelNext);
822*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
823*9880d681SAndroid Build Coastguard Worker
824*9880d681SAndroid Build Coastguard Worker // X86 sect diff's must be followed by a relocation of type
825*9880d681SAndroid Build Coastguard Worker // GENERIC_RELOC_PAIR.
826*9880d681SAndroid Build Coastguard Worker unsigned RType = Obj->getAnyRelocationType(RENext);
827*9880d681SAndroid Build Coastguard Worker if (RType != MachO::GENERIC_RELOC_PAIR)
828*9880d681SAndroid Build Coastguard Worker report_fatal_error("Expected GENERIC_RELOC_PAIR after "
829*9880d681SAndroid Build Coastguard Worker "GENERIC_RELOC_LOCAL_SECTDIFF.");
830*9880d681SAndroid Build Coastguard Worker
831*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
832*9880d681SAndroid Build Coastguard Worker fmt << "-";
833*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RENext, fmt);
834*9880d681SAndroid Build Coastguard Worker break;
835*9880d681SAndroid Build Coastguard Worker }
836*9880d681SAndroid Build Coastguard Worker case MachO::GENERIC_RELOC_TLV: {
837*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
838*9880d681SAndroid Build Coastguard Worker fmt << "@TLV";
839*9880d681SAndroid Build Coastguard Worker if (IsPCRel)
840*9880d681SAndroid Build Coastguard Worker fmt << "P";
841*9880d681SAndroid Build Coastguard Worker break;
842*9880d681SAndroid Build Coastguard Worker }
843*9880d681SAndroid Build Coastguard Worker default:
844*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
845*9880d681SAndroid Build Coastguard Worker }
846*9880d681SAndroid Build Coastguard Worker } else { // ARM-specific relocations
847*9880d681SAndroid Build Coastguard Worker switch (Type) {
848*9880d681SAndroid Build Coastguard Worker case MachO::ARM_RELOC_HALF:
849*9880d681SAndroid Build Coastguard Worker case MachO::ARM_RELOC_HALF_SECTDIFF: {
850*9880d681SAndroid Build Coastguard Worker // Half relocations steal a bit from the length field to encode
851*9880d681SAndroid Build Coastguard Worker // whether this is an upper16 or a lower16 relocation.
852*9880d681SAndroid Build Coastguard Worker bool isUpper = Obj->getAnyRelocationLength(RE) >> 1;
853*9880d681SAndroid Build Coastguard Worker
854*9880d681SAndroid Build Coastguard Worker if (isUpper)
855*9880d681SAndroid Build Coastguard Worker fmt << ":upper16:(";
856*9880d681SAndroid Build Coastguard Worker else
857*9880d681SAndroid Build Coastguard Worker fmt << ":lower16:(";
858*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
859*9880d681SAndroid Build Coastguard Worker
860*9880d681SAndroid Build Coastguard Worker DataRefImpl RelNext = Rel;
861*9880d681SAndroid Build Coastguard Worker Obj->moveRelocationNext(RelNext);
862*9880d681SAndroid Build Coastguard Worker MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
863*9880d681SAndroid Build Coastguard Worker
864*9880d681SAndroid Build Coastguard Worker // ARM half relocs must be followed by a relocation of type
865*9880d681SAndroid Build Coastguard Worker // ARM_RELOC_PAIR.
866*9880d681SAndroid Build Coastguard Worker unsigned RType = Obj->getAnyRelocationType(RENext);
867*9880d681SAndroid Build Coastguard Worker if (RType != MachO::ARM_RELOC_PAIR)
868*9880d681SAndroid Build Coastguard Worker report_fatal_error("Expected ARM_RELOC_PAIR after "
869*9880d681SAndroid Build Coastguard Worker "ARM_RELOC_HALF");
870*9880d681SAndroid Build Coastguard Worker
871*9880d681SAndroid Build Coastguard Worker // NOTE: The half of the target virtual address is stashed in the
872*9880d681SAndroid Build Coastguard Worker // address field of the secondary relocation, but we can't reverse
873*9880d681SAndroid Build Coastguard Worker // engineer the constant offset from it without decoding the movw/movt
874*9880d681SAndroid Build Coastguard Worker // instruction to find the other half in its immediate field.
875*9880d681SAndroid Build Coastguard Worker
876*9880d681SAndroid Build Coastguard Worker // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
877*9880d681SAndroid Build Coastguard Worker // symbol/section pointer of the follow-on relocation.
878*9880d681SAndroid Build Coastguard Worker if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
879*9880d681SAndroid Build Coastguard Worker fmt << "-";
880*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RENext, fmt);
881*9880d681SAndroid Build Coastguard Worker }
882*9880d681SAndroid Build Coastguard Worker
883*9880d681SAndroid Build Coastguard Worker fmt << ")";
884*9880d681SAndroid Build Coastguard Worker break;
885*9880d681SAndroid Build Coastguard Worker }
886*9880d681SAndroid Build Coastguard Worker default: { printRelocationTargetName(Obj, RE, fmt); }
887*9880d681SAndroid Build Coastguard Worker }
888*9880d681SAndroid Build Coastguard Worker }
889*9880d681SAndroid Build Coastguard Worker } else
890*9880d681SAndroid Build Coastguard Worker printRelocationTargetName(Obj, RE, fmt);
891*9880d681SAndroid Build Coastguard Worker
892*9880d681SAndroid Build Coastguard Worker fmt.flush();
893*9880d681SAndroid Build Coastguard Worker Result.append(fmtbuf.begin(), fmtbuf.end());
894*9880d681SAndroid Build Coastguard Worker return std::error_code();
895*9880d681SAndroid Build Coastguard Worker }
896*9880d681SAndroid Build Coastguard Worker
getRelocationValueString(const RelocationRef & Rel,SmallVectorImpl<char> & Result)897*9880d681SAndroid Build Coastguard Worker static std::error_code getRelocationValueString(const RelocationRef &Rel,
898*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<char> &Result) {
899*9880d681SAndroid Build Coastguard Worker const ObjectFile *Obj = Rel.getObject();
900*9880d681SAndroid Build Coastguard Worker if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
901*9880d681SAndroid Build Coastguard Worker return getRelocationValueString(ELF, Rel, Result);
902*9880d681SAndroid Build Coastguard Worker if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
903*9880d681SAndroid Build Coastguard Worker return getRelocationValueString(COFF, Rel, Result);
904*9880d681SAndroid Build Coastguard Worker auto *MachO = cast<MachOObjectFile>(Obj);
905*9880d681SAndroid Build Coastguard Worker return getRelocationValueString(MachO, Rel, Result);
906*9880d681SAndroid Build Coastguard Worker }
907*9880d681SAndroid Build Coastguard Worker
908*9880d681SAndroid Build Coastguard Worker /// @brief Indicates whether this relocation should hidden when listing
909*9880d681SAndroid Build Coastguard Worker /// relocations, usually because it is the trailing part of a multipart
910*9880d681SAndroid Build Coastguard Worker /// relocation that will be printed as part of the leading relocation.
getHidden(RelocationRef RelRef)911*9880d681SAndroid Build Coastguard Worker static bool getHidden(RelocationRef RelRef) {
912*9880d681SAndroid Build Coastguard Worker const ObjectFile *Obj = RelRef.getObject();
913*9880d681SAndroid Build Coastguard Worker auto *MachO = dyn_cast<MachOObjectFile>(Obj);
914*9880d681SAndroid Build Coastguard Worker if (!MachO)
915*9880d681SAndroid Build Coastguard Worker return false;
916*9880d681SAndroid Build Coastguard Worker
917*9880d681SAndroid Build Coastguard Worker unsigned Arch = MachO->getArch();
918*9880d681SAndroid Build Coastguard Worker DataRefImpl Rel = RelRef.getRawDataRefImpl();
919*9880d681SAndroid Build Coastguard Worker uint64_t Type = MachO->getRelocationType(Rel);
920*9880d681SAndroid Build Coastguard Worker
921*9880d681SAndroid Build Coastguard Worker // On arches that use the generic relocations, GENERIC_RELOC_PAIR
922*9880d681SAndroid Build Coastguard Worker // is always hidden.
923*9880d681SAndroid Build Coastguard Worker if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
924*9880d681SAndroid Build Coastguard Worker if (Type == MachO::GENERIC_RELOC_PAIR)
925*9880d681SAndroid Build Coastguard Worker return true;
926*9880d681SAndroid Build Coastguard Worker } else if (Arch == Triple::x86_64) {
927*9880d681SAndroid Build Coastguard Worker // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
928*9880d681SAndroid Build Coastguard Worker // an X86_64_RELOC_SUBTRACTOR.
929*9880d681SAndroid Build Coastguard Worker if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
930*9880d681SAndroid Build Coastguard Worker DataRefImpl RelPrev = Rel;
931*9880d681SAndroid Build Coastguard Worker RelPrev.d.a--;
932*9880d681SAndroid Build Coastguard Worker uint64_t PrevType = MachO->getRelocationType(RelPrev);
933*9880d681SAndroid Build Coastguard Worker if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
934*9880d681SAndroid Build Coastguard Worker return true;
935*9880d681SAndroid Build Coastguard Worker }
936*9880d681SAndroid Build Coastguard Worker }
937*9880d681SAndroid Build Coastguard Worker
938*9880d681SAndroid Build Coastguard Worker return false;
939*9880d681SAndroid Build Coastguard Worker }
940*9880d681SAndroid Build Coastguard Worker
DisassembleObject(const ObjectFile * Obj,bool InlineRelocs)941*9880d681SAndroid Build Coastguard Worker static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
942*9880d681SAndroid Build Coastguard Worker const Target *TheTarget = getTarget(Obj);
943*9880d681SAndroid Build Coastguard Worker
944*9880d681SAndroid Build Coastguard Worker // Package up features to be passed to target/subtarget
945*9880d681SAndroid Build Coastguard Worker SubtargetFeatures Features = Obj->getFeatures();
946*9880d681SAndroid Build Coastguard Worker if (MAttrs.size()) {
947*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != MAttrs.size(); ++i)
948*9880d681SAndroid Build Coastguard Worker Features.AddFeature(MAttrs[i]);
949*9880d681SAndroid Build Coastguard Worker }
950*9880d681SAndroid Build Coastguard Worker
951*9880d681SAndroid Build Coastguard Worker std::unique_ptr<const MCRegisterInfo> MRI(
952*9880d681SAndroid Build Coastguard Worker TheTarget->createMCRegInfo(TripleName));
953*9880d681SAndroid Build Coastguard Worker if (!MRI)
954*9880d681SAndroid Build Coastguard Worker report_fatal_error("error: no register info for target " + TripleName);
955*9880d681SAndroid Build Coastguard Worker
956*9880d681SAndroid Build Coastguard Worker // Set up disassembler.
957*9880d681SAndroid Build Coastguard Worker std::unique_ptr<const MCAsmInfo> AsmInfo(
958*9880d681SAndroid Build Coastguard Worker TheTarget->createMCAsmInfo(*MRI, TripleName));
959*9880d681SAndroid Build Coastguard Worker if (!AsmInfo)
960*9880d681SAndroid Build Coastguard Worker report_fatal_error("error: no assembly info for target " + TripleName);
961*9880d681SAndroid Build Coastguard Worker std::unique_ptr<const MCSubtargetInfo> STI(
962*9880d681SAndroid Build Coastguard Worker TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
963*9880d681SAndroid Build Coastguard Worker if (!STI)
964*9880d681SAndroid Build Coastguard Worker report_fatal_error("error: no subtarget info for target " + TripleName);
965*9880d681SAndroid Build Coastguard Worker std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
966*9880d681SAndroid Build Coastguard Worker if (!MII)
967*9880d681SAndroid Build Coastguard Worker report_fatal_error("error: no instruction info for target " + TripleName);
968*9880d681SAndroid Build Coastguard Worker std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
969*9880d681SAndroid Build Coastguard Worker MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
970*9880d681SAndroid Build Coastguard Worker
971*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCDisassembler> DisAsm(
972*9880d681SAndroid Build Coastguard Worker TheTarget->createMCDisassembler(*STI, Ctx));
973*9880d681SAndroid Build Coastguard Worker if (!DisAsm)
974*9880d681SAndroid Build Coastguard Worker report_fatal_error("error: no disassembler for target " + TripleName);
975*9880d681SAndroid Build Coastguard Worker
976*9880d681SAndroid Build Coastguard Worker std::unique_ptr<const MCInstrAnalysis> MIA(
977*9880d681SAndroid Build Coastguard Worker TheTarget->createMCInstrAnalysis(MII.get()));
978*9880d681SAndroid Build Coastguard Worker
979*9880d681SAndroid Build Coastguard Worker int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
980*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
981*9880d681SAndroid Build Coastguard Worker Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
982*9880d681SAndroid Build Coastguard Worker if (!IP)
983*9880d681SAndroid Build Coastguard Worker report_fatal_error("error: no instruction printer for target " +
984*9880d681SAndroid Build Coastguard Worker TripleName);
985*9880d681SAndroid Build Coastguard Worker IP->setPrintImmHex(PrintImmHex);
986*9880d681SAndroid Build Coastguard Worker PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
987*9880d681SAndroid Build Coastguard Worker
988*9880d681SAndroid Build Coastguard Worker StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
989*9880d681SAndroid Build Coastguard Worker "\t\t\t%08" PRIx64 ": ";
990*9880d681SAndroid Build Coastguard Worker
991*9880d681SAndroid Build Coastguard Worker // Create a mapping, RelocSecs = SectionRelocMap[S], where sections
992*9880d681SAndroid Build Coastguard Worker // in RelocSecs contain the relocations for section S.
993*9880d681SAndroid Build Coastguard Worker std::error_code EC;
994*9880d681SAndroid Build Coastguard Worker std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap;
995*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
996*9880d681SAndroid Build Coastguard Worker section_iterator Sec2 = Section.getRelocatedSection();
997*9880d681SAndroid Build Coastguard Worker if (Sec2 != Obj->section_end())
998*9880d681SAndroid Build Coastguard Worker SectionRelocMap[*Sec2].push_back(Section);
999*9880d681SAndroid Build Coastguard Worker }
1000*9880d681SAndroid Build Coastguard Worker
1001*9880d681SAndroid Build Coastguard Worker // Create a mapping from virtual address to symbol name. This is used to
1002*9880d681SAndroid Build Coastguard Worker // pretty print the symbols while disassembling.
1003*9880d681SAndroid Build Coastguard Worker typedef std::vector<std::pair<uint64_t, StringRef>> SectionSymbolsTy;
1004*9880d681SAndroid Build Coastguard Worker std::map<SectionRef, SectionSymbolsTy> AllSymbols;
1005*9880d681SAndroid Build Coastguard Worker for (const SymbolRef &Symbol : Obj->symbols()) {
1006*9880d681SAndroid Build Coastguard Worker Expected<uint64_t> AddressOrErr = Symbol.getAddress();
1007*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(AddressOrErr.takeError()));
1008*9880d681SAndroid Build Coastguard Worker uint64_t Address = *AddressOrErr;
1009*9880d681SAndroid Build Coastguard Worker
1010*9880d681SAndroid Build Coastguard Worker Expected<StringRef> Name = Symbol.getName();
1011*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(Name.takeError()));
1012*9880d681SAndroid Build Coastguard Worker if (Name->empty())
1013*9880d681SAndroid Build Coastguard Worker continue;
1014*9880d681SAndroid Build Coastguard Worker
1015*9880d681SAndroid Build Coastguard Worker Expected<section_iterator> SectionOrErr = Symbol.getSection();
1016*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(SectionOrErr.takeError()));
1017*9880d681SAndroid Build Coastguard Worker section_iterator SecI = *SectionOrErr;
1018*9880d681SAndroid Build Coastguard Worker if (SecI == Obj->section_end())
1019*9880d681SAndroid Build Coastguard Worker continue;
1020*9880d681SAndroid Build Coastguard Worker
1021*9880d681SAndroid Build Coastguard Worker AllSymbols[*SecI].emplace_back(Address, *Name);
1022*9880d681SAndroid Build Coastguard Worker }
1023*9880d681SAndroid Build Coastguard Worker
1024*9880d681SAndroid Build Coastguard Worker // Create a mapping from virtual address to section.
1025*9880d681SAndroid Build Coastguard Worker std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
1026*9880d681SAndroid Build Coastguard Worker for (SectionRef Sec : Obj->sections())
1027*9880d681SAndroid Build Coastguard Worker SectionAddresses.emplace_back(Sec.getAddress(), Sec);
1028*9880d681SAndroid Build Coastguard Worker array_pod_sort(SectionAddresses.begin(), SectionAddresses.end());
1029*9880d681SAndroid Build Coastguard Worker
1030*9880d681SAndroid Build Coastguard Worker // Linked executables (.exe and .dll files) typically don't include a real
1031*9880d681SAndroid Build Coastguard Worker // symbol table but they might contain an export table.
1032*9880d681SAndroid Build Coastguard Worker if (const auto *COFFObj = dyn_cast<COFFObjectFile>(Obj)) {
1033*9880d681SAndroid Build Coastguard Worker for (const auto &ExportEntry : COFFObj->export_directories()) {
1034*9880d681SAndroid Build Coastguard Worker StringRef Name;
1035*9880d681SAndroid Build Coastguard Worker error(ExportEntry.getSymbolName(Name));
1036*9880d681SAndroid Build Coastguard Worker if (Name.empty())
1037*9880d681SAndroid Build Coastguard Worker continue;
1038*9880d681SAndroid Build Coastguard Worker uint32_t RVA;
1039*9880d681SAndroid Build Coastguard Worker error(ExportEntry.getExportRVA(RVA));
1040*9880d681SAndroid Build Coastguard Worker
1041*9880d681SAndroid Build Coastguard Worker uint64_t VA = COFFObj->getImageBase() + RVA;
1042*9880d681SAndroid Build Coastguard Worker auto Sec = std::upper_bound(
1043*9880d681SAndroid Build Coastguard Worker SectionAddresses.begin(), SectionAddresses.end(), VA,
1044*9880d681SAndroid Build Coastguard Worker [](uint64_t LHS, const std::pair<uint64_t, SectionRef> &RHS) {
1045*9880d681SAndroid Build Coastguard Worker return LHS < RHS.first;
1046*9880d681SAndroid Build Coastguard Worker });
1047*9880d681SAndroid Build Coastguard Worker if (Sec != SectionAddresses.begin())
1048*9880d681SAndroid Build Coastguard Worker --Sec;
1049*9880d681SAndroid Build Coastguard Worker else
1050*9880d681SAndroid Build Coastguard Worker Sec = SectionAddresses.end();
1051*9880d681SAndroid Build Coastguard Worker
1052*9880d681SAndroid Build Coastguard Worker if (Sec != SectionAddresses.end())
1053*9880d681SAndroid Build Coastguard Worker AllSymbols[Sec->second].emplace_back(VA, Name);
1054*9880d681SAndroid Build Coastguard Worker }
1055*9880d681SAndroid Build Coastguard Worker }
1056*9880d681SAndroid Build Coastguard Worker
1057*9880d681SAndroid Build Coastguard Worker // Sort all the symbols, this allows us to use a simple binary search to find
1058*9880d681SAndroid Build Coastguard Worker // a symbol near an address.
1059*9880d681SAndroid Build Coastguard Worker for (std::pair<const SectionRef, SectionSymbolsTy> &SecSyms : AllSymbols)
1060*9880d681SAndroid Build Coastguard Worker array_pod_sort(SecSyms.second.begin(), SecSyms.second.end());
1061*9880d681SAndroid Build Coastguard Worker
1062*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1063*9880d681SAndroid Build Coastguard Worker if (!DisassembleAll && (!Section.isText() || Section.isVirtual()))
1064*9880d681SAndroid Build Coastguard Worker continue;
1065*9880d681SAndroid Build Coastguard Worker
1066*9880d681SAndroid Build Coastguard Worker uint64_t SectionAddr = Section.getAddress();
1067*9880d681SAndroid Build Coastguard Worker uint64_t SectSize = Section.getSize();
1068*9880d681SAndroid Build Coastguard Worker if (!SectSize)
1069*9880d681SAndroid Build Coastguard Worker continue;
1070*9880d681SAndroid Build Coastguard Worker
1071*9880d681SAndroid Build Coastguard Worker // Get the list of all the symbols in this section.
1072*9880d681SAndroid Build Coastguard Worker SectionSymbolsTy &Symbols = AllSymbols[Section];
1073*9880d681SAndroid Build Coastguard Worker std::vector<uint64_t> DataMappingSymsAddr;
1074*9880d681SAndroid Build Coastguard Worker std::vector<uint64_t> TextMappingSymsAddr;
1075*9880d681SAndroid Build Coastguard Worker if (Obj->isELF() && Obj->getArch() == Triple::aarch64) {
1076*9880d681SAndroid Build Coastguard Worker for (const auto &Symb : Symbols) {
1077*9880d681SAndroid Build Coastguard Worker uint64_t Address = Symb.first;
1078*9880d681SAndroid Build Coastguard Worker StringRef Name = Symb.second;
1079*9880d681SAndroid Build Coastguard Worker if (Name.startswith("$d"))
1080*9880d681SAndroid Build Coastguard Worker DataMappingSymsAddr.push_back(Address - SectionAddr);
1081*9880d681SAndroid Build Coastguard Worker if (Name.startswith("$x"))
1082*9880d681SAndroid Build Coastguard Worker TextMappingSymsAddr.push_back(Address - SectionAddr);
1083*9880d681SAndroid Build Coastguard Worker }
1084*9880d681SAndroid Build Coastguard Worker }
1085*9880d681SAndroid Build Coastguard Worker
1086*9880d681SAndroid Build Coastguard Worker std::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end());
1087*9880d681SAndroid Build Coastguard Worker std::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end());
1088*9880d681SAndroid Build Coastguard Worker
1089*9880d681SAndroid Build Coastguard Worker // Make a list of all the relocations for this section.
1090*9880d681SAndroid Build Coastguard Worker std::vector<RelocationRef> Rels;
1091*9880d681SAndroid Build Coastguard Worker if (InlineRelocs) {
1092*9880d681SAndroid Build Coastguard Worker for (const SectionRef &RelocSec : SectionRelocMap[Section]) {
1093*9880d681SAndroid Build Coastguard Worker for (const RelocationRef &Reloc : RelocSec.relocations()) {
1094*9880d681SAndroid Build Coastguard Worker Rels.push_back(Reloc);
1095*9880d681SAndroid Build Coastguard Worker }
1096*9880d681SAndroid Build Coastguard Worker }
1097*9880d681SAndroid Build Coastguard Worker }
1098*9880d681SAndroid Build Coastguard Worker
1099*9880d681SAndroid Build Coastguard Worker // Sort relocations by address.
1100*9880d681SAndroid Build Coastguard Worker std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
1101*9880d681SAndroid Build Coastguard Worker
1102*9880d681SAndroid Build Coastguard Worker StringRef SegmentName = "";
1103*9880d681SAndroid Build Coastguard Worker if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
1104*9880d681SAndroid Build Coastguard Worker DataRefImpl DR = Section.getRawDataRefImpl();
1105*9880d681SAndroid Build Coastguard Worker SegmentName = MachO->getSectionFinalSegmentName(DR);
1106*9880d681SAndroid Build Coastguard Worker }
1107*9880d681SAndroid Build Coastguard Worker StringRef name;
1108*9880d681SAndroid Build Coastguard Worker error(Section.getName(name));
1109*9880d681SAndroid Build Coastguard Worker outs() << "Disassembly of section ";
1110*9880d681SAndroid Build Coastguard Worker if (!SegmentName.empty())
1111*9880d681SAndroid Build Coastguard Worker outs() << SegmentName << ",";
1112*9880d681SAndroid Build Coastguard Worker outs() << name << ':';
1113*9880d681SAndroid Build Coastguard Worker
1114*9880d681SAndroid Build Coastguard Worker // If the section has no symbol at the start, just insert a dummy one.
1115*9880d681SAndroid Build Coastguard Worker if (Symbols.empty() || Symbols[0].first != 0)
1116*9880d681SAndroid Build Coastguard Worker Symbols.insert(Symbols.begin(), std::make_pair(SectionAddr, name));
1117*9880d681SAndroid Build Coastguard Worker
1118*9880d681SAndroid Build Coastguard Worker SmallString<40> Comments;
1119*9880d681SAndroid Build Coastguard Worker raw_svector_ostream CommentStream(Comments);
1120*9880d681SAndroid Build Coastguard Worker
1121*9880d681SAndroid Build Coastguard Worker StringRef BytesStr;
1122*9880d681SAndroid Build Coastguard Worker error(Section.getContents(BytesStr));
1123*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
1124*9880d681SAndroid Build Coastguard Worker BytesStr.size());
1125*9880d681SAndroid Build Coastguard Worker
1126*9880d681SAndroid Build Coastguard Worker uint64_t Size;
1127*9880d681SAndroid Build Coastguard Worker uint64_t Index;
1128*9880d681SAndroid Build Coastguard Worker
1129*9880d681SAndroid Build Coastguard Worker std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
1130*9880d681SAndroid Build Coastguard Worker std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
1131*9880d681SAndroid Build Coastguard Worker // Disassemble symbol by symbol.
1132*9880d681SAndroid Build Coastguard Worker for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
1133*9880d681SAndroid Build Coastguard Worker
1134*9880d681SAndroid Build Coastguard Worker uint64_t Start = Symbols[si].first - SectionAddr;
1135*9880d681SAndroid Build Coastguard Worker // The end is either the section end or the beginning of the next
1136*9880d681SAndroid Build Coastguard Worker // symbol.
1137*9880d681SAndroid Build Coastguard Worker uint64_t End =
1138*9880d681SAndroid Build Coastguard Worker (si == se - 1) ? SectSize : Symbols[si + 1].first - SectionAddr;
1139*9880d681SAndroid Build Coastguard Worker // Don't try to disassemble beyond the end of section contents.
1140*9880d681SAndroid Build Coastguard Worker if (End > SectSize)
1141*9880d681SAndroid Build Coastguard Worker End = SectSize;
1142*9880d681SAndroid Build Coastguard Worker // If this symbol has the same address as the next symbol, then skip it.
1143*9880d681SAndroid Build Coastguard Worker if (Start >= End)
1144*9880d681SAndroid Build Coastguard Worker continue;
1145*9880d681SAndroid Build Coastguard Worker
1146*9880d681SAndroid Build Coastguard Worker if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
1147*9880d681SAndroid Build Coastguard Worker // make size 4 bytes folded
1148*9880d681SAndroid Build Coastguard Worker End = Start + ((End - Start) & ~0x3ull);
1149*9880d681SAndroid Build Coastguard Worker Start += 256; // add sizeof(amd_kernel_code_t)
1150*9880d681SAndroid Build Coastguard Worker // cut trailing zeroes - up to 256 bytes (align)
1151*9880d681SAndroid Build Coastguard Worker const uint64_t EndAlign = 256;
1152*9880d681SAndroid Build Coastguard Worker const auto Limit = End - (std::min)(EndAlign, End - Start);
1153*9880d681SAndroid Build Coastguard Worker while (End > Limit &&
1154*9880d681SAndroid Build Coastguard Worker *reinterpret_cast<const support::ulittle32_t*>(&Bytes[End - 4]) == 0)
1155*9880d681SAndroid Build Coastguard Worker End -= 4;
1156*9880d681SAndroid Build Coastguard Worker }
1157*9880d681SAndroid Build Coastguard Worker
1158*9880d681SAndroid Build Coastguard Worker outs() << '\n' << Symbols[si].second << ":\n";
1159*9880d681SAndroid Build Coastguard Worker
1160*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
1161*9880d681SAndroid Build Coastguard Worker raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
1162*9880d681SAndroid Build Coastguard Worker #else
1163*9880d681SAndroid Build Coastguard Worker raw_ostream &DebugOut = nulls();
1164*9880d681SAndroid Build Coastguard Worker #endif
1165*9880d681SAndroid Build Coastguard Worker
1166*9880d681SAndroid Build Coastguard Worker for (Index = Start; Index < End; Index += Size) {
1167*9880d681SAndroid Build Coastguard Worker MCInst Inst;
1168*9880d681SAndroid Build Coastguard Worker
1169*9880d681SAndroid Build Coastguard Worker // AArch64 ELF binaries can interleave data and text in the
1170*9880d681SAndroid Build Coastguard Worker // same section. We rely on the markers introduced to
1171*9880d681SAndroid Build Coastguard Worker // understand what we need to dump.
1172*9880d681SAndroid Build Coastguard Worker if (Obj->isELF() && Obj->getArch() == Triple::aarch64) {
1173*9880d681SAndroid Build Coastguard Worker uint64_t Stride = 0;
1174*9880d681SAndroid Build Coastguard Worker
1175*9880d681SAndroid Build Coastguard Worker auto DAI = std::lower_bound(DataMappingSymsAddr.begin(),
1176*9880d681SAndroid Build Coastguard Worker DataMappingSymsAddr.end(), Index);
1177*9880d681SAndroid Build Coastguard Worker if (DAI != DataMappingSymsAddr.end() && *DAI == Index) {
1178*9880d681SAndroid Build Coastguard Worker // Switch to data.
1179*9880d681SAndroid Build Coastguard Worker while (Index < End) {
1180*9880d681SAndroid Build Coastguard Worker outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1181*9880d681SAndroid Build Coastguard Worker outs() << "\t";
1182*9880d681SAndroid Build Coastguard Worker if (Index + 4 <= End) {
1183*9880d681SAndroid Build Coastguard Worker Stride = 4;
1184*9880d681SAndroid Build Coastguard Worker dumpBytes(Bytes.slice(Index, 4), outs());
1185*9880d681SAndroid Build Coastguard Worker outs() << "\t.word";
1186*9880d681SAndroid Build Coastguard Worker } else if (Index + 2 <= End) {
1187*9880d681SAndroid Build Coastguard Worker Stride = 2;
1188*9880d681SAndroid Build Coastguard Worker dumpBytes(Bytes.slice(Index, 2), outs());
1189*9880d681SAndroid Build Coastguard Worker outs() << "\t.short";
1190*9880d681SAndroid Build Coastguard Worker } else {
1191*9880d681SAndroid Build Coastguard Worker Stride = 1;
1192*9880d681SAndroid Build Coastguard Worker dumpBytes(Bytes.slice(Index, 1), outs());
1193*9880d681SAndroid Build Coastguard Worker outs() << "\t.byte";
1194*9880d681SAndroid Build Coastguard Worker }
1195*9880d681SAndroid Build Coastguard Worker Index += Stride;
1196*9880d681SAndroid Build Coastguard Worker outs() << "\n";
1197*9880d681SAndroid Build Coastguard Worker auto TAI = std::lower_bound(TextMappingSymsAddr.begin(),
1198*9880d681SAndroid Build Coastguard Worker TextMappingSymsAddr.end(), Index);
1199*9880d681SAndroid Build Coastguard Worker if (TAI != TextMappingSymsAddr.end() && *TAI == Index)
1200*9880d681SAndroid Build Coastguard Worker break;
1201*9880d681SAndroid Build Coastguard Worker }
1202*9880d681SAndroid Build Coastguard Worker }
1203*9880d681SAndroid Build Coastguard Worker }
1204*9880d681SAndroid Build Coastguard Worker
1205*9880d681SAndroid Build Coastguard Worker if (Index >= End)
1206*9880d681SAndroid Build Coastguard Worker break;
1207*9880d681SAndroid Build Coastguard Worker
1208*9880d681SAndroid Build Coastguard Worker bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
1209*9880d681SAndroid Build Coastguard Worker SectionAddr + Index, DebugOut,
1210*9880d681SAndroid Build Coastguard Worker CommentStream);
1211*9880d681SAndroid Build Coastguard Worker if (Size == 0)
1212*9880d681SAndroid Build Coastguard Worker Size = 1;
1213*9880d681SAndroid Build Coastguard Worker PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
1214*9880d681SAndroid Build Coastguard Worker Bytes.slice(Index, Size),
1215*9880d681SAndroid Build Coastguard Worker SectionAddr + Index, outs(), "", *STI);
1216*9880d681SAndroid Build Coastguard Worker outs() << CommentStream.str();
1217*9880d681SAndroid Build Coastguard Worker Comments.clear();
1218*9880d681SAndroid Build Coastguard Worker
1219*9880d681SAndroid Build Coastguard Worker // Try to resolve the target of a call, tail call, etc. to a specific
1220*9880d681SAndroid Build Coastguard Worker // symbol.
1221*9880d681SAndroid Build Coastguard Worker if (MIA && (MIA->isCall(Inst) || MIA->isUnconditionalBranch(Inst) ||
1222*9880d681SAndroid Build Coastguard Worker MIA->isConditionalBranch(Inst))) {
1223*9880d681SAndroid Build Coastguard Worker uint64_t Target;
1224*9880d681SAndroid Build Coastguard Worker if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
1225*9880d681SAndroid Build Coastguard Worker // In a relocatable object, the target's section must reside in
1226*9880d681SAndroid Build Coastguard Worker // the same section as the call instruction or it is accessed
1227*9880d681SAndroid Build Coastguard Worker // through a relocation.
1228*9880d681SAndroid Build Coastguard Worker //
1229*9880d681SAndroid Build Coastguard Worker // In a non-relocatable object, the target may be in any section.
1230*9880d681SAndroid Build Coastguard Worker //
1231*9880d681SAndroid Build Coastguard Worker // N.B. We don't walk the relocations in the relocatable case yet.
1232*9880d681SAndroid Build Coastguard Worker auto *TargetSectionSymbols = &Symbols;
1233*9880d681SAndroid Build Coastguard Worker if (!Obj->isRelocatableObject()) {
1234*9880d681SAndroid Build Coastguard Worker auto SectionAddress = std::upper_bound(
1235*9880d681SAndroid Build Coastguard Worker SectionAddresses.begin(), SectionAddresses.end(), Target,
1236*9880d681SAndroid Build Coastguard Worker [](uint64_t LHS,
1237*9880d681SAndroid Build Coastguard Worker const std::pair<uint64_t, SectionRef> &RHS) {
1238*9880d681SAndroid Build Coastguard Worker return LHS < RHS.first;
1239*9880d681SAndroid Build Coastguard Worker });
1240*9880d681SAndroid Build Coastguard Worker if (SectionAddress != SectionAddresses.begin()) {
1241*9880d681SAndroid Build Coastguard Worker --SectionAddress;
1242*9880d681SAndroid Build Coastguard Worker TargetSectionSymbols = &AllSymbols[SectionAddress->second];
1243*9880d681SAndroid Build Coastguard Worker } else {
1244*9880d681SAndroid Build Coastguard Worker TargetSectionSymbols = nullptr;
1245*9880d681SAndroid Build Coastguard Worker }
1246*9880d681SAndroid Build Coastguard Worker }
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker // Find the first symbol in the section whose offset is less than
1249*9880d681SAndroid Build Coastguard Worker // or equal to the target.
1250*9880d681SAndroid Build Coastguard Worker if (TargetSectionSymbols) {
1251*9880d681SAndroid Build Coastguard Worker auto TargetSym = std::upper_bound(
1252*9880d681SAndroid Build Coastguard Worker TargetSectionSymbols->begin(), TargetSectionSymbols->end(),
1253*9880d681SAndroid Build Coastguard Worker Target, [](uint64_t LHS,
1254*9880d681SAndroid Build Coastguard Worker const std::pair<uint64_t, StringRef> &RHS) {
1255*9880d681SAndroid Build Coastguard Worker return LHS < RHS.first;
1256*9880d681SAndroid Build Coastguard Worker });
1257*9880d681SAndroid Build Coastguard Worker if (TargetSym != TargetSectionSymbols->begin()) {
1258*9880d681SAndroid Build Coastguard Worker --TargetSym;
1259*9880d681SAndroid Build Coastguard Worker uint64_t TargetAddress = std::get<0>(*TargetSym);
1260*9880d681SAndroid Build Coastguard Worker StringRef TargetName = std::get<1>(*TargetSym);
1261*9880d681SAndroid Build Coastguard Worker outs() << " <" << TargetName;
1262*9880d681SAndroid Build Coastguard Worker uint64_t Disp = Target - TargetAddress;
1263*9880d681SAndroid Build Coastguard Worker if (Disp)
1264*9880d681SAndroid Build Coastguard Worker outs() << "+0x" << utohexstr(Disp);
1265*9880d681SAndroid Build Coastguard Worker outs() << '>';
1266*9880d681SAndroid Build Coastguard Worker }
1267*9880d681SAndroid Build Coastguard Worker }
1268*9880d681SAndroid Build Coastguard Worker }
1269*9880d681SAndroid Build Coastguard Worker }
1270*9880d681SAndroid Build Coastguard Worker outs() << "\n";
1271*9880d681SAndroid Build Coastguard Worker
1272*9880d681SAndroid Build Coastguard Worker // Print relocation for instruction.
1273*9880d681SAndroid Build Coastguard Worker while (rel_cur != rel_end) {
1274*9880d681SAndroid Build Coastguard Worker bool hidden = getHidden(*rel_cur);
1275*9880d681SAndroid Build Coastguard Worker uint64_t addr = rel_cur->getOffset();
1276*9880d681SAndroid Build Coastguard Worker SmallString<16> name;
1277*9880d681SAndroid Build Coastguard Worker SmallString<32> val;
1278*9880d681SAndroid Build Coastguard Worker
1279*9880d681SAndroid Build Coastguard Worker // If this relocation is hidden, skip it.
1280*9880d681SAndroid Build Coastguard Worker if (hidden) goto skip_print_rel;
1281*9880d681SAndroid Build Coastguard Worker
1282*9880d681SAndroid Build Coastguard Worker // Stop when rel_cur's address is past the current instruction.
1283*9880d681SAndroid Build Coastguard Worker if (addr >= Index + Size) break;
1284*9880d681SAndroid Build Coastguard Worker rel_cur->getTypeName(name);
1285*9880d681SAndroid Build Coastguard Worker error(getRelocationValueString(*rel_cur, val));
1286*9880d681SAndroid Build Coastguard Worker outs() << format(Fmt.data(), SectionAddr + addr) << name
1287*9880d681SAndroid Build Coastguard Worker << "\t" << val << "\n";
1288*9880d681SAndroid Build Coastguard Worker
1289*9880d681SAndroid Build Coastguard Worker skip_print_rel:
1290*9880d681SAndroid Build Coastguard Worker ++rel_cur;
1291*9880d681SAndroid Build Coastguard Worker }
1292*9880d681SAndroid Build Coastguard Worker }
1293*9880d681SAndroid Build Coastguard Worker }
1294*9880d681SAndroid Build Coastguard Worker }
1295*9880d681SAndroid Build Coastguard Worker }
1296*9880d681SAndroid Build Coastguard Worker
PrintRelocations(const ObjectFile * Obj)1297*9880d681SAndroid Build Coastguard Worker void llvm::PrintRelocations(const ObjectFile *Obj) {
1298*9880d681SAndroid Build Coastguard Worker StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
1299*9880d681SAndroid Build Coastguard Worker "%08" PRIx64;
1300*9880d681SAndroid Build Coastguard Worker // Regular objdump doesn't print relocations in non-relocatable object
1301*9880d681SAndroid Build Coastguard Worker // files.
1302*9880d681SAndroid Build Coastguard Worker if (!Obj->isRelocatableObject())
1303*9880d681SAndroid Build Coastguard Worker return;
1304*9880d681SAndroid Build Coastguard Worker
1305*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1306*9880d681SAndroid Build Coastguard Worker if (Section.relocation_begin() == Section.relocation_end())
1307*9880d681SAndroid Build Coastguard Worker continue;
1308*9880d681SAndroid Build Coastguard Worker StringRef secname;
1309*9880d681SAndroid Build Coastguard Worker error(Section.getName(secname));
1310*9880d681SAndroid Build Coastguard Worker outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
1311*9880d681SAndroid Build Coastguard Worker for (const RelocationRef &Reloc : Section.relocations()) {
1312*9880d681SAndroid Build Coastguard Worker bool hidden = getHidden(Reloc);
1313*9880d681SAndroid Build Coastguard Worker uint64_t address = Reloc.getOffset();
1314*9880d681SAndroid Build Coastguard Worker SmallString<32> relocname;
1315*9880d681SAndroid Build Coastguard Worker SmallString<32> valuestr;
1316*9880d681SAndroid Build Coastguard Worker if (hidden)
1317*9880d681SAndroid Build Coastguard Worker continue;
1318*9880d681SAndroid Build Coastguard Worker Reloc.getTypeName(relocname);
1319*9880d681SAndroid Build Coastguard Worker error(getRelocationValueString(Reloc, valuestr));
1320*9880d681SAndroid Build Coastguard Worker outs() << format(Fmt.data(), address) << " " << relocname << " "
1321*9880d681SAndroid Build Coastguard Worker << valuestr << "\n";
1322*9880d681SAndroid Build Coastguard Worker }
1323*9880d681SAndroid Build Coastguard Worker outs() << "\n";
1324*9880d681SAndroid Build Coastguard Worker }
1325*9880d681SAndroid Build Coastguard Worker }
1326*9880d681SAndroid Build Coastguard Worker
PrintSectionHeaders(const ObjectFile * Obj)1327*9880d681SAndroid Build Coastguard Worker void llvm::PrintSectionHeaders(const ObjectFile *Obj) {
1328*9880d681SAndroid Build Coastguard Worker outs() << "Sections:\n"
1329*9880d681SAndroid Build Coastguard Worker "Idx Name Size Address Type\n";
1330*9880d681SAndroid Build Coastguard Worker unsigned i = 0;
1331*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1332*9880d681SAndroid Build Coastguard Worker StringRef Name;
1333*9880d681SAndroid Build Coastguard Worker error(Section.getName(Name));
1334*9880d681SAndroid Build Coastguard Worker uint64_t Address = Section.getAddress();
1335*9880d681SAndroid Build Coastguard Worker uint64_t Size = Section.getSize();
1336*9880d681SAndroid Build Coastguard Worker bool Text = Section.isText();
1337*9880d681SAndroid Build Coastguard Worker bool Data = Section.isData();
1338*9880d681SAndroid Build Coastguard Worker bool BSS = Section.isBSS();
1339*9880d681SAndroid Build Coastguard Worker std::string Type = (std::string(Text ? "TEXT " : "") +
1340*9880d681SAndroid Build Coastguard Worker (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
1341*9880d681SAndroid Build Coastguard Worker outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", i,
1342*9880d681SAndroid Build Coastguard Worker Name.str().c_str(), Size, Address, Type.c_str());
1343*9880d681SAndroid Build Coastguard Worker ++i;
1344*9880d681SAndroid Build Coastguard Worker }
1345*9880d681SAndroid Build Coastguard Worker }
1346*9880d681SAndroid Build Coastguard Worker
PrintSectionContents(const ObjectFile * Obj)1347*9880d681SAndroid Build Coastguard Worker void llvm::PrintSectionContents(const ObjectFile *Obj) {
1348*9880d681SAndroid Build Coastguard Worker std::error_code EC;
1349*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1350*9880d681SAndroid Build Coastguard Worker StringRef Name;
1351*9880d681SAndroid Build Coastguard Worker StringRef Contents;
1352*9880d681SAndroid Build Coastguard Worker error(Section.getName(Name));
1353*9880d681SAndroid Build Coastguard Worker uint64_t BaseAddr = Section.getAddress();
1354*9880d681SAndroid Build Coastguard Worker uint64_t Size = Section.getSize();
1355*9880d681SAndroid Build Coastguard Worker if (!Size)
1356*9880d681SAndroid Build Coastguard Worker continue;
1357*9880d681SAndroid Build Coastguard Worker
1358*9880d681SAndroid Build Coastguard Worker outs() << "Contents of section " << Name << ":\n";
1359*9880d681SAndroid Build Coastguard Worker if (Section.isBSS()) {
1360*9880d681SAndroid Build Coastguard Worker outs() << format("<skipping contents of bss section at [%04" PRIx64
1361*9880d681SAndroid Build Coastguard Worker ", %04" PRIx64 ")>\n",
1362*9880d681SAndroid Build Coastguard Worker BaseAddr, BaseAddr + Size);
1363*9880d681SAndroid Build Coastguard Worker continue;
1364*9880d681SAndroid Build Coastguard Worker }
1365*9880d681SAndroid Build Coastguard Worker
1366*9880d681SAndroid Build Coastguard Worker error(Section.getContents(Contents));
1367*9880d681SAndroid Build Coastguard Worker
1368*9880d681SAndroid Build Coastguard Worker // Dump out the content as hex and printable ascii characters.
1369*9880d681SAndroid Build Coastguard Worker for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
1370*9880d681SAndroid Build Coastguard Worker outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
1371*9880d681SAndroid Build Coastguard Worker // Dump line of hex.
1372*9880d681SAndroid Build Coastguard Worker for (std::size_t i = 0; i < 16; ++i) {
1373*9880d681SAndroid Build Coastguard Worker if (i != 0 && i % 4 == 0)
1374*9880d681SAndroid Build Coastguard Worker outs() << ' ';
1375*9880d681SAndroid Build Coastguard Worker if (addr + i < end)
1376*9880d681SAndroid Build Coastguard Worker outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true)
1377*9880d681SAndroid Build Coastguard Worker << hexdigit(Contents[addr + i] & 0xF, true);
1378*9880d681SAndroid Build Coastguard Worker else
1379*9880d681SAndroid Build Coastguard Worker outs() << " ";
1380*9880d681SAndroid Build Coastguard Worker }
1381*9880d681SAndroid Build Coastguard Worker // Print ascii.
1382*9880d681SAndroid Build Coastguard Worker outs() << " ";
1383*9880d681SAndroid Build Coastguard Worker for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
1384*9880d681SAndroid Build Coastguard Worker if (std::isprint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF))
1385*9880d681SAndroid Build Coastguard Worker outs() << Contents[addr + i];
1386*9880d681SAndroid Build Coastguard Worker else
1387*9880d681SAndroid Build Coastguard Worker outs() << ".";
1388*9880d681SAndroid Build Coastguard Worker }
1389*9880d681SAndroid Build Coastguard Worker outs() << "\n";
1390*9880d681SAndroid Build Coastguard Worker }
1391*9880d681SAndroid Build Coastguard Worker }
1392*9880d681SAndroid Build Coastguard Worker }
1393*9880d681SAndroid Build Coastguard Worker
PrintSymbolTable(const ObjectFile * o,StringRef ArchiveName,StringRef ArchitectureName)1394*9880d681SAndroid Build Coastguard Worker void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName,
1395*9880d681SAndroid Build Coastguard Worker StringRef ArchitectureName) {
1396*9880d681SAndroid Build Coastguard Worker outs() << "SYMBOL TABLE:\n";
1397*9880d681SAndroid Build Coastguard Worker
1398*9880d681SAndroid Build Coastguard Worker if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) {
1399*9880d681SAndroid Build Coastguard Worker printCOFFSymbolTable(coff);
1400*9880d681SAndroid Build Coastguard Worker return;
1401*9880d681SAndroid Build Coastguard Worker }
1402*9880d681SAndroid Build Coastguard Worker for (const SymbolRef &Symbol : o->symbols()) {
1403*9880d681SAndroid Build Coastguard Worker Expected<uint64_t> AddressOrError = Symbol.getAddress();
1404*9880d681SAndroid Build Coastguard Worker if (!AddressOrError)
1405*9880d681SAndroid Build Coastguard Worker report_error(ArchiveName, o->getFileName(), AddressOrError.takeError());
1406*9880d681SAndroid Build Coastguard Worker uint64_t Address = *AddressOrError;
1407*9880d681SAndroid Build Coastguard Worker Expected<SymbolRef::Type> TypeOrError = Symbol.getType();
1408*9880d681SAndroid Build Coastguard Worker if (!TypeOrError)
1409*9880d681SAndroid Build Coastguard Worker report_error(ArchiveName, o->getFileName(), TypeOrError.takeError());
1410*9880d681SAndroid Build Coastguard Worker SymbolRef::Type Type = *TypeOrError;
1411*9880d681SAndroid Build Coastguard Worker uint32_t Flags = Symbol.getFlags();
1412*9880d681SAndroid Build Coastguard Worker Expected<section_iterator> SectionOrErr = Symbol.getSection();
1413*9880d681SAndroid Build Coastguard Worker error(errorToErrorCode(SectionOrErr.takeError()));
1414*9880d681SAndroid Build Coastguard Worker section_iterator Section = *SectionOrErr;
1415*9880d681SAndroid Build Coastguard Worker StringRef Name;
1416*9880d681SAndroid Build Coastguard Worker if (Type == SymbolRef::ST_Debug && Section != o->section_end()) {
1417*9880d681SAndroid Build Coastguard Worker Section->getName(Name);
1418*9880d681SAndroid Build Coastguard Worker } else {
1419*9880d681SAndroid Build Coastguard Worker Expected<StringRef> NameOrErr = Symbol.getName();
1420*9880d681SAndroid Build Coastguard Worker if (!NameOrErr)
1421*9880d681SAndroid Build Coastguard Worker report_error(ArchiveName, o->getFileName(), NameOrErr.takeError(),
1422*9880d681SAndroid Build Coastguard Worker ArchitectureName);
1423*9880d681SAndroid Build Coastguard Worker Name = *NameOrErr;
1424*9880d681SAndroid Build Coastguard Worker }
1425*9880d681SAndroid Build Coastguard Worker
1426*9880d681SAndroid Build Coastguard Worker bool Global = Flags & SymbolRef::SF_Global;
1427*9880d681SAndroid Build Coastguard Worker bool Weak = Flags & SymbolRef::SF_Weak;
1428*9880d681SAndroid Build Coastguard Worker bool Absolute = Flags & SymbolRef::SF_Absolute;
1429*9880d681SAndroid Build Coastguard Worker bool Common = Flags & SymbolRef::SF_Common;
1430*9880d681SAndroid Build Coastguard Worker bool Hidden = Flags & SymbolRef::SF_Hidden;
1431*9880d681SAndroid Build Coastguard Worker
1432*9880d681SAndroid Build Coastguard Worker char GlobLoc = ' ';
1433*9880d681SAndroid Build Coastguard Worker if (Type != SymbolRef::ST_Unknown)
1434*9880d681SAndroid Build Coastguard Worker GlobLoc = Global ? 'g' : 'l';
1435*9880d681SAndroid Build Coastguard Worker char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
1436*9880d681SAndroid Build Coastguard Worker ? 'd' : ' ';
1437*9880d681SAndroid Build Coastguard Worker char FileFunc = ' ';
1438*9880d681SAndroid Build Coastguard Worker if (Type == SymbolRef::ST_File)
1439*9880d681SAndroid Build Coastguard Worker FileFunc = 'f';
1440*9880d681SAndroid Build Coastguard Worker else if (Type == SymbolRef::ST_Function)
1441*9880d681SAndroid Build Coastguard Worker FileFunc = 'F';
1442*9880d681SAndroid Build Coastguard Worker
1443*9880d681SAndroid Build Coastguard Worker const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 :
1444*9880d681SAndroid Build Coastguard Worker "%08" PRIx64;
1445*9880d681SAndroid Build Coastguard Worker
1446*9880d681SAndroid Build Coastguard Worker outs() << format(Fmt, Address) << " "
1447*9880d681SAndroid Build Coastguard Worker << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
1448*9880d681SAndroid Build Coastguard Worker << (Weak ? 'w' : ' ') // Weak?
1449*9880d681SAndroid Build Coastguard Worker << ' ' // Constructor. Not supported yet.
1450*9880d681SAndroid Build Coastguard Worker << ' ' // Warning. Not supported yet.
1451*9880d681SAndroid Build Coastguard Worker << ' ' // Indirect reference to another symbol.
1452*9880d681SAndroid Build Coastguard Worker << Debug // Debugging (d) or dynamic (D) symbol.
1453*9880d681SAndroid Build Coastguard Worker << FileFunc // Name of function (F), file (f) or object (O).
1454*9880d681SAndroid Build Coastguard Worker << ' ';
1455*9880d681SAndroid Build Coastguard Worker if (Absolute) {
1456*9880d681SAndroid Build Coastguard Worker outs() << "*ABS*";
1457*9880d681SAndroid Build Coastguard Worker } else if (Common) {
1458*9880d681SAndroid Build Coastguard Worker outs() << "*COM*";
1459*9880d681SAndroid Build Coastguard Worker } else if (Section == o->section_end()) {
1460*9880d681SAndroid Build Coastguard Worker outs() << "*UND*";
1461*9880d681SAndroid Build Coastguard Worker } else {
1462*9880d681SAndroid Build Coastguard Worker if (const MachOObjectFile *MachO =
1463*9880d681SAndroid Build Coastguard Worker dyn_cast<const MachOObjectFile>(o)) {
1464*9880d681SAndroid Build Coastguard Worker DataRefImpl DR = Section->getRawDataRefImpl();
1465*9880d681SAndroid Build Coastguard Worker StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
1466*9880d681SAndroid Build Coastguard Worker outs() << SegmentName << ",";
1467*9880d681SAndroid Build Coastguard Worker }
1468*9880d681SAndroid Build Coastguard Worker StringRef SectionName;
1469*9880d681SAndroid Build Coastguard Worker error(Section->getName(SectionName));
1470*9880d681SAndroid Build Coastguard Worker outs() << SectionName;
1471*9880d681SAndroid Build Coastguard Worker }
1472*9880d681SAndroid Build Coastguard Worker
1473*9880d681SAndroid Build Coastguard Worker outs() << '\t';
1474*9880d681SAndroid Build Coastguard Worker if (Common || isa<ELFObjectFileBase>(o)) {
1475*9880d681SAndroid Build Coastguard Worker uint64_t Val =
1476*9880d681SAndroid Build Coastguard Worker Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
1477*9880d681SAndroid Build Coastguard Worker outs() << format("\t %08" PRIx64 " ", Val);
1478*9880d681SAndroid Build Coastguard Worker }
1479*9880d681SAndroid Build Coastguard Worker
1480*9880d681SAndroid Build Coastguard Worker if (Hidden) {
1481*9880d681SAndroid Build Coastguard Worker outs() << ".hidden ";
1482*9880d681SAndroid Build Coastguard Worker }
1483*9880d681SAndroid Build Coastguard Worker outs() << Name
1484*9880d681SAndroid Build Coastguard Worker << '\n';
1485*9880d681SAndroid Build Coastguard Worker }
1486*9880d681SAndroid Build Coastguard Worker }
1487*9880d681SAndroid Build Coastguard Worker
PrintUnwindInfo(const ObjectFile * o)1488*9880d681SAndroid Build Coastguard Worker static void PrintUnwindInfo(const ObjectFile *o) {
1489*9880d681SAndroid Build Coastguard Worker outs() << "Unwind info:\n\n";
1490*9880d681SAndroid Build Coastguard Worker
1491*9880d681SAndroid Build Coastguard Worker if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) {
1492*9880d681SAndroid Build Coastguard Worker printCOFFUnwindInfo(coff);
1493*9880d681SAndroid Build Coastguard Worker } else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1494*9880d681SAndroid Build Coastguard Worker printMachOUnwindInfo(MachO);
1495*9880d681SAndroid Build Coastguard Worker else {
1496*9880d681SAndroid Build Coastguard Worker // TODO: Extract DWARF dump tool to objdump.
1497*9880d681SAndroid Build Coastguard Worker errs() << "This operation is only currently supported "
1498*9880d681SAndroid Build Coastguard Worker "for COFF and MachO object files.\n";
1499*9880d681SAndroid Build Coastguard Worker return;
1500*9880d681SAndroid Build Coastguard Worker }
1501*9880d681SAndroid Build Coastguard Worker }
1502*9880d681SAndroid Build Coastguard Worker
printExportsTrie(const ObjectFile * o)1503*9880d681SAndroid Build Coastguard Worker void llvm::printExportsTrie(const ObjectFile *o) {
1504*9880d681SAndroid Build Coastguard Worker outs() << "Exports trie:\n";
1505*9880d681SAndroid Build Coastguard Worker if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1506*9880d681SAndroid Build Coastguard Worker printMachOExportsTrie(MachO);
1507*9880d681SAndroid Build Coastguard Worker else {
1508*9880d681SAndroid Build Coastguard Worker errs() << "This operation is only currently supported "
1509*9880d681SAndroid Build Coastguard Worker "for Mach-O executable files.\n";
1510*9880d681SAndroid Build Coastguard Worker return;
1511*9880d681SAndroid Build Coastguard Worker }
1512*9880d681SAndroid Build Coastguard Worker }
1513*9880d681SAndroid Build Coastguard Worker
printRebaseTable(const ObjectFile * o)1514*9880d681SAndroid Build Coastguard Worker void llvm::printRebaseTable(const ObjectFile *o) {
1515*9880d681SAndroid Build Coastguard Worker outs() << "Rebase table:\n";
1516*9880d681SAndroid Build Coastguard Worker if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1517*9880d681SAndroid Build Coastguard Worker printMachORebaseTable(MachO);
1518*9880d681SAndroid Build Coastguard Worker else {
1519*9880d681SAndroid Build Coastguard Worker errs() << "This operation is only currently supported "
1520*9880d681SAndroid Build Coastguard Worker "for Mach-O executable files.\n";
1521*9880d681SAndroid Build Coastguard Worker return;
1522*9880d681SAndroid Build Coastguard Worker }
1523*9880d681SAndroid Build Coastguard Worker }
1524*9880d681SAndroid Build Coastguard Worker
printBindTable(const ObjectFile * o)1525*9880d681SAndroid Build Coastguard Worker void llvm::printBindTable(const ObjectFile *o) {
1526*9880d681SAndroid Build Coastguard Worker outs() << "Bind table:\n";
1527*9880d681SAndroid Build Coastguard Worker if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1528*9880d681SAndroid Build Coastguard Worker printMachOBindTable(MachO);
1529*9880d681SAndroid Build Coastguard Worker else {
1530*9880d681SAndroid Build Coastguard Worker errs() << "This operation is only currently supported "
1531*9880d681SAndroid Build Coastguard Worker "for Mach-O executable files.\n";
1532*9880d681SAndroid Build Coastguard Worker return;
1533*9880d681SAndroid Build Coastguard Worker }
1534*9880d681SAndroid Build Coastguard Worker }
1535*9880d681SAndroid Build Coastguard Worker
printLazyBindTable(const ObjectFile * o)1536*9880d681SAndroid Build Coastguard Worker void llvm::printLazyBindTable(const ObjectFile *o) {
1537*9880d681SAndroid Build Coastguard Worker outs() << "Lazy bind table:\n";
1538*9880d681SAndroid Build Coastguard Worker if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1539*9880d681SAndroid Build Coastguard Worker printMachOLazyBindTable(MachO);
1540*9880d681SAndroid Build Coastguard Worker else {
1541*9880d681SAndroid Build Coastguard Worker errs() << "This operation is only currently supported "
1542*9880d681SAndroid Build Coastguard Worker "for Mach-O executable files.\n";
1543*9880d681SAndroid Build Coastguard Worker return;
1544*9880d681SAndroid Build Coastguard Worker }
1545*9880d681SAndroid Build Coastguard Worker }
1546*9880d681SAndroid Build Coastguard Worker
printWeakBindTable(const ObjectFile * o)1547*9880d681SAndroid Build Coastguard Worker void llvm::printWeakBindTable(const ObjectFile *o) {
1548*9880d681SAndroid Build Coastguard Worker outs() << "Weak bind table:\n";
1549*9880d681SAndroid Build Coastguard Worker if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1550*9880d681SAndroid Build Coastguard Worker printMachOWeakBindTable(MachO);
1551*9880d681SAndroid Build Coastguard Worker else {
1552*9880d681SAndroid Build Coastguard Worker errs() << "This operation is only currently supported "
1553*9880d681SAndroid Build Coastguard Worker "for Mach-O executable files.\n";
1554*9880d681SAndroid Build Coastguard Worker return;
1555*9880d681SAndroid Build Coastguard Worker }
1556*9880d681SAndroid Build Coastguard Worker }
1557*9880d681SAndroid Build Coastguard Worker
1558*9880d681SAndroid Build Coastguard Worker /// Dump the raw contents of the __clangast section so the output can be piped
1559*9880d681SAndroid Build Coastguard Worker /// into llvm-bcanalyzer.
printRawClangAST(const ObjectFile * Obj)1560*9880d681SAndroid Build Coastguard Worker void llvm::printRawClangAST(const ObjectFile *Obj) {
1561*9880d681SAndroid Build Coastguard Worker if (outs().is_displayed()) {
1562*9880d681SAndroid Build Coastguard Worker errs() << "The -raw-clang-ast option will dump the raw binary contents of "
1563*9880d681SAndroid Build Coastguard Worker "the clang ast section.\n"
1564*9880d681SAndroid Build Coastguard Worker "Please redirect the output to a file or another program such as "
1565*9880d681SAndroid Build Coastguard Worker "llvm-bcanalyzer.\n";
1566*9880d681SAndroid Build Coastguard Worker return;
1567*9880d681SAndroid Build Coastguard Worker }
1568*9880d681SAndroid Build Coastguard Worker
1569*9880d681SAndroid Build Coastguard Worker StringRef ClangASTSectionName("__clangast");
1570*9880d681SAndroid Build Coastguard Worker if (isa<COFFObjectFile>(Obj)) {
1571*9880d681SAndroid Build Coastguard Worker ClangASTSectionName = "clangast";
1572*9880d681SAndroid Build Coastguard Worker }
1573*9880d681SAndroid Build Coastguard Worker
1574*9880d681SAndroid Build Coastguard Worker Optional<object::SectionRef> ClangASTSection;
1575*9880d681SAndroid Build Coastguard Worker for (auto Sec : ToolSectionFilter(*Obj)) {
1576*9880d681SAndroid Build Coastguard Worker StringRef Name;
1577*9880d681SAndroid Build Coastguard Worker Sec.getName(Name);
1578*9880d681SAndroid Build Coastguard Worker if (Name == ClangASTSectionName) {
1579*9880d681SAndroid Build Coastguard Worker ClangASTSection = Sec;
1580*9880d681SAndroid Build Coastguard Worker break;
1581*9880d681SAndroid Build Coastguard Worker }
1582*9880d681SAndroid Build Coastguard Worker }
1583*9880d681SAndroid Build Coastguard Worker if (!ClangASTSection)
1584*9880d681SAndroid Build Coastguard Worker return;
1585*9880d681SAndroid Build Coastguard Worker
1586*9880d681SAndroid Build Coastguard Worker StringRef ClangASTContents;
1587*9880d681SAndroid Build Coastguard Worker error(ClangASTSection.getValue().getContents(ClangASTContents));
1588*9880d681SAndroid Build Coastguard Worker outs().write(ClangASTContents.data(), ClangASTContents.size());
1589*9880d681SAndroid Build Coastguard Worker }
1590*9880d681SAndroid Build Coastguard Worker
printFaultMaps(const ObjectFile * Obj)1591*9880d681SAndroid Build Coastguard Worker static void printFaultMaps(const ObjectFile *Obj) {
1592*9880d681SAndroid Build Coastguard Worker const char *FaultMapSectionName = nullptr;
1593*9880d681SAndroid Build Coastguard Worker
1594*9880d681SAndroid Build Coastguard Worker if (isa<ELFObjectFileBase>(Obj)) {
1595*9880d681SAndroid Build Coastguard Worker FaultMapSectionName = ".llvm_faultmaps";
1596*9880d681SAndroid Build Coastguard Worker } else if (isa<MachOObjectFile>(Obj)) {
1597*9880d681SAndroid Build Coastguard Worker FaultMapSectionName = "__llvm_faultmaps";
1598*9880d681SAndroid Build Coastguard Worker } else {
1599*9880d681SAndroid Build Coastguard Worker errs() << "This operation is only currently supported "
1600*9880d681SAndroid Build Coastguard Worker "for ELF and Mach-O executable files.\n";
1601*9880d681SAndroid Build Coastguard Worker return;
1602*9880d681SAndroid Build Coastguard Worker }
1603*9880d681SAndroid Build Coastguard Worker
1604*9880d681SAndroid Build Coastguard Worker Optional<object::SectionRef> FaultMapSection;
1605*9880d681SAndroid Build Coastguard Worker
1606*9880d681SAndroid Build Coastguard Worker for (auto Sec : ToolSectionFilter(*Obj)) {
1607*9880d681SAndroid Build Coastguard Worker StringRef Name;
1608*9880d681SAndroid Build Coastguard Worker Sec.getName(Name);
1609*9880d681SAndroid Build Coastguard Worker if (Name == FaultMapSectionName) {
1610*9880d681SAndroid Build Coastguard Worker FaultMapSection = Sec;
1611*9880d681SAndroid Build Coastguard Worker break;
1612*9880d681SAndroid Build Coastguard Worker }
1613*9880d681SAndroid Build Coastguard Worker }
1614*9880d681SAndroid Build Coastguard Worker
1615*9880d681SAndroid Build Coastguard Worker outs() << "FaultMap table:\n";
1616*9880d681SAndroid Build Coastguard Worker
1617*9880d681SAndroid Build Coastguard Worker if (!FaultMapSection.hasValue()) {
1618*9880d681SAndroid Build Coastguard Worker outs() << "<not found>\n";
1619*9880d681SAndroid Build Coastguard Worker return;
1620*9880d681SAndroid Build Coastguard Worker }
1621*9880d681SAndroid Build Coastguard Worker
1622*9880d681SAndroid Build Coastguard Worker StringRef FaultMapContents;
1623*9880d681SAndroid Build Coastguard Worker error(FaultMapSection.getValue().getContents(FaultMapContents));
1624*9880d681SAndroid Build Coastguard Worker
1625*9880d681SAndroid Build Coastguard Worker FaultMapParser FMP(FaultMapContents.bytes_begin(),
1626*9880d681SAndroid Build Coastguard Worker FaultMapContents.bytes_end());
1627*9880d681SAndroid Build Coastguard Worker
1628*9880d681SAndroid Build Coastguard Worker outs() << FMP;
1629*9880d681SAndroid Build Coastguard Worker }
1630*9880d681SAndroid Build Coastguard Worker
printPrivateFileHeaders(const ObjectFile * o)1631*9880d681SAndroid Build Coastguard Worker static void printPrivateFileHeaders(const ObjectFile *o) {
1632*9880d681SAndroid Build Coastguard Worker if (o->isELF())
1633*9880d681SAndroid Build Coastguard Worker printELFFileHeader(o);
1634*9880d681SAndroid Build Coastguard Worker else if (o->isCOFF())
1635*9880d681SAndroid Build Coastguard Worker printCOFFFileHeader(o);
1636*9880d681SAndroid Build Coastguard Worker else if (o->isMachO()) {
1637*9880d681SAndroid Build Coastguard Worker printMachOFileHeader(o);
1638*9880d681SAndroid Build Coastguard Worker printMachOLoadCommands(o);
1639*9880d681SAndroid Build Coastguard Worker } else
1640*9880d681SAndroid Build Coastguard Worker report_fatal_error("Invalid/Unsupported object file format");
1641*9880d681SAndroid Build Coastguard Worker }
1642*9880d681SAndroid Build Coastguard Worker
printFirstPrivateFileHeader(const ObjectFile * o)1643*9880d681SAndroid Build Coastguard Worker static void printFirstPrivateFileHeader(const ObjectFile *o) {
1644*9880d681SAndroid Build Coastguard Worker if (o->isELF())
1645*9880d681SAndroid Build Coastguard Worker printELFFileHeader(o);
1646*9880d681SAndroid Build Coastguard Worker else if (o->isCOFF())
1647*9880d681SAndroid Build Coastguard Worker printCOFFFileHeader(o);
1648*9880d681SAndroid Build Coastguard Worker else if (o->isMachO())
1649*9880d681SAndroid Build Coastguard Worker printMachOFileHeader(o);
1650*9880d681SAndroid Build Coastguard Worker else
1651*9880d681SAndroid Build Coastguard Worker report_fatal_error("Invalid/Unsupported object file format");
1652*9880d681SAndroid Build Coastguard Worker }
1653*9880d681SAndroid Build Coastguard Worker
DumpObject(const ObjectFile * o,const Archive * a=nullptr)1654*9880d681SAndroid Build Coastguard Worker static void DumpObject(const ObjectFile *o, const Archive *a = nullptr) {
1655*9880d681SAndroid Build Coastguard Worker StringRef ArchiveName = a != nullptr ? a->getFileName() : "";
1656*9880d681SAndroid Build Coastguard Worker // Avoid other output when using a raw option.
1657*9880d681SAndroid Build Coastguard Worker if (!RawClangAST) {
1658*9880d681SAndroid Build Coastguard Worker outs() << '\n';
1659*9880d681SAndroid Build Coastguard Worker if (a)
1660*9880d681SAndroid Build Coastguard Worker outs() << a->getFileName() << "(" << o->getFileName() << ")";
1661*9880d681SAndroid Build Coastguard Worker else
1662*9880d681SAndroid Build Coastguard Worker outs() << o->getFileName();
1663*9880d681SAndroid Build Coastguard Worker outs() << ":\tfile format " << o->getFileFormatName() << "\n\n";
1664*9880d681SAndroid Build Coastguard Worker }
1665*9880d681SAndroid Build Coastguard Worker
1666*9880d681SAndroid Build Coastguard Worker if (Disassemble)
1667*9880d681SAndroid Build Coastguard Worker DisassembleObject(o, Relocations);
1668*9880d681SAndroid Build Coastguard Worker if (Relocations && !Disassemble)
1669*9880d681SAndroid Build Coastguard Worker PrintRelocations(o);
1670*9880d681SAndroid Build Coastguard Worker if (SectionHeaders)
1671*9880d681SAndroid Build Coastguard Worker PrintSectionHeaders(o);
1672*9880d681SAndroid Build Coastguard Worker if (SectionContents)
1673*9880d681SAndroid Build Coastguard Worker PrintSectionContents(o);
1674*9880d681SAndroid Build Coastguard Worker if (SymbolTable)
1675*9880d681SAndroid Build Coastguard Worker PrintSymbolTable(o, ArchiveName);
1676*9880d681SAndroid Build Coastguard Worker if (UnwindInfo)
1677*9880d681SAndroid Build Coastguard Worker PrintUnwindInfo(o);
1678*9880d681SAndroid Build Coastguard Worker if (PrivateHeaders)
1679*9880d681SAndroid Build Coastguard Worker printPrivateFileHeaders(o);
1680*9880d681SAndroid Build Coastguard Worker if (FirstPrivateHeader)
1681*9880d681SAndroid Build Coastguard Worker printFirstPrivateFileHeader(o);
1682*9880d681SAndroid Build Coastguard Worker if (ExportsTrie)
1683*9880d681SAndroid Build Coastguard Worker printExportsTrie(o);
1684*9880d681SAndroid Build Coastguard Worker if (Rebase)
1685*9880d681SAndroid Build Coastguard Worker printRebaseTable(o);
1686*9880d681SAndroid Build Coastguard Worker if (Bind)
1687*9880d681SAndroid Build Coastguard Worker printBindTable(o);
1688*9880d681SAndroid Build Coastguard Worker if (LazyBind)
1689*9880d681SAndroid Build Coastguard Worker printLazyBindTable(o);
1690*9880d681SAndroid Build Coastguard Worker if (WeakBind)
1691*9880d681SAndroid Build Coastguard Worker printWeakBindTable(o);
1692*9880d681SAndroid Build Coastguard Worker if (RawClangAST)
1693*9880d681SAndroid Build Coastguard Worker printRawClangAST(o);
1694*9880d681SAndroid Build Coastguard Worker if (PrintFaultMaps)
1695*9880d681SAndroid Build Coastguard Worker printFaultMaps(o);
1696*9880d681SAndroid Build Coastguard Worker if (DwarfDumpType != DIDT_Null) {
1697*9880d681SAndroid Build Coastguard Worker std::unique_ptr<DIContext> DICtx(new DWARFContextInMemory(*o));
1698*9880d681SAndroid Build Coastguard Worker // Dump the complete DWARF structure.
1699*9880d681SAndroid Build Coastguard Worker DICtx->dump(outs(), DwarfDumpType, true /* DumpEH */);
1700*9880d681SAndroid Build Coastguard Worker }
1701*9880d681SAndroid Build Coastguard Worker }
1702*9880d681SAndroid Build Coastguard Worker
1703*9880d681SAndroid Build Coastguard Worker /// @brief Dump each object file in \a a;
DumpArchive(const Archive * a)1704*9880d681SAndroid Build Coastguard Worker static void DumpArchive(const Archive *a) {
1705*9880d681SAndroid Build Coastguard Worker Error Err;
1706*9880d681SAndroid Build Coastguard Worker for (auto &C : a->children(Err)) {
1707*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1708*9880d681SAndroid Build Coastguard Worker if (!ChildOrErr) {
1709*9880d681SAndroid Build Coastguard Worker if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
1710*9880d681SAndroid Build Coastguard Worker report_error(a->getFileName(), C, std::move(E));
1711*9880d681SAndroid Build Coastguard Worker continue;
1712*9880d681SAndroid Build Coastguard Worker }
1713*9880d681SAndroid Build Coastguard Worker if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
1714*9880d681SAndroid Build Coastguard Worker DumpObject(o, a);
1715*9880d681SAndroid Build Coastguard Worker else
1716*9880d681SAndroid Build Coastguard Worker report_error(a->getFileName(), object_error::invalid_file_type);
1717*9880d681SAndroid Build Coastguard Worker }
1718*9880d681SAndroid Build Coastguard Worker if (Err)
1719*9880d681SAndroid Build Coastguard Worker report_error(a->getFileName(), std::move(Err));
1720*9880d681SAndroid Build Coastguard Worker }
1721*9880d681SAndroid Build Coastguard Worker
1722*9880d681SAndroid Build Coastguard Worker /// @brief Open file and figure out how to dump it.
DumpInput(StringRef file)1723*9880d681SAndroid Build Coastguard Worker static void DumpInput(StringRef file) {
1724*9880d681SAndroid Build Coastguard Worker
1725*9880d681SAndroid Build Coastguard Worker // If we are using the Mach-O specific object file parser, then let it parse
1726*9880d681SAndroid Build Coastguard Worker // the file and process the command line options. So the -arch flags can
1727*9880d681SAndroid Build Coastguard Worker // be used to select specific slices, etc.
1728*9880d681SAndroid Build Coastguard Worker if (MachOOpt) {
1729*9880d681SAndroid Build Coastguard Worker ParseInputMachO(file);
1730*9880d681SAndroid Build Coastguard Worker return;
1731*9880d681SAndroid Build Coastguard Worker }
1732*9880d681SAndroid Build Coastguard Worker
1733*9880d681SAndroid Build Coastguard Worker // Attempt to open the binary.
1734*9880d681SAndroid Build Coastguard Worker Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
1735*9880d681SAndroid Build Coastguard Worker if (!BinaryOrErr)
1736*9880d681SAndroid Build Coastguard Worker report_error(file, BinaryOrErr.takeError());
1737*9880d681SAndroid Build Coastguard Worker Binary &Binary = *BinaryOrErr.get().getBinary();
1738*9880d681SAndroid Build Coastguard Worker
1739*9880d681SAndroid Build Coastguard Worker if (Archive *a = dyn_cast<Archive>(&Binary))
1740*9880d681SAndroid Build Coastguard Worker DumpArchive(a);
1741*9880d681SAndroid Build Coastguard Worker else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary))
1742*9880d681SAndroid Build Coastguard Worker DumpObject(o);
1743*9880d681SAndroid Build Coastguard Worker else
1744*9880d681SAndroid Build Coastguard Worker report_error(file, object_error::invalid_file_type);
1745*9880d681SAndroid Build Coastguard Worker }
1746*9880d681SAndroid Build Coastguard Worker
main(int argc,char ** argv)1747*9880d681SAndroid Build Coastguard Worker int main(int argc, char **argv) {
1748*9880d681SAndroid Build Coastguard Worker // Print a stack trace if we signal out.
1749*9880d681SAndroid Build Coastguard Worker sys::PrintStackTraceOnErrorSignal(argv[0]);
1750*9880d681SAndroid Build Coastguard Worker PrettyStackTraceProgram X(argc, argv);
1751*9880d681SAndroid Build Coastguard Worker llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
1752*9880d681SAndroid Build Coastguard Worker
1753*9880d681SAndroid Build Coastguard Worker // Initialize targets and assembly printers/parsers.
1754*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllTargetInfos();
1755*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllTargetMCs();
1756*9880d681SAndroid Build Coastguard Worker llvm::InitializeAllDisassemblers();
1757*9880d681SAndroid Build Coastguard Worker
1758*9880d681SAndroid Build Coastguard Worker // Register the target printer for --version.
1759*9880d681SAndroid Build Coastguard Worker cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
1760*9880d681SAndroid Build Coastguard Worker
1761*9880d681SAndroid Build Coastguard Worker cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
1762*9880d681SAndroid Build Coastguard Worker TripleName = Triple::normalize(TripleName);
1763*9880d681SAndroid Build Coastguard Worker
1764*9880d681SAndroid Build Coastguard Worker ToolName = argv[0];
1765*9880d681SAndroid Build Coastguard Worker
1766*9880d681SAndroid Build Coastguard Worker // Defaults to a.out if no filenames specified.
1767*9880d681SAndroid Build Coastguard Worker if (InputFilenames.size() == 0)
1768*9880d681SAndroid Build Coastguard Worker InputFilenames.push_back("a.out");
1769*9880d681SAndroid Build Coastguard Worker
1770*9880d681SAndroid Build Coastguard Worker if (DisassembleAll)
1771*9880d681SAndroid Build Coastguard Worker Disassemble = true;
1772*9880d681SAndroid Build Coastguard Worker if (!Disassemble
1773*9880d681SAndroid Build Coastguard Worker && !Relocations
1774*9880d681SAndroid Build Coastguard Worker && !SectionHeaders
1775*9880d681SAndroid Build Coastguard Worker && !SectionContents
1776*9880d681SAndroid Build Coastguard Worker && !SymbolTable
1777*9880d681SAndroid Build Coastguard Worker && !UnwindInfo
1778*9880d681SAndroid Build Coastguard Worker && !PrivateHeaders
1779*9880d681SAndroid Build Coastguard Worker && !FirstPrivateHeader
1780*9880d681SAndroid Build Coastguard Worker && !ExportsTrie
1781*9880d681SAndroid Build Coastguard Worker && !Rebase
1782*9880d681SAndroid Build Coastguard Worker && !Bind
1783*9880d681SAndroid Build Coastguard Worker && !LazyBind
1784*9880d681SAndroid Build Coastguard Worker && !WeakBind
1785*9880d681SAndroid Build Coastguard Worker && !RawClangAST
1786*9880d681SAndroid Build Coastguard Worker && !(UniversalHeaders && MachOOpt)
1787*9880d681SAndroid Build Coastguard Worker && !(ArchiveHeaders && MachOOpt)
1788*9880d681SAndroid Build Coastguard Worker && !(IndirectSymbols && MachOOpt)
1789*9880d681SAndroid Build Coastguard Worker && !(DataInCode && MachOOpt)
1790*9880d681SAndroid Build Coastguard Worker && !(LinkOptHints && MachOOpt)
1791*9880d681SAndroid Build Coastguard Worker && !(InfoPlist && MachOOpt)
1792*9880d681SAndroid Build Coastguard Worker && !(DylibsUsed && MachOOpt)
1793*9880d681SAndroid Build Coastguard Worker && !(DylibId && MachOOpt)
1794*9880d681SAndroid Build Coastguard Worker && !(ObjcMetaData && MachOOpt)
1795*9880d681SAndroid Build Coastguard Worker && !(FilterSections.size() != 0 && MachOOpt)
1796*9880d681SAndroid Build Coastguard Worker && !PrintFaultMaps
1797*9880d681SAndroid Build Coastguard Worker && DwarfDumpType == DIDT_Null) {
1798*9880d681SAndroid Build Coastguard Worker cl::PrintHelpMessage();
1799*9880d681SAndroid Build Coastguard Worker return 2;
1800*9880d681SAndroid Build Coastguard Worker }
1801*9880d681SAndroid Build Coastguard Worker
1802*9880d681SAndroid Build Coastguard Worker std::for_each(InputFilenames.begin(), InputFilenames.end(),
1803*9880d681SAndroid Build Coastguard Worker DumpInput);
1804*9880d681SAndroid Build Coastguard Worker
1805*9880d681SAndroid Build Coastguard Worker return EXIT_SUCCESS;
1806*9880d681SAndroid Build Coastguard Worker }
1807