blob: 1460fb0f0abb1c935d710547f4f6c76a67ba54ac [file] [log] [blame]
Michael J. Spencer2670c252011-01-20 06:39:06 +00001//===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This program is a utility that works like binutils "objdump", that is, it
11// dumps out a plethora of information about an object file depending on the
12// flags.
13//
Michael J. Spencerd7e70032013-02-05 20:27:22 +000014// The flags and output of this program should be near identical to those of
15// binutils objdump.
16//
Michael J. Spencer2670c252011-01-20 06:39:06 +000017//===----------------------------------------------------------------------===//
18
Benjamin Kramer43a772e2011-09-19 17:56:04 +000019#include "llvm-objdump.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000020#include "llvm/ADT/STLExtras.h"
Michael J. Spencer4e25c022011-10-17 17:13:22 +000021#include "llvm/ADT/StringExtras.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000022#include "llvm/ADT/Triple.h"
23#include "llvm/MC/MCAsmInfo.h"
Ahmed Bougachaad1084d2013-05-24 00:39:57 +000024#include "llvm/MC/MCContext.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000025#include "llvm/MC/MCDisassembler.h"
26#include "llvm/MC/MCInst.h"
27#include "llvm/MC/MCInstPrinter.h"
Ahmed Bougachaaa790682013-05-24 01:07:04 +000028#include "llvm/MC/MCInstrAnalysis.h"
Craig Topper54bfde72012-04-02 06:09:36 +000029#include "llvm/MC/MCInstrInfo.h"
Ahmed Bougachaad1084d2013-05-24 00:39:57 +000030#include "llvm/MC/MCObjectFileInfo.h"
Jim Grosbachfd93a592012-03-05 19:33:20 +000031#include "llvm/MC/MCRegisterInfo.h"
Ahmed Bougachaad1084d2013-05-24 00:39:57 +000032#include "llvm/MC/MCRelocationInfo.h"
Ahmed Bougachaaa790682013-05-24 01:07:04 +000033#include "llvm/MC/MCSubtargetInfo.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000034#include "llvm/Object/Archive.h"
Rafael Espindola37070a52015-06-03 04:48:06 +000035#include "llvm/Object/ELFObjectFile.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000036#include "llvm/Object/COFF.h"
Rafael Espindolaa9f810b2012-12-21 03:47:03 +000037#include "llvm/Object/MachO.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000038#include "llvm/Object/ObjectFile.h"
Michael J. Spencerba4a3622011-10-08 00:18:30 +000039#include "llvm/Support/Casting.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000040#include "llvm/Support/CommandLine.h"
41#include "llvm/Support/Debug.h"
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +000042#include "llvm/Support/Errc.h"
Michael J. Spencerba4a3622011-10-08 00:18:30 +000043#include "llvm/Support/FileSystem.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000044#include "llvm/Support/Format.h"
Benjamin Kramerbf115312011-07-25 23:04:36 +000045#include "llvm/Support/GraphWriter.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000046#include "llvm/Support/Host.h"
47#include "llvm/Support/ManagedStatic.h"
48#include "llvm/Support/MemoryBuffer.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000049#include "llvm/Support/PrettyStackTrace.h"
50#include "llvm/Support/Signals.h"
51#include "llvm/Support/SourceMgr.h"
Evan Cheng2bb40352011-08-24 18:08:43 +000052#include "llvm/Support/TargetRegistry.h"
53#include "llvm/Support/TargetSelect.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000054#include "llvm/Support/raw_ostream.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000055#include <algorithm>
Benjamin Kramera5177e62012-03-23 11:49:32 +000056#include <cctype>
Michael J. Spencer2670c252011-01-20 06:39:06 +000057#include <cstring>
Rafael Espindolaa6e9c3e2014-06-12 17:38:55 +000058#include <system_error>
Ahmed Bougacha17926472013-08-21 07:29:02 +000059
Michael J. Spencer2670c252011-01-20 06:39:06 +000060using namespace llvm;
61using namespace object;
62
Benjamin Kramer43a772e2011-09-19 17:56:04 +000063static cl::list<std::string>
64InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
Michael J. Spencer2670c252011-01-20 06:39:06 +000065
Kevin Enderbye2297dd2015-01-07 21:02:18 +000066cl::opt<bool>
67llvm::Disassemble("disassemble",
Benjamin Kramer43a772e2011-09-19 17:56:04 +000068 cl::desc("Display assembler mnemonics for the machine instructions"));
69static cl::alias
70Disassembled("d", cl::desc("Alias for --disassemble"),
71 cl::aliasopt(Disassemble));
Michael J. Spencer2670c252011-01-20 06:39:06 +000072
Kevin Enderby98da6132015-01-20 21:47:46 +000073cl::opt<bool>
74llvm::Relocations("r", cl::desc("Display the relocation entries in the file"));
Michael J. Spencerba4a3622011-10-08 00:18:30 +000075
Kevin Enderby98da6132015-01-20 21:47:46 +000076cl::opt<bool>
77llvm::SectionContents("s", cl::desc("Display the content of each section"));
Michael J. Spencer4e25c022011-10-17 17:13:22 +000078
Kevin Enderby98da6132015-01-20 21:47:46 +000079cl::opt<bool>
80llvm::SymbolTable("t", cl::desc("Display the symbol table"));
Michael J. Spencerbfa06782011-10-18 19:32:17 +000081
Kevin Enderbye2297dd2015-01-07 21:02:18 +000082cl::opt<bool>
83llvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
Nick Kledzikd04bc352014-08-30 00:20:14 +000084
Kevin Enderbye2297dd2015-01-07 21:02:18 +000085cl::opt<bool>
86llvm::Rebase("rebase", cl::desc("Display mach-o rebasing info"));
Nick Kledzikac431442014-09-12 21:34:15 +000087
Kevin Enderbye2297dd2015-01-07 21:02:18 +000088cl::opt<bool>
89llvm::Bind("bind", cl::desc("Display mach-o binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +000090
Kevin Enderbye2297dd2015-01-07 21:02:18 +000091cl::opt<bool>
92llvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +000093
Kevin Enderbye2297dd2015-01-07 21:02:18 +000094cl::opt<bool>
95llvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +000096
97static cl::opt<bool>
Rafael Espindolaa9f810b2012-12-21 03:47:03 +000098MachOOpt("macho", cl::desc("Use MachO specific object file parser"));
Benjamin Kramer43a772e2011-09-19 17:56:04 +000099static cl::alias
Rafael Espindolaa9f810b2012-12-21 03:47:03 +0000100MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt));
Benjamin Kramer87ee76c2011-07-20 19:37:35 +0000101
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000102cl::opt<std::string>
103llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
104 "see -version for available targets"));
105
106cl::opt<std::string>
Kevin Enderbyc9595622014-08-06 23:24:41 +0000107llvm::MCPU("mcpu",
108 cl::desc("Target a specific cpu type (-mcpu=help for details)"),
109 cl::value_desc("cpu-name"),
110 cl::init(""));
111
112cl::opt<std::string>
Kevin Enderbyef3ad2f2014-12-04 23:56:27 +0000113llvm::ArchName("arch-name", cl::desc("Target arch to disassemble for, "
Michael J. Spencer2670c252011-01-20 06:39:06 +0000114 "see -version for available targets"));
115
Kevin Enderby98da6132015-01-20 21:47:46 +0000116cl::opt<bool>
117llvm::SectionHeaders("section-headers", cl::desc("Display summaries of the "
118 "headers for each section."));
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000119static cl::alias
120SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
121 cl::aliasopt(SectionHeaders));
122static cl::alias
123SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
124 cl::aliasopt(SectionHeaders));
125
Kevin Enderbyc9595622014-08-06 23:24:41 +0000126cl::list<std::string>
127llvm::MAttrs("mattr",
Jack Carter551efd72012-08-28 19:24:49 +0000128 cl::CommaSeparated,
129 cl::desc("Target specific attributes"),
130 cl::value_desc("a1,+a2,-a3,..."));
131
Kevin Enderbybf246f52014-09-24 23:08:22 +0000132cl::opt<bool>
133llvm::NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling "
134 "instructions, do not print "
135 "the instruction bytes."));
Eli Bendersky3a6808c2012-11-20 22:57:02 +0000136
Kevin Enderby98da6132015-01-20 21:47:46 +0000137cl::opt<bool>
138llvm::UnwindInfo("unwind-info", cl::desc("Display unwind information"));
Michael J. Spencer0c6ec482012-12-05 20:12:35 +0000139
140static cl::alias
141UnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
142 cl::aliasopt(UnwindInfo));
143
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000144cl::opt<bool>
145llvm::PrivateHeaders("private-headers",
146 cl::desc("Display format specific file headers"));
Michael J. Spencer209565db2013-01-06 03:56:49 +0000147
148static cl::alias
149PrivateHeadersShort("p", cl::desc("Alias for --private-headers"),
150 cl::aliasopt(PrivateHeaders));
151
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000152cl::opt<bool>
153 llvm::PrintImmHex("print-imm-hex",
154 cl::desc("Use hex format for immediate values"));
155
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000156static StringRef ToolName;
Rui Ueyama98fe58a2014-11-26 22:17:25 +0000157static int ReturnValue = EXIT_SUCCESS;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000158
Rafael Espindola4453e42942014-06-13 03:07:50 +0000159bool llvm::error(std::error_code EC) {
Mark Seaborneb03ac52014-01-25 00:32:01 +0000160 if (!EC)
161 return false;
Michael J. Spencer1d6167f2011-06-25 17:55:23 +0000162
Mark Seaborneb03ac52014-01-25 00:32:01 +0000163 outs() << ToolName << ": error reading file: " << EC.message() << ".\n";
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000164 outs().flush();
Rui Ueyama98fe58a2014-11-26 22:17:25 +0000165 ReturnValue = EXIT_FAILURE;
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000166 return true;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000167}
168
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +0000169static void report_error(StringRef File, std::error_code EC) {
170 assert(EC);
171 errs() << ToolName << ": '" << File << "': " << EC.message() << ".\n";
172 ReturnValue = EXIT_FAILURE;
173}
174
Craig Toppere6cb63e2014-04-25 04:24:47 +0000175static const Target *getTarget(const ObjectFile *Obj = nullptr) {
Michael J. Spencer2670c252011-01-20 06:39:06 +0000176 // Figure out the target triple.
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000177 llvm::Triple TheTriple("unknown-unknown-unknown");
Michael J. Spencer05350e6d2011-01-20 07:22:04 +0000178 if (TripleName.empty()) {
Ahmed Bougachaad1084d2013-05-24 00:39:57 +0000179 if (Obj) {
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000180 TheTriple.setArch(Triple::ArchType(Obj->getArch()));
Ahmed Bougachaad1084d2013-05-24 00:39:57 +0000181 // TheTriple defaults to ELF, and COFF doesn't have an environment:
182 // the best we can do here is indicate that it is mach-o.
183 if (Obj->isMachO())
Saleem Abdulrasool35476332014-03-06 20:47:11 +0000184 TheTriple.setObjectFormat(Triple::MachO);
Saleem Abdulrasool98938f12014-04-17 06:17:23 +0000185
186 if (Obj->isCOFF()) {
187 const auto COFFObj = dyn_cast<COFFObjectFile>(Obj);
188 if (COFFObj->getArch() == Triple::thumb)
189 TheTriple.setTriple("thumbv7-windows");
190 }
Ahmed Bougachaad1084d2013-05-24 00:39:57 +0000191 }
Michael J. Spencer05350e6d2011-01-20 07:22:04 +0000192 } else
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000193 TheTriple.setTriple(Triple::normalize(TripleName));
Michael J. Spencer2670c252011-01-20 06:39:06 +0000194
195 // Get the target specific parser.
196 std::string Error;
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000197 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
198 Error);
199 if (!TheTarget) {
200 errs() << ToolName << ": " << Error;
Craig Toppere6cb63e2014-04-25 04:24:47 +0000201 return nullptr;
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000202 }
Michael J. Spencer2670c252011-01-20 06:39:06 +0000203
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000204 // Update the triple name and return the found target.
205 TripleName = TheTriple.getTriple();
206 return TheTarget;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000207}
208
Michael J. Spencer0c6ec482012-12-05 20:12:35 +0000209bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
Michael J. Spencer51862b32011-10-13 22:17:18 +0000210 uint64_t a_addr, b_addr;
Rafael Espindola1e483872013-04-25 12:28:45 +0000211 if (error(a.getOffset(a_addr))) return false;
212 if (error(b.getOffset(b_addr))) return false;
Michael J. Spencer51862b32011-10-13 22:17:18 +0000213 return a_addr < b_addr;
214}
215
Colin LeMahieufb76b002015-05-28 19:07:14 +0000216namespace {
217class PrettyPrinter {
218public:
Colin LeMahieu0b5890d2015-05-28 20:59:08 +0000219 virtual ~PrettyPrinter(){}
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000220 virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
Colin LeMahieufb76b002015-05-28 19:07:14 +0000221 ArrayRef<uint8_t> Bytes, uint64_t Address,
222 raw_ostream &OS, StringRef Annot,
223 MCSubtargetInfo const &STI) {
224 outs() << format("%8" PRIx64 ":", Address);
225 if (!NoShowRawInsn) {
226 outs() << "\t";
227 dumpBytes(Bytes, outs());
228 }
229 IP.printInst(MI, outs(), "", STI);
230 }
231};
232PrettyPrinter PrettyPrinterInst;
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000233class HexagonPrettyPrinter : public PrettyPrinter {
234public:
235 void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
236 raw_ostream &OS) {
237 uint32_t opcode =
238 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
239 OS << format("%8" PRIx64 ":", Address);
240 if (!NoShowRawInsn) {
241 OS << "\t";
242 dumpBytes(Bytes.slice(0, 4), OS);
243 OS << format("%08" PRIx32, opcode);
244 }
245 }
246 void printInst(MCInstPrinter &IP, const MCInst *MI,
247 ArrayRef<uint8_t> Bytes, uint64_t Address,
248 raw_ostream &OS, StringRef Annot,
249 MCSubtargetInfo const &STI) override {
250 std::string Buffer;
251 {
252 raw_string_ostream TempStream(Buffer);
253 IP.printInst(MI, TempStream, "", STI);
254 }
255 StringRef Contents(Buffer);
256 // Split off bundle attributes
257 auto PacketBundle = Contents.rsplit('\n');
258 // Split off first instruction from the rest
259 auto HeadTail = PacketBundle.first.split('\n');
260 auto Preamble = " { ";
261 auto Separator = "";
262 while(!HeadTail.first.empty()) {
263 OS << Separator;
264 Separator = "\n";
265 printLead(Bytes, Address, OS);
266 OS << Preamble;
267 Preamble = " ";
268 StringRef Inst;
269 auto Duplex = HeadTail.first.split('\v');
270 if(!Duplex.second.empty()){
271 OS << Duplex.first;
272 OS << "; ";
273 Inst = Duplex.second;
274 }
275 else
276 Inst = HeadTail.first;
277 OS << Inst;
278 Bytes = Bytes.slice(4);
279 Address += 4;
280 HeadTail = HeadTail.second.split('\n');
281 }
282 OS << " } " << PacketBundle.second;
283 }
284};
285HexagonPrettyPrinter HexagonPrettyPrinterInst;
Colin LeMahieu35436a22015-05-29 14:48:25 +0000286PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000287 switch(Triple.getArch()) {
288 default:
289 return PrettyPrinterInst;
290 case Triple::hexagon:
291 return HexagonPrettyPrinterInst;
292 }
Colin LeMahieufb76b002015-05-28 19:07:14 +0000293}
294}
295
Rafael Espindola37070a52015-06-03 04:48:06 +0000296template <class ELFT>
297static const typename ELFObjectFile<ELFT>::Elf_Rel *
298getRel(const ELFFile<ELFT> &EF, DataRefImpl Rel) {
299 typedef typename ELFObjectFile<ELFT>::Elf_Rel Elf_Rel;
300 return EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
301}
302
303template <class ELFT>
304static const typename ELFObjectFile<ELFT>::Elf_Rela *
305getRela(const ELFFile<ELFT> &EF, DataRefImpl Rela) {
306 typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
307 return EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
308}
309
310template <class ELFT>
311static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
312 DataRefImpl Rel,
313 SmallVectorImpl<char> &Result) {
314 typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
315 typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
316 const ELFFile<ELFT> &EF = *Obj->getELFFile();
317
318 const Elf_Shdr *sec = EF.getSection(Rel.d.a);
319 uint8_t type;
320 StringRef res;
321 int64_t addend = 0;
322 uint16_t symbol_index = 0;
323 switch (sec->sh_type) {
324 default:
325 return object_error::parse_failed;
326 case ELF::SHT_REL: {
327 type = getRel(EF, Rel)->getType(EF.isMips64EL());
328 symbol_index = getRel(EF, Rel)->getSymbol(EF.isMips64EL());
329 // TODO: Read implicit addend from section data.
330 break;
331 }
332 case ELF::SHT_RELA: {
333 type = getRela(EF, Rel)->getType(EF.isMips64EL());
334 symbol_index = getRela(EF, Rel)->getSymbol(EF.isMips64EL());
335 addend = getRela(EF, Rel)->r_addend;
336 break;
337 }
338 }
339 const Elf_Sym *symb =
340 EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index);
Rafael Espindola75d5b542015-06-03 05:14:22 +0000341 StringRef Target;
342 const Elf_Shdr *SymSec = EF.getSection(symb);
343 if (symb->getType() == ELF::STT_SECTION) {
344 ErrorOr<StringRef> SecName = EF.getSectionName(SymSec);
345 if (std::error_code EC = SecName.getError())
346 return EC;
347 Target = *SecName;
348 } else {
349 ErrorOr<StringRef> SymName =
350 EF.getSymbolName(EF.getSection(sec->sh_link), symb);
351 if (!SymName)
352 return SymName.getError();
353 Target = *SymName;
354 }
Rafael Espindola37070a52015-06-03 04:48:06 +0000355 switch (EF.getHeader()->e_machine) {
356 case ELF::EM_X86_64:
357 switch (type) {
358 case ELF::R_X86_64_PC8:
359 case ELF::R_X86_64_PC16:
360 case ELF::R_X86_64_PC32: {
361 std::string fmtbuf;
362 raw_string_ostream fmt(fmtbuf);
Rafael Espindola75d5b542015-06-03 05:14:22 +0000363 fmt << Target << (addend < 0 ? "" : "+") << addend << "-P";
Rafael Espindola37070a52015-06-03 04:48:06 +0000364 fmt.flush();
365 Result.append(fmtbuf.begin(), fmtbuf.end());
366 } break;
367 case ELF::R_X86_64_8:
368 case ELF::R_X86_64_16:
369 case ELF::R_X86_64_32:
370 case ELF::R_X86_64_32S:
371 case ELF::R_X86_64_64: {
372 std::string fmtbuf;
373 raw_string_ostream fmt(fmtbuf);
Rafael Espindola75d5b542015-06-03 05:14:22 +0000374 fmt << Target << (addend < 0 ? "" : "+") << addend;
Rafael Espindola37070a52015-06-03 04:48:06 +0000375 fmt.flush();
376 Result.append(fmtbuf.begin(), fmtbuf.end());
377 } break;
378 default:
379 res = "Unknown";
380 }
381 break;
382 case ELF::EM_AARCH64: {
383 std::string fmtbuf;
384 raw_string_ostream fmt(fmtbuf);
Rafael Espindola75d5b542015-06-03 05:14:22 +0000385 fmt << Target;
Rafael Espindola37070a52015-06-03 04:48:06 +0000386 if (addend != 0)
387 fmt << (addend < 0 ? "" : "+") << addend;
388 fmt.flush();
389 Result.append(fmtbuf.begin(), fmtbuf.end());
390 break;
391 }
392 case ELF::EM_386:
393 case ELF::EM_ARM:
394 case ELF::EM_HEXAGON:
395 case ELF::EM_MIPS:
Rafael Espindola75d5b542015-06-03 05:14:22 +0000396 res = Target;
Rafael Espindola37070a52015-06-03 04:48:06 +0000397 break;
398 default:
399 res = "Unknown";
400 }
401 if (Result.empty())
402 Result.append(res.begin(), res.end());
403 return object_error::success;
404}
405
406static std::error_code getRelocationValueString(const ELFObjectFileBase *Obj,
407 const RelocationRef &RelRef,
408 SmallVectorImpl<char> &Result) {
409 DataRefImpl Rel = RelRef.getRawDataRefImpl();
410 if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
411 return getRelocationValueString(ELF32LE, Rel, Result);
412 if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
413 return getRelocationValueString(ELF64LE, Rel, Result);
414 if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
415 return getRelocationValueString(ELF32BE, Rel, Result);
416 auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
417 return getRelocationValueString(ELF64BE, Rel, Result);
418}
419
420static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
421 const RelocationRef &Rel,
422 SmallVectorImpl<char> &Result) {
423 symbol_iterator SymI = Rel.getSymbol();
424 StringRef SymName;
425 if (std::error_code EC = SymI->getName(SymName))
426 return EC;
427 Result.append(SymName.begin(), SymName.end());
428 return object_error::success;
429}
430
431static void printRelocationTargetName(const MachOObjectFile *O,
432 const MachO::any_relocation_info &RE,
433 raw_string_ostream &fmt) {
434 bool IsScattered = O->isRelocationScattered(RE);
435
436 // Target of a scattered relocation is an address. In the interest of
437 // generating pretty output, scan through the symbol table looking for a
438 // symbol that aligns with that address. If we find one, print it.
439 // Otherwise, we just print the hex address of the target.
440 if (IsScattered) {
441 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
442
443 for (const SymbolRef &Symbol : O->symbols()) {
444 std::error_code ec;
445 uint64_t Addr;
446 StringRef Name;
447
448 if ((ec = Symbol.getAddress(Addr)))
449 report_fatal_error(ec.message());
450 if (Addr != Val)
451 continue;
452 if ((ec = Symbol.getName(Name)))
453 report_fatal_error(ec.message());
454 fmt << Name;
455 return;
456 }
457
458 // If we couldn't find a symbol that this relocation refers to, try
459 // to find a section beginning instead.
460 for (const SectionRef &Section : O->sections()) {
461 std::error_code ec;
462
463 StringRef Name;
464 uint64_t Addr = Section.getAddress();
465 if (Addr != Val)
466 continue;
467 if ((ec = Section.getName(Name)))
468 report_fatal_error(ec.message());
469 fmt << Name;
470 return;
471 }
472
473 fmt << format("0x%x", Val);
474 return;
475 }
476
477 StringRef S;
478 bool isExtern = O->getPlainRelocationExternal(RE);
479 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
480
481 if (isExtern) {
482 symbol_iterator SI = O->symbol_begin();
483 advance(SI, Val);
484 SI->getName(S);
485 } else {
486 section_iterator SI = O->section_begin();
487 // Adjust for the fact that sections are 1-indexed.
488 advance(SI, Val - 1);
489 SI->getName(S);
490 }
491
492 fmt << S;
493}
494
495static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
496 const RelocationRef &RelRef,
497 SmallVectorImpl<char> &Result) {
498 DataRefImpl Rel = RelRef.getRawDataRefImpl();
499 MachO::any_relocation_info RE = Obj->getRelocation(Rel);
500
501 unsigned Arch = Obj->getArch();
502
503 std::string fmtbuf;
504 raw_string_ostream fmt(fmtbuf);
505 unsigned Type = Obj->getAnyRelocationType(RE);
506 bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
507
508 // Determine any addends that should be displayed with the relocation.
509 // These require decoding the relocation type, which is triple-specific.
510
511 // X86_64 has entirely custom relocation types.
512 if (Arch == Triple::x86_64) {
513 bool isPCRel = Obj->getAnyRelocationPCRel(RE);
514
515 switch (Type) {
516 case MachO::X86_64_RELOC_GOT_LOAD:
517 case MachO::X86_64_RELOC_GOT: {
518 printRelocationTargetName(Obj, RE, fmt);
519 fmt << "@GOT";
520 if (isPCRel)
521 fmt << "PCREL";
522 break;
523 }
524 case MachO::X86_64_RELOC_SUBTRACTOR: {
525 DataRefImpl RelNext = Rel;
526 Obj->moveRelocationNext(RelNext);
527 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
528
529 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
530 // X86_64_RELOC_UNSIGNED.
531 // NOTE: Scattered relocations don't exist on x86_64.
532 unsigned RType = Obj->getAnyRelocationType(RENext);
533 if (RType != MachO::X86_64_RELOC_UNSIGNED)
534 report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
535 "X86_64_RELOC_SUBTRACTOR.");
536
537 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
538 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
539 printRelocationTargetName(Obj, RENext, fmt);
540 fmt << "-";
541 printRelocationTargetName(Obj, RE, fmt);
542 break;
543 }
544 case MachO::X86_64_RELOC_TLV:
545 printRelocationTargetName(Obj, RE, fmt);
546 fmt << "@TLV";
547 if (isPCRel)
548 fmt << "P";
549 break;
550 case MachO::X86_64_RELOC_SIGNED_1:
551 printRelocationTargetName(Obj, RE, fmt);
552 fmt << "-1";
553 break;
554 case MachO::X86_64_RELOC_SIGNED_2:
555 printRelocationTargetName(Obj, RE, fmt);
556 fmt << "-2";
557 break;
558 case MachO::X86_64_RELOC_SIGNED_4:
559 printRelocationTargetName(Obj, RE, fmt);
560 fmt << "-4";
561 break;
562 default:
563 printRelocationTargetName(Obj, RE, fmt);
564 break;
565 }
566 // X86 and ARM share some relocation types in common.
567 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
568 Arch == Triple::ppc) {
569 // Generic relocation types...
570 switch (Type) {
571 case MachO::GENERIC_RELOC_PAIR: // prints no info
572 return object_error::success;
573 case MachO::GENERIC_RELOC_SECTDIFF: {
574 DataRefImpl RelNext = Rel;
575 Obj->moveRelocationNext(RelNext);
576 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
577
578 // X86 sect diff's must be followed by a relocation of type
579 // GENERIC_RELOC_PAIR.
580 unsigned RType = Obj->getAnyRelocationType(RENext);
581
582 if (RType != MachO::GENERIC_RELOC_PAIR)
583 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
584 "GENERIC_RELOC_SECTDIFF.");
585
586 printRelocationTargetName(Obj, RE, fmt);
587 fmt << "-";
588 printRelocationTargetName(Obj, RENext, fmt);
589 break;
590 }
591 }
592
593 if (Arch == Triple::x86 || Arch == Triple::ppc) {
594 switch (Type) {
595 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
596 DataRefImpl RelNext = Rel;
597 Obj->moveRelocationNext(RelNext);
598 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
599
600 // X86 sect diff's must be followed by a relocation of type
601 // GENERIC_RELOC_PAIR.
602 unsigned RType = Obj->getAnyRelocationType(RENext);
603 if (RType != MachO::GENERIC_RELOC_PAIR)
604 report_fatal_error("Expected GENERIC_RELOC_PAIR after "
605 "GENERIC_RELOC_LOCAL_SECTDIFF.");
606
607 printRelocationTargetName(Obj, RE, fmt);
608 fmt << "-";
609 printRelocationTargetName(Obj, RENext, fmt);
610 break;
611 }
612 case MachO::GENERIC_RELOC_TLV: {
613 printRelocationTargetName(Obj, RE, fmt);
614 fmt << "@TLV";
615 if (IsPCRel)
616 fmt << "P";
617 break;
618 }
619 default:
620 printRelocationTargetName(Obj, RE, fmt);
621 }
622 } else { // ARM-specific relocations
623 switch (Type) {
624 case MachO::ARM_RELOC_HALF:
625 case MachO::ARM_RELOC_HALF_SECTDIFF: {
626 // Half relocations steal a bit from the length field to encode
627 // whether this is an upper16 or a lower16 relocation.
628 bool isUpper = Obj->getAnyRelocationLength(RE) >> 1;
629
630 if (isUpper)
631 fmt << ":upper16:(";
632 else
633 fmt << ":lower16:(";
634 printRelocationTargetName(Obj, RE, fmt);
635
636 DataRefImpl RelNext = Rel;
637 Obj->moveRelocationNext(RelNext);
638 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
639
640 // ARM half relocs must be followed by a relocation of type
641 // ARM_RELOC_PAIR.
642 unsigned RType = Obj->getAnyRelocationType(RENext);
643 if (RType != MachO::ARM_RELOC_PAIR)
644 report_fatal_error("Expected ARM_RELOC_PAIR after "
645 "ARM_RELOC_HALF");
646
647 // NOTE: The half of the target virtual address is stashed in the
648 // address field of the secondary relocation, but we can't reverse
649 // engineer the constant offset from it without decoding the movw/movt
650 // instruction to find the other half in its immediate field.
651
652 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
653 // symbol/section pointer of the follow-on relocation.
654 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
655 fmt << "-";
656 printRelocationTargetName(Obj, RENext, fmt);
657 }
658
659 fmt << ")";
660 break;
661 }
662 default: { printRelocationTargetName(Obj, RE, fmt); }
663 }
664 }
665 } else
666 printRelocationTargetName(Obj, RE, fmt);
667
668 fmt.flush();
669 Result.append(fmtbuf.begin(), fmtbuf.end());
670 return object_error::success;
671}
672
673static std::error_code getRelocationValueString(const RelocationRef &Rel,
674 SmallVectorImpl<char> &Result) {
675 const ObjectFile *Obj = Rel.getObjectFile();
676 if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
677 return getRelocationValueString(ELF, Rel, Result);
678 if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
679 return getRelocationValueString(COFF, Rel, Result);
680 auto *MachO = cast<MachOObjectFile>(Obj);
681 return getRelocationValueString(MachO, Rel, Result);
682}
683
Michael J. Spencer51862b32011-10-13 22:17:18 +0000684static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
Jim Grosbachaf9aec02012-08-07 17:53:14 +0000685 const Target *TheTarget = getTarget(Obj);
686 // getTarget() will have already issued a diagnostic if necessary, so
687 // just bail here if it failed.
688 if (!TheTarget)
Michael J. Spencer2670c252011-01-20 06:39:06 +0000689 return;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000690
Jack Carter551efd72012-08-28 19:24:49 +0000691 // Package up features to be passed to target/subtarget
692 std::string FeaturesStr;
693 if (MAttrs.size()) {
694 SubtargetFeatures Features;
695 for (unsigned i = 0; i != MAttrs.size(); ++i)
696 Features.AddFeature(MAttrs[i]);
697 FeaturesStr = Features.getString();
698 }
699
Ahmed Charles56440fd2014-03-06 05:51:42 +0000700 std::unique_ptr<const MCRegisterInfo> MRI(
701 TheTarget->createMCRegInfo(TripleName));
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000702 if (!MRI) {
703 errs() << "error: no register info for target " << TripleName << "\n";
704 return;
705 }
706
707 // Set up disassembler.
Ahmed Charles56440fd2014-03-06 05:51:42 +0000708 std::unique_ptr<const MCAsmInfo> AsmInfo(
709 TheTarget->createMCAsmInfo(*MRI, TripleName));
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000710 if (!AsmInfo) {
711 errs() << "error: no assembly info for target " << TripleName << "\n";
712 return;
713 }
714
Ahmed Charles56440fd2014-03-06 05:51:42 +0000715 std::unique_ptr<const MCSubtargetInfo> STI(
Kevin Enderbyc9595622014-08-06 23:24:41 +0000716 TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000717 if (!STI) {
718 errs() << "error: no subtarget info for target " << TripleName << "\n";
719 return;
720 }
721
Ahmed Charles56440fd2014-03-06 05:51:42 +0000722 std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000723 if (!MII) {
724 errs() << "error: no instruction info for target " << TripleName << "\n";
725 return;
726 }
727
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000728 std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
729 MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
730
731 std::unique_ptr<MCDisassembler> DisAsm(
732 TheTarget->createMCDisassembler(*STI, Ctx));
733
Ahmed Bougachaad1084d2013-05-24 00:39:57 +0000734 if (!DisAsm) {
735 errs() << "error: no disassembler for target " << TripleName << "\n";
736 return;
737 }
738
Ahmed Charles56440fd2014-03-06 05:51:42 +0000739 std::unique_ptr<const MCInstrAnalysis> MIA(
740 TheTarget->createMCInstrAnalysis(MII.get()));
Ahmed Bougachaaa790682013-05-24 01:07:04 +0000741
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000742 int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
Ahmed Charles56440fd2014-03-06 05:51:42 +0000743 std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
Eric Christopherf8019402015-03-31 00:10:04 +0000744 Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000745 if (!IP) {
746 errs() << "error: no instruction printer for target " << TripleName
747 << '\n';
748 return;
749 }
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000750 IP->setPrintImmHex(PrintImmHex);
Colin LeMahieu35436a22015-05-29 14:48:25 +0000751 PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000752
Greg Fitzgerald18432272014-03-20 22:55:15 +0000753 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
754 "\t\t\t%08" PRIx64 ": ";
755
Mark Seaborn0929d3d2014-01-25 17:38:19 +0000756 // Create a mapping, RelocSecs = SectionRelocMap[S], where sections
757 // in RelocSecs contain the relocations for section S.
Rafael Espindola4453e42942014-06-13 03:07:50 +0000758 std::error_code EC;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000759 std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap;
760 for (const SectionRef &Section : Obj->sections()) {
761 section_iterator Sec2 = Section.getRelocatedSection();
Rafael Espindolab5155a52014-02-10 20:24:04 +0000762 if (Sec2 != Obj->section_end())
Alexey Samsonov48803e52014-03-13 14:37:36 +0000763 SectionRelocMap[*Sec2].push_back(Section);
Mark Seaborn0929d3d2014-01-25 17:38:19 +0000764 }
765
Alexey Samsonov48803e52014-03-13 14:37:36 +0000766 for (const SectionRef &Section : Obj->sections()) {
David Majnemer236b0ca2014-11-17 11:17:17 +0000767 if (!Section.isText() || Section.isVirtual())
Mark Seaborneb03ac52014-01-25 00:32:01 +0000768 continue;
Michael J. Spencer1d6167f2011-06-25 17:55:23 +0000769
Rafael Espindola80291272014-10-08 15:28:58 +0000770 uint64_t SectionAddr = Section.getAddress();
771 uint64_t SectSize = Section.getSize();
David Majnemer185b5b12014-11-11 09:58:25 +0000772 if (!SectSize)
773 continue;
Simon Atanasyan2b614e12014-02-24 22:12:11 +0000774
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000775 // Make a list of all the symbols in this section.
Alexey Samsonov464d2e42014-03-17 07:28:19 +0000776 std::vector<std::pair<uint64_t, StringRef>> Symbols;
777 for (const SymbolRef &Symbol : Obj->symbols()) {
Rafael Espindola80291272014-10-08 15:28:58 +0000778 if (Section.containsSymbol(Symbol)) {
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000779 uint64_t Address;
Alexey Samsonov464d2e42014-03-17 07:28:19 +0000780 if (error(Symbol.getAddress(Address)))
Mark Seaborneb03ac52014-01-25 00:32:01 +0000781 break;
782 if (Address == UnknownAddressOrSize)
783 continue;
Cameron Zwarich07f0f772012-02-03 04:13:37 +0000784 Address -= SectionAddr;
Simon Atanasyan2b614e12014-02-24 22:12:11 +0000785 if (Address >= SectSize)
786 continue;
Cameron Zwarich07f0f772012-02-03 04:13:37 +0000787
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000788 StringRef Name;
Alexey Samsonov464d2e42014-03-17 07:28:19 +0000789 if (error(Symbol.getName(Name)))
Mark Seaborneb03ac52014-01-25 00:32:01 +0000790 break;
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000791 Symbols.push_back(std::make_pair(Address, Name));
792 }
793 }
794
795 // Sort the symbols by address, just in case they didn't come in that way.
796 array_pod_sort(Symbols.begin(), Symbols.end());
797
Michael J. Spencer51862b32011-10-13 22:17:18 +0000798 // Make a list of all the relocations for this section.
799 std::vector<RelocationRef> Rels;
800 if (InlineRelocs) {
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000801 for (const SectionRef &RelocSec : SectionRelocMap[Section]) {
802 for (const RelocationRef &Reloc : RelocSec.relocations()) {
803 Rels.push_back(Reloc);
804 }
Michael J. Spencer51862b32011-10-13 22:17:18 +0000805 }
806 }
807
808 // Sort relocations by address.
809 std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
810
Rafael Espindolaa9f810b2012-12-21 03:47:03 +0000811 StringRef SegmentName = "";
Mark Seaborneb03ac52014-01-25 00:32:01 +0000812 if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
Alexey Samsonov48803e52014-03-13 14:37:36 +0000813 DataRefImpl DR = Section.getRawDataRefImpl();
Rafael Espindola56f976f2013-04-18 18:08:55 +0000814 SegmentName = MachO->getSectionFinalSegmentName(DR);
Rafael Espindolaa9f810b2012-12-21 03:47:03 +0000815 }
Michael J. Spencer1d6167f2011-06-25 17:55:23 +0000816 StringRef name;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000817 if (error(Section.getName(name)))
Mark Seaborneb03ac52014-01-25 00:32:01 +0000818 break;
Rafael Espindolaa9f810b2012-12-21 03:47:03 +0000819 outs() << "Disassembly of section ";
820 if (!SegmentName.empty())
821 outs() << SegmentName << ",";
822 outs() << name << ':';
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000823
Rafael Espindola7884c952015-06-04 15:01:05 +0000824 // If the section has no symbol at the start, just insert a dummy one.
825 if (Symbols.empty() || Symbols[0].first != 0)
826 Symbols.insert(Symbols.begin(), std::make_pair(0, name));
Alp Tokere69170a2014-06-26 22:52:05 +0000827
828 SmallString<40> Comments;
829 raw_svector_ostream CommentStream(Comments);
Ahmed Bougachaad1084d2013-05-24 00:39:57 +0000830
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000831 StringRef BytesStr;
832 if (error(Section.getContents(BytesStr)))
Mark Seaborneb03ac52014-01-25 00:32:01 +0000833 break;
Aaron Ballman106fd7b2014-11-12 14:01:17 +0000834 ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
835 BytesStr.size());
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000836
Michael J. Spencer2670c252011-01-20 06:39:06 +0000837 uint64_t Size;
838 uint64_t Index;
839
Michael J. Spencer51862b32011-10-13 22:17:18 +0000840 std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
841 std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000842 // Disassemble symbol by symbol.
843 for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
Rafael Espindolae45c7402014-08-17 16:31:39 +0000844
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000845 uint64_t Start = Symbols[si].first;
Rafael Espindolae45c7402014-08-17 16:31:39 +0000846 // The end is either the section end or the beginning of the next symbol.
847 uint64_t End = (si == se - 1) ? SectSize : Symbols[si + 1].first;
848 // If this symbol has the same address as the next symbol, then skip it.
849 if (Start == End)
Michael J. Spenceree84f642011-10-13 20:37:08 +0000850 continue;
851
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000852 outs() << '\n' << Symbols[si].second << ":\n";
Michael J. Spencer2670c252011-01-20 06:39:06 +0000853
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000854#ifndef NDEBUG
Mark Seaborneb03ac52014-01-25 00:32:01 +0000855 raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000856#else
Mark Seaborneb03ac52014-01-25 00:32:01 +0000857 raw_ostream &DebugOut = nulls();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000858#endif
859
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000860 for (Index = Start; Index < End; Index += Size) {
861 MCInst Inst;
Owen Andersona0c3b972011-09-15 23:38:46 +0000862
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000863 if (DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
864 SectionAddr + Index, DebugOut,
865 CommentStream)) {
Colin LeMahieu68d967d2015-05-29 14:44:13 +0000866 PIP.printInst(*IP, &Inst,
Colin LeMahieufb76b002015-05-28 19:07:14 +0000867 Bytes.slice(Index, Size),
868 SectionAddr + Index, outs(), "", *STI);
Alp Tokere69170a2014-06-26 22:52:05 +0000869 outs() << CommentStream.str();
Ahmed Bougachaad1084d2013-05-24 00:39:57 +0000870 Comments.clear();
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000871 outs() << "\n";
872 } else {
873 errs() << ToolName << ": warning: invalid instruction encoding\n";
874 if (Size == 0)
875 Size = 1; // skip illegible bytes
Benjamin Kramere0dda9c2011-07-15 18:39:24 +0000876 }
Michael J. Spencer51862b32011-10-13 22:17:18 +0000877
878 // Print relocation for instruction.
879 while (rel_cur != rel_end) {
Owen Andersonfa3e5202011-10-25 20:35:53 +0000880 bool hidden = false;
Michael J. Spencer51862b32011-10-13 22:17:18 +0000881 uint64_t addr;
882 SmallString<16> name;
883 SmallString<32> val;
Owen Andersonfa3e5202011-10-25 20:35:53 +0000884
885 // If this relocation is hidden, skip it.
886 if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
887 if (hidden) goto skip_print_rel;
888
Rafael Espindola1e483872013-04-25 12:28:45 +0000889 if (error(rel_cur->getOffset(addr))) goto skip_print_rel;
Michael J. Spencer51862b32011-10-13 22:17:18 +0000890 // Stop when rel_cur's address is past the current instruction.
Owen Andersonf20e3e52011-10-25 20:15:39 +0000891 if (addr >= Index + Size) break;
Michael J. Spencer51862b32011-10-13 22:17:18 +0000892 if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
Rafael Espindola37070a52015-06-03 04:48:06 +0000893 if (error(getRelocationValueString(*rel_cur, val)))
894 goto skip_print_rel;
Greg Fitzgerald18432272014-03-20 22:55:15 +0000895 outs() << format(Fmt.data(), SectionAddr + addr) << name
Benjamin Kramer82803112012-03-10 02:04:38 +0000896 << "\t" << val << "\n";
Michael J. Spencer51862b32011-10-13 22:17:18 +0000897
898 skip_print_rel:
899 ++rel_cur;
900 }
Benjamin Kramer87ee76c2011-07-20 19:37:35 +0000901 }
Michael J. Spencer2670c252011-01-20 06:39:06 +0000902 }
903 }
904}
905
Kevin Enderby98da6132015-01-20 21:47:46 +0000906void llvm::PrintRelocations(const ObjectFile *Obj) {
Greg Fitzgerald18432272014-03-20 22:55:15 +0000907 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
908 "%08" PRIx64;
Rafael Espindolac66d7612014-08-17 19:09:37 +0000909 // Regular objdump doesn't print relocations in non-relocatable object
910 // files.
911 if (!Obj->isRelocatableObject())
912 return;
913
Alexey Samsonov48803e52014-03-13 14:37:36 +0000914 for (const SectionRef &Section : Obj->sections()) {
915 if (Section.relocation_begin() == Section.relocation_end())
Michael J. Spencerba4a3622011-10-08 00:18:30 +0000916 continue;
917 StringRef secname;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000918 if (error(Section.getName(secname)))
919 continue;
Michael J. Spencerba4a3622011-10-08 00:18:30 +0000920 outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000921 for (const RelocationRef &Reloc : Section.relocations()) {
Owen Andersonfa3e5202011-10-25 20:35:53 +0000922 bool hidden;
Michael J. Spencerba4a3622011-10-08 00:18:30 +0000923 uint64_t address;
924 SmallString<32> relocname;
925 SmallString<32> valuestr;
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000926 if (error(Reloc.getHidden(hidden)))
927 continue;
928 if (hidden)
929 continue;
930 if (error(Reloc.getTypeName(relocname)))
931 continue;
932 if (error(Reloc.getOffset(address)))
933 continue;
Rafael Espindola37070a52015-06-03 04:48:06 +0000934 if (error(getRelocationValueString(Reloc, valuestr)))
Alexey Samsonovaa4d2952014-03-14 14:22:49 +0000935 continue;
Greg Fitzgerald18432272014-03-20 22:55:15 +0000936 outs() << format(Fmt.data(), address) << " " << relocname << " "
937 << valuestr << "\n";
Michael J. Spencerba4a3622011-10-08 00:18:30 +0000938 }
939 outs() << "\n";
940 }
941}
942
Kevin Enderby98da6132015-01-20 21:47:46 +0000943void llvm::PrintSectionHeaders(const ObjectFile *Obj) {
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000944 outs() << "Sections:\n"
945 "Idx Name Size Address Type\n";
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000946 unsigned i = 0;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000947 for (const SectionRef &Section : Obj->sections()) {
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000948 StringRef Name;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000949 if (error(Section.getName(Name)))
Mark Seaborneb03ac52014-01-25 00:32:01 +0000950 return;
Rafael Espindola80291272014-10-08 15:28:58 +0000951 uint64_t Address = Section.getAddress();
952 uint64_t Size = Section.getSize();
953 bool Text = Section.isText();
954 bool Data = Section.isData();
955 bool BSS = Section.isBSS();
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000956 std::string Type = (std::string(Text ? "TEXT " : "") +
Michael J. Spencer8f67d472011-10-13 20:37:20 +0000957 (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
Alexey Samsonov48803e52014-03-13 14:37:36 +0000958 outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", i,
959 Name.str().c_str(), Size, Address, Type.c_str());
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000960 ++i;
961 }
962}
963
Kevin Enderby98da6132015-01-20 21:47:46 +0000964void llvm::PrintSectionContents(const ObjectFile *Obj) {
Rafael Espindola4453e42942014-06-13 03:07:50 +0000965 std::error_code EC;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000966 for (const SectionRef &Section : Obj->sections()) {
Michael J. Spencer4e25c022011-10-17 17:13:22 +0000967 StringRef Name;
968 StringRef Contents;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000969 if (error(Section.getName(Name)))
970 continue;
Rafael Espindola80291272014-10-08 15:28:58 +0000971 uint64_t BaseAddr = Section.getAddress();
David Majnemer185b5b12014-11-11 09:58:25 +0000972 uint64_t Size = Section.getSize();
973 if (!Size)
974 continue;
Michael J. Spencer4e25c022011-10-17 17:13:22 +0000975
976 outs() << "Contents of section " << Name << ":\n";
David Majnemer185b5b12014-11-11 09:58:25 +0000977 if (Section.isBSS()) {
Alexey Samsonov209095c2013-04-16 10:53:11 +0000978 outs() << format("<skipping contents of bss section at [%04" PRIx64
David Majnemer8f6b04c2014-07-14 16:20:14 +0000979 ", %04" PRIx64 ")>\n",
980 BaseAddr, BaseAddr + Size);
Alexey Samsonov209095c2013-04-16 10:53:11 +0000981 continue;
982 }
Michael J. Spencer4e25c022011-10-17 17:13:22 +0000983
David Majnemer8f6b04c2014-07-14 16:20:14 +0000984 if (error(Section.getContents(Contents)))
985 continue;
986
Michael J. Spencer4e25c022011-10-17 17:13:22 +0000987 // Dump out the content as hex and printable ascii characters.
988 for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
Benjamin Kramer82803112012-03-10 02:04:38 +0000989 outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
Michael J. Spencer4e25c022011-10-17 17:13:22 +0000990 // Dump line of hex.
991 for (std::size_t i = 0; i < 16; ++i) {
992 if (i != 0 && i % 4 == 0)
993 outs() << ' ';
994 if (addr + i < end)
995 outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true)
996 << hexdigit(Contents[addr + i] & 0xF, true);
997 else
998 outs() << " ";
999 }
1000 // Print ascii.
1001 outs() << " ";
1002 for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
Guy Benyei83c74e92013-02-12 21:21:59 +00001003 if (std::isprint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF))
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001004 outs() << Contents[addr + i];
1005 else
1006 outs() << ".";
1007 }
1008 outs() << "\n";
1009 }
1010 }
1011}
1012
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001013static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
David Majnemer44f51e52014-09-10 12:51:52 +00001014 for (unsigned SI = 0, SE = coff->getNumberOfSymbols(); SI != SE; ++SI) {
1015 ErrorOr<COFFSymbolRef> Symbol = coff->getSymbol(SI);
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001016 StringRef Name;
David Majnemer44f51e52014-09-10 12:51:52 +00001017 if (error(Symbol.getError()))
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001018 return;
1019
David Majnemer44f51e52014-09-10 12:51:52 +00001020 if (error(coff->getSymbolName(*Symbol, Name)))
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001021 return;
1022
1023 outs() << "[" << format("%2d", SI) << "]"
David Majnemer44f51e52014-09-10 12:51:52 +00001024 << "(sec " << format("%2d", int(Symbol->getSectionNumber())) << ")"
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001025 << "(fl 0x00)" // Flag bits, which COFF doesn't have.
David Majnemer44f51e52014-09-10 12:51:52 +00001026 << "(ty " << format("%3x", unsigned(Symbol->getType())) << ")"
1027 << "(scl " << format("%3x", unsigned(Symbol->getStorageClass())) << ") "
1028 << "(nx " << unsigned(Symbol->getNumberOfAuxSymbols()) << ") "
1029 << "0x" << format("%08x", unsigned(Symbol->getValue())) << " "
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001030 << Name << "\n";
1031
David Majnemer44f51e52014-09-10 12:51:52 +00001032 for (unsigned AI = 0, AE = Symbol->getNumberOfAuxSymbols(); AI < AE; ++AI, ++SI) {
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001033 if (Symbol->isSectionDefinition()) {
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001034 const coff_aux_section_definition *asd;
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001035 if (error(coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd)))
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001036 return;
Saleem Abdulrasool9ede5c72014-04-13 03:11:08 +00001037
David Majnemer4d571592014-09-15 19:42:42 +00001038 int32_t AuxNumber = asd->getNumber(Symbol->isBigObj());
1039
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001040 outs() << "AUX "
1041 << format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
1042 , unsigned(asd->Length)
1043 , unsigned(asd->NumberOfRelocations)
1044 , unsigned(asd->NumberOfLinenumbers)
1045 , unsigned(asd->CheckSum))
1046 << format("assoc %d comdat %d\n"
David Majnemer4d571592014-09-15 19:42:42 +00001047 , unsigned(AuxNumber)
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001048 , unsigned(asd->Selection));
Saleem Abdulrasool7050eed2014-04-14 02:37:28 +00001049 } else if (Symbol->isFileRecord()) {
David Majnemer44f51e52014-09-10 12:51:52 +00001050 const char *FileName;
1051 if (error(coff->getAuxSymbol<char>(SI + 1, FileName)))
Saleem Abdulrasool63a0dd62014-04-13 22:54:11 +00001052 return;
Saleem Abdulrasoold38c6b12014-04-14 02:37:23 +00001053
David Majnemer44f51e52014-09-10 12:51:52 +00001054 StringRef Name(FileName, Symbol->getNumberOfAuxSymbols() *
1055 coff->getSymbolTableEntrySize());
Saleem Abdulrasoold38c6b12014-04-14 02:37:23 +00001056 outs() << "AUX " << Name.rtrim(StringRef("\0", 1)) << '\n';
Saleem Abdulrasool13a3f692014-04-14 16:38:25 +00001057
David Majnemer44f51e52014-09-10 12:51:52 +00001058 SI = SI + Symbol->getNumberOfAuxSymbols();
Saleem Abdulrasool13a3f692014-04-14 16:38:25 +00001059 break;
Saleem Abdulrasoold38c6b12014-04-14 02:37:23 +00001060 } else {
1061 outs() << "AUX Unknown\n";
Saleem Abdulrasool9ede5c72014-04-13 03:11:08 +00001062 }
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001063 }
1064 }
1065}
1066
Kevin Enderby98da6132015-01-20 21:47:46 +00001067void llvm::PrintSymbolTable(const ObjectFile *o) {
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001068 outs() << "SYMBOL TABLE:\n";
1069
Rui Ueyama4e39f712014-03-18 18:58:51 +00001070 if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) {
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001071 PrintCOFFSymbolTable(coff);
Rui Ueyama4e39f712014-03-18 18:58:51 +00001072 return;
1073 }
1074 for (const SymbolRef &Symbol : o->symbols()) {
Rui Ueyama4e39f712014-03-18 18:58:51 +00001075 uint64_t Address;
1076 SymbolRef::Type Type;
Rui Ueyama4e39f712014-03-18 18:58:51 +00001077 uint32_t Flags = Symbol.getFlags();
1078 section_iterator Section = o->section_end();
Rui Ueyama4e39f712014-03-18 18:58:51 +00001079 if (error(Symbol.getAddress(Address)))
1080 continue;
1081 if (error(Symbol.getType(Type)))
1082 continue;
Rafael Espindola5eb02e42015-06-01 00:27:26 +00001083 uint64_t Size = Symbol.getSize();
Rui Ueyama4e39f712014-03-18 18:58:51 +00001084 if (error(Symbol.getSection(Section)))
1085 continue;
Rafael Espindola75d5b542015-06-03 05:14:22 +00001086 StringRef Name;
1087 if (Type == SymbolRef::ST_Debug && Section != o->section_end()) {
1088 Section->getName(Name);
1089 } else if (error(Symbol.getName(Name))) {
1090 continue;
1091 }
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001092
Rui Ueyama4e39f712014-03-18 18:58:51 +00001093 bool Global = Flags & SymbolRef::SF_Global;
1094 bool Weak = Flags & SymbolRef::SF_Weak;
1095 bool Absolute = Flags & SymbolRef::SF_Absolute;
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001096 bool Common = Flags & SymbolRef::SF_Common;
Davide Italianocd2514d2015-04-30 23:08:53 +00001097 bool Hidden = Flags & SymbolRef::SF_Hidden;
David Meyer1df4b842012-02-28 23:47:53 +00001098
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001099 if (Common) {
Rafael Espindolaa4d224722015-05-31 23:52:50 +00001100 uint32_t Alignment = Symbol.getAlignment();
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001101 Address = Size;
1102 Size = Alignment;
1103 }
Rui Ueyama4e39f712014-03-18 18:58:51 +00001104 if (Address == UnknownAddressOrSize)
1105 Address = 0;
1106 if (Size == UnknownAddressOrSize)
1107 Size = 0;
1108 char GlobLoc = ' ';
1109 if (Type != SymbolRef::ST_Unknown)
1110 GlobLoc = Global ? 'g' : 'l';
1111 char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
1112 ? 'd' : ' ';
1113 char FileFunc = ' ';
1114 if (Type == SymbolRef::ST_File)
1115 FileFunc = 'f';
1116 else if (Type == SymbolRef::ST_Function)
1117 FileFunc = 'F';
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001118
Rui Ueyama4e39f712014-03-18 18:58:51 +00001119 const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 :
1120 "%08" PRIx64;
Michael J. Spencerd857c1c2013-01-10 22:40:50 +00001121
Rui Ueyama4e39f712014-03-18 18:58:51 +00001122 outs() << format(Fmt, Address) << " "
1123 << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
1124 << (Weak ? 'w' : ' ') // Weak?
1125 << ' ' // Constructor. Not supported yet.
1126 << ' ' // Warning. Not supported yet.
1127 << ' ' // Indirect reference to another symbol.
1128 << Debug // Debugging (d) or dynamic (D) symbol.
1129 << FileFunc // Name of function (F), file (f) or object (O).
1130 << ' ';
1131 if (Absolute) {
1132 outs() << "*ABS*";
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001133 } else if (Common) {
1134 outs() << "*COM*";
Rui Ueyama4e39f712014-03-18 18:58:51 +00001135 } else if (Section == o->section_end()) {
1136 outs() << "*UND*";
1137 } else {
1138 if (const MachOObjectFile *MachO =
1139 dyn_cast<const MachOObjectFile>(o)) {
1140 DataRefImpl DR = Section->getRawDataRefImpl();
1141 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
1142 outs() << SegmentName << ",";
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001143 }
Rui Ueyama4e39f712014-03-18 18:58:51 +00001144 StringRef SectionName;
1145 if (error(Section->getName(SectionName)))
1146 SectionName = "";
1147 outs() << SectionName;
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001148 }
Rui Ueyama4e39f712014-03-18 18:58:51 +00001149 outs() << '\t'
Davide Italianocd2514d2015-04-30 23:08:53 +00001150 << format("%08" PRIx64 " ", Size);
1151 if (Hidden) {
1152 outs() << ".hidden ";
1153 }
1154 outs() << Name
Rui Ueyama4e39f712014-03-18 18:58:51 +00001155 << '\n';
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001156 }
1157}
1158
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001159static void PrintUnwindInfo(const ObjectFile *o) {
1160 outs() << "Unwind info:\n\n";
1161
1162 if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) {
1163 printCOFFUnwindInfo(coff);
Tim Northover4bd286a2014-08-01 13:07:19 +00001164 } else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1165 printMachOUnwindInfo(MachO);
1166 else {
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001167 // TODO: Extract DWARF dump tool to objdump.
1168 errs() << "This operation is only currently supported "
Tim Northover4bd286a2014-08-01 13:07:19 +00001169 "for COFF and MachO object files.\n";
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001170 return;
1171 }
1172}
1173
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001174void llvm::printExportsTrie(const ObjectFile *o) {
Nick Kledzikd04bc352014-08-30 00:20:14 +00001175 outs() << "Exports trie:\n";
1176 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1177 printMachOExportsTrie(MachO);
1178 else {
1179 errs() << "This operation is only currently supported "
1180 "for Mach-O executable files.\n";
1181 return;
1182 }
1183}
1184
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001185void llvm::printRebaseTable(const ObjectFile *o) {
Nick Kledzikac431442014-09-12 21:34:15 +00001186 outs() << "Rebase table:\n";
1187 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1188 printMachORebaseTable(MachO);
1189 else {
1190 errs() << "This operation is only currently supported "
1191 "for Mach-O executable files.\n";
1192 return;
1193 }
1194}
1195
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001196void llvm::printBindTable(const ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001197 outs() << "Bind table:\n";
1198 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1199 printMachOBindTable(MachO);
1200 else {
1201 errs() << "This operation is only currently supported "
1202 "for Mach-O executable files.\n";
1203 return;
1204 }
1205}
1206
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001207void llvm::printLazyBindTable(const ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001208 outs() << "Lazy bind table:\n";
1209 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1210 printMachOLazyBindTable(MachO);
1211 else {
1212 errs() << "This operation is only currently supported "
1213 "for Mach-O executable files.\n";
1214 return;
1215 }
1216}
1217
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001218void llvm::printWeakBindTable(const ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001219 outs() << "Weak bind table:\n";
1220 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1221 printMachOWeakBindTable(MachO);
1222 else {
1223 errs() << "This operation is only currently supported "
1224 "for Mach-O executable files.\n";
1225 return;
1226 }
1227}
Nick Kledzikac431442014-09-12 21:34:15 +00001228
Rui Ueyamac2bed422013-09-27 21:04:00 +00001229static void printPrivateFileHeader(const ObjectFile *o) {
1230 if (o->isELF()) {
1231 printELFFileHeader(o);
1232 } else if (o->isCOFF()) {
1233 printCOFFFileHeader(o);
Kevin Enderbyb76d3862014-08-22 20:35:18 +00001234 } else if (o->isMachO()) {
1235 printMachOFileHeader(o);
Rui Ueyamac2bed422013-09-27 21:04:00 +00001236 }
1237}
1238
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001239static void DumpObject(const ObjectFile *o) {
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001240 outs() << '\n';
1241 outs() << o->getFileName()
1242 << ":\tfile format " << o->getFileFormatName() << "\n\n";
1243
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001244 if (Disassemble)
Michael J. Spencer51862b32011-10-13 22:17:18 +00001245 DisassembleObject(o, Relocations);
1246 if (Relocations && !Disassemble)
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001247 PrintRelocations(o);
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001248 if (SectionHeaders)
1249 PrintSectionHeaders(o);
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001250 if (SectionContents)
1251 PrintSectionContents(o);
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001252 if (SymbolTable)
1253 PrintSymbolTable(o);
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001254 if (UnwindInfo)
1255 PrintUnwindInfo(o);
Rui Ueyamac2bed422013-09-27 21:04:00 +00001256 if (PrivateHeaders)
1257 printPrivateFileHeader(o);
Nick Kledzikd04bc352014-08-30 00:20:14 +00001258 if (ExportsTrie)
1259 printExportsTrie(o);
Nick Kledzikac431442014-09-12 21:34:15 +00001260 if (Rebase)
1261 printRebaseTable(o);
Nick Kledzik56ebef42014-09-16 01:41:51 +00001262 if (Bind)
1263 printBindTable(o);
1264 if (LazyBind)
1265 printLazyBindTable(o);
1266 if (WeakBind)
1267 printWeakBindTable(o);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001268}
1269
1270/// @brief Dump each object file in \a a;
1271static void DumpArchive(const Archive *a) {
Mark Seaborneb03ac52014-01-25 00:32:01 +00001272 for (Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e;
1273 ++i) {
Rafael Espindolaae460022014-06-16 16:08:36 +00001274 ErrorOr<std::unique_ptr<Binary>> ChildOrErr = i->getAsBinary();
1275 if (std::error_code EC = ChildOrErr.getError()) {
Michael J. Spencer53723de2011-11-16 01:24:41 +00001276 // Ignore non-object files.
Mark Seaborneb03ac52014-01-25 00:32:01 +00001277 if (EC != object_error::invalid_file_type)
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +00001278 report_error(a->getFileName(), EC);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001279 continue;
1280 }
Rafael Espindolaae460022014-06-16 16:08:36 +00001281 if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001282 DumpObject(o);
1283 else
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +00001284 report_error(a->getFileName(), object_error::invalid_file_type);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001285 }
1286}
1287
1288/// @brief Open file and figure out how to dump it.
1289static void DumpInput(StringRef file) {
1290 // If file isn't stdin, check that it exists.
1291 if (file != "-" && !sys::fs::exists(file)) {
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +00001292 report_error(file, errc::no_such_file_or_directory);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001293 return;
1294 }
1295
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001296 // If we are using the Mach-O specific object file parser, then let it parse
1297 // the file and process the command line options. So the -arch flags can
1298 // be used to select specific slices, etc.
1299 if (MachOOpt) {
1300 ParseInputMachO(file);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001301 return;
1302 }
1303
1304 // Attempt to open the binary.
Rafael Espindola48af1c22014-08-19 18:44:46 +00001305 ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
Rafael Espindola4453e42942014-06-13 03:07:50 +00001306 if (std::error_code EC = BinaryOrErr.getError()) {
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +00001307 report_error(file, EC);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001308 return;
1309 }
Rafael Espindola48af1c22014-08-19 18:44:46 +00001310 Binary &Binary = *BinaryOrErr.get().getBinary();
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001311
Rafael Espindola3f6481d2014-08-01 14:31:55 +00001312 if (Archive *a = dyn_cast<Archive>(&Binary))
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001313 DumpArchive(a);
Rafael Espindola3f6481d2014-08-01 14:31:55 +00001314 else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary))
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001315 DumpObject(o);
Jim Grosbachaf9aec02012-08-07 17:53:14 +00001316 else
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +00001317 report_error(file, object_error::invalid_file_type);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001318}
1319
Michael J. Spencer2670c252011-01-20 06:39:06 +00001320int main(int argc, char **argv) {
1321 // Print a stack trace if we signal out.
1322 sys::PrintStackTraceOnErrorSignal();
1323 PrettyStackTraceProgram X(argc, argv);
1324 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
1325
1326 // Initialize targets and assembly printers/parsers.
1327 llvm::InitializeAllTargetInfos();
Evan Cheng8c886a42011-07-22 21:58:54 +00001328 llvm::InitializeAllTargetMCs();
Michael J. Spencer2670c252011-01-20 06:39:06 +00001329 llvm::InitializeAllAsmParsers();
1330 llvm::InitializeAllDisassemblers();
1331
Pete Cooper28fb4fc2012-05-03 23:20:10 +00001332 // Register the target printer for --version.
1333 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
1334
Michael J. Spencer2670c252011-01-20 06:39:06 +00001335 cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
1336 TripleName = Triple::normalize(TripleName);
1337
1338 ToolName = argv[0];
1339
1340 // Defaults to a.out if no filenames specified.
1341 if (InputFilenames.size() == 0)
1342 InputFilenames.push_back("a.out");
1343
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001344 if (!Disassemble
1345 && !Relocations
1346 && !SectionHeaders
1347 && !SectionContents
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001348 && !SymbolTable
Michael J. Spencer209565db2013-01-06 03:56:49 +00001349 && !UnwindInfo
Nick Kledzikd04bc352014-08-30 00:20:14 +00001350 && !PrivateHeaders
Nick Kledzikac431442014-09-12 21:34:15 +00001351 && !ExportsTrie
Nick Kledzik56ebef42014-09-16 01:41:51 +00001352 && !Rebase
1353 && !Bind
1354 && !LazyBind
Kevin Enderby131d1772015-01-09 19:22:37 +00001355 && !WeakBind
Kevin Enderby13023a12015-01-15 23:19:11 +00001356 && !(UniversalHeaders && MachOOpt)
Kevin Enderbya7bdc7e2015-01-22 18:55:27 +00001357 && !(ArchiveHeaders && MachOOpt)
Kevin Enderby69fe98d2015-01-23 18:52:17 +00001358 && !(IndirectSymbols && MachOOpt)
Kevin Enderby9a509442015-01-27 21:28:24 +00001359 && !(DataInCode && MachOOpt)
Kevin Enderbyf6d25852015-01-31 00:37:11 +00001360 && !(LinkOptHints && MachOOpt)
Kevin Enderbycd66be52015-03-11 22:06:32 +00001361 && !(InfoPlist && MachOOpt)
Kevin Enderbybc847fa2015-03-16 20:08:09 +00001362 && !(DylibsUsed && MachOOpt)
1363 && !(DylibId && MachOOpt)
Kevin Enderby0fc11822015-04-01 20:57:01 +00001364 && !(ObjcMetaData && MachOOpt)
Kevin Enderbyf6d25852015-01-31 00:37:11 +00001365 && !(DumpSections.size() != 0 && MachOOpt)) {
Michael J. Spencer2670c252011-01-20 06:39:06 +00001366 cl::PrintHelpMessage();
1367 return 2;
1368 }
1369
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001370 std::for_each(InputFilenames.begin(), InputFilenames.end(),
1371 DumpInput);
Michael J. Spencer2670c252011-01-20 06:39:06 +00001372
Rui Ueyama98fe58a2014-11-26 22:17:25 +00001373 return ReturnValue;
Michael J. Spencer2670c252011-01-20 06:39:06 +00001374}