blob: 78e2388596e04da38eaf89cfb8aec00f685130a4 [file] [log] [blame]
Michael J. Spencer2670c252011-01-20 06:39:06 +00001//===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Michael J. Spencer2670c252011-01-20 06:39:06 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This program is a utility that works like binutils "objdump", that is, it
10// dumps out a plethora of information about an object file depending on the
11// flags.
12//
Michael J. Spencerd7e70032013-02-05 20:27:22 +000013// The flags and output of this program should be near identical to those of
14// binutils objdump.
15//
Michael J. Spencer2670c252011-01-20 06:39:06 +000016//===----------------------------------------------------------------------===//
17
Benjamin Kramer43a772e2011-09-19 17:56:04 +000018#include "llvm-objdump.h"
Sanjoy Das6f567a42015-06-22 18:03:02 +000019#include "llvm/ADT/Optional.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"
Rafael Aulerb0e4b912018-03-09 19:13:44 +000022#include "llvm/ADT/StringSet.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000023#include "llvm/ADT/Triple.h"
Sanjoy Das3f1bc3b2015-06-23 20:09:03 +000024#include "llvm/CodeGen/FaultMaps.h"
Igor Laevsky03a670c2016-01-26 15:09:42 +000025#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +000026#include "llvm/DebugInfo/Symbolize/Symbolize.h"
Paul Semel007dedb2018-07-18 16:39:21 +000027#include "llvm/Demangle/Demangle.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000028#include "llvm/MC/MCAsmInfo.h"
Ahmed Bougachaad1084d2013-05-24 00:39:57 +000029#include "llvm/MC/MCContext.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000030#include "llvm/MC/MCDisassembler/MCDisassembler.h"
31#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000032#include "llvm/MC/MCInst.h"
33#include "llvm/MC/MCInstPrinter.h"
Ahmed Bougachaaa790682013-05-24 01:07:04 +000034#include "llvm/MC/MCInstrAnalysis.h"
Craig Topper54bfde72012-04-02 06:09:36 +000035#include "llvm/MC/MCInstrInfo.h"
Ahmed Bougachaad1084d2013-05-24 00:39:57 +000036#include "llvm/MC/MCObjectFileInfo.h"
Jim Grosbachfd93a592012-03-05 19:33:20 +000037#include "llvm/MC/MCRegisterInfo.h"
Ahmed Bougachaaa790682013-05-24 01:07:04 +000038#include "llvm/MC/MCSubtargetInfo.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000039#include "llvm/Object/Archive.h"
40#include "llvm/Object/COFF.h"
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +000041#include "llvm/Object/COFFImportFile.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000042#include "llvm/Object/ELFObjectFile.h"
Rafael Espindolaa9f810b2012-12-21 03:47:03 +000043#include "llvm/Object/MachO.h"
Dave Lee3fb120f2018-08-03 00:06:38 +000044#include "llvm/Object/MachOUniversal.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000045#include "llvm/Object/ObjectFile.h"
Sam Clegg4df5d762017-06-27 20:40:53 +000046#include "llvm/Object/Wasm.h"
Michael J. Spencerba4a3622011-10-08 00:18:30 +000047#include "llvm/Support/Casting.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000048#include "llvm/Support/CommandLine.h"
49#include "llvm/Support/Debug.h"
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +000050#include "llvm/Support/Errc.h"
Michael J. Spencerba4a3622011-10-08 00:18:30 +000051#include "llvm/Support/FileSystem.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000052#include "llvm/Support/Format.h"
Benjamin Kramerbf115312011-07-25 23:04:36 +000053#include "llvm/Support/GraphWriter.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000054#include "llvm/Support/Host.h"
Rui Ueyama197194b2018-04-13 18:26:06 +000055#include "llvm/Support/InitLLVM.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000056#include "llvm/Support/MemoryBuffer.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000057#include "llvm/Support/SourceMgr.h"
Joel Galenson134cf472018-08-24 15:21:57 +000058#include "llvm/Support/StringSaver.h"
Evan Cheng2bb40352011-08-24 18:08:43 +000059#include "llvm/Support/TargetRegistry.h"
60#include "llvm/Support/TargetSelect.h"
Jonas Devliegheree787efd2018-11-11 22:12:04 +000061#include "llvm/Support/WithColor.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000062#include "llvm/Support/raw_ostream.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000063#include <algorithm>
Benjamin Kramera5177e62012-03-23 11:49:32 +000064#include <cctype>
Michael J. Spencer2670c252011-01-20 06:39:06 +000065#include <cstring>
Rafael Espindolaa6e9c3e2014-06-12 17:38:55 +000066#include <system_error>
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +000067#include <unordered_map>
Rafael Espindolac398e672017-07-19 22:27:28 +000068#include <utility>
Ahmed Bougacha17926472013-08-21 07:29:02 +000069
Michael J. Spencer2670c252011-01-20 06:39:06 +000070using namespace llvm;
71using namespace object;
72
George Rimar4c3b2972019-01-28 10:44:01 +000073cl::opt<unsigned long long> AdjustVMA(
74 "adjust-vma",
75 cl::desc("Increase the displayed address by the specified offset"),
76 cl::value_desc("offset"), cl::init(0));
77
Fangrui Song8513cd42018-06-27 20:45:11 +000078cl::opt<bool>
79 llvm::AllHeaders("all-headers",
80 cl::desc("Display all available header information"));
81static cl::alias AllHeadersShort("x", cl::desc("Alias for --all-headers"),
Matthew Voss0f436772019-02-19 19:46:08 +000082 cl::NotHidden, cl::Grouping,
83 cl::aliasopt(AllHeaders));
Fangrui Song8513cd42018-06-27 20:45:11 +000084
Benjamin Kramer43a772e2011-09-19 17:56:04 +000085static cl::list<std::string>
86InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
Michael J. Spencer2670c252011-01-20 06:39:06 +000087
Kevin Enderbye2297dd2015-01-07 21:02:18 +000088cl::opt<bool>
89llvm::Disassemble("disassemble",
Benjamin Kramer43a772e2011-09-19 17:56:04 +000090 cl::desc("Display assembler mnemonics for the machine instructions"));
George Rimar845d3292019-01-18 10:41:26 +000091static cl::alias Disassembled("d", cl::desc("Alias for --disassemble"),
Matthew Voss0f436772019-02-19 19:46:08 +000092 cl::NotHidden, cl::Grouping,
93 cl::aliasopt(Disassemble));
Colin LeMahieu77804be2015-07-29 15:45:39 +000094
95cl::opt<bool>
96llvm::DisassembleAll("disassemble-all",
97 cl::desc("Display assembler mnemonics for the machine instructions"));
George Rimar845d3292019-01-18 10:41:26 +000098static cl::alias DisassembleAlld("D", cl::desc("Alias for --disassemble-all"),
Matthew Voss0f436772019-02-19 19:46:08 +000099 cl::NotHidden, cl::Grouping,
100 cl::aliasopt(DisassembleAll));
Michael J. Spencer2670c252011-01-20 06:39:06 +0000101
Zachary Turner030ad372018-08-20 22:18:21 +0000102cl::opt<bool> llvm::Demangle("demangle", cl::desc("Demangle symbols names"),
103 cl::init(false));
Paul Semel007dedb2018-07-18 16:39:21 +0000104
105static cl::alias DemangleShort("C", cl::desc("Alias for --demangle"),
Matthew Voss0f436772019-02-19 19:46:08 +0000106 cl::NotHidden, cl::Grouping,
107 cl::aliasopt(llvm::Demangle));
Paul Semel007dedb2018-07-18 16:39:21 +0000108
Rafael Aulerb0e4b912018-03-09 19:13:44 +0000109static cl::list<std::string>
Matthew Voss0f436772019-02-19 19:46:08 +0000110DisassembleFunctions("disassemble-functions",
Rafael Aulerb0e4b912018-03-09 19:13:44 +0000111 cl::CommaSeparated,
112 cl::desc("List of functions to disassemble"));
113static StringSet<> DisasmFuncsSet;
114
Kevin Enderby98da6132015-01-20 21:47:46 +0000115cl::opt<bool>
Kristina Brooks31579e92018-10-31 09:34:08 +0000116llvm::Relocations("reloc",
117 cl::desc("Display the relocation entries in the file"));
118static cl::alias RelocationsShort("r", cl::desc("Alias for --reloc"),
Matthew Voss0f436772019-02-19 19:46:08 +0000119 cl::NotHidden, cl::Grouping,
Kristina Brooks31579e92018-10-31 09:34:08 +0000120 cl::aliasopt(llvm::Relocations));
Michael J. Spencerba4a3622011-10-08 00:18:30 +0000121
Kevin Enderby98da6132015-01-20 21:47:46 +0000122cl::opt<bool>
Paul Semelcb0f0432018-06-07 13:30:55 +0000123llvm::DynamicRelocations("dynamic-reloc",
124 cl::desc("Display the dynamic relocation entries in the file"));
George Rimar845d3292019-01-18 10:41:26 +0000125static cl::alias DynamicRelocationsd("R", cl::desc("Alias for --dynamic-reloc"),
Matthew Voss0f436772019-02-19 19:46:08 +0000126 cl::NotHidden, cl::Grouping,
George Rimar845d3292019-01-18 10:41:26 +0000127 cl::aliasopt(DynamicRelocations));
Paul Semelcb0f0432018-06-07 13:30:55 +0000128
129cl::opt<bool>
James Hendersonb55b6582018-10-29 10:05:39 +0000130 llvm::SectionContents("full-contents",
131 cl::desc("Display the content of each section"));
132static cl::alias SectionContentsShort("s",
133 cl::desc("Alias for --full-contents"),
Matthew Voss0f436772019-02-19 19:46:08 +0000134 cl::NotHidden, cl::Grouping,
James Hendersonb55b6582018-10-29 10:05:39 +0000135 cl::aliasopt(SectionContents));
Michael J. Spencer4e25c022011-10-17 17:13:22 +0000136
Kristina Brooks3baa5f72018-10-31 05:45:01 +0000137cl::opt<bool> llvm::SymbolTable("syms", cl::desc("Display the symbol table"));
138static cl::alias SymbolTableShort("t", cl::desc("Alias for --syms"),
Matthew Voss0f436772019-02-19 19:46:08 +0000139 cl::NotHidden, cl::Grouping,
Kristina Brooks3baa5f72018-10-31 05:45:01 +0000140 cl::aliasopt(llvm::SymbolTable));
Michael J. Spencerbfa06782011-10-18 19:32:17 +0000141
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000142cl::opt<bool>
143llvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
Nick Kledzikd04bc352014-08-30 00:20:14 +0000144
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000145cl::opt<bool>
146llvm::Rebase("rebase", cl::desc("Display mach-o rebasing info"));
Nick Kledzikac431442014-09-12 21:34:15 +0000147
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000148cl::opt<bool>
149llvm::Bind("bind", cl::desc("Display mach-o binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +0000150
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000151cl::opt<bool>
152llvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +0000153
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000154cl::opt<bool>
155llvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +0000156
Adrian Prantl437105a2015-07-08 02:04:15 +0000157cl::opt<bool>
158llvm::RawClangAST("raw-clang-ast",
159 cl::desc("Dump the raw binary contents of the clang AST section"));
160
Nick Kledzik56ebef42014-09-16 01:41:51 +0000161static cl::opt<bool>
Rafael Espindolaa9f810b2012-12-21 03:47:03 +0000162MachOOpt("macho", cl::desc("Use MachO specific object file parser"));
George Rimar845d3292019-01-18 10:41:26 +0000163static cl::alias MachOm("m", cl::desc("Alias for --macho"), cl::NotHidden,
Matthew Voss0f436772019-02-19 19:46:08 +0000164 cl::Grouping, cl::aliasopt(MachOOpt));
Benjamin Kramer87ee76c2011-07-20 19:37:35 +0000165
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000166cl::opt<std::string>
167llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
168 "see -version for available targets"));
169
170cl::opt<std::string>
Kevin Enderbyc9595622014-08-06 23:24:41 +0000171llvm::MCPU("mcpu",
172 cl::desc("Target a specific cpu type (-mcpu=help for details)"),
173 cl::value_desc("cpu-name"),
174 cl::init(""));
175
176cl::opt<std::string>
Kevin Enderbyef3ad2f2014-12-04 23:56:27 +0000177llvm::ArchName("arch-name", cl::desc("Target arch to disassemble for, "
Michael J. Spencer2670c252011-01-20 06:39:06 +0000178 "see -version for available targets"));
179
Kevin Enderby98da6132015-01-20 21:47:46 +0000180cl::opt<bool>
181llvm::SectionHeaders("section-headers", cl::desc("Display summaries of the "
182 "headers for each section."));
George Rimar845d3292019-01-18 10:41:26 +0000183static cl::alias SectionHeadersShort("headers",
184 cl::desc("Alias for --section-headers"),
185 cl::NotHidden,
186 cl::aliasopt(SectionHeaders));
187static cl::alias SectionHeadersShorter("h",
188 cl::desc("Alias for --section-headers"),
Matthew Voss0f436772019-02-19 19:46:08 +0000189 cl::NotHidden, cl::Grouping,
George Rimar845d3292019-01-18 10:41:26 +0000190 cl::aliasopt(SectionHeaders));
Colin LeMahieufcc32762015-07-29 19:08:10 +0000191
George Rimar87fa2e62019-01-28 14:11:35 +0000192static cl::opt<bool>
193 ShowLMA("show-lma",
194 cl::desc("Display LMA column when dumping ELF section headers"));
195
Colin LeMahieu77804be2015-07-29 15:45:39 +0000196cl::list<std::string>
Colin LeMahieufcc32762015-07-29 19:08:10 +0000197llvm::FilterSections("section", cl::desc("Operate on the specified sections only. "
198 "With -macho dump segment,section"));
George Rimar845d3292019-01-18 10:41:26 +0000199cl::alias static FilterSectionsj("j", cl::desc("Alias for --section"),
Jordan Rupprechtae672b42019-03-21 18:45:44 +0000200 cl::NotHidden, cl::Grouping, cl::Prefix,
George Rimar845d3292019-01-18 10:41:26 +0000201 cl::aliasopt(llvm::FilterSections));
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000202
Kevin Enderbyc9595622014-08-06 23:24:41 +0000203cl::list<std::string>
204llvm::MAttrs("mattr",
Jack Carter551efd72012-08-28 19:24:49 +0000205 cl::CommaSeparated,
206 cl::desc("Target specific attributes"),
207 cl::value_desc("a1,+a2,-a3,..."));
208
Kevin Enderbybf246f52014-09-24 23:08:22 +0000209cl::opt<bool>
210llvm::NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling "
211 "instructions, do not print "
212 "the instruction bytes."));
Saleem Abdulrasooldea14b22017-02-08 18:11:31 +0000213cl::opt<bool>
214llvm::NoLeadingAddr("no-leading-addr", cl::desc("Print no leading address"));
Eli Bendersky3a6808c2012-11-20 22:57:02 +0000215
Kevin Enderby98da6132015-01-20 21:47:46 +0000216cl::opt<bool>
217llvm::UnwindInfo("unwind-info", cl::desc("Display unwind information"));
Michael J. Spencer0c6ec482012-12-05 20:12:35 +0000218
George Rimar845d3292019-01-18 10:41:26 +0000219static cl::alias UnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
Matthew Voss0f436772019-02-19 19:46:08 +0000220 cl::NotHidden, cl::Grouping,
221 cl::aliasopt(UnwindInfo));
Michael J. Spencer0c6ec482012-12-05 20:12:35 +0000222
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000223cl::opt<bool>
224llvm::PrivateHeaders("private-headers",
225 cl::desc("Display format specific file headers"));
Michael J. Spencer209565db2013-01-06 03:56:49 +0000226
Kevin Enderby0ae163f2016-01-13 00:25:36 +0000227cl::opt<bool>
228llvm::FirstPrivateHeader("private-header",
229 cl::desc("Display only the first format specific file "
230 "header"));
231
George Rimar845d3292019-01-18 10:41:26 +0000232static cl::alias PrivateHeadersShort("p",
233 cl::desc("Alias for --private-headers"),
Matthew Voss0f436772019-02-19 19:46:08 +0000234 cl::NotHidden, cl::Grouping,
George Rimar845d3292019-01-18 10:41:26 +0000235 cl::aliasopt(PrivateHeaders));
Michael J. Spencer209565db2013-01-06 03:56:49 +0000236
Paul Semeld2af4d62018-07-04 15:25:03 +0000237cl::opt<bool> llvm::FileHeaders(
238 "file-headers",
239 cl::desc("Display the contents of the overall file header"));
240
241static cl::alias FileHeadersShort("f", cl::desc("Alias for --file-headers"),
Matthew Voss0f436772019-02-19 19:46:08 +0000242 cl::NotHidden, cl::Grouping,
243 cl::aliasopt(FileHeaders));
Paul Semeld2af4d62018-07-04 15:25:03 +0000244
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000245cl::opt<bool>
Paul Semel0dc92f62018-07-05 14:43:29 +0000246 llvm::ArchiveHeaders("archive-headers",
247 cl::desc("Display archive header information"));
248
George Rimar845d3292019-01-18 10:41:26 +0000249cl::alias ArchiveHeadersShort("a", cl::desc("Alias for --archive-headers"),
Matthew Voss0f436772019-02-19 19:46:08 +0000250 cl::NotHidden, cl::Grouping,
251 cl::aliasopt(ArchiveHeaders));
Paul Semel0dc92f62018-07-05 14:43:29 +0000252
253cl::opt<bool>
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000254 llvm::PrintImmHex("print-imm-hex",
Colin LeMahieuefe37322016-04-08 18:15:37 +0000255 cl::desc("Use hex format for immediate values"));
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000256
Sanjoy Das6f567a42015-06-22 18:03:02 +0000257cl::opt<bool> PrintFaultMaps("fault-map-section",
258 cl::desc("Display contents of faultmap section"));
259
Igor Laevsky03a670c2016-01-26 15:09:42 +0000260cl::opt<DIDumpType> llvm::DwarfDumpType(
261 "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
Jonas Devliegherec0a758d2017-09-18 14:15:57 +0000262 cl::values(clEnumValN(DIDT_DebugFrame, "frames", ".debug_frame")));
Igor Laevsky03a670c2016-01-26 15:09:42 +0000263
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +0000264cl::opt<bool> PrintSource(
265 "source",
266 cl::desc(
Alex Denisova07169e2018-02-02 19:20:37 +0000267 "Display source inlined with disassembly. Implies disassemble object"));
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +0000268
George Rimar845d3292019-01-18 10:41:26 +0000269cl::alias PrintSourceShort("S", cl::desc("Alias for -source"), cl::NotHidden,
Matthew Voss0f436772019-02-19 19:46:08 +0000270 cl::Grouping, cl::aliasopt(PrintSource));
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +0000271
272cl::opt<bool> PrintLines("line-numbers",
273 cl::desc("Display source line numbers with "
274 "disassembly. Implies disassemble object"));
275
276cl::alias PrintLinesShort("l", cl::desc("Alias for -line-numbers"),
Matthew Voss0f436772019-02-19 19:46:08 +0000277 cl::NotHidden, cl::Grouping,
278 cl::aliasopt(PrintLines));
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +0000279
280cl::opt<unsigned long long>
281 StartAddress("start-address", cl::desc("Disassemble beginning at address"),
282 cl::value_desc("address"), cl::init(0));
283cl::opt<unsigned long long>
George Rimar70d197d2019-01-10 14:55:26 +0000284 StopAddress("stop-address",
George Rimar3687c3e92019-01-15 14:03:50 +0000285 cl::desc("Stop disassembly at address"),
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +0000286 cl::value_desc("address"), cl::init(UINT64_MAX));
George Rimar70d197d2019-01-10 14:55:26 +0000287
George Rimar3687c3e92019-01-15 14:03:50 +0000288cl::opt<bool> DisassembleZeroes(
289 "disassemble-zeroes",
290 cl::desc("Do not skip blocks of zeroes when disassembling"));
George Rimar70d197d2019-01-10 14:55:26 +0000291cl::alias DisassembleZeroesShort("z",
292 cl::desc("Alias for --disassemble-zeroes"),
Matthew Voss0f436772019-02-19 19:46:08 +0000293 cl::NotHidden, cl::Grouping,
George Rimar70d197d2019-01-10 14:55:26 +0000294 cl::aliasopt(DisassembleZeroes));
295
Igor Kudrin2d3faad2019-02-26 12:15:14 +0000296static cl::list<std::string>
297 DisassemblerOptions("disassembler-options",
298 cl::desc("Pass target specific disassembler options"),
299 cl::value_desc("options"), cl::CommaSeparated);
300static cl::alias
301 DisassemblerOptionsShort("M", cl::desc("Alias for --disassembler-options"),
Jordan Rupprechtae672b42019-03-21 18:45:44 +0000302 cl::NotHidden, cl::Grouping, cl::Prefix,
303 cl::CommaSeparated,
Igor Kudrin2d3faad2019-02-26 12:15:14 +0000304 cl::aliasopt(DisassemblerOptions));
305
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000306static StringRef ToolName;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000307
Clement Courbetd1a3bd42019-01-18 15:26:14 +0000308typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
Clement Courbet2d7d4a32019-01-18 09:40:19 +0000309
George Rimarc1964882019-01-18 11:33:26 +0000310SectionFilter llvm::ToolSectionFilter(llvm::object::ObjectFile const &O) {
David Majnemer42531262016-08-12 03:55:06 +0000311 return SectionFilter(
312 [](llvm::object::SectionRef const &S) {
313 if (FilterSections.empty())
314 return true;
315 llvm::StringRef String;
316 std::error_code error = S.getName(String);
317 if (error)
318 return false;
319 return is_contained(FilterSections, String);
320 },
321 O);
Colin LeMahieu77804be2015-07-29 15:45:39 +0000322}
Colin LeMahieu77804be2015-07-29 15:45:39 +0000323
Davide Italianoccd53fe2015-08-05 07:18:31 +0000324void llvm::error(std::error_code EC) {
Mark Seaborneb03ac52014-01-25 00:32:01 +0000325 if (!EC)
Davide Italianoccd53fe2015-08-05 07:18:31 +0000326 return;
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000327 WithColor::error(errs(), ToolName)
328 << "reading file: " << EC.message() << ".\n";
Davide Italiano140af642015-12-25 18:16:45 +0000329 errs().flush();
Davide Italiano7f6c3012015-08-06 00:18:52 +0000330 exit(1);
Michael J. Spencer2670c252011-01-20 06:39:06 +0000331}
332
Kevin Enderby42398052016-06-28 23:16:13 +0000333LLVM_ATTRIBUTE_NORETURN void llvm::error(Twine Message) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000334 WithColor::error(errs(), ToolName) << Message << ".\n";
Kevin Enderby42398052016-06-28 23:16:13 +0000335 errs().flush();
336 exit(1);
337}
338
Paul Semel007dedb2018-07-18 16:39:21 +0000339void llvm::warn(StringRef Message) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000340 WithColor::warning(errs(), ToolName) << Message << ".\n";
Paul Semel007dedb2018-07-18 16:39:21 +0000341 errs().flush();
342}
343
Davide Italianoed9d95b2015-12-29 13:41:02 +0000344LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000345 Twine Message) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000346 WithColor::error(errs(), ToolName)
347 << "'" << File << "': " << Message << ".\n";
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000348 exit(1);
349}
350
351LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
Davide Italianoed9d95b2015-12-29 13:41:02 +0000352 std::error_code EC) {
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +0000353 assert(EC);
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000354 WithColor::error(errs(), ToolName)
355 << "'" << File << "': " << EC.message() << ".\n";
Davide Italianoccd53fe2015-08-05 07:18:31 +0000356 exit(1);
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +0000357}
358
Fangrui Songe7834bd2019-04-07 08:19:55 +0000359LLVM_ATTRIBUTE_NORETURN void llvm::report_error(Error E, StringRef File) {
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000360 assert(E);
361 std::string Buf;
362 raw_string_ostream OS(Buf);
Jonas Devlieghere45eb84f2018-11-11 01:46:03 +0000363 logAllUnhandledErrors(std::move(E), OS);
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000364 OS.flush();
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000365 WithColor::error(errs(), ToolName) << "'" << File << "': " << Buf;
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000366 exit(1);
367}
368
Fangrui Songe7834bd2019-04-07 08:19:55 +0000369LLVM_ATTRIBUTE_NORETURN void llvm::report_error(Error E, StringRef ArchiveName,
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000370 StringRef FileName,
Kevin Enderby9acb1092016-05-31 20:35:34 +0000371 StringRef ArchitectureName) {
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000372 assert(E);
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000373 WithColor::error(errs(), ToolName);
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000374 if (ArchiveName != "")
375 errs() << ArchiveName << "(" << FileName << ")";
376 else
Justin Bogner31d8b7d2016-10-26 22:37:52 +0000377 errs() << "'" << FileName << "'";
Kevin Enderby9acb1092016-05-31 20:35:34 +0000378 if (!ArchitectureName.empty())
379 errs() << " (for architecture " << ArchitectureName << ")";
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000380 std::string Buf;
381 raw_string_ostream OS(Buf);
Jonas Devlieghere45eb84f2018-11-11 01:46:03 +0000382 logAllUnhandledErrors(std::move(E), OS);
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000383 OS.flush();
Justin Bogner31d8b7d2016-10-26 22:37:52 +0000384 errs() << ": " << Buf;
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000385 exit(1);
386}
387
Fangrui Songe7834bd2019-04-07 08:19:55 +0000388LLVM_ATTRIBUTE_NORETURN void llvm::report_error(Error E, StringRef ArchiveName,
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000389 const object::Archive::Child &C,
Kevin Enderby9acb1092016-05-31 20:35:34 +0000390 StringRef ArchitectureName) {
Kevin Enderbyf4586032016-07-29 17:44:13 +0000391 Expected<StringRef> NameOrErr = C.getName();
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000392 // TODO: if we have a error getting the name then it would be nice to print
393 // the index of which archive member this is and or its offset in the
394 // archive instead of "???" as the name.
Kevin Enderbyf4586032016-07-29 17:44:13 +0000395 if (!NameOrErr) {
396 consumeError(NameOrErr.takeError());
Fangrui Songe7834bd2019-04-07 08:19:55 +0000397 llvm::report_error(std::move(E), ArchiveName, "???", ArchitectureName);
Kevin Enderbyf4586032016-07-29 17:44:13 +0000398 } else
Fangrui Songe7834bd2019-04-07 08:19:55 +0000399 llvm::report_error(std::move(E), ArchiveName, NameOrErr.get(),
Kevin Enderby9acb1092016-05-31 20:35:34 +0000400 ArchitectureName);
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000401}
402
Craig Toppere6cb63e2014-04-25 04:24:47 +0000403static const Target *getTarget(const ObjectFile *Obj = nullptr) {
Michael J. Spencer2670c252011-01-20 06:39:06 +0000404 // Figure out the target triple.
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000405 llvm::Triple TheTriple("unknown-unknown-unknown");
Michael J. Spencer05350e6d2011-01-20 07:22:04 +0000406 if (TripleName.empty()) {
George Rimar73a27232019-01-15 09:19:18 +0000407 if (Obj)
Vlad Tsyrklevichde620462017-09-19 02:22:48 +0000408 TheTriple = Obj->makeTriple();
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000409 } else {
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000410 TheTriple.setTriple(Triple::normalize(TripleName));
Vlad Tsyrklevichde620462017-09-19 02:22:48 +0000411
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000412 // Use the triple, but also try to combine with ARM build attributes.
413 if (Obj) {
414 auto Arch = Obj->getArch();
George Rimar73a27232019-01-15 09:19:18 +0000415 if (Arch == Triple::arm || Arch == Triple::armeb)
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000416 Obj->setARMSubArch(TheTriple);
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000417 }
418 }
Michael J. Spencer2670c252011-01-20 06:39:06 +0000419
420 // Get the target specific parser.
421 std::string Error;
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000422 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
423 Error);
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000424 if (!TheTarget) {
425 if (Obj)
426 report_error(Obj->getFileName(), "can't find target: " + Error);
427 else
428 error("can't find target: " + Error);
429 }
Michael J. Spencer2670c252011-01-20 06:39:06 +0000430
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000431 // Update the triple name and return the found target.
432 TripleName = TheTriple.getTriple();
433 return TheTarget;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000434}
435
George Rimar73a27232019-01-15 09:19:18 +0000436bool llvm::isRelocAddressLess(RelocationRef A, RelocationRef B) {
437 return A.getOffset() < B.getOffset();
Michael J. Spencer51862b32011-10-13 22:17:18 +0000438}
439
Rafael Espindola37070a52015-06-03 04:48:06 +0000440static std::error_code getRelocationValueString(const RelocationRef &Rel,
441 SmallVectorImpl<char> &Result) {
Rafael Espindola854038e2015-06-26 14:51:16 +0000442 const ObjectFile *Obj = Rel.getObject();
Rafael Espindola37070a52015-06-03 04:48:06 +0000443 if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000444 return getELFRelocationValueString(ELF, Rel, Result);
Rafael Espindola37070a52015-06-03 04:48:06 +0000445 if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000446 return getCOFFRelocationValueString(COFF, Rel, Result);
Sam Clegg4df5d762017-06-27 20:40:53 +0000447 if (auto *Wasm = dyn_cast<WasmObjectFile>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000448 return getWasmRelocationValueString(Wasm, Rel, Result);
Sam Clegg4df5d762017-06-27 20:40:53 +0000449 if (auto *MachO = dyn_cast<MachOObjectFile>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000450 return getMachORelocationValueString(MachO, Rel, Result);
Sam Clegg4df5d762017-06-27 20:40:53 +0000451 llvm_unreachable("unknown object file format");
Rafael Espindola37070a52015-06-03 04:48:06 +0000452}
453
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +0000454/// Indicates whether this relocation should hidden when listing
Rafael Espindola0ad71d92015-06-30 03:41:26 +0000455/// relocations, usually because it is the trailing part of a multipart
456/// relocation that will be printed as part of the leading relocation.
457static bool getHidden(RelocationRef RelRef) {
George Rimar73a27232019-01-15 09:19:18 +0000458 auto *MachO = dyn_cast<MachOObjectFile>(RelRef.getObject());
Rafael Espindola0ad71d92015-06-30 03:41:26 +0000459 if (!MachO)
460 return false;
461
462 unsigned Arch = MachO->getArch();
463 DataRefImpl Rel = RelRef.getRawDataRefImpl();
464 uint64_t Type = MachO->getRelocationType(Rel);
465
466 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
467 // is always hidden.
George Rimar73a27232019-01-15 09:19:18 +0000468 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc)
469 return Type == MachO::GENERIC_RELOC_PAIR;
470
471 if (Arch == Triple::x86_64) {
Rafael Espindola0ad71d92015-06-30 03:41:26 +0000472 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
473 // an X86_64_RELOC_SUBTRACTOR.
474 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
475 DataRefImpl RelPrev = Rel;
476 RelPrev.d.a--;
477 uint64_t PrevType = MachO->getRelocationType(RelPrev);
478 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
479 return true;
480 }
481 }
482
483 return false;
484}
485
Sid Manningd9f28732018-05-14 19:46:08 +0000486namespace {
487class SourcePrinter {
488protected:
489 DILineInfo OldLineInfo;
490 const ObjectFile *Obj = nullptr;
491 std::unique_ptr<symbolize::LLVMSymbolizer> Symbolizer;
492 // File name to file contents of source
493 std::unordered_map<std::string, std::unique_ptr<MemoryBuffer>> SourceCache;
494 // Mark the line endings of the cached source
495 std::unordered_map<std::string, std::vector<StringRef>> LineCache;
496
497private:
498 bool cacheSource(const DILineInfo& LineInfoFile);
499
500public:
501 SourcePrinter() = default;
502 SourcePrinter(const ObjectFile *Obj, StringRef DefaultArch) : Obj(Obj) {
503 symbolize::LLVMSymbolizer::Options SymbolizerOpts(
504 DILineInfoSpecifier::FunctionNameKind::None, true, false, false,
505 DefaultArch);
506 Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts));
507 }
508 virtual ~SourcePrinter() = default;
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000509 virtual void printSourceLine(raw_ostream &OS,
510 object::SectionedAddress Address,
Sid Manningd9f28732018-05-14 19:46:08 +0000511 StringRef Delimiter = "; ");
512};
513
514bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
515 std::unique_ptr<MemoryBuffer> Buffer;
516 if (LineInfo.Source) {
517 Buffer = MemoryBuffer::getMemBuffer(*LineInfo.Source);
518 } else {
519 auto BufferOrError = MemoryBuffer::getFile(LineInfo.FileName);
520 if (!BufferOrError)
521 return false;
522 Buffer = std::move(*BufferOrError);
523 }
524 // Chomp the file to get lines
525 size_t BufferSize = Buffer->getBufferSize();
526 const char *BufferStart = Buffer->getBufferStart();
527 for (const char *Start = BufferStart, *End = BufferStart;
528 End < BufferStart + BufferSize; End++)
529 if (*End == '\n' || End == BufferStart + BufferSize - 1 ||
530 (*End == '\r' && *(End + 1) == '\n')) {
531 LineCache[LineInfo.FileName].push_back(StringRef(Start, End - Start));
532 if (*End == '\r')
533 End++;
534 Start = End + 1;
535 }
536 SourceCache[LineInfo.FileName] = std::move(Buffer);
537 return true;
538}
539
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000540void SourcePrinter::printSourceLine(raw_ostream &OS,
541 object::SectionedAddress Address,
Sid Manningd9f28732018-05-14 19:46:08 +0000542 StringRef Delimiter) {
543 if (!Symbolizer)
544 return;
545 DILineInfo LineInfo = DILineInfo();
Eric Christopher1857edb2019-03-28 01:12:13 +0000546 auto ExpectedLineInfo =
Sid Manningd9f28732018-05-14 19:46:08 +0000547 Symbolizer->symbolizeCode(Obj->getFileName(), Address);
Eric Christopher1857edb2019-03-28 01:12:13 +0000548 if (!ExpectedLineInfo)
549 consumeError(ExpectedLineInfo.takeError());
Sid Manningd9f28732018-05-14 19:46:08 +0000550 else
Eric Christopher1857edb2019-03-28 01:12:13 +0000551 LineInfo = *ExpectedLineInfo;
Sid Manningd9f28732018-05-14 19:46:08 +0000552
553 if ((LineInfo.FileName == "<invalid>") || OldLineInfo.Line == LineInfo.Line ||
554 LineInfo.Line == 0)
555 return;
556
557 if (PrintLines)
558 OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line << "\n";
559 if (PrintSource) {
560 if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
561 if (!cacheSource(LineInfo))
562 return;
563 auto FileBuffer = SourceCache.find(LineInfo.FileName);
564 if (FileBuffer != SourceCache.end()) {
565 auto LineBuffer = LineCache.find(LineInfo.FileName);
566 if (LineBuffer != LineCache.end()) {
567 if (LineInfo.Line > LineBuffer->second.size())
568 return;
569 // Vector begins at 0, line numbers are non-zero
570 OS << Delimiter << LineBuffer->second[LineInfo.Line - 1].ltrim()
571 << "\n";
572 }
573 }
574 }
575 OldLineInfo = LineInfo;
576}
577
578static bool isArmElf(const ObjectFile *Obj) {
579 return (Obj->isELF() &&
580 (Obj->getArch() == Triple::aarch64 ||
581 Obj->getArch() == Triple::aarch64_be ||
582 Obj->getArch() == Triple::arm || Obj->getArch() == Triple::armeb ||
583 Obj->getArch() == Triple::thumb ||
584 Obj->getArch() == Triple::thumbeb));
585}
586
George Rimar617adef2019-01-23 13:39:12 +0000587static void printRelocation(const RelocationRef &Rel, uint64_t Address,
588 uint8_t AddrSize) {
589 StringRef Fmt =
590 AddrSize > 4 ? "\t\t%016" PRIx64 ": " : "\t\t\t%08" PRIx64 ": ";
591 SmallString<16> Name;
592 SmallString<32> Val;
593 Rel.getTypeName(Name);
594 error(getRelocationValueString(Rel, Val));
595 outs() << format(Fmt.data(), Address) << Name << "\t" << Val << "\n";
596}
597
Sid Manningd9f28732018-05-14 19:46:08 +0000598class PrettyPrinter {
599public:
600 virtual ~PrettyPrinter() = default;
601 virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000602 ArrayRef<uint8_t> Bytes,
603 object::SectionedAddress Address, raw_ostream &OS,
604 StringRef Annot, MCSubtargetInfo const &STI,
605 SourcePrinter *SP,
Sid Manningd9f28732018-05-14 19:46:08 +0000606 std::vector<RelocationRef> *Rels = nullptr) {
607 if (SP && (PrintSource || PrintLines))
608 SP->printSourceLine(OS, Address);
609 if (!NoLeadingAddr)
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000610 OS << format("%8" PRIx64 ":", Address.Address);
Sid Manningd9f28732018-05-14 19:46:08 +0000611 if (!NoShowRawInsn) {
612 OS << "\t";
613 dumpBytes(Bytes, OS);
614 }
615 if (MI)
616 IP.printInst(MI, OS, "", STI);
617 else
618 OS << " <unknown>";
619 }
620};
621PrettyPrinter PrettyPrinterInst;
622class HexagonPrettyPrinter : public PrettyPrinter {
623public:
624 void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
625 raw_ostream &OS) {
626 uint32_t opcode =
627 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
628 if (!NoLeadingAddr)
629 OS << format("%8" PRIx64 ":", Address);
630 if (!NoShowRawInsn) {
631 OS << "\t";
632 dumpBytes(Bytes.slice(0, 4), OS);
633 OS << format("%08" PRIx32, opcode);
634 }
635 }
636 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000637 object::SectionedAddress Address, raw_ostream &OS,
638 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
Sid Manningd9f28732018-05-14 19:46:08 +0000639 std::vector<RelocationRef> *Rels) override {
640 if (SP && (PrintSource || PrintLines))
641 SP->printSourceLine(OS, Address, "");
642 if (!MI) {
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000643 printLead(Bytes, Address.Address, OS);
Sid Manningd9f28732018-05-14 19:46:08 +0000644 OS << " <unknown>";
645 return;
646 }
647 std::string Buffer;
648 {
649 raw_string_ostream TempStream(Buffer);
650 IP.printInst(MI, TempStream, "", STI);
651 }
652 StringRef Contents(Buffer);
653 // Split off bundle attributes
654 auto PacketBundle = Contents.rsplit('\n');
655 // Split off first instruction from the rest
656 auto HeadTail = PacketBundle.first.split('\n');
657 auto Preamble = " { ";
658 auto Separator = "";
Sid Manningd9f28732018-05-14 19:46:08 +0000659
660 // Hexagon's packets require relocations to be inline rather than
661 // clustered at the end of the packet.
George Rimar617adef2019-01-23 13:39:12 +0000662 std::vector<RelocationRef>::const_iterator RelCur = Rels->begin();
663 std::vector<RelocationRef>::const_iterator RelEnd = Rels->end();
Sid Manningd9f28732018-05-14 19:46:08 +0000664 auto PrintReloc = [&]() -> void {
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000665 while ((RelCur != RelEnd) && (RelCur->getOffset() <= Address.Address)) {
666 if (RelCur->getOffset() == Address.Address) {
667 printRelocation(*RelCur, Address.Address, 4);
Sid Manningd9f28732018-05-14 19:46:08 +0000668 return;
669 }
George Rimar73a27232019-01-15 09:19:18 +0000670 ++RelCur;
Sid Manningd9f28732018-05-14 19:46:08 +0000671 }
672 };
673
George Rimar73a27232019-01-15 09:19:18 +0000674 while (!HeadTail.first.empty()) {
Sid Manningd9f28732018-05-14 19:46:08 +0000675 OS << Separator;
676 Separator = "\n";
677 if (SP && (PrintSource || PrintLines))
678 SP->printSourceLine(OS, Address, "");
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000679 printLead(Bytes, Address.Address, OS);
Sid Manningd9f28732018-05-14 19:46:08 +0000680 OS << Preamble;
681 Preamble = " ";
682 StringRef Inst;
683 auto Duplex = HeadTail.first.split('\v');
George Rimar73a27232019-01-15 09:19:18 +0000684 if (!Duplex.second.empty()) {
Sid Manningd9f28732018-05-14 19:46:08 +0000685 OS << Duplex.first;
686 OS << "; ";
687 Inst = Duplex.second;
688 }
689 else
690 Inst = HeadTail.first;
691 OS << Inst;
692 HeadTail = HeadTail.second.split('\n');
693 if (HeadTail.first.empty())
694 OS << " } " << PacketBundle.second;
695 PrintReloc();
696 Bytes = Bytes.slice(4);
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000697 Address.Address += 4;
Sid Manningd9f28732018-05-14 19:46:08 +0000698 }
699 }
700};
701HexagonPrettyPrinter HexagonPrettyPrinterInst;
702
703class AMDGCNPrettyPrinter : public PrettyPrinter {
704public:
705 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000706 object::SectionedAddress Address, raw_ostream &OS,
707 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
Sid Manningd9f28732018-05-14 19:46:08 +0000708 std::vector<RelocationRef> *Rels) override {
709 if (SP && (PrintSource || PrintLines))
710 SP->printSourceLine(OS, Address);
711
712 typedef support::ulittle32_t U32;
713
714 if (MI) {
715 SmallString<40> InstStr;
716 raw_svector_ostream IS(InstStr);
717
718 IP.printInst(MI, IS, "", STI);
719
720 OS << left_justify(IS.str(), 60);
721 } else {
722 // an unrecognized encoding - this is probably data so represent it
723 // using the .long directive, or .byte directive if fewer than 4 bytes
724 // remaining
725 if (Bytes.size() >= 4) {
726 OS << format("\t.long 0x%08" PRIx32 " ",
727 static_cast<uint32_t>(*reinterpret_cast<const U32*>(Bytes.data())));
728 OS.indent(42);
729 } else {
730 OS << format("\t.byte 0x%02" PRIx8, Bytes[0]);
731 for (unsigned int i = 1; i < Bytes.size(); i++)
732 OS << format(", 0x%02" PRIx8, Bytes[i]);
733 OS.indent(55 - (6 * Bytes.size()));
734 }
735 }
736
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000737 OS << format("// %012" PRIX64 ": ", Address.Address);
Sid Manningd9f28732018-05-14 19:46:08 +0000738 if (Bytes.size() >=4) {
739 for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
740 Bytes.size() / sizeof(U32)))
741 // D should be explicitly casted to uint32_t here as it is passed
742 // by format to snprintf as vararg.
743 OS << format("%08" PRIX32 " ", static_cast<uint32_t>(D));
744 } else {
745 for (unsigned int i = 0; i < Bytes.size(); i++)
746 OS << format("%02" PRIX8 " ", Bytes[i]);
747 }
748
749 if (!Annot.empty())
750 OS << "// " << Annot;
751 }
752};
753AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
754
755class BPFPrettyPrinter : public PrettyPrinter {
756public:
757 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000758 object::SectionedAddress Address, raw_ostream &OS,
759 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
Sid Manningd9f28732018-05-14 19:46:08 +0000760 std::vector<RelocationRef> *Rels) override {
761 if (SP && (PrintSource || PrintLines))
762 SP->printSourceLine(OS, Address);
763 if (!NoLeadingAddr)
Alexey Lapshin77fc1f62019-02-27 13:17:36 +0000764 OS << format("%8" PRId64 ":", Address.Address / 8);
Sid Manningd9f28732018-05-14 19:46:08 +0000765 if (!NoShowRawInsn) {
766 OS << "\t";
767 dumpBytes(Bytes, OS);
768 }
769 if (MI)
770 IP.printInst(MI, OS, "", STI);
771 else
772 OS << " <unknown>";
773 }
774};
775BPFPrettyPrinter BPFPrettyPrinterInst;
776
777PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
778 switch(Triple.getArch()) {
779 default:
780 return PrettyPrinterInst;
781 case Triple::hexagon:
782 return HexagonPrettyPrinterInst;
783 case Triple::amdgcn:
784 return AMDGCNPrettyPrinterInst;
785 case Triple::bpfel:
786 case Triple::bpfeb:
787 return BPFPrettyPrinterInst;
788 }
789}
790}
791
Sam Koltonc05d7782016-08-17 10:17:57 +0000792static uint8_t getElfSymbolType(const ObjectFile *Obj, const SymbolRef &Sym) {
793 assert(Obj->isELF());
794 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
795 return Elf32LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
796 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
797 return Elf64LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
798 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
799 return Elf32BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
800 if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
801 return Elf64BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
802 llvm_unreachable("Unsupported binary format");
803}
804
Sam Parker5fba45a2017-02-08 09:44:18 +0000805template <class ELFT> static void
806addDynamicElfSymbols(const ELFObjectFile<ELFT> *Obj,
807 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
808 for (auto Symbol : Obj->getDynamicSymbolIterators()) {
809 uint8_t SymbolType = Symbol.getELFType();
810 if (SymbolType != ELF::STT_FUNC || Symbol.getSize() == 0)
811 continue;
812
Fangrui Songe7834bd2019-04-07 08:19:55 +0000813 uint64_t Address = unwrapOrError(Symbol.getAddress(), Obj->getFileName());
814 StringRef Name = unwrapOrError(Symbol.getName(), Obj->getFileName());
815 if (Name.empty())
Sam Parker5fba45a2017-02-08 09:44:18 +0000816 continue;
817
Fangrui Songe7834bd2019-04-07 08:19:55 +0000818 section_iterator SecI =
819 unwrapOrError(Symbol.getSection(), Obj->getFileName());
Sam Parker5fba45a2017-02-08 09:44:18 +0000820 if (SecI == Obj->section_end())
821 continue;
822
Fangrui Songe7834bd2019-04-07 08:19:55 +0000823 AllSymbols[*SecI].emplace_back(Address, Name, SymbolType);
Sam Parker5fba45a2017-02-08 09:44:18 +0000824 }
825}
826
827static void
828addDynamicElfSymbols(const ObjectFile *Obj,
829 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
830 assert(Obj->isELF());
831 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
832 addDynamicElfSymbols(Elf32LEObj, AllSymbols);
833 else if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
834 addDynamicElfSymbols(Elf64LEObj, AllSymbols);
835 else if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
836 addDynamicElfSymbols(Elf32BEObj, AllSymbols);
837 else if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
838 addDynamicElfSymbols(Elf64BEObj, AllSymbols);
839 else
840 llvm_unreachable("Unsupported binary format");
841}
842
Joel Galenson134cf472018-08-24 15:21:57 +0000843static void addPltEntries(const ObjectFile *Obj,
844 std::map<SectionRef, SectionSymbolsTy> &AllSymbols,
845 StringSaver &Saver) {
846 Optional<SectionRef> Plt = None;
847 for (const SectionRef &Section : Obj->sections()) {
848 StringRef Name;
849 if (Section.getName(Name))
850 continue;
851 if (Name == ".plt")
852 Plt = Section;
853 }
854 if (!Plt)
855 return;
856 if (auto *ElfObj = dyn_cast<ELFObjectFileBase>(Obj)) {
857 for (auto PltEntry : ElfObj->getPltAddresses()) {
858 SymbolRef Symbol(PltEntry.first, ElfObj);
Joel Galenson134cf472018-08-24 15:21:57 +0000859 uint8_t SymbolType = getElfSymbolType(Obj, Symbol);
860
Fangrui Songe7834bd2019-04-07 08:19:55 +0000861 StringRef Name = unwrapOrError(Symbol.getName(), Obj->getFileName());
862 if (!Name.empty())
863 AllSymbols[*Plt].emplace_back(
864 PltEntry.second, Saver.save((Name + "@plt").str()), SymbolType);
Joel Galenson134cf472018-08-24 15:21:57 +0000865 }
866 }
867}
868
George Rimar70d197d2019-01-10 14:55:26 +0000869// Normally the disassembly output will skip blocks of zeroes. This function
870// returns the number of zero bytes that can be skipped when dumping the
871// disassembly of the instructions in Buf.
872static size_t countSkippableZeroBytes(ArrayRef<uint8_t> Buf) {
George Rimar70d197d2019-01-10 14:55:26 +0000873 // Find the number of leading zeroes.
874 size_t N = 0;
875 while (N < Buf.size() && !Buf[N])
876 ++N;
877
878 // We may want to skip blocks of zero bytes, but unless we see
879 // at least 8 of them in a row.
880 if (N < 8)
881 return 0;
882
883 // We skip zeroes in multiples of 4 because do not want to truncate an
884 // instruction if it starts with a zero byte.
885 return N & ~0x3;
886}
887
George Rimar121fcd72019-01-22 14:09:37 +0000888// Returns a map from sections to their relocations.
889static std::map<SectionRef, std::vector<RelocationRef>>
890getRelocsMap(llvm::object::ObjectFile const &Obj) {
891 std::map<SectionRef, std::vector<RelocationRef>> Ret;
892 for (const SectionRef &Section : ToolSectionFilter(Obj)) {
893 section_iterator RelSec = Section.getRelocatedSection();
894 if (RelSec == Obj.section_end())
895 continue;
896 std::vector<RelocationRef> &V = Ret[*RelSec];
897 for (const RelocationRef &R : Section.relocations())
898 V.push_back(R);
899 // Sort relocations by address.
900 llvm::sort(V, isRelocAddressLess);
901 }
902 return Ret;
903}
904
George Rimar4c3b2972019-01-28 10:44:01 +0000905// Used for --adjust-vma to check if address should be adjusted by the
906// specified value for a given section.
907// For ELF we do not adjust non-allocatable sections like debug ones,
908// because they are not loadable.
909// TODO: implement for other file formats.
910static bool shouldAdjustVA(const SectionRef &Section) {
911 const ObjectFile *Obj = Section.getObject();
912 if (isa<object::ELFObjectFileBase>(Obj))
913 return ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC;
914 return false;
915}
916
George Rimarbcbe98b2019-01-23 10:33:26 +0000917static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
918 MCContext &Ctx, MCDisassembler *DisAsm,
919 const MCInstrAnalysis *MIA, MCInstPrinter *IP,
920 const MCSubtargetInfo *STI, PrettyPrinter &PIP,
921 SourcePrinter &SP, bool InlineRelocs) {
George Rimar121fcd72019-01-22 14:09:37 +0000922 std::map<SectionRef, std::vector<RelocationRef>> RelocMap;
923 if (InlineRelocs)
924 RelocMap = getRelocsMap(*Obj);
Mark Seaborn0929d3d2014-01-25 17:38:19 +0000925
David Majnemer81afca62015-07-07 22:06:59 +0000926 // Create a mapping from virtual address to symbol name. This is used to
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000927 // pretty print the symbols while disassembling.
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000928 std::map<SectionRef, SectionSymbolsTy> AllSymbols;
Sterling Augustinebc78b622018-06-28 18:57:13 +0000929 SectionSymbolsTy AbsoluteSymbols;
Fangrui Songe7834bd2019-04-07 08:19:55 +0000930 const StringRef FileName = Obj->getFileName();
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000931 for (const SymbolRef &Symbol : Obj->symbols()) {
Fangrui Songe7834bd2019-04-07 08:19:55 +0000932 uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName);
David Majnemer2603a8fa2015-07-09 18:11:40 +0000933
Fangrui Songe7834bd2019-04-07 08:19:55 +0000934 StringRef Name = unwrapOrError(Symbol.getName(), FileName);
935 if (Name.empty())
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000936 continue;
David Majnemer81afca62015-07-07 22:06:59 +0000937
Sam Koltonc05d7782016-08-17 10:17:57 +0000938 uint8_t SymbolType = ELF::STT_NOTYPE;
Matt Davis82937e42019-01-31 19:42:21 +0000939 if (Obj->isELF()) {
Sam Koltonc05d7782016-08-17 10:17:57 +0000940 SymbolType = getElfSymbolType(Obj, Symbol);
Matt Davis82937e42019-01-31 19:42:21 +0000941 if (SymbolType == ELF::STT_SECTION)
942 continue;
943 }
David Majnemer81afca62015-07-07 22:06:59 +0000944
Fangrui Songe7834bd2019-04-07 08:19:55 +0000945 section_iterator SecI = unwrapOrError(Symbol.getSection(), FileName);
Sterling Augustinebc78b622018-06-28 18:57:13 +0000946 if (SecI != Obj->section_end())
Fangrui Songe7834bd2019-04-07 08:19:55 +0000947 AllSymbols[*SecI].emplace_back(Address, Name, SymbolType);
Sterling Augustinebc78b622018-06-28 18:57:13 +0000948 else
Fangrui Songe7834bd2019-04-07 08:19:55 +0000949 AbsoluteSymbols.emplace_back(Address, Name, SymbolType);
David Majnemer81afca62015-07-07 22:06:59 +0000950 }
Sam Parker5fba45a2017-02-08 09:44:18 +0000951 if (AllSymbols.empty() && Obj->isELF())
952 addDynamicElfSymbols(Obj, AllSymbols);
David Majnemer81afca62015-07-07 22:06:59 +0000953
Joel Galenson134cf472018-08-24 15:21:57 +0000954 BumpPtrAllocator A;
955 StringSaver Saver(A);
956 addPltEntries(Obj, AllSymbols, Saver);
957
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000958 // Create a mapping from virtual address to section.
959 std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
960 for (SectionRef Sec : Obj->sections())
961 SectionAddresses.emplace_back(Sec.getAddress(), Sec);
962 array_pod_sort(SectionAddresses.begin(), SectionAddresses.end());
963
964 // Linked executables (.exe and .dll files) typically don't include a real
965 // symbol table but they might contain an export table.
966 if (const auto *COFFObj = dyn_cast<COFFObjectFile>(Obj)) {
967 for (const auto &ExportEntry : COFFObj->export_directories()) {
968 StringRef Name;
969 error(ExportEntry.getSymbolName(Name));
970 if (Name.empty())
971 continue;
972 uint32_t RVA;
973 error(ExportEntry.getExportRVA(RVA));
974
975 uint64_t VA = COFFObj->getImageBase() + RVA;
Fangrui Song545ed222019-04-07 05:32:16 +0000976 auto Sec = llvm::upper_bound(
977 SectionAddresses, VA,
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000978 [](uint64_t LHS, const std::pair<uint64_t, SectionRef> &RHS) {
979 return LHS < RHS.first;
980 });
Fangrui Song545ed222019-04-07 05:32:16 +0000981 if (Sec != SectionAddresses.begin()) {
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000982 --Sec;
Sam Koltonc05d7782016-08-17 10:17:57 +0000983 AllSymbols[Sec->second].emplace_back(VA, Name, ELF::STT_NOTYPE);
Fangrui Song545ed222019-04-07 05:32:16 +0000984 } else
Sterling Augustinebc78b622018-06-28 18:57:13 +0000985 AbsoluteSymbols.emplace_back(VA, Name, ELF::STT_NOTYPE);
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000986 }
987 }
988
989 // Sort all the symbols, this allows us to use a simple binary search to find
990 // a symbol near an address.
991 for (std::pair<const SectionRef, SectionSymbolsTy> &SecSyms : AllSymbols)
992 array_pod_sort(SecSyms.second.begin(), SecSyms.second.end());
Sterling Augustinebc78b622018-06-28 18:57:13 +0000993 array_pod_sort(AbsoluteSymbols.begin(), AbsoluteSymbols.end());
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000994
Colin LeMahieu77804be2015-07-29 15:45:39 +0000995 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Colin LeMahieuf34933e2015-07-23 20:58:49 +0000996 if (!DisassembleAll && (!Section.isText() || Section.isVirtual()))
Mark Seaborneb03ac52014-01-25 00:32:01 +0000997 continue;
Michael J. Spencer1d6167f2011-06-25 17:55:23 +0000998
Rafael Espindola80291272014-10-08 15:28:58 +0000999 uint64_t SectionAddr = Section.getAddress();
1000 uint64_t SectSize = Section.getSize();
David Majnemer185b5b12014-11-11 09:58:25 +00001001 if (!SectSize)
1002 continue;
Simon Atanasyan2b614e12014-02-24 22:12:11 +00001003
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001004 // Get the list of all the symbols in this section.
1005 SectionSymbolsTy &Symbols = AllSymbols[Section];
Davide Italianof0706882015-10-01 21:57:09 +00001006 std::vector<uint64_t> DataMappingSymsAddr;
1007 std::vector<uint64_t> TextMappingSymsAddr;
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001008 if (isArmElf(Obj)) {
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001009 for (const auto &Symb : Symbols) {
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001010 uint64_t Address = std::get<0>(Symb);
1011 StringRef Name = std::get<1>(Symb);
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001012 if (Name.startswith("$d"))
David Majnemer153722d2015-11-18 04:35:32 +00001013 DataMappingSymsAddr.push_back(Address - SectionAddr);
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001014 if (Name.startswith("$x"))
David Majnemer153722d2015-11-18 04:35:32 +00001015 TextMappingSymsAddr.push_back(Address - SectionAddr);
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001016 if (Name.startswith("$a"))
1017 TextMappingSymsAddr.push_back(Address - SectionAddr);
1018 if (Name.startswith("$t"))
1019 TextMappingSymsAddr.push_back(Address - SectionAddr);
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001020 }
1021 }
1022
Fangrui Song0cac7262018-09-27 02:13:45 +00001023 llvm::sort(DataMappingSymsAddr);
1024 llvm::sort(TextMappingSymsAddr);
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001025
Sam Kolton3381d7a2016-10-06 13:46:08 +00001026 if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
1027 // AMDGPU disassembler uses symbolizer for printing labels
1028 std::unique_ptr<MCRelocationInfo> RelInfo(
1029 TheTarget->createMCRelocationInfo(TripleName, Ctx));
1030 if (RelInfo) {
1031 std::unique_ptr<MCSymbolizer> Symbolizer(
1032 TheTarget->createMCSymbolizer(
1033 TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo)));
1034 DisAsm->setSymbolizer(std::move(Symbolizer));
1035 }
1036 }
1037
Rafael Espindolaa9f810b2012-12-21 03:47:03 +00001038 StringRef SegmentName = "";
Mark Seaborneb03ac52014-01-25 00:32:01 +00001039 if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
Alexey Samsonov48803e52014-03-13 14:37:36 +00001040 DataRefImpl DR = Section.getRawDataRefImpl();
Rafael Espindola56f976f2013-04-18 18:08:55 +00001041 SegmentName = MachO->getSectionFinalSegmentName(DR);
Rafael Espindolaa9f810b2012-12-21 03:47:03 +00001042 }
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001043 StringRef SectionName;
1044 error(Section.getName(SectionName));
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001045
Rafael Espindola7884c952015-06-04 15:01:05 +00001046 // If the section has no symbol at the start, just insert a dummy one.
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001047 if (Symbols.empty() || std::get<0>(Symbols[0]) != 0) {
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001048 Symbols.insert(
1049 Symbols.begin(),
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001050 std::make_tuple(SectionAddr, SectionName,
1051 Section.isText() ? ELF::STT_FUNC : ELF::STT_OBJECT));
Sam Koltonc05d7782016-08-17 10:17:57 +00001052 }
Alp Tokere69170a2014-06-26 22:52:05 +00001053
1054 SmallString<40> Comments;
1055 raw_svector_ostream CommentStream(Comments);
Ahmed Bougachaad1084d2013-05-24 00:39:57 +00001056
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001057 StringRef BytesStr;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001058 error(Section.getContents(BytesStr));
Fangrui Song6a0746a2019-04-07 03:58:42 +00001059 ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(BytesStr);
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001060
George Rimar4c3b2972019-01-28 10:44:01 +00001061 uint64_t VMAAdjustment = 0;
1062 if (shouldAdjustVA(Section))
1063 VMAAdjustment = AdjustVMA;
1064
Michael J. Spencer2670c252011-01-20 06:39:06 +00001065 uint64_t Size;
1066 uint64_t Index;
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001067 bool PrintedSection = false;
George Rimar121fcd72019-01-22 14:09:37 +00001068 std::vector<RelocationRef> Rels = RelocMap[Section];
George Rimar73a27232019-01-15 09:19:18 +00001069 std::vector<RelocationRef>::const_iterator RelCur = Rels.begin();
1070 std::vector<RelocationRef>::const_iterator RelEnd = Rels.end();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001071 // Disassemble symbol by symbol.
George Rimar73a27232019-01-15 09:19:18 +00001072 for (unsigned SI = 0, SE = Symbols.size(); SI != SE; ++SI) {
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001073 uint64_t Start = std::get<0>(Symbols[SI]) - SectionAddr;
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001074 // The end is either the section end or the beginning of the next
1075 // symbol.
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001076 uint64_t End = (SI == SE - 1)
1077 ? SectSize
1078 : std::get<0>(Symbols[SI + 1]) - SectionAddr;
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001079 // Don't try to disassemble beyond the end of section contents.
1080 if (End > SectSize)
1081 End = SectSize;
Rafael Espindolae45c7402014-08-17 16:31:39 +00001082 // If this symbol has the same address as the next symbol, then skip it.
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001083 if (Start >= End)
Michael J. Spenceree84f642011-10-13 20:37:08 +00001084 continue;
1085
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001086 // Check if we need to skip symbol
1087 // Skip if the symbol's data is not between StartAddress and StopAddress
1088 if (End + SectionAddr < StartAddress ||
1089 Start + SectionAddr > StopAddress) {
1090 continue;
1091 }
1092
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001093 /// Skip if user requested specific symbols and this is not in the list
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001094 if (!DisasmFuncsSet.empty() &&
1095 !DisasmFuncsSet.count(std::get<1>(Symbols[SI])))
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001096 continue;
1097
1098 if (!PrintedSection) {
1099 PrintedSection = true;
1100 outs() << "Disassembly of section ";
1101 if (!SegmentName.empty())
1102 outs() << SegmentName << ",";
1103 outs() << SectionName << ':';
1104 }
1105
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001106 // Stop disassembly at the stop address specified
1107 if (End + SectionAddr > StopAddress)
1108 End = StopAddress - SectionAddr;
1109
Valery Pykhtinde048052016-04-07 07:24:01 +00001110 if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001111 if (std::get<2>(Symbols[SI]) == ELF::STT_AMDGPU_HSA_KERNEL) {
Sam Koltonc05d7782016-08-17 10:17:57 +00001112 // skip amd_kernel_code_t at the begining of kernel symbol (256 bytes)
1113 Start += 256;
1114 }
George Rimar73a27232019-01-15 09:19:18 +00001115 if (SI == SE - 1 ||
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001116 std::get<2>(Symbols[SI + 1]) == ELF::STT_AMDGPU_HSA_KERNEL) {
Sam Koltonc05d7782016-08-17 10:17:57 +00001117 // cut trailing zeroes at the end of kernel
1118 // cut up to 256 bytes
1119 const uint64_t EndAlign = 256;
1120 const auto Limit = End - (std::min)(EndAlign, End - Start);
1121 while (End > Limit &&
1122 *reinterpret_cast<const support::ulittle32_t*>(&Bytes[End - 4]) == 0)
1123 End -= 4;
1124 }
Valery Pykhtinde048052016-04-07 07:24:01 +00001125 }
1126
George Rimar6622d412018-12-19 10:21:45 +00001127 outs() << '\n';
George Rimar3ba0f3c02019-01-09 14:43:33 +00001128 if (!NoLeadingAddr)
George Rimar4c3b2972019-01-28 10:44:01 +00001129 outs() << format("%016" PRIx64 " ",
1130 SectionAddr + Start + VMAAdjustment);
George Rimar3ba0f3c02019-01-09 14:43:33 +00001131
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001132 StringRef SymbolName = std::get<1>(Symbols[SI]);
George Rimar6622d412018-12-19 10:21:45 +00001133 if (Demangle)
1134 outs() << demangle(SymbolName) << ":\n";
1135 else
1136 outs() << SymbolName << ":\n";
Michael J. Spencer2670c252011-01-20 06:39:06 +00001137
Francis Visoiu Mistrih18346822018-04-19 17:02:57 +00001138 // Don't print raw contents of a virtual section. A virtual section
1139 // doesn't have any contents in the file.
1140 if (Section.isVirtual()) {
1141 outs() << "...\n";
1142 continue;
1143 }
1144
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001145#ifndef NDEBUG
Mark Seaborneb03ac52014-01-25 00:32:01 +00001146 raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001147#else
Mark Seaborneb03ac52014-01-25 00:32:01 +00001148 raw_ostream &DebugOut = nulls();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001149#endif
1150
Wouter van Oortmerssenf3b762a2019-01-17 18:14:09 +00001151 // Some targets (like WebAssembly) have a special prelude at the start
1152 // of each symbol.
1153 DisAsm->onSymbolStart(SymbolName, Size, Bytes.slice(Start, End - Start),
1154 SectionAddr + Start, DebugOut, CommentStream);
1155 Start += Size;
1156
Benjamin Kramer43a772e2011-09-19 17:56:04 +00001157 for (Index = Start; Index < End; Index += Size) {
1158 MCInst Inst;
Owen Andersona0c3b972011-09-15 23:38:46 +00001159
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001160 if (Index + SectionAddr < StartAddress ||
1161 Index + SectionAddr > StopAddress) {
1162 // skip byte by byte till StartAddress is reached
1163 Size = 1;
1164 continue;
1165 }
Davide Italianof0706882015-10-01 21:57:09 +00001166 // AArch64 ELF binaries can interleave data and text in the
1167 // same section. We rely on the markers introduced to
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001168 // understand what we need to dump. If the data marker is within a
1169 // function, it is denoted as a word/short etc
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001170 if (isArmElf(Obj) && std::get<2>(Symbols[SI]) != ELF::STT_OBJECT &&
Fangrui Song545ed222019-04-07 05:32:16 +00001171 !DisassembleAll &&
1172 std::binary_search(DataMappingSymsAddr.begin(),
1173 DataMappingSymsAddr.end(), Index)) {
1174 // Switch to data.
1175 support::endianness Endian =
1176 Obj->isLittleEndian() ? support::little : support::big;
1177 while (Index < End) {
1178 outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1179 outs() << "\t";
1180 if (Index + 4 <= End) {
1181 dumpBytes(Bytes.slice(Index, 4), outs());
1182 outs() << "\t.word\t"
1183 << format_hex(support::endian::read32(Bytes.data() + Index,
1184 Endian),
1185 10);
1186 Index += 4;
1187 } else if (Index + 2 <= End) {
1188 dumpBytes(Bytes.slice(Index, 2), outs());
1189 outs() << "\t\t.short\t"
1190 << format_hex(support::endian::read16(Bytes.data() + Index,
1191 Endian),
1192 6);
1193 Index += 2;
1194 } else {
1195 dumpBytes(Bytes.slice(Index, 1), outs());
1196 outs() << "\t\t.byte\t" << format_hex(Bytes[0], 4);
1197 ++Index;
Davide Italianof0706882015-10-01 21:57:09 +00001198 }
Fangrui Song545ed222019-04-07 05:32:16 +00001199 outs() << "\n";
1200 if (std::binary_search(TextMappingSymsAddr.begin(),
1201 TextMappingSymsAddr.end(), Index))
1202 break;
Davide Italianof0706882015-10-01 21:57:09 +00001203 }
1204 }
1205
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001206 // If there is a data symbol inside an ELF text section and we are only
1207 // disassembling text (applicable all architectures),
1208 // we are in a situation where we must print the data and not
1209 // disassemble it.
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001210 if (Obj->isELF() && std::get<2>(Symbols[SI]) == ELF::STT_OBJECT &&
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001211 !DisassembleAll && Section.isText()) {
1212 // print out data up to 8 bytes at a time in hex and ascii
1213 uint8_t AsciiData[9] = {'\0'};
1214 uint8_t Byte;
1215 int NumBytes = 0;
1216
1217 for (Index = Start; Index < End; Index += 1) {
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001218 if (((SectionAddr + Index) < StartAddress) ||
1219 ((SectionAddr + Index) > StopAddress))
1220 continue;
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001221 if (NumBytes == 0) {
1222 outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1223 outs() << "\t";
1224 }
1225 Byte = Bytes.slice(Index)[0];
1226 outs() << format(" %02x", Byte);
Michael Kruse6f1da6e2018-07-26 15:31:41 +00001227 AsciiData[NumBytes] = isPrint(Byte) ? Byte : '.';
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001228
1229 uint8_t IndentOffset = 0;
1230 NumBytes++;
1231 if (Index == End - 1 || NumBytes > 8) {
1232 // Indent the space for less than 8 bytes data.
1233 // 2 spaces for byte and one for space between bytes
1234 IndentOffset = 3 * (8 - NumBytes);
Sid Manning5d9c8ad2019-02-01 19:11:47 +00001235 for (int Excess = NumBytes; Excess < 8; Excess++)
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001236 AsciiData[Excess] = '\0';
1237 NumBytes = 8;
1238 }
1239 if (NumBytes == 8) {
1240 AsciiData[8] = '\0';
1241 outs() << std::string(IndentOffset, ' ') << " ";
1242 outs() << reinterpret_cast<char *>(AsciiData);
1243 outs() << '\n';
1244 NumBytes = 0;
1245 }
1246 }
1247 }
Davide Italianof0706882015-10-01 21:57:09 +00001248 if (Index >= End)
1249 break;
1250
George Rimarc5f29202019-02-19 12:38:36 +00001251 // When -z or --disassemble-zeroes are given we always dissasemble them.
1252 // Otherwise we might want to skip zero bytes we see.
1253 if (!DisassembleZeroes) {
1254 uint64_t MaxOffset = End - Index;
1255 // For -reloc: print zero blocks patched by relocations, so that
1256 // relocations can be shown in the dump.
1257 if (RelCur != RelEnd)
1258 MaxOffset = RelCur->getOffset() - Index;
1259
1260 if (size_t N =
1261 countSkippableZeroBytes(Bytes.slice(Index, MaxOffset))) {
1262 outs() << "\t\t..." << '\n';
1263 Index += N;
1264 if (Index >= End)
1265 break;
1266 }
George Rimar70d197d2019-01-10 14:55:26 +00001267 }
1268
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001269 // Disassemble a real instruction or a data when disassemble all is
1270 // provided
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001271 bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
1272 SectionAddr + Index, DebugOut,
1273 CommentStream);
1274 if (Size == 0)
1275 Size = 1;
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +00001276
Alexey Lapshin77fc1f62019-02-27 13:17:36 +00001277 PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
1278 Bytes.slice(Index, Size),
1279 {SectionAddr + Index + VMAAdjustment, Section.getIndex()},
1280 outs(), "", *STI, &SP, &Rels);
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001281 outs() << CommentStream.str();
1282 Comments.clear();
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001283
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001284 // Try to resolve the target of a call, tail call, etc. to a specific
1285 // symbol.
1286 if (MIA && (MIA->isCall(Inst) || MIA->isUnconditionalBranch(Inst) ||
1287 MIA->isConditionalBranch(Inst))) {
1288 uint64_t Target;
1289 if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
1290 // In a relocatable object, the target's section must reside in
1291 // the same section as the call instruction or it is accessed
1292 // through a relocation.
1293 //
1294 // In a non-relocatable object, the target may be in any section.
1295 //
1296 // N.B. We don't walk the relocations in the relocatable case yet.
1297 auto *TargetSectionSymbols = &Symbols;
1298 if (!Obj->isRelocatableObject()) {
Fangrui Song545ed222019-04-07 05:32:16 +00001299 auto SectionAddress = llvm::upper_bound(
1300 SectionAddresses, Target,
1301 [](uint64_t LHS, const std::pair<uint64_t, SectionRef> &RHS) {
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001302 return LHS < RHS.first;
1303 });
1304 if (SectionAddress != SectionAddresses.begin()) {
1305 --SectionAddress;
1306 TargetSectionSymbols = &AllSymbols[SectionAddress->second];
1307 } else {
Sterling Augustinebc78b622018-06-28 18:57:13 +00001308 TargetSectionSymbols = &AbsoluteSymbols;
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001309 }
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001310 }
David Majnemer2603a8fa2015-07-09 18:11:40 +00001311
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001312 // Find the first symbol in the section whose offset is less than
Sterling Augustinebc78b622018-06-28 18:57:13 +00001313 // or equal to the target. If there isn't a section that contains
1314 // the target, find the nearest preceding absolute symbol.
Fangrui Song545ed222019-04-07 05:32:16 +00001315 auto TargetSym = llvm::upper_bound(
1316 *TargetSectionSymbols, Target,
1317 [](uint64_t LHS,
1318 const std::tuple<uint64_t, StringRef, uint8_t> &RHS) {
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001319 return LHS < std::get<0>(RHS);
Sterling Augustinebc78b622018-06-28 18:57:13 +00001320 });
1321 if (TargetSym == TargetSectionSymbols->begin()) {
1322 TargetSectionSymbols = &AbsoluteSymbols;
Fangrui Song545ed222019-04-07 05:32:16 +00001323 TargetSym = llvm::upper_bound(
1324 AbsoluteSymbols, Target,
1325 [](uint64_t LHS,
1326 const std::tuple<uint64_t, StringRef, uint8_t> &RHS) {
1327 return LHS < std::get<0>(RHS);
1328 });
Sterling Augustinebc78b622018-06-28 18:57:13 +00001329 }
1330 if (TargetSym != TargetSectionSymbols->begin()) {
1331 --TargetSym;
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001332 uint64_t TargetAddress = std::get<0>(*TargetSym);
1333 StringRef TargetName = std::get<1>(*TargetSym);
1334 outs() << " <" << TargetName;
1335 uint64_t Disp = Target - TargetAddress;
Sterling Augustinebc78b622018-06-28 18:57:13 +00001336 if (Disp)
1337 outs() << "+0x" << Twine::utohexstr(Disp);
1338 outs() << '>';
David Majnemer81afca62015-07-07 22:06:59 +00001339 }
1340 }
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001341 }
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001342 outs() << "\n";
Michael J. Spencer51862b32011-10-13 22:17:18 +00001343
Sid Manningd9f28732018-05-14 19:46:08 +00001344 // Hexagon does this in pretty printer
George Rimarfd383e72019-01-23 10:52:38 +00001345 if (Obj->getArch() != Triple::hexagon) {
Sid Manningd9f28732018-05-14 19:46:08 +00001346 // Print relocation for instruction.
George Rimar73a27232019-01-15 09:19:18 +00001347 while (RelCur != RelEnd) {
George Rimar617adef2019-01-23 13:39:12 +00001348 uint64_t Offset = RelCur->getOffset();
Sid Manningd9f28732018-05-14 19:46:08 +00001349 // If this relocation is hidden, skip it.
George Rimar617adef2019-01-23 13:39:12 +00001350 if (getHidden(*RelCur) || ((SectionAddr + Offset) < StartAddress)) {
George Rimar73a27232019-01-15 09:19:18 +00001351 ++RelCur;
Sid Manningd9f28732018-05-14 19:46:08 +00001352 continue;
1353 }
1354
George Rimar740974d2019-01-28 10:48:54 +00001355 // Stop when RelCur's offset is past the current instruction.
George Rimar617adef2019-01-23 13:39:12 +00001356 if (Offset >= Index + Size)
George Rimar73a27232019-01-15 09:19:18 +00001357 break;
George Rimar617adef2019-01-23 13:39:12 +00001358
George Rimar4c3b2972019-01-28 10:44:01 +00001359 // When --adjust-vma is used, update the address printed.
1360 if (RelCur->getSymbol() != Obj->symbol_end()) {
1361 Expected<section_iterator> SymSI =
1362 RelCur->getSymbol()->getSection();
1363 if (SymSI && *SymSI != Obj->section_end() &&
1364 (shouldAdjustVA(**SymSI)))
1365 Offset += AdjustVMA;
1366 }
1367
George Rimar617adef2019-01-23 13:39:12 +00001368 printRelocation(*RelCur, SectionAddr + Offset,
1369 Obj->getBytesInAddress());
George Rimar73a27232019-01-15 09:19:18 +00001370 ++RelCur;
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001371 }
George Rimarfd383e72019-01-23 10:52:38 +00001372 }
Benjamin Kramer87ee76c2011-07-20 19:37:35 +00001373 }
Michael J. Spencer2670c252011-01-20 06:39:06 +00001374 }
1375 }
1376}
1377
George Rimarbcbe98b2019-01-23 10:33:26 +00001378static void disassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
1379 if (StartAddress > StopAddress)
1380 error("Start address should be less than stop address");
1381
1382 const Target *TheTarget = getTarget(Obj);
1383
1384 // Package up features to be passed to target/subtarget
1385 SubtargetFeatures Features = Obj->getFeatures();
1386 if (!MAttrs.empty())
1387 for (unsigned I = 0; I != MAttrs.size(); ++I)
1388 Features.AddFeature(MAttrs[I]);
1389
1390 std::unique_ptr<const MCRegisterInfo> MRI(
1391 TheTarget->createMCRegInfo(TripleName));
1392 if (!MRI)
1393 report_error(Obj->getFileName(),
1394 "no register info for target " + TripleName);
1395
1396 // Set up disassembler.
1397 std::unique_ptr<const MCAsmInfo> AsmInfo(
1398 TheTarget->createMCAsmInfo(*MRI, TripleName));
1399 if (!AsmInfo)
1400 report_error(Obj->getFileName(),
1401 "no assembly info for target " + TripleName);
1402 std::unique_ptr<const MCSubtargetInfo> STI(
1403 TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
1404 if (!STI)
1405 report_error(Obj->getFileName(),
1406 "no subtarget info for target " + TripleName);
1407 std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
1408 if (!MII)
1409 report_error(Obj->getFileName(),
1410 "no instruction info for target " + TripleName);
1411 MCObjectFileInfo MOFI;
1412 MCContext Ctx(AsmInfo.get(), MRI.get(), &MOFI);
1413 // FIXME: for now initialize MCObjectFileInfo with default values
1414 MOFI.InitMCObjectFileInfo(Triple(TripleName), false, Ctx);
1415
1416 std::unique_ptr<MCDisassembler> DisAsm(
1417 TheTarget->createMCDisassembler(*STI, Ctx));
1418 if (!DisAsm)
1419 report_error(Obj->getFileName(),
1420 "no disassembler for target " + TripleName);
1421
1422 std::unique_ptr<const MCInstrAnalysis> MIA(
1423 TheTarget->createMCInstrAnalysis(MII.get()));
1424
1425 int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
1426 std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
1427 Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
1428 if (!IP)
1429 report_error(Obj->getFileName(),
1430 "no instruction printer for target " + TripleName);
1431 IP->setPrintImmHex(PrintImmHex);
1432
1433 PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
1434 SourcePrinter SP(Obj, TheTarget->getName());
1435
Igor Kudrin2d3faad2019-02-26 12:15:14 +00001436 for (StringRef Opt : DisassemblerOptions)
1437 if (!IP->applyTargetSpecificCLOption(Opt))
1438 error("Unrecognized disassembler option: " + Opt);
1439
George Rimarbcbe98b2019-01-23 10:33:26 +00001440 disassembleObject(TheTarget, Obj, Ctx, DisAsm.get(), MIA.get(), IP.get(),
1441 STI.get(), PIP, SP, InlineRelocs);
1442}
1443
George Rimar73a27232019-01-15 09:19:18 +00001444void llvm::printRelocations(const ObjectFile *Obj) {
Greg Fitzgerald18432272014-03-20 22:55:15 +00001445 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
1446 "%08" PRIx64;
Rafael Espindola9219fe72016-03-21 20:59:15 +00001447 // Regular objdump doesn't print relocations in non-relocatable object
1448 // files.
1449 if (!Obj->isRelocatableObject())
1450 return;
Rafael Espindolac66d7612014-08-17 19:09:37 +00001451
Colin LeMahieu77804be2015-07-29 15:45:39 +00001452 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Alexey Samsonov48803e52014-03-13 14:37:36 +00001453 if (Section.relocation_begin() == Section.relocation_end())
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001454 continue;
George Rimar73a27232019-01-15 09:19:18 +00001455 StringRef SecName;
1456 error(Section.getName(SecName));
1457 outs() << "RELOCATION RECORDS FOR [" << SecName << "]:\n";
Alexey Samsonovaa4d2952014-03-14 14:22:49 +00001458 for (const RelocationRef &Reloc : Section.relocations()) {
George Rimar73a27232019-01-15 09:19:18 +00001459 uint64_t Address = Reloc.getOffset();
1460 SmallString<32> RelocName;
1461 SmallString<32> ValueStr;
1462 if (Address < StartAddress || Address > StopAddress || getHidden(Reloc))
Alexey Samsonovaa4d2952014-03-14 14:22:49 +00001463 continue;
George Rimar73a27232019-01-15 09:19:18 +00001464 Reloc.getTypeName(RelocName);
1465 error(getRelocationValueString(Reloc, ValueStr));
1466 outs() << format(Fmt.data(), Address) << " " << RelocName << " "
1467 << ValueStr << "\n";
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001468 }
1469 outs() << "\n";
1470 }
1471}
1472
George Rimar73a27232019-01-15 09:19:18 +00001473void llvm::printDynamicRelocations(const ObjectFile *Obj) {
Paul Semelcb0f0432018-06-07 13:30:55 +00001474 // For the moment, this option is for ELF only
1475 if (!Obj->isELF())
1476 return;
1477
1478 const auto *Elf = dyn_cast<ELFObjectFileBase>(Obj);
Paul Semelcb0f0432018-06-07 13:30:55 +00001479 if (!Elf || Elf->getEType() != ELF::ET_DYN) {
1480 error("not a dynamic object");
1481 return;
1482 }
1483
Paul Semelcb0f0432018-06-07 13:30:55 +00001484 std::vector<SectionRef> DynRelSec = Obj->dynamic_relocation_sections();
1485 if (DynRelSec.empty())
1486 return;
1487
1488 outs() << "DYNAMIC RELOCATION RECORDS\n";
George Rimar73a27232019-01-15 09:19:18 +00001489 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
Paul Semelcb0f0432018-06-07 13:30:55 +00001490 for (const SectionRef &Section : DynRelSec) {
1491 if (Section.relocation_begin() == Section.relocation_end())
1492 continue;
1493 for (const RelocationRef &Reloc : Section.relocations()) {
George Rimar73a27232019-01-15 09:19:18 +00001494 uint64_t Address = Reloc.getOffset();
1495 SmallString<32> RelocName;
1496 SmallString<32> ValueStr;
1497 Reloc.getTypeName(RelocName);
1498 error(getRelocationValueString(Reloc, ValueStr));
1499 outs() << format(Fmt.data(), Address) << " " << RelocName << " "
1500 << ValueStr << "\n";
Paul Semelcb0f0432018-06-07 13:30:55 +00001501 }
1502 }
1503}
1504
George Rimar87fa2e62019-01-28 14:11:35 +00001505// Returns true if we need to show LMA column when dumping section headers. We
1506// show it only when the platform is ELF and either we have at least one section
1507// whose VMA and LMA are different and/or when --show-lma flag is used.
1508static bool shouldDisplayLMA(const ObjectFile *Obj) {
1509 if (!Obj->isELF())
1510 return false;
1511 for (const SectionRef &S : ToolSectionFilter(*Obj))
1512 if (S.getAddress() != getELFSectionLMA(S))
1513 return true;
1514 return ShowLMA;
1515}
1516
George Rimar73a27232019-01-15 09:19:18 +00001517void llvm::printSectionHeaders(const ObjectFile *Obj) {
George Rimar87fa2e62019-01-28 14:11:35 +00001518 bool HasLMAColumn = shouldDisplayLMA(Obj);
1519 if (HasLMAColumn)
1520 outs() << "Sections:\n"
1521 "Idx Name Size VMA LMA "
1522 "Type\n";
1523 else
1524 outs() << "Sections:\n"
1525 "Idx Name Size VMA Type\n";
1526
Colin LeMahieu77804be2015-07-29 15:45:39 +00001527 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001528 StringRef Name;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001529 error(Section.getName(Name));
George Rimar87fa2e62019-01-28 14:11:35 +00001530 uint64_t VMA = Section.getAddress();
George Rimar4463ebe2019-01-28 16:36:12 +00001531 if (shouldAdjustVA(Section))
1532 VMA += AdjustVMA;
1533
Rafael Espindola80291272014-10-08 15:28:58 +00001534 uint64_t Size = Section.getSize();
1535 bool Text = Section.isText();
1536 bool Data = Section.isData();
1537 bool BSS = Section.isBSS();
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001538 std::string Type = (std::string(Text ? "TEXT " : "") +
Michael J. Spencer8f67d472011-10-13 20:37:20 +00001539 (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
George Rimar87fa2e62019-01-28 14:11:35 +00001540
1541 if (HasLMAColumn)
1542 outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %016" PRIx64
1543 " %s\n",
1544 (unsigned)Section.getIndex(), Name.str().c_str(), Size,
1545 VMA, getELFSectionLMA(Section), Type.c_str());
1546 else
1547 outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
1548 (unsigned)Section.getIndex(), Name.str().c_str(), Size,
1549 VMA, Type.c_str());
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001550 }
Xing GUO785edea2018-11-17 08:12:48 +00001551 outs() << "\n";
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001552}
1553
George Rimar73a27232019-01-15 09:19:18 +00001554void llvm::printSectionContents(const ObjectFile *Obj) {
Rafael Espindola4453e42942014-06-13 03:07:50 +00001555 std::error_code EC;
Colin LeMahieu77804be2015-07-29 15:45:39 +00001556 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001557 StringRef Name;
1558 StringRef Contents;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001559 error(Section.getName(Name));
Rafael Espindola80291272014-10-08 15:28:58 +00001560 uint64_t BaseAddr = Section.getAddress();
David Majnemer185b5b12014-11-11 09:58:25 +00001561 uint64_t Size = Section.getSize();
1562 if (!Size)
1563 continue;
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001564
1565 outs() << "Contents of section " << Name << ":\n";
David Majnemer185b5b12014-11-11 09:58:25 +00001566 if (Section.isBSS()) {
Alexey Samsonov209095c2013-04-16 10:53:11 +00001567 outs() << format("<skipping contents of bss section at [%04" PRIx64
David Majnemer8f6b04c2014-07-14 16:20:14 +00001568 ", %04" PRIx64 ")>\n",
1569 BaseAddr, BaseAddr + Size);
Alexey Samsonov209095c2013-04-16 10:53:11 +00001570 continue;
1571 }
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001572
Davide Italianoccd53fe2015-08-05 07:18:31 +00001573 error(Section.getContents(Contents));
David Majnemer8f6b04c2014-07-14 16:20:14 +00001574
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001575 // Dump out the content as hex and printable ascii characters.
George Rimar73a27232019-01-15 09:19:18 +00001576 for (std::size_t Addr = 0, End = Contents.size(); Addr < End; Addr += 16) {
1577 outs() << format(" %04" PRIx64 " ", BaseAddr + Addr);
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001578 // Dump line of hex.
George Rimar73a27232019-01-15 09:19:18 +00001579 for (std::size_t I = 0; I < 16; ++I) {
1580 if (I != 0 && I % 4 == 0)
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001581 outs() << ' ';
George Rimar73a27232019-01-15 09:19:18 +00001582 if (Addr + I < End)
1583 outs() << hexdigit((Contents[Addr + I] >> 4) & 0xF, true)
1584 << hexdigit(Contents[Addr + I] & 0xF, true);
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001585 else
1586 outs() << " ";
1587 }
1588 // Print ascii.
1589 outs() << " ";
George Rimar73a27232019-01-15 09:19:18 +00001590 for (std::size_t I = 0; I < 16 && Addr + I < End; ++I) {
1591 if (isPrint(static_cast<unsigned char>(Contents[Addr + I]) & 0xFF))
1592 outs() << Contents[Addr + I];
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001593 else
1594 outs() << ".";
1595 }
1596 outs() << "\n";
1597 }
1598 }
1599}
1600
George Rimar73a27232019-01-15 09:19:18 +00001601void llvm::printSymbolTable(const ObjectFile *O, StringRef ArchiveName,
Kevin Enderby9acb1092016-05-31 20:35:34 +00001602 StringRef ArchitectureName) {
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001603 outs() << "SYMBOL TABLE:\n";
1604
George Rimar73a27232019-01-15 09:19:18 +00001605 if (const COFFObjectFile *Coff = dyn_cast<const COFFObjectFile>(O)) {
1606 printCOFFSymbolTable(Coff);
Rui Ueyama4e39f712014-03-18 18:58:51 +00001607 return;
1608 }
George Rimar8e0a70b2019-01-10 16:24:10 +00001609
Fangrui Songe7834bd2019-04-07 08:19:55 +00001610 const StringRef FileName = O->getFileName();
George Rimar73a27232019-01-15 09:19:18 +00001611 for (auto I = O->symbol_begin(), E = O->symbol_end(); I != E; ++I) {
George Rimar8e0a70b2019-01-10 16:24:10 +00001612 // Skip printing the special zero symbol when dumping an ELF file.
1613 // This makes the output consistent with the GNU objdump.
George Rimar73a27232019-01-15 09:19:18 +00001614 if (I == O->symbol_begin() && isa<ELFObjectFileBase>(O))
George Rimar8e0a70b2019-01-10 16:24:10 +00001615 continue;
1616
1617 const SymbolRef &Symbol = *I;
Fangrui Songe7834bd2019-04-07 08:19:55 +00001618 uint64_t Address = unwrapOrError(Symbol.getAddress(), ArchiveName, FileName,
1619 ArchitectureName);
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001620 if ((Address < StartAddress) || (Address > StopAddress))
1621 continue;
Fangrui Songe7834bd2019-04-07 08:19:55 +00001622 SymbolRef::Type Type = unwrapOrError(Symbol.getType(), ArchiveName,
1623 FileName, ArchitectureName);
Rui Ueyama4e39f712014-03-18 18:58:51 +00001624 uint32_t Flags = Symbol.getFlags();
Fangrui Songe7834bd2019-04-07 08:19:55 +00001625 section_iterator Section = unwrapOrError(Symbol.getSection(), ArchiveName,
1626 FileName, ArchitectureName);
Rafael Espindola75d5b542015-06-03 05:14:22 +00001627 StringRef Name;
Fangrui Songe7834bd2019-04-07 08:19:55 +00001628 if (Type == SymbolRef::ST_Debug && Section != O->section_end())
Rafael Espindola75d5b542015-06-03 05:14:22 +00001629 Section->getName(Name);
Fangrui Songe7834bd2019-04-07 08:19:55 +00001630 else
1631 Name = unwrapOrError(Symbol.getName(), ArchiveName, FileName,
1632 ArchitectureName);
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001633
Rui Ueyama4e39f712014-03-18 18:58:51 +00001634 bool Global = Flags & SymbolRef::SF_Global;
1635 bool Weak = Flags & SymbolRef::SF_Weak;
1636 bool Absolute = Flags & SymbolRef::SF_Absolute;
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001637 bool Common = Flags & SymbolRef::SF_Common;
Davide Italianocd2514d2015-04-30 23:08:53 +00001638 bool Hidden = Flags & SymbolRef::SF_Hidden;
David Meyer1df4b842012-02-28 23:47:53 +00001639
Rui Ueyama4e39f712014-03-18 18:58:51 +00001640 char GlobLoc = ' ';
1641 if (Type != SymbolRef::ST_Unknown)
1642 GlobLoc = Global ? 'g' : 'l';
1643 char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
1644 ? 'd' : ' ';
1645 char FileFunc = ' ';
1646 if (Type == SymbolRef::ST_File)
1647 FileFunc = 'f';
1648 else if (Type == SymbolRef::ST_Function)
1649 FileFunc = 'F';
Kristina Brooks0674f9d2018-11-11 17:47:13 +00001650 else if (Type == SymbolRef::ST_Data)
1651 FileFunc = 'O';
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001652
George Rimar73a27232019-01-15 09:19:18 +00001653 const char *Fmt = O->getBytesInAddress() > 4 ? "%016" PRIx64 :
Rui Ueyama4e39f712014-03-18 18:58:51 +00001654 "%08" PRIx64;
Michael J. Spencerd857c1c2013-01-10 22:40:50 +00001655
Rui Ueyama4e39f712014-03-18 18:58:51 +00001656 outs() << format(Fmt, Address) << " "
1657 << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
1658 << (Weak ? 'w' : ' ') // Weak?
1659 << ' ' // Constructor. Not supported yet.
1660 << ' ' // Warning. Not supported yet.
1661 << ' ' // Indirect reference to another symbol.
1662 << Debug // Debugging (d) or dynamic (D) symbol.
1663 << FileFunc // Name of function (F), file (f) or object (O).
1664 << ' ';
1665 if (Absolute) {
1666 outs() << "*ABS*";
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001667 } else if (Common) {
1668 outs() << "*COM*";
George Rimar73a27232019-01-15 09:19:18 +00001669 } else if (Section == O->section_end()) {
Rui Ueyama4e39f712014-03-18 18:58:51 +00001670 outs() << "*UND*";
1671 } else {
1672 if (const MachOObjectFile *MachO =
George Rimar73a27232019-01-15 09:19:18 +00001673 dyn_cast<const MachOObjectFile>(O)) {
Rui Ueyama4e39f712014-03-18 18:58:51 +00001674 DataRefImpl DR = Section->getRawDataRefImpl();
1675 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
1676 outs() << SegmentName << ",";
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001677 }
Rui Ueyama4e39f712014-03-18 18:58:51 +00001678 StringRef SectionName;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001679 error(Section->getName(SectionName));
Rui Ueyama4e39f712014-03-18 18:58:51 +00001680 outs() << SectionName;
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001681 }
Rafael Espindola5f7ade22015-06-23 15:45:38 +00001682
1683 outs() << '\t';
George Rimar73a27232019-01-15 09:19:18 +00001684 if (Common || isa<ELFObjectFileBase>(O)) {
Rafael Espindoladbb6bd32015-06-25 22:10:04 +00001685 uint64_t Val =
1686 Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
Rafael Espindolaae3ac082015-06-23 18:34:25 +00001687 outs() << format("\t %08" PRIx64 " ", Val);
1688 }
Rafael Espindola5f7ade22015-06-23 15:45:38 +00001689
George Rimar73a27232019-01-15 09:19:18 +00001690 if (Hidden)
Davide Italianocd2514d2015-04-30 23:08:53 +00001691 outs() << ".hidden ";
George Rimar6622d412018-12-19 10:21:45 +00001692
1693 if (Demangle)
1694 outs() << demangle(Name) << '\n';
1695 else
1696 outs() << Name << '\n';
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001697 }
1698}
1699
George Rimar73a27232019-01-15 09:19:18 +00001700static void printUnwindInfo(const ObjectFile *O) {
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001701 outs() << "Unwind info:\n\n";
1702
George Rimar73a27232019-01-15 09:19:18 +00001703 if (const COFFObjectFile *Coff = dyn_cast<COFFObjectFile>(O))
1704 printCOFFUnwindInfo(Coff);
1705 else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O))
Tim Northover4bd286a2014-08-01 13:07:19 +00001706 printMachOUnwindInfo(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001707 else
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001708 // TODO: Extract DWARF dump tool to objdump.
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001709 WithColor::error(errs(), ToolName)
1710 << "This operation is only currently supported "
1711 "for COFF and MachO object files.\n";
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001712}
1713
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001714void llvm::printExportsTrie(const ObjectFile *o) {
Nick Kledzikd04bc352014-08-30 00:20:14 +00001715 outs() << "Exports trie:\n";
1716 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1717 printMachOExportsTrie(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001718 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001719 WithColor::error(errs(), ToolName)
1720 << "This operation is only currently supported "
1721 "for Mach-O executable files.\n";
Nick Kledzikd04bc352014-08-30 00:20:14 +00001722}
1723
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001724void llvm::printRebaseTable(ObjectFile *o) {
Nick Kledzikac431442014-09-12 21:34:15 +00001725 outs() << "Rebase table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001726 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzikac431442014-09-12 21:34:15 +00001727 printMachORebaseTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001728 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001729 WithColor::error(errs(), ToolName)
1730 << "This operation is only currently supported "
1731 "for Mach-O executable files.\n";
Nick Kledzikac431442014-09-12 21:34:15 +00001732}
1733
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001734void llvm::printBindTable(ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001735 outs() << "Bind table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001736 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzik56ebef42014-09-16 01:41:51 +00001737 printMachOBindTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001738 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001739 WithColor::error(errs(), ToolName)
1740 << "This operation is only currently supported "
1741 "for Mach-O executable files.\n";
Nick Kledzik56ebef42014-09-16 01:41:51 +00001742}
1743
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001744void llvm::printLazyBindTable(ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001745 outs() << "Lazy bind table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001746 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzik56ebef42014-09-16 01:41:51 +00001747 printMachOLazyBindTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001748 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001749 WithColor::error(errs(), ToolName)
1750 << "This operation is only currently supported "
1751 "for Mach-O executable files.\n";
Nick Kledzik56ebef42014-09-16 01:41:51 +00001752}
1753
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001754void llvm::printWeakBindTable(ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001755 outs() << "Weak bind table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001756 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzik56ebef42014-09-16 01:41:51 +00001757 printMachOWeakBindTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001758 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001759 WithColor::error(errs(), ToolName)
1760 << "This operation is only currently supported "
1761 "for Mach-O executable files.\n";
Nick Kledzik56ebef42014-09-16 01:41:51 +00001762}
Nick Kledzikac431442014-09-12 21:34:15 +00001763
Adrian Prantl437105a2015-07-08 02:04:15 +00001764/// Dump the raw contents of the __clangast section so the output can be piped
1765/// into llvm-bcanalyzer.
1766void llvm::printRawClangAST(const ObjectFile *Obj) {
1767 if (outs().is_displayed()) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001768 WithColor::error(errs(), ToolName)
1769 << "The -raw-clang-ast option will dump the raw binary contents of "
1770 "the clang ast section.\n"
1771 "Please redirect the output to a file or another program such as "
1772 "llvm-bcanalyzer.\n";
Adrian Prantl437105a2015-07-08 02:04:15 +00001773 return;
1774 }
1775
1776 StringRef ClangASTSectionName("__clangast");
1777 if (isa<COFFObjectFile>(Obj)) {
1778 ClangASTSectionName = "clangast";
1779 }
1780
1781 Optional<object::SectionRef> ClangASTSection;
Colin LeMahieu77804be2015-07-29 15:45:39 +00001782 for (auto Sec : ToolSectionFilter(*Obj)) {
Adrian Prantl437105a2015-07-08 02:04:15 +00001783 StringRef Name;
1784 Sec.getName(Name);
1785 if (Name == ClangASTSectionName) {
1786 ClangASTSection = Sec;
1787 break;
1788 }
1789 }
1790 if (!ClangASTSection)
1791 return;
1792
1793 StringRef ClangASTContents;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001794 error(ClangASTSection.getValue().getContents(ClangASTContents));
Adrian Prantl437105a2015-07-08 02:04:15 +00001795 outs().write(ClangASTContents.data(), ClangASTContents.size());
1796}
1797
Sanjoy Das6f567a42015-06-22 18:03:02 +00001798static void printFaultMaps(const ObjectFile *Obj) {
George Rimar73a27232019-01-15 09:19:18 +00001799 StringRef FaultMapSectionName;
Sanjoy Das6f567a42015-06-22 18:03:02 +00001800
1801 if (isa<ELFObjectFileBase>(Obj)) {
1802 FaultMapSectionName = ".llvm_faultmaps";
1803 } else if (isa<MachOObjectFile>(Obj)) {
1804 FaultMapSectionName = "__llvm_faultmaps";
1805 } else {
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001806 WithColor::error(errs(), ToolName)
1807 << "This operation is only currently supported "
1808 "for ELF and Mach-O executable files.\n";
Sanjoy Das6f567a42015-06-22 18:03:02 +00001809 return;
1810 }
1811
1812 Optional<object::SectionRef> FaultMapSection;
1813
Colin LeMahieu77804be2015-07-29 15:45:39 +00001814 for (auto Sec : ToolSectionFilter(*Obj)) {
Sanjoy Das6f567a42015-06-22 18:03:02 +00001815 StringRef Name;
1816 Sec.getName(Name);
1817 if (Name == FaultMapSectionName) {
1818 FaultMapSection = Sec;
1819 break;
1820 }
1821 }
1822
1823 outs() << "FaultMap table:\n";
1824
1825 if (!FaultMapSection.hasValue()) {
1826 outs() << "<not found>\n";
1827 return;
1828 }
1829
1830 StringRef FaultMapContents;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001831 error(FaultMapSection.getValue().getContents(FaultMapContents));
Sanjoy Das6f567a42015-06-22 18:03:02 +00001832
1833 FaultMapParser FMP(FaultMapContents.bytes_begin(),
1834 FaultMapContents.bytes_end());
1835
1836 outs() << FMP;
1837}
1838
George Rimar73a27232019-01-15 09:19:18 +00001839static void printPrivateFileHeaders(const ObjectFile *O, bool OnlyFirst) {
1840 if (O->isELF()) {
1841 printELFFileHeader(O);
Xing GUO56d651d2019-02-25 13:13:19 +00001842 printELFDynamicSection(O);
1843 printELFSymbolVersionInfo(O);
1844 return;
Paul Semel0913dcd2018-07-25 11:09:20 +00001845 }
George Rimar73a27232019-01-15 09:19:18 +00001846 if (O->isCOFF())
1847 return printCOFFFileHeader(O);
1848 if (O->isWasm())
1849 return printWasmFileHeader(O);
1850 if (O->isMachO()) {
1851 printMachOFileHeader(O);
1852 if (!OnlyFirst)
1853 printMachOLoadCommands(O);
Davide Italiano1bdaa202016-09-18 04:39:15 +00001854 return;
1855 }
George Rimar73a27232019-01-15 09:19:18 +00001856 report_error(O->getFileName(), "Invalid/Unsupported object file format");
Rui Ueyamac2bed422013-09-27 21:04:00 +00001857}
1858
George Rimar73a27232019-01-15 09:19:18 +00001859static void printFileHeaders(const ObjectFile *O) {
1860 if (!O->isELF() && !O->isCOFF())
1861 report_error(O->getFileName(), "Invalid/Unsupported object file format");
Paul Semeld2af4d62018-07-04 15:25:03 +00001862
George Rimar73a27232019-01-15 09:19:18 +00001863 Triple::ArchType AT = O->getArch();
Paul Semeld2af4d62018-07-04 15:25:03 +00001864 outs() << "architecture: " << Triple::getArchTypeName(AT) << "\n";
Fangrui Songe7834bd2019-04-07 08:19:55 +00001865 uint64_t Address = unwrapOrError(O->getStartAddress(), O->getFileName());
Petar Jovanovic8d947ba2018-10-19 22:16:49 +00001866
George Rimar73a27232019-01-15 09:19:18 +00001867 StringRef Fmt = O->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
Paul Semeld2af4d62018-07-04 15:25:03 +00001868 outs() << "start address: "
George Rimar9b6fe7e2019-01-12 12:17:24 +00001869 << "0x" << format(Fmt.data(), Address) << "\n\n";
Paul Semeld2af4d62018-07-04 15:25:03 +00001870}
1871
Paul Semel0dc92f62018-07-05 14:43:29 +00001872static void printArchiveChild(StringRef Filename, const Archive::Child &C) {
1873 Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
1874 if (!ModeOrErr) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001875 WithColor::error(errs(), ToolName) << "ill-formed archive entry.\n";
Paul Semel0dc92f62018-07-05 14:43:29 +00001876 consumeError(ModeOrErr.takeError());
1877 return;
1878 }
1879 sys::fs::perms Mode = ModeOrErr.get();
1880 outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
1881 outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
1882 outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
1883 outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
1884 outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
1885 outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
1886 outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
1887 outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
1888 outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
1889
1890 outs() << " ";
1891
Fangrui Songe7834bd2019-04-07 08:19:55 +00001892 outs() << format("%d/%d %6" PRId64 " ", unwrapOrError(C.getUID(), Filename),
1893 unwrapOrError(C.getGID(), Filename),
1894 unwrapOrError(C.getRawSize(), Filename));
Paul Semel0dc92f62018-07-05 14:43:29 +00001895
1896 StringRef RawLastModified = C.getRawLastModified();
1897 unsigned Seconds;
1898 if (RawLastModified.getAsInteger(10, Seconds))
1899 outs() << "(date: \"" << RawLastModified
1900 << "\" contains non-decimal chars) ";
1901 else {
1902 // Since ctime(3) returns a 26 character string of the form:
1903 // "Sun Sep 16 01:03:52 1973\n\0"
1904 // just print 24 characters.
1905 time_t t = Seconds;
1906 outs() << format("%.24s ", ctime(&t));
1907 }
1908
1909 StringRef Name = "";
1910 Expected<StringRef> NameOrErr = C.getName();
1911 if (!NameOrErr) {
1912 consumeError(NameOrErr.takeError());
Fangrui Songe7834bd2019-04-07 08:19:55 +00001913 Name = unwrapOrError(C.getRawName(), Filename);
Paul Semel0dc92f62018-07-05 14:43:29 +00001914 } else {
1915 Name = NameOrErr.get();
1916 }
1917 outs() << Name << "\n";
1918}
1919
George Rimar73a27232019-01-15 09:19:18 +00001920static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
1921 const Archive::Child *C = nullptr) {
Adrian Prantl437105a2015-07-08 02:04:15 +00001922 // Avoid other output when using a raw option.
1923 if (!RawClangAST) {
1924 outs() << '\n';
George Rimar73a27232019-01-15 09:19:18 +00001925 if (A)
1926 outs() << A->getFileName() << "(" << O->getFileName() << ")";
Kevin Enderbyac9e1552016-05-17 17:10:12 +00001927 else
George Rimar73a27232019-01-15 09:19:18 +00001928 outs() << O->getFileName();
1929 outs() << ":\tfile format " << O->getFileFormatName() << "\n\n";
Adrian Prantl437105a2015-07-08 02:04:15 +00001930 }
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001931
George Rimar73a27232019-01-15 09:19:18 +00001932 StringRef ArchiveName = A ? A->getFileName() : "";
George Rimar9b6fe7e2019-01-12 12:17:24 +00001933 if (FileHeaders)
George Rimar73a27232019-01-15 09:19:18 +00001934 printFileHeaders(O);
1935 if (ArchiveHeaders && !MachOOpt && C)
1936 printArchiveChild(ArchiveName, *C);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001937 if (Disassemble)
George Rimar73a27232019-01-15 09:19:18 +00001938 disassembleObject(O, Relocations);
Michael J. Spencer51862b32011-10-13 22:17:18 +00001939 if (Relocations && !Disassemble)
George Rimar73a27232019-01-15 09:19:18 +00001940 printRelocations(O);
Paul Semelcb0f0432018-06-07 13:30:55 +00001941 if (DynamicRelocations)
George Rimar73a27232019-01-15 09:19:18 +00001942 printDynamicRelocations(O);
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001943 if (SectionHeaders)
George Rimar73a27232019-01-15 09:19:18 +00001944 printSectionHeaders(O);
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001945 if (SectionContents)
George Rimar73a27232019-01-15 09:19:18 +00001946 printSectionContents(O);
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001947 if (SymbolTable)
George Rimar73a27232019-01-15 09:19:18 +00001948 printSymbolTable(O, ArchiveName);
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001949 if (UnwindInfo)
George Rimar73a27232019-01-15 09:19:18 +00001950 printUnwindInfo(O);
Davide Italiano1bdaa202016-09-18 04:39:15 +00001951 if (PrivateHeaders || FirstPrivateHeader)
George Rimar73a27232019-01-15 09:19:18 +00001952 printPrivateFileHeaders(O, FirstPrivateHeader);
Nick Kledzikd04bc352014-08-30 00:20:14 +00001953 if (ExportsTrie)
George Rimar73a27232019-01-15 09:19:18 +00001954 printExportsTrie(O);
Nick Kledzikac431442014-09-12 21:34:15 +00001955 if (Rebase)
George Rimar73a27232019-01-15 09:19:18 +00001956 printRebaseTable(O);
Nick Kledzik56ebef42014-09-16 01:41:51 +00001957 if (Bind)
George Rimar73a27232019-01-15 09:19:18 +00001958 printBindTable(O);
Nick Kledzik56ebef42014-09-16 01:41:51 +00001959 if (LazyBind)
George Rimar73a27232019-01-15 09:19:18 +00001960 printLazyBindTable(O);
Nick Kledzik56ebef42014-09-16 01:41:51 +00001961 if (WeakBind)
George Rimar73a27232019-01-15 09:19:18 +00001962 printWeakBindTable(O);
Adrian Prantl437105a2015-07-08 02:04:15 +00001963 if (RawClangAST)
George Rimar73a27232019-01-15 09:19:18 +00001964 printRawClangAST(O);
Sanjoy Das6f567a42015-06-22 18:03:02 +00001965 if (PrintFaultMaps)
George Rimar73a27232019-01-15 09:19:18 +00001966 printFaultMaps(O);
Igor Laevsky03a670c2016-01-26 15:09:42 +00001967 if (DwarfDumpType != DIDT_Null) {
George Rimar73a27232019-01-15 09:19:18 +00001968 std::unique_ptr<DIContext> DICtx = DWARFContext::create(*O);
Igor Laevsky03a670c2016-01-26 15:09:42 +00001969 // Dump the complete DWARF structure.
Adrian Prantlf4bc1f72017-06-01 18:18:23 +00001970 DIDumpOptions DumpOpts;
1971 DumpOpts.DumpType = DwarfDumpType;
Adrian Prantlf4bc1f72017-06-01 18:18:23 +00001972 DICtx->dump(outs(), DumpOpts);
Igor Laevsky03a670c2016-01-26 15:09:42 +00001973 }
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001974}
1975
George Rimar73a27232019-01-15 09:19:18 +00001976static void dumpObject(const COFFImportFile *I, const Archive *A,
Paul Semel0dc92f62018-07-05 14:43:29 +00001977 const Archive::Child *C = nullptr) {
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +00001978 StringRef ArchiveName = A ? A->getFileName() : "";
1979
1980 // Avoid other output when using a raw option.
1981 if (!RawClangAST)
1982 outs() << '\n'
1983 << ArchiveName << "(" << I->getFileName() << ")"
1984 << ":\tfile format COFF-import-file"
1985 << "\n\n";
1986
James Hendersonc1608c92018-10-29 14:17:08 +00001987 if (ArchiveHeaders && !MachOOpt && C)
1988 printArchiveChild(ArchiveName, *C);
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +00001989 if (SymbolTable)
1990 printCOFFSymbolTable(I);
1991}
1992
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +00001993/// Dump each object file in \a a;
George Rimar73a27232019-01-15 09:19:18 +00001994static void dumpArchive(const Archive *A) {
Mehdi Amini41af4302016-11-11 04:28:40 +00001995 Error Err = Error::success();
George Rimar73a27232019-01-15 09:19:18 +00001996 for (auto &C : A->children(Err)) {
Kevin Enderbyac9e1552016-05-17 17:10:12 +00001997 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1998 if (!ChildOrErr) {
1999 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
Fangrui Songe7834bd2019-04-07 08:19:55 +00002000 report_error(std::move(E), A->getFileName(), C);
Kevin Enderbyac9e1552016-05-17 17:10:12 +00002001 continue;
2002 }
George Rimar73a27232019-01-15 09:19:18 +00002003 if (ObjectFile *O = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
2004 dumpObject(O, A, &C);
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +00002005 else if (COFFImportFile *I = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
George Rimar73a27232019-01-15 09:19:18 +00002006 dumpObject(I, A, &C);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002007 else
George Rimar73a27232019-01-15 09:19:18 +00002008 report_error(A->getFileName(), object_error::invalid_file_type);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002009 }
Lang Hamesfc209622016-07-14 02:24:01 +00002010 if (Err)
Fangrui Songe7834bd2019-04-07 08:19:55 +00002011 report_error(std::move(Err), A->getFileName());
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002012}
2013
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +00002014/// Open file and figure out how to dump it.
George Rimar73a27232019-01-15 09:19:18 +00002015static void dumpInput(StringRef file) {
Kevin Enderbye2297dd2015-01-07 21:02:18 +00002016 // If we are using the Mach-O specific object file parser, then let it parse
2017 // the file and process the command line options. So the -arch flags can
2018 // be used to select specific slices, etc.
2019 if (MachOOpt) {
George Rimar73a27232019-01-15 09:19:18 +00002020 parseInputMachO(file);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002021 return;
2022 }
2023
2024 // Attempt to open the binary.
Fangrui Songe7834bd2019-04-07 08:19:55 +00002025 OwningBinary<Binary> OBinary = unwrapOrError(createBinary(file), file);
2026 Binary &Binary = *OBinary.getBinary();
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002027
George Rimar73a27232019-01-15 09:19:18 +00002028 if (Archive *A = dyn_cast<Archive>(&Binary))
2029 dumpArchive(A);
2030 else if (ObjectFile *O = dyn_cast<ObjectFile>(&Binary))
2031 dumpObject(O);
Dave Lee3fb120f2018-08-03 00:06:38 +00002032 else if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Binary))
George Rimar73a27232019-01-15 09:19:18 +00002033 parseInputMachO(UB);
Jim Grosbachaf9aec02012-08-07 17:53:14 +00002034 else
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +00002035 report_error(file, object_error::invalid_file_type);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002036}
2037
Michael J. Spencer2670c252011-01-20 06:39:06 +00002038int main(int argc, char **argv) {
Rui Ueyama197194b2018-04-13 18:26:06 +00002039 InitLLVM X(argc, argv);
Michael J. Spencer2670c252011-01-20 06:39:06 +00002040
2041 // Initialize targets and assembly printers/parsers.
2042 llvm::InitializeAllTargetInfos();
Evan Cheng8c886a42011-07-22 21:58:54 +00002043 llvm::InitializeAllTargetMCs();
Michael J. Spencer2670c252011-01-20 06:39:06 +00002044 llvm::InitializeAllDisassemblers();
2045
Pete Cooper28fb4fc2012-05-03 23:20:10 +00002046 // Register the target printer for --version.
2047 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
2048
Michael J. Spencer2670c252011-01-20 06:39:06 +00002049 cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
Michael J. Spencer2670c252011-01-20 06:39:06 +00002050
2051 ToolName = argv[0];
2052
2053 // Defaults to a.out if no filenames specified.
Jordan Rupprecht16a0de22018-12-20 00:57:06 +00002054 if (InputFilenames.empty())
Michael J. Spencer2670c252011-01-20 06:39:06 +00002055 InputFilenames.push_back("a.out");
2056
Fangrui Song8513cd42018-06-27 20:45:11 +00002057 if (AllHeaders)
George Rimar5e364332019-01-18 12:01:59 +00002058 ArchiveHeaders = FileHeaders = PrivateHeaders = Relocations =
2059 SectionHeaders = SymbolTable = true;
Fangrui Song8513cd42018-06-27 20:45:11 +00002060
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +00002061 if (DisassembleAll || PrintSource || PrintLines)
Colin LeMahieuf34933e2015-07-23 20:58:49 +00002062 Disassemble = true;
Paul Semel007dedb2018-07-18 16:39:21 +00002063
Michael J. Spencerbfa06782011-10-18 19:32:17 +00002064 if (!Disassemble
2065 && !Relocations
Paul Semelcb0f0432018-06-07 13:30:55 +00002066 && !DynamicRelocations
Michael J. Spencerbfa06782011-10-18 19:32:17 +00002067 && !SectionHeaders
2068 && !SectionContents
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00002069 && !SymbolTable
Michael J. Spencer209565db2013-01-06 03:56:49 +00002070 && !UnwindInfo
Nick Kledzikd04bc352014-08-30 00:20:14 +00002071 && !PrivateHeaders
Paul Semeld2af4d62018-07-04 15:25:03 +00002072 && !FileHeaders
Kevin Enderby0ae163f2016-01-13 00:25:36 +00002073 && !FirstPrivateHeader
Nick Kledzikac431442014-09-12 21:34:15 +00002074 && !ExportsTrie
Nick Kledzik56ebef42014-09-16 01:41:51 +00002075 && !Rebase
2076 && !Bind
2077 && !LazyBind
Kevin Enderby131d1772015-01-09 19:22:37 +00002078 && !WeakBind
Adrian Prantl437105a2015-07-08 02:04:15 +00002079 && !RawClangAST
Kevin Enderby13023a12015-01-15 23:19:11 +00002080 && !(UniversalHeaders && MachOOpt)
Paul Semel0dc92f62018-07-05 14:43:29 +00002081 && !ArchiveHeaders
Kevin Enderby69fe98d2015-01-23 18:52:17 +00002082 && !(IndirectSymbols && MachOOpt)
Kevin Enderby9a509442015-01-27 21:28:24 +00002083 && !(DataInCode && MachOOpt)
Kevin Enderbyf6d25852015-01-31 00:37:11 +00002084 && !(LinkOptHints && MachOOpt)
Kevin Enderbycd66be52015-03-11 22:06:32 +00002085 && !(InfoPlist && MachOOpt)
Kevin Enderbybc847fa2015-03-16 20:08:09 +00002086 && !(DylibsUsed && MachOOpt)
2087 && !(DylibId && MachOOpt)
Kevin Enderby0fc11822015-04-01 20:57:01 +00002088 && !(ObjcMetaData && MachOOpt)
Jordan Rupprecht16a0de22018-12-20 00:57:06 +00002089 && !(!FilterSections.empty() && MachOOpt)
Igor Laevsky03a670c2016-01-26 15:09:42 +00002090 && !PrintFaultMaps
2091 && DwarfDumpType == DIDT_Null) {
Michael J. Spencer2670c252011-01-20 06:39:06 +00002092 cl::PrintHelpMessage();
Dimitry Andrice4f5d012017-12-18 19:46:56 +00002093 return 2;
2094 }
2095
Rafael Aulerb0e4b912018-03-09 19:13:44 +00002096 DisasmFuncsSet.insert(DisassembleFunctions.begin(),
2097 DisassembleFunctions.end());
2098
George Rimar73a27232019-01-15 09:19:18 +00002099 llvm::for_each(InputFilenames, dumpInput);
Dimitry Andrice4f5d012017-12-18 19:46:56 +00002100
2101 return EXIT_SUCCESS;
2102}