blob: d26e49779a231bc3d51379cfad58a5728c3a033c [file] [log] [blame]
Michael J. Spencer2670c252011-01-20 06:39:06 +00001//===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This program is a utility that works like binutils "objdump", that is, it
11// dumps out a plethora of information about an object file depending on the
12// flags.
13//
Michael J. Spencerd7e70032013-02-05 20:27:22 +000014// The flags and output of this program should be near identical to those of
15// binutils objdump.
16//
Michael J. Spencer2670c252011-01-20 06:39:06 +000017//===----------------------------------------------------------------------===//
18
Benjamin Kramer43a772e2011-09-19 17:56:04 +000019#include "llvm-objdump.h"
Sanjoy Das6f567a42015-06-22 18:03:02 +000020#include "llvm/ADT/Optional.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000021#include "llvm/ADT/STLExtras.h"
Michael J. Spencer4e25c022011-10-17 17:13:22 +000022#include "llvm/ADT/StringExtras.h"
Rafael Aulerb0e4b912018-03-09 19:13:44 +000023#include "llvm/ADT/StringSet.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000024#include "llvm/ADT/Triple.h"
Sanjoy Das3f1bc3b2015-06-23 20:09:03 +000025#include "llvm/CodeGen/FaultMaps.h"
Igor Laevsky03a670c2016-01-26 15:09:42 +000026#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +000027#include "llvm/DebugInfo/Symbolize/Symbolize.h"
Paul Semel007dedb2018-07-18 16:39:21 +000028#include "llvm/Demangle/Demangle.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000029#include "llvm/MC/MCAsmInfo.h"
Ahmed Bougachaad1084d2013-05-24 00:39:57 +000030#include "llvm/MC/MCContext.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000031#include "llvm/MC/MCDisassembler/MCDisassembler.h"
32#include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000033#include "llvm/MC/MCInst.h"
34#include "llvm/MC/MCInstPrinter.h"
Ahmed Bougachaaa790682013-05-24 01:07:04 +000035#include "llvm/MC/MCInstrAnalysis.h"
Craig Topper54bfde72012-04-02 06:09:36 +000036#include "llvm/MC/MCInstrInfo.h"
Ahmed Bougachaad1084d2013-05-24 00:39:57 +000037#include "llvm/MC/MCObjectFileInfo.h"
Jim Grosbachfd93a592012-03-05 19:33:20 +000038#include "llvm/MC/MCRegisterInfo.h"
Ahmed Bougachaaa790682013-05-24 01:07:04 +000039#include "llvm/MC/MCSubtargetInfo.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000040#include "llvm/Object/Archive.h"
41#include "llvm/Object/COFF.h"
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +000042#include "llvm/Object/COFFImportFile.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000043#include "llvm/Object/ELFObjectFile.h"
Rafael Espindolaa9f810b2012-12-21 03:47:03 +000044#include "llvm/Object/MachO.h"
Dave Lee3fb120f2018-08-03 00:06:38 +000045#include "llvm/Object/MachOUniversal.h"
Chandler Carruth4d88a1c2012-12-04 10:44:52 +000046#include "llvm/Object/ObjectFile.h"
Sam Clegg4df5d762017-06-27 20:40:53 +000047#include "llvm/Object/Wasm.h"
Michael J. Spencerba4a3622011-10-08 00:18:30 +000048#include "llvm/Support/Casting.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000049#include "llvm/Support/CommandLine.h"
50#include "llvm/Support/Debug.h"
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +000051#include "llvm/Support/Errc.h"
Michael J. Spencerba4a3622011-10-08 00:18:30 +000052#include "llvm/Support/FileSystem.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000053#include "llvm/Support/Format.h"
Benjamin Kramerbf115312011-07-25 23:04:36 +000054#include "llvm/Support/GraphWriter.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000055#include "llvm/Support/Host.h"
Rui Ueyama197194b2018-04-13 18:26:06 +000056#include "llvm/Support/InitLLVM.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000057#include "llvm/Support/MemoryBuffer.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000058#include "llvm/Support/SourceMgr.h"
Joel Galenson134cf472018-08-24 15:21:57 +000059#include "llvm/Support/StringSaver.h"
Evan Cheng2bb40352011-08-24 18:08:43 +000060#include "llvm/Support/TargetRegistry.h"
61#include "llvm/Support/TargetSelect.h"
Jonas Devliegheree787efd2018-11-11 22:12:04 +000062#include "llvm/Support/WithColor.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000063#include "llvm/Support/raw_ostream.h"
Michael J. Spencer2670c252011-01-20 06:39:06 +000064#include <algorithm>
Benjamin Kramera5177e62012-03-23 11:49:32 +000065#include <cctype>
Michael J. Spencer2670c252011-01-20 06:39:06 +000066#include <cstring>
Rafael Espindolaa6e9c3e2014-06-12 17:38:55 +000067#include <system_error>
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +000068#include <unordered_map>
Rafael Espindolac398e672017-07-19 22:27:28 +000069#include <utility>
Ahmed Bougacha17926472013-08-21 07:29:02 +000070
Michael J. Spencer2670c252011-01-20 06:39:06 +000071using namespace llvm;
72using namespace object;
73
Fangrui Song8513cd42018-06-27 20:45:11 +000074cl::opt<bool>
75 llvm::AllHeaders("all-headers",
76 cl::desc("Display all available header information"));
77static cl::alias AllHeadersShort("x", cl::desc("Alias for --all-headers"),
George Rimar845d3292019-01-18 10:41:26 +000078 cl::NotHidden, cl::aliasopt(AllHeaders));
Fangrui Song8513cd42018-06-27 20:45:11 +000079
Benjamin Kramer43a772e2011-09-19 17:56:04 +000080static cl::list<std::string>
81InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
Michael J. Spencer2670c252011-01-20 06:39:06 +000082
Kevin Enderbye2297dd2015-01-07 21:02:18 +000083cl::opt<bool>
84llvm::Disassemble("disassemble",
Benjamin Kramer43a772e2011-09-19 17:56:04 +000085 cl::desc("Display assembler mnemonics for the machine instructions"));
George Rimar845d3292019-01-18 10:41:26 +000086static cl::alias Disassembled("d", cl::desc("Alias for --disassemble"),
87 cl::NotHidden, cl::aliasopt(Disassemble));
Colin LeMahieu77804be2015-07-29 15:45:39 +000088
89cl::opt<bool>
90llvm::DisassembleAll("disassemble-all",
91 cl::desc("Display assembler mnemonics for the machine instructions"));
George Rimar845d3292019-01-18 10:41:26 +000092static cl::alias DisassembleAlld("D", cl::desc("Alias for --disassemble-all"),
93 cl::NotHidden, cl::aliasopt(DisassembleAll));
Michael J. Spencer2670c252011-01-20 06:39:06 +000094
Zachary Turner030ad372018-08-20 22:18:21 +000095cl::opt<bool> llvm::Demangle("demangle", cl::desc("Demangle symbols names"),
96 cl::init(false));
Paul Semel007dedb2018-07-18 16:39:21 +000097
98static cl::alias DemangleShort("C", cl::desc("Alias for --demangle"),
George Rimar845d3292019-01-18 10:41:26 +000099 cl::NotHidden, cl::aliasopt(llvm::Demangle));
Paul Semel007dedb2018-07-18 16:39:21 +0000100
Rafael Aulerb0e4b912018-03-09 19:13:44 +0000101static cl::list<std::string>
102DisassembleFunctions("df",
103 cl::CommaSeparated,
104 cl::desc("List of functions to disassemble"));
105static StringSet<> DisasmFuncsSet;
106
Kevin Enderby98da6132015-01-20 21:47:46 +0000107cl::opt<bool>
Kristina Brooks31579e92018-10-31 09:34:08 +0000108llvm::Relocations("reloc",
109 cl::desc("Display the relocation entries in the file"));
110static cl::alias RelocationsShort("r", cl::desc("Alias for --reloc"),
111 cl::NotHidden,
112 cl::aliasopt(llvm::Relocations));
Michael J. Spencerba4a3622011-10-08 00:18:30 +0000113
Kevin Enderby98da6132015-01-20 21:47:46 +0000114cl::opt<bool>
Paul Semelcb0f0432018-06-07 13:30:55 +0000115llvm::DynamicRelocations("dynamic-reloc",
116 cl::desc("Display the dynamic relocation entries in the file"));
George Rimar845d3292019-01-18 10:41:26 +0000117static cl::alias DynamicRelocationsd("R", cl::desc("Alias for --dynamic-reloc"),
118 cl::NotHidden,
119 cl::aliasopt(DynamicRelocations));
Paul Semelcb0f0432018-06-07 13:30:55 +0000120
121cl::opt<bool>
James Hendersonb55b6582018-10-29 10:05:39 +0000122 llvm::SectionContents("full-contents",
123 cl::desc("Display the content of each section"));
124static cl::alias SectionContentsShort("s",
125 cl::desc("Alias for --full-contents"),
George Rimar845d3292019-01-18 10:41:26 +0000126 cl::NotHidden,
James Hendersonb55b6582018-10-29 10:05:39 +0000127 cl::aliasopt(SectionContents));
Michael J. Spencer4e25c022011-10-17 17:13:22 +0000128
Kristina Brooks3baa5f72018-10-31 05:45:01 +0000129cl::opt<bool> llvm::SymbolTable("syms", cl::desc("Display the symbol table"));
130static cl::alias SymbolTableShort("t", cl::desc("Alias for --syms"),
Kristina Brooks889356e2018-10-31 09:35:25 +0000131 cl::NotHidden,
Kristina Brooks3baa5f72018-10-31 05:45:01 +0000132 cl::aliasopt(llvm::SymbolTable));
Michael J. Spencerbfa06782011-10-18 19:32:17 +0000133
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000134cl::opt<bool>
135llvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
Nick Kledzikd04bc352014-08-30 00:20:14 +0000136
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000137cl::opt<bool>
138llvm::Rebase("rebase", cl::desc("Display mach-o rebasing info"));
Nick Kledzikac431442014-09-12 21:34:15 +0000139
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000140cl::opt<bool>
141llvm::Bind("bind", cl::desc("Display mach-o binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +0000142
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000143cl::opt<bool>
144llvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +0000145
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000146cl::opt<bool>
147llvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
Nick Kledzik56ebef42014-09-16 01:41:51 +0000148
Adrian Prantl437105a2015-07-08 02:04:15 +0000149cl::opt<bool>
150llvm::RawClangAST("raw-clang-ast",
151 cl::desc("Dump the raw binary contents of the clang AST section"));
152
Nick Kledzik56ebef42014-09-16 01:41:51 +0000153static cl::opt<bool>
Rafael Espindolaa9f810b2012-12-21 03:47:03 +0000154MachOOpt("macho", cl::desc("Use MachO specific object file parser"));
George Rimar845d3292019-01-18 10:41:26 +0000155static cl::alias MachOm("m", cl::desc("Alias for --macho"), cl::NotHidden,
156 cl::aliasopt(MachOOpt));
Benjamin Kramer87ee76c2011-07-20 19:37:35 +0000157
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000158cl::opt<std::string>
159llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
160 "see -version for available targets"));
161
162cl::opt<std::string>
Kevin Enderbyc9595622014-08-06 23:24:41 +0000163llvm::MCPU("mcpu",
164 cl::desc("Target a specific cpu type (-mcpu=help for details)"),
165 cl::value_desc("cpu-name"),
166 cl::init(""));
167
168cl::opt<std::string>
Kevin Enderbyef3ad2f2014-12-04 23:56:27 +0000169llvm::ArchName("arch-name", cl::desc("Target arch to disassemble for, "
Michael J. Spencer2670c252011-01-20 06:39:06 +0000170 "see -version for available targets"));
171
Kevin Enderby98da6132015-01-20 21:47:46 +0000172cl::opt<bool>
173llvm::SectionHeaders("section-headers", cl::desc("Display summaries of the "
174 "headers for each section."));
George Rimar845d3292019-01-18 10:41:26 +0000175static cl::alias SectionHeadersShort("headers",
176 cl::desc("Alias for --section-headers"),
177 cl::NotHidden,
178 cl::aliasopt(SectionHeaders));
179static cl::alias SectionHeadersShorter("h",
180 cl::desc("Alias for --section-headers"),
181 cl::NotHidden,
182 cl::aliasopt(SectionHeaders));
Colin LeMahieufcc32762015-07-29 19:08:10 +0000183
Colin LeMahieu77804be2015-07-29 15:45:39 +0000184cl::list<std::string>
Colin LeMahieufcc32762015-07-29 19:08:10 +0000185llvm::FilterSections("section", cl::desc("Operate on the specified sections only. "
186 "With -macho dump segment,section"));
George Rimar845d3292019-01-18 10:41:26 +0000187cl::alias static FilterSectionsj("j", cl::desc("Alias for --section"),
188 cl::NotHidden,
189 cl::aliasopt(llvm::FilterSections));
Nick Lewyckyfcf84622011-10-10 21:21:34 +0000190
Kevin Enderbyc9595622014-08-06 23:24:41 +0000191cl::list<std::string>
192llvm::MAttrs("mattr",
Jack Carter551efd72012-08-28 19:24:49 +0000193 cl::CommaSeparated,
194 cl::desc("Target specific attributes"),
195 cl::value_desc("a1,+a2,-a3,..."));
196
Kevin Enderbybf246f52014-09-24 23:08:22 +0000197cl::opt<bool>
198llvm::NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling "
199 "instructions, do not print "
200 "the instruction bytes."));
Saleem Abdulrasooldea14b22017-02-08 18:11:31 +0000201cl::opt<bool>
202llvm::NoLeadingAddr("no-leading-addr", cl::desc("Print no leading address"));
Eli Bendersky3a6808c2012-11-20 22:57:02 +0000203
Kevin Enderby98da6132015-01-20 21:47:46 +0000204cl::opt<bool>
205llvm::UnwindInfo("unwind-info", cl::desc("Display unwind information"));
Michael J. Spencer0c6ec482012-12-05 20:12:35 +0000206
George Rimar845d3292019-01-18 10:41:26 +0000207static cl::alias UnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
208 cl::NotHidden, cl::aliasopt(UnwindInfo));
Michael J. Spencer0c6ec482012-12-05 20:12:35 +0000209
Kevin Enderbye2297dd2015-01-07 21:02:18 +0000210cl::opt<bool>
211llvm::PrivateHeaders("private-headers",
212 cl::desc("Display format specific file headers"));
Michael J. Spencer209565db2013-01-06 03:56:49 +0000213
Kevin Enderby0ae163f2016-01-13 00:25:36 +0000214cl::opt<bool>
215llvm::FirstPrivateHeader("private-header",
216 cl::desc("Display only the first format specific file "
217 "header"));
218
George Rimar845d3292019-01-18 10:41:26 +0000219static cl::alias PrivateHeadersShort("p",
220 cl::desc("Alias for --private-headers"),
221 cl::NotHidden,
222 cl::aliasopt(PrivateHeaders));
Michael J. Spencer209565db2013-01-06 03:56:49 +0000223
Paul Semeld2af4d62018-07-04 15:25:03 +0000224cl::opt<bool> llvm::FileHeaders(
225 "file-headers",
226 cl::desc("Display the contents of the overall file header"));
227
228static cl::alias FileHeadersShort("f", cl::desc("Alias for --file-headers"),
George Rimar845d3292019-01-18 10:41:26 +0000229 cl::NotHidden, cl::aliasopt(FileHeaders));
Paul Semeld2af4d62018-07-04 15:25:03 +0000230
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000231cl::opt<bool>
Paul Semel0dc92f62018-07-05 14:43:29 +0000232 llvm::ArchiveHeaders("archive-headers",
233 cl::desc("Display archive header information"));
234
George Rimar845d3292019-01-18 10:41:26 +0000235cl::alias ArchiveHeadersShort("a", cl::desc("Alias for --archive-headers"),
236 cl::NotHidden, cl::aliasopt(ArchiveHeaders));
Paul Semel0dc92f62018-07-05 14:43:29 +0000237
238cl::opt<bool>
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000239 llvm::PrintImmHex("print-imm-hex",
Colin LeMahieuefe37322016-04-08 18:15:37 +0000240 cl::desc("Use hex format for immediate values"));
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000241
Sanjoy Das6f567a42015-06-22 18:03:02 +0000242cl::opt<bool> PrintFaultMaps("fault-map-section",
243 cl::desc("Display contents of faultmap section"));
244
Igor Laevsky03a670c2016-01-26 15:09:42 +0000245cl::opt<DIDumpType> llvm::DwarfDumpType(
246 "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
Jonas Devliegherec0a758d2017-09-18 14:15:57 +0000247 cl::values(clEnumValN(DIDT_DebugFrame, "frames", ".debug_frame")));
Igor Laevsky03a670c2016-01-26 15:09:42 +0000248
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +0000249cl::opt<bool> PrintSource(
250 "source",
251 cl::desc(
Alex Denisova07169e2018-02-02 19:20:37 +0000252 "Display source inlined with disassembly. Implies disassemble object"));
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +0000253
George Rimar845d3292019-01-18 10:41:26 +0000254cl::alias PrintSourceShort("S", cl::desc("Alias for -source"), cl::NotHidden,
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +0000255 cl::aliasopt(PrintSource));
256
257cl::opt<bool> PrintLines("line-numbers",
258 cl::desc("Display source line numbers with "
259 "disassembly. Implies disassemble object"));
260
261cl::alias PrintLinesShort("l", cl::desc("Alias for -line-numbers"),
George Rimar845d3292019-01-18 10:41:26 +0000262 cl::NotHidden, cl::aliasopt(PrintLines));
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +0000263
264cl::opt<unsigned long long>
265 StartAddress("start-address", cl::desc("Disassemble beginning at address"),
266 cl::value_desc("address"), cl::init(0));
267cl::opt<unsigned long long>
George Rimar70d197d2019-01-10 14:55:26 +0000268 StopAddress("stop-address",
George Rimar3687c3e92019-01-15 14:03:50 +0000269 cl::desc("Stop disassembly at address"),
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +0000270 cl::value_desc("address"), cl::init(UINT64_MAX));
George Rimar70d197d2019-01-10 14:55:26 +0000271
George Rimar3687c3e92019-01-15 14:03:50 +0000272cl::opt<bool> DisassembleZeroes(
273 "disassemble-zeroes",
274 cl::desc("Do not skip blocks of zeroes when disassembling"));
George Rimar70d197d2019-01-10 14:55:26 +0000275cl::alias DisassembleZeroesShort("z",
276 cl::desc("Alias for --disassemble-zeroes"),
George Rimar845d3292019-01-18 10:41:26 +0000277 cl::NotHidden,
George Rimar70d197d2019-01-10 14:55:26 +0000278 cl::aliasopt(DisassembleZeroes));
279
Benjamin Kramer43a772e2011-09-19 17:56:04 +0000280static StringRef ToolName;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000281
Clement Courbetd1a3bd42019-01-18 15:26:14 +0000282typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
Clement Courbet2d7d4a32019-01-18 09:40:19 +0000283
George Rimarc1964882019-01-18 11:33:26 +0000284SectionFilter llvm::ToolSectionFilter(llvm::object::ObjectFile const &O) {
David Majnemer42531262016-08-12 03:55:06 +0000285 return SectionFilter(
286 [](llvm::object::SectionRef const &S) {
287 if (FilterSections.empty())
288 return true;
289 llvm::StringRef String;
290 std::error_code error = S.getName(String);
291 if (error)
292 return false;
293 return is_contained(FilterSections, String);
294 },
295 O);
Colin LeMahieu77804be2015-07-29 15:45:39 +0000296}
Colin LeMahieu77804be2015-07-29 15:45:39 +0000297
Davide Italianoccd53fe2015-08-05 07:18:31 +0000298void llvm::error(std::error_code EC) {
Mark Seaborneb03ac52014-01-25 00:32:01 +0000299 if (!EC)
Davide Italianoccd53fe2015-08-05 07:18:31 +0000300 return;
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000301 WithColor::error(errs(), ToolName)
302 << "reading file: " << EC.message() << ".\n";
Davide Italiano140af642015-12-25 18:16:45 +0000303 errs().flush();
Davide Italiano7f6c3012015-08-06 00:18:52 +0000304 exit(1);
Michael J. Spencer2670c252011-01-20 06:39:06 +0000305}
306
Kevin Enderby42398052016-06-28 23:16:13 +0000307LLVM_ATTRIBUTE_NORETURN void llvm::error(Twine Message) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000308 WithColor::error(errs(), ToolName) << Message << ".\n";
Kevin Enderby42398052016-06-28 23:16:13 +0000309 errs().flush();
310 exit(1);
311}
312
Paul Semel007dedb2018-07-18 16:39:21 +0000313void llvm::warn(StringRef Message) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000314 WithColor::warning(errs(), ToolName) << Message << ".\n";
Paul Semel007dedb2018-07-18 16:39:21 +0000315 errs().flush();
316}
317
Davide Italianoed9d95b2015-12-29 13:41:02 +0000318LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000319 Twine Message) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000320 WithColor::error(errs(), ToolName)
321 << "'" << File << "': " << Message << ".\n";
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000322 exit(1);
323}
324
325LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
Davide Italianoed9d95b2015-12-29 13:41:02 +0000326 std::error_code EC) {
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +0000327 assert(EC);
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000328 WithColor::error(errs(), ToolName)
329 << "'" << File << "': " << EC.message() << ".\n";
Davide Italianoccd53fe2015-08-05 07:18:31 +0000330 exit(1);
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +0000331}
332
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000333LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
334 llvm::Error E) {
335 assert(E);
336 std::string Buf;
337 raw_string_ostream OS(Buf);
Jonas Devlieghere45eb84f2018-11-11 01:46:03 +0000338 logAllUnhandledErrors(std::move(E), OS);
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000339 OS.flush();
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000340 WithColor::error(errs(), ToolName) << "'" << File << "': " << Buf;
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +0000341 exit(1);
342}
343
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000344LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
345 StringRef FileName,
Kevin Enderby9acb1092016-05-31 20:35:34 +0000346 llvm::Error E,
347 StringRef ArchitectureName) {
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000348 assert(E);
Jonas Devliegheree787efd2018-11-11 22:12:04 +0000349 WithColor::error(errs(), ToolName);
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000350 if (ArchiveName != "")
351 errs() << ArchiveName << "(" << FileName << ")";
352 else
Justin Bogner31d8b7d2016-10-26 22:37:52 +0000353 errs() << "'" << FileName << "'";
Kevin Enderby9acb1092016-05-31 20:35:34 +0000354 if (!ArchitectureName.empty())
355 errs() << " (for architecture " << ArchitectureName << ")";
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000356 std::string Buf;
357 raw_string_ostream OS(Buf);
Jonas Devlieghere45eb84f2018-11-11 01:46:03 +0000358 logAllUnhandledErrors(std::move(E), OS);
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000359 OS.flush();
Justin Bogner31d8b7d2016-10-26 22:37:52 +0000360 errs() << ": " << Buf;
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000361 exit(1);
362}
363
364LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
365 const object::Archive::Child &C,
Kevin Enderby9acb1092016-05-31 20:35:34 +0000366 llvm::Error E,
367 StringRef ArchitectureName) {
Kevin Enderbyf4586032016-07-29 17:44:13 +0000368 Expected<StringRef> NameOrErr = C.getName();
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000369 // TODO: if we have a error getting the name then it would be nice to print
370 // the index of which archive member this is and or its offset in the
371 // archive instead of "???" as the name.
Kevin Enderbyf4586032016-07-29 17:44:13 +0000372 if (!NameOrErr) {
373 consumeError(NameOrErr.takeError());
Kevin Enderby9acb1092016-05-31 20:35:34 +0000374 llvm::report_error(ArchiveName, "???", std::move(E), ArchitectureName);
Kevin Enderbyf4586032016-07-29 17:44:13 +0000375 } else
Kevin Enderby9acb1092016-05-31 20:35:34 +0000376 llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E),
377 ArchitectureName);
Kevin Enderbyac9e1552016-05-17 17:10:12 +0000378}
379
Craig Toppere6cb63e2014-04-25 04:24:47 +0000380static const Target *getTarget(const ObjectFile *Obj = nullptr) {
Michael J. Spencer2670c252011-01-20 06:39:06 +0000381 // Figure out the target triple.
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000382 llvm::Triple TheTriple("unknown-unknown-unknown");
Michael J. Spencer05350e6d2011-01-20 07:22:04 +0000383 if (TripleName.empty()) {
George Rimar73a27232019-01-15 09:19:18 +0000384 if (Obj)
Vlad Tsyrklevichde620462017-09-19 02:22:48 +0000385 TheTriple = Obj->makeTriple();
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000386 } else {
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000387 TheTriple.setTriple(Triple::normalize(TripleName));
Vlad Tsyrklevichde620462017-09-19 02:22:48 +0000388
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000389 // Use the triple, but also try to combine with ARM build attributes.
390 if (Obj) {
391 auto Arch = Obj->getArch();
George Rimar73a27232019-01-15 09:19:18 +0000392 if (Arch == Triple::arm || Arch == Triple::armeb)
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000393 Obj->setARMSubArch(TheTriple);
Sam Parkerdf7c6ef2017-01-18 13:52:12 +0000394 }
395 }
Michael J. Spencer2670c252011-01-20 06:39:06 +0000396
397 // Get the target specific parser.
398 std::string Error;
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000399 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
400 Error);
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000401 if (!TheTarget) {
402 if (Obj)
403 report_error(Obj->getFileName(), "can't find target: " + Error);
404 else
405 error("can't find target: " + Error);
406 }
Michael J. Spencer2670c252011-01-20 06:39:06 +0000407
Kevin Enderbyfe3d0052012-05-08 23:38:45 +0000408 // Update the triple name and return the found target.
409 TripleName = TheTriple.getTriple();
410 return TheTarget;
Michael J. Spencer2670c252011-01-20 06:39:06 +0000411}
412
George Rimar73a27232019-01-15 09:19:18 +0000413bool llvm::isRelocAddressLess(RelocationRef A, RelocationRef B) {
414 return A.getOffset() < B.getOffset();
Michael J. Spencer51862b32011-10-13 22:17:18 +0000415}
416
Rafael Espindola37070a52015-06-03 04:48:06 +0000417static std::error_code getRelocationValueString(const RelocationRef &Rel,
418 SmallVectorImpl<char> &Result) {
Rafael Espindola854038e2015-06-26 14:51:16 +0000419 const ObjectFile *Obj = Rel.getObject();
Rafael Espindola37070a52015-06-03 04:48:06 +0000420 if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000421 return getELFRelocationValueString(ELF, Rel, Result);
Rafael Espindola37070a52015-06-03 04:48:06 +0000422 if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000423 return getCOFFRelocationValueString(COFF, Rel, Result);
Sam Clegg4df5d762017-06-27 20:40:53 +0000424 if (auto *Wasm = dyn_cast<WasmObjectFile>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000425 return getWasmRelocationValueString(Wasm, Rel, Result);
Sam Clegg4df5d762017-06-27 20:40:53 +0000426 if (auto *MachO = dyn_cast<MachOObjectFile>(Obj))
George Rimarc1964882019-01-18 11:33:26 +0000427 return getMachORelocationValueString(MachO, Rel, Result);
Sam Clegg4df5d762017-06-27 20:40:53 +0000428 llvm_unreachable("unknown object file format");
Rafael Espindola37070a52015-06-03 04:48:06 +0000429}
430
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +0000431/// Indicates whether this relocation should hidden when listing
Rafael Espindola0ad71d92015-06-30 03:41:26 +0000432/// relocations, usually because it is the trailing part of a multipart
433/// relocation that will be printed as part of the leading relocation.
434static bool getHidden(RelocationRef RelRef) {
George Rimar73a27232019-01-15 09:19:18 +0000435 auto *MachO = dyn_cast<MachOObjectFile>(RelRef.getObject());
Rafael Espindola0ad71d92015-06-30 03:41:26 +0000436 if (!MachO)
437 return false;
438
439 unsigned Arch = MachO->getArch();
440 DataRefImpl Rel = RelRef.getRawDataRefImpl();
441 uint64_t Type = MachO->getRelocationType(Rel);
442
443 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
444 // is always hidden.
George Rimar73a27232019-01-15 09:19:18 +0000445 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc)
446 return Type == MachO::GENERIC_RELOC_PAIR;
447
448 if (Arch == Triple::x86_64) {
Rafael Espindola0ad71d92015-06-30 03:41:26 +0000449 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
450 // an X86_64_RELOC_SUBTRACTOR.
451 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
452 DataRefImpl RelPrev = Rel;
453 RelPrev.d.a--;
454 uint64_t PrevType = MachO->getRelocationType(RelPrev);
455 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
456 return true;
457 }
458 }
459
460 return false;
461}
462
Sid Manningd9f28732018-05-14 19:46:08 +0000463namespace {
464class SourcePrinter {
465protected:
466 DILineInfo OldLineInfo;
467 const ObjectFile *Obj = nullptr;
468 std::unique_ptr<symbolize::LLVMSymbolizer> Symbolizer;
469 // File name to file contents of source
470 std::unordered_map<std::string, std::unique_ptr<MemoryBuffer>> SourceCache;
471 // Mark the line endings of the cached source
472 std::unordered_map<std::string, std::vector<StringRef>> LineCache;
473
474private:
475 bool cacheSource(const DILineInfo& LineInfoFile);
476
477public:
478 SourcePrinter() = default;
479 SourcePrinter(const ObjectFile *Obj, StringRef DefaultArch) : Obj(Obj) {
480 symbolize::LLVMSymbolizer::Options SymbolizerOpts(
481 DILineInfoSpecifier::FunctionNameKind::None, true, false, false,
482 DefaultArch);
483 Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts));
484 }
485 virtual ~SourcePrinter() = default;
486 virtual void printSourceLine(raw_ostream &OS, uint64_t Address,
487 StringRef Delimiter = "; ");
488};
489
490bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
491 std::unique_ptr<MemoryBuffer> Buffer;
492 if (LineInfo.Source) {
493 Buffer = MemoryBuffer::getMemBuffer(*LineInfo.Source);
494 } else {
495 auto BufferOrError = MemoryBuffer::getFile(LineInfo.FileName);
496 if (!BufferOrError)
497 return false;
498 Buffer = std::move(*BufferOrError);
499 }
500 // Chomp the file to get lines
501 size_t BufferSize = Buffer->getBufferSize();
502 const char *BufferStart = Buffer->getBufferStart();
503 for (const char *Start = BufferStart, *End = BufferStart;
504 End < BufferStart + BufferSize; End++)
505 if (*End == '\n' || End == BufferStart + BufferSize - 1 ||
506 (*End == '\r' && *(End + 1) == '\n')) {
507 LineCache[LineInfo.FileName].push_back(StringRef(Start, End - Start));
508 if (*End == '\r')
509 End++;
510 Start = End + 1;
511 }
512 SourceCache[LineInfo.FileName] = std::move(Buffer);
513 return true;
514}
515
516void SourcePrinter::printSourceLine(raw_ostream &OS, uint64_t Address,
517 StringRef Delimiter) {
518 if (!Symbolizer)
519 return;
520 DILineInfo LineInfo = DILineInfo();
521 auto ExpectecLineInfo =
522 Symbolizer->symbolizeCode(Obj->getFileName(), Address);
523 if (!ExpectecLineInfo)
524 consumeError(ExpectecLineInfo.takeError());
525 else
526 LineInfo = *ExpectecLineInfo;
527
528 if ((LineInfo.FileName == "<invalid>") || OldLineInfo.Line == LineInfo.Line ||
529 LineInfo.Line == 0)
530 return;
531
532 if (PrintLines)
533 OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line << "\n";
534 if (PrintSource) {
535 if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
536 if (!cacheSource(LineInfo))
537 return;
538 auto FileBuffer = SourceCache.find(LineInfo.FileName);
539 if (FileBuffer != SourceCache.end()) {
540 auto LineBuffer = LineCache.find(LineInfo.FileName);
541 if (LineBuffer != LineCache.end()) {
542 if (LineInfo.Line > LineBuffer->second.size())
543 return;
544 // Vector begins at 0, line numbers are non-zero
545 OS << Delimiter << LineBuffer->second[LineInfo.Line - 1].ltrim()
546 << "\n";
547 }
548 }
549 }
550 OldLineInfo = LineInfo;
551}
552
553static bool isArmElf(const ObjectFile *Obj) {
554 return (Obj->isELF() &&
555 (Obj->getArch() == Triple::aarch64 ||
556 Obj->getArch() == Triple::aarch64_be ||
557 Obj->getArch() == Triple::arm || Obj->getArch() == Triple::armeb ||
558 Obj->getArch() == Triple::thumb ||
559 Obj->getArch() == Triple::thumbeb));
560}
561
562class PrettyPrinter {
563public:
564 virtual ~PrettyPrinter() = default;
565 virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
566 ArrayRef<uint8_t> Bytes, uint64_t Address,
567 raw_ostream &OS, StringRef Annot,
568 MCSubtargetInfo const &STI, SourcePrinter *SP,
569 std::vector<RelocationRef> *Rels = nullptr) {
570 if (SP && (PrintSource || PrintLines))
571 SP->printSourceLine(OS, Address);
572 if (!NoLeadingAddr)
573 OS << format("%8" PRIx64 ":", Address);
574 if (!NoShowRawInsn) {
575 OS << "\t";
576 dumpBytes(Bytes, OS);
577 }
578 if (MI)
579 IP.printInst(MI, OS, "", STI);
580 else
581 OS << " <unknown>";
582 }
583};
584PrettyPrinter PrettyPrinterInst;
585class HexagonPrettyPrinter : public PrettyPrinter {
586public:
587 void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
588 raw_ostream &OS) {
589 uint32_t opcode =
590 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
591 if (!NoLeadingAddr)
592 OS << format("%8" PRIx64 ":", Address);
593 if (!NoShowRawInsn) {
594 OS << "\t";
595 dumpBytes(Bytes.slice(0, 4), OS);
596 OS << format("%08" PRIx32, opcode);
597 }
598 }
599 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
600 uint64_t Address, raw_ostream &OS, StringRef Annot,
601 MCSubtargetInfo const &STI, SourcePrinter *SP,
602 std::vector<RelocationRef> *Rels) override {
603 if (SP && (PrintSource || PrintLines))
604 SP->printSourceLine(OS, Address, "");
605 if (!MI) {
606 printLead(Bytes, Address, OS);
607 OS << " <unknown>";
608 return;
609 }
610 std::string Buffer;
611 {
612 raw_string_ostream TempStream(Buffer);
613 IP.printInst(MI, TempStream, "", STI);
614 }
615 StringRef Contents(Buffer);
616 // Split off bundle attributes
617 auto PacketBundle = Contents.rsplit('\n');
618 // Split off first instruction from the rest
619 auto HeadTail = PacketBundle.first.split('\n');
620 auto Preamble = " { ";
621 auto Separator = "";
622 StringRef Fmt = "\t\t\t%08" PRIx64 ": ";
George Rimar73a27232019-01-15 09:19:18 +0000623 std::vector<RelocationRef>::const_iterator RelCur = Rels->begin();
624 std::vector<RelocationRef>::const_iterator RelEnd = Rels->end();
Sid Manningd9f28732018-05-14 19:46:08 +0000625
626 // Hexagon's packets require relocations to be inline rather than
627 // clustered at the end of the packet.
628 auto PrintReloc = [&]() -> void {
George Rimar73a27232019-01-15 09:19:18 +0000629 while ((RelCur != RelEnd) && (RelCur->getOffset() <= Address)) {
630 if (RelCur->getOffset() == Address) {
631 SmallString<16> Name;
632 SmallString<32> Val;
633 RelCur->getTypeName(Name);
634 error(getRelocationValueString(*RelCur, Val));
635 OS << Separator << format(Fmt.data(), Address) << Name << "\t" << Val
Sid Manningd9f28732018-05-14 19:46:08 +0000636 << "\n";
637 return;
638 }
George Rimar73a27232019-01-15 09:19:18 +0000639 ++RelCur;
Sid Manningd9f28732018-05-14 19:46:08 +0000640 }
641 };
642
George Rimar73a27232019-01-15 09:19:18 +0000643 while (!HeadTail.first.empty()) {
Sid Manningd9f28732018-05-14 19:46:08 +0000644 OS << Separator;
645 Separator = "\n";
646 if (SP && (PrintSource || PrintLines))
647 SP->printSourceLine(OS, Address, "");
648 printLead(Bytes, Address, OS);
649 OS << Preamble;
650 Preamble = " ";
651 StringRef Inst;
652 auto Duplex = HeadTail.first.split('\v');
George Rimar73a27232019-01-15 09:19:18 +0000653 if (!Duplex.second.empty()) {
Sid Manningd9f28732018-05-14 19:46:08 +0000654 OS << Duplex.first;
655 OS << "; ";
656 Inst = Duplex.second;
657 }
658 else
659 Inst = HeadTail.first;
660 OS << Inst;
661 HeadTail = HeadTail.second.split('\n');
662 if (HeadTail.first.empty())
663 OS << " } " << PacketBundle.second;
664 PrintReloc();
665 Bytes = Bytes.slice(4);
666 Address += 4;
667 }
668 }
669};
670HexagonPrettyPrinter HexagonPrettyPrinterInst;
671
672class AMDGCNPrettyPrinter : public PrettyPrinter {
673public:
674 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
675 uint64_t Address, raw_ostream &OS, StringRef Annot,
676 MCSubtargetInfo const &STI, SourcePrinter *SP,
677 std::vector<RelocationRef> *Rels) override {
678 if (SP && (PrintSource || PrintLines))
679 SP->printSourceLine(OS, Address);
680
681 typedef support::ulittle32_t U32;
682
683 if (MI) {
684 SmallString<40> InstStr;
685 raw_svector_ostream IS(InstStr);
686
687 IP.printInst(MI, IS, "", STI);
688
689 OS << left_justify(IS.str(), 60);
690 } else {
691 // an unrecognized encoding - this is probably data so represent it
692 // using the .long directive, or .byte directive if fewer than 4 bytes
693 // remaining
694 if (Bytes.size() >= 4) {
695 OS << format("\t.long 0x%08" PRIx32 " ",
696 static_cast<uint32_t>(*reinterpret_cast<const U32*>(Bytes.data())));
697 OS.indent(42);
698 } else {
699 OS << format("\t.byte 0x%02" PRIx8, Bytes[0]);
700 for (unsigned int i = 1; i < Bytes.size(); i++)
701 OS << format(", 0x%02" PRIx8, Bytes[i]);
702 OS.indent(55 - (6 * Bytes.size()));
703 }
704 }
705
706 OS << format("// %012" PRIX64 ": ", Address);
707 if (Bytes.size() >=4) {
708 for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
709 Bytes.size() / sizeof(U32)))
710 // D should be explicitly casted to uint32_t here as it is passed
711 // by format to snprintf as vararg.
712 OS << format("%08" PRIX32 " ", static_cast<uint32_t>(D));
713 } else {
714 for (unsigned int i = 0; i < Bytes.size(); i++)
715 OS << format("%02" PRIX8 " ", Bytes[i]);
716 }
717
718 if (!Annot.empty())
719 OS << "// " << Annot;
720 }
721};
722AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
723
724class BPFPrettyPrinter : public PrettyPrinter {
725public:
726 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
727 uint64_t Address, raw_ostream &OS, StringRef Annot,
728 MCSubtargetInfo const &STI, SourcePrinter *SP,
729 std::vector<RelocationRef> *Rels) override {
730 if (SP && (PrintSource || PrintLines))
731 SP->printSourceLine(OS, Address);
732 if (!NoLeadingAddr)
733 OS << format("%8" PRId64 ":", Address / 8);
734 if (!NoShowRawInsn) {
735 OS << "\t";
736 dumpBytes(Bytes, OS);
737 }
738 if (MI)
739 IP.printInst(MI, OS, "", STI);
740 else
741 OS << " <unknown>";
742 }
743};
744BPFPrettyPrinter BPFPrettyPrinterInst;
745
746PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
747 switch(Triple.getArch()) {
748 default:
749 return PrettyPrinterInst;
750 case Triple::hexagon:
751 return HexagonPrettyPrinterInst;
752 case Triple::amdgcn:
753 return AMDGCNPrettyPrinterInst;
754 case Triple::bpfel:
755 case Triple::bpfeb:
756 return BPFPrettyPrinterInst;
757 }
758}
759}
760
Sam Koltonc05d7782016-08-17 10:17:57 +0000761static uint8_t getElfSymbolType(const ObjectFile *Obj, const SymbolRef &Sym) {
762 assert(Obj->isELF());
763 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
764 return Elf32LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
765 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
766 return Elf64LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
767 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
768 return Elf32BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
769 if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
770 return Elf64BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
771 llvm_unreachable("Unsupported binary format");
772}
773
Sam Parker5fba45a2017-02-08 09:44:18 +0000774template <class ELFT> static void
775addDynamicElfSymbols(const ELFObjectFile<ELFT> *Obj,
776 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
777 for (auto Symbol : Obj->getDynamicSymbolIterators()) {
778 uint8_t SymbolType = Symbol.getELFType();
779 if (SymbolType != ELF::STT_FUNC || Symbol.getSize() == 0)
780 continue;
781
782 Expected<uint64_t> AddressOrErr = Symbol.getAddress();
783 if (!AddressOrErr)
784 report_error(Obj->getFileName(), AddressOrErr.takeError());
Sam Parker5fba45a2017-02-08 09:44:18 +0000785
786 Expected<StringRef> Name = Symbol.getName();
787 if (!Name)
788 report_error(Obj->getFileName(), Name.takeError());
789 if (Name->empty())
790 continue;
791
792 Expected<section_iterator> SectionOrErr = Symbol.getSection();
793 if (!SectionOrErr)
794 report_error(Obj->getFileName(), SectionOrErr.takeError());
795 section_iterator SecI = *SectionOrErr;
796 if (SecI == Obj->section_end())
797 continue;
798
George Rimar73a27232019-01-15 09:19:18 +0000799 AllSymbols[*SecI].emplace_back(*AddressOrErr, *Name, SymbolType);
Sam Parker5fba45a2017-02-08 09:44:18 +0000800 }
801}
802
803static void
804addDynamicElfSymbols(const ObjectFile *Obj,
805 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
806 assert(Obj->isELF());
807 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
808 addDynamicElfSymbols(Elf32LEObj, AllSymbols);
809 else if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
810 addDynamicElfSymbols(Elf64LEObj, AllSymbols);
811 else if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
812 addDynamicElfSymbols(Elf32BEObj, AllSymbols);
813 else if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
814 addDynamicElfSymbols(Elf64BEObj, AllSymbols);
815 else
816 llvm_unreachable("Unsupported binary format");
817}
818
Joel Galenson134cf472018-08-24 15:21:57 +0000819static void addPltEntries(const ObjectFile *Obj,
820 std::map<SectionRef, SectionSymbolsTy> &AllSymbols,
821 StringSaver &Saver) {
822 Optional<SectionRef> Plt = None;
823 for (const SectionRef &Section : Obj->sections()) {
824 StringRef Name;
825 if (Section.getName(Name))
826 continue;
827 if (Name == ".plt")
828 Plt = Section;
829 }
830 if (!Plt)
831 return;
832 if (auto *ElfObj = dyn_cast<ELFObjectFileBase>(Obj)) {
833 for (auto PltEntry : ElfObj->getPltAddresses()) {
834 SymbolRef Symbol(PltEntry.first, ElfObj);
Joel Galenson134cf472018-08-24 15:21:57 +0000835 uint8_t SymbolType = getElfSymbolType(Obj, Symbol);
836
837 Expected<StringRef> NameOrErr = Symbol.getName();
838 if (!NameOrErr)
839 report_error(Obj->getFileName(), NameOrErr.takeError());
840 if (NameOrErr->empty())
841 continue;
842 StringRef Name = Saver.save((*NameOrErr + "@plt").str());
843
844 AllSymbols[*Plt].emplace_back(PltEntry.second, Name, SymbolType);
845 }
846 }
847}
848
George Rimar70d197d2019-01-10 14:55:26 +0000849// Normally the disassembly output will skip blocks of zeroes. This function
850// returns the number of zero bytes that can be skipped when dumping the
851// disassembly of the instructions in Buf.
852static size_t countSkippableZeroBytes(ArrayRef<uint8_t> Buf) {
853 // When -z or --disassemble-zeroes are given we always dissasemble them.
854 if (DisassembleZeroes)
855 return 0;
856
857 // Find the number of leading zeroes.
858 size_t N = 0;
859 while (N < Buf.size() && !Buf[N])
860 ++N;
861
862 // We may want to skip blocks of zero bytes, but unless we see
863 // at least 8 of them in a row.
864 if (N < 8)
865 return 0;
866
867 // We skip zeroes in multiples of 4 because do not want to truncate an
868 // instruction if it starts with a zero byte.
869 return N & ~0x3;
870}
871
George Rimar73a27232019-01-15 09:19:18 +0000872static void disassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +0000873 if (StartAddress > StopAddress)
874 error("Start address should be less than stop address");
875
Jim Grosbachaf9aec02012-08-07 17:53:14 +0000876 const Target *TheTarget = getTarget(Obj);
Michael J. Spencer2670c252011-01-20 06:39:06 +0000877
Jack Carter551efd72012-08-28 19:24:49 +0000878 // Package up features to be passed to target/subtarget
Daniel Sanders1d148642016-06-16 09:17:03 +0000879 SubtargetFeatures Features = Obj->getFeatures();
George Rimar73a27232019-01-15 09:19:18 +0000880 if (!MAttrs.empty())
881 for (unsigned I = 0; I != MAttrs.size(); ++I)
882 Features.AddFeature(MAttrs[I]);
Jack Carter551efd72012-08-28 19:24:49 +0000883
Ahmed Charles56440fd2014-03-06 05:51:42 +0000884 std::unique_ptr<const MCRegisterInfo> MRI(
885 TheTarget->createMCRegInfo(TripleName));
Davide Italiano711e4952015-12-17 01:59:50 +0000886 if (!MRI)
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000887 report_error(Obj->getFileName(), "no register info for target " +
888 TripleName);
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000889
890 // Set up disassembler.
Ahmed Charles56440fd2014-03-06 05:51:42 +0000891 std::unique_ptr<const MCAsmInfo> AsmInfo(
892 TheTarget->createMCAsmInfo(*MRI, TripleName));
Davide Italiano711e4952015-12-17 01:59:50 +0000893 if (!AsmInfo)
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000894 report_error(Obj->getFileName(), "no assembly info for target " +
895 TripleName);
Ahmed Charles56440fd2014-03-06 05:51:42 +0000896 std::unique_ptr<const MCSubtargetInfo> STI(
Daniel Sanders1d148642016-06-16 09:17:03 +0000897 TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
Davide Italiano711e4952015-12-17 01:59:50 +0000898 if (!STI)
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000899 report_error(Obj->getFileName(), "no subtarget info for target " +
900 TripleName);
Ahmed Charles56440fd2014-03-06 05:51:42 +0000901 std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
Davide Italiano711e4952015-12-17 01:59:50 +0000902 if (!MII)
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000903 report_error(Obj->getFileName(), "no instruction info for target " +
904 TripleName);
Sam Kolton3381d7a2016-10-06 13:46:08 +0000905 MCObjectFileInfo MOFI;
906 MCContext Ctx(AsmInfo.get(), MRI.get(), &MOFI);
907 // FIXME: for now initialize MCObjectFileInfo with default values
Rafael Espindola9f929952017-08-02 20:32:26 +0000908 MOFI.InitMCObjectFileInfo(Triple(TripleName), false, Ctx);
Lang Hamesa1bc0f52014-04-15 04:40:56 +0000909
910 std::unique_ptr<MCDisassembler> DisAsm(
911 TheTarget->createMCDisassembler(*STI, Ctx));
Davide Italiano711e4952015-12-17 01:59:50 +0000912 if (!DisAsm)
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000913 report_error(Obj->getFileName(), "no disassembler for target " +
914 TripleName);
Ahmed Bougachaad1084d2013-05-24 00:39:57 +0000915
Ahmed Charles56440fd2014-03-06 05:51:42 +0000916 std::unique_ptr<const MCInstrAnalysis> MIA(
917 TheTarget->createMCInstrAnalysis(MII.get()));
Ahmed Bougachaaa790682013-05-24 01:07:04 +0000918
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000919 int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
Daniel Sanders50f17232015-09-15 16:17:27 +0000920 std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
921 Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
Davide Italiano711e4952015-12-17 01:59:50 +0000922 if (!IP)
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000923 report_error(Obj->getFileName(), "no instruction printer for target " +
924 TripleName);
Colin LeMahieu14ec76e2015-06-07 21:07:17 +0000925 IP->setPrintImmHex(PrintImmHex);
Colin LeMahieu35436a22015-05-29 14:48:25 +0000926 PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
Ahmed Bougacha0835ca12013-05-16 21:28:23 +0000927
Greg Fitzgerald18432272014-03-20 22:55:15 +0000928 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
929 "\t\t\t%08" PRIx64 ": ";
930
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +0000931 SourcePrinter SP(Obj, TheTarget->getName());
932
Mark Seaborn0929d3d2014-01-25 17:38:19 +0000933 // Create a mapping, RelocSecs = SectionRelocMap[S], where sections
934 // in RelocSecs contain the relocations for section S.
Rafael Espindola4453e42942014-06-13 03:07:50 +0000935 std::error_code EC;
Alexey Samsonov48803e52014-03-13 14:37:36 +0000936 std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap;
Colin LeMahieu77804be2015-07-29 15:45:39 +0000937 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Alexey Samsonov48803e52014-03-13 14:37:36 +0000938 section_iterator Sec2 = Section.getRelocatedSection();
Rafael Espindolab5155a52014-02-10 20:24:04 +0000939 if (Sec2 != Obj->section_end())
Alexey Samsonov48803e52014-03-13 14:37:36 +0000940 SectionRelocMap[*Sec2].push_back(Section);
Mark Seaborn0929d3d2014-01-25 17:38:19 +0000941 }
942
David Majnemer81afca62015-07-07 22:06:59 +0000943 // Create a mapping from virtual address to symbol name. This is used to
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000944 // pretty print the symbols while disassembling.
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000945 std::map<SectionRef, SectionSymbolsTy> AllSymbols;
Sterling Augustinebc78b622018-06-28 18:57:13 +0000946 SectionSymbolsTy AbsoluteSymbols;
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000947 for (const SymbolRef &Symbol : Obj->symbols()) {
Kevin Enderby931cb652016-06-24 18:24:42 +0000948 Expected<uint64_t> AddressOrErr = Symbol.getAddress();
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000949 if (!AddressOrErr)
950 report_error(Obj->getFileName(), AddressOrErr.takeError());
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000951 uint64_t Address = *AddressOrErr;
David Majnemer2603a8fa2015-07-09 18:11:40 +0000952
Kevin Enderby81e8b7d2016-04-20 21:24:34 +0000953 Expected<StringRef> Name = Symbol.getName();
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000954 if (!Name)
955 report_error(Obj->getFileName(), Name.takeError());
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000956 if (Name->empty())
957 continue;
David Majnemer81afca62015-07-07 22:06:59 +0000958
Kevin Enderby7bd8d992016-05-02 20:28:12 +0000959 Expected<section_iterator> SectionOrErr = Symbol.getSection();
Kevin Enderby7fa40c92016-11-16 22:17:38 +0000960 if (!SectionOrErr)
961 report_error(Obj->getFileName(), SectionOrErr.takeError());
Hemant Kulkarni5b60f632016-08-25 19:41:08 +0000962
Sam Koltonc05d7782016-08-17 10:17:57 +0000963 uint8_t SymbolType = ELF::STT_NOTYPE;
Hemant Kulkarni5b60f632016-08-25 19:41:08 +0000964 if (Obj->isELF())
Sam Koltonc05d7782016-08-17 10:17:57 +0000965 SymbolType = getElfSymbolType(Obj, Symbol);
David Majnemer81afca62015-07-07 22:06:59 +0000966
Sterling Augustinebc78b622018-06-28 18:57:13 +0000967 section_iterator SecI = *SectionOrErr;
968 if (SecI != Obj->section_end())
969 AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType);
970 else
971 AbsoluteSymbols.emplace_back(Address, *Name, SymbolType);
972
Sam Koltonc05d7782016-08-17 10:17:57 +0000973
David Majnemer81afca62015-07-07 22:06:59 +0000974 }
Sam Parker5fba45a2017-02-08 09:44:18 +0000975 if (AllSymbols.empty() && Obj->isELF())
976 addDynamicElfSymbols(Obj, AllSymbols);
David Majnemer81afca62015-07-07 22:06:59 +0000977
Joel Galenson134cf472018-08-24 15:21:57 +0000978 BumpPtrAllocator A;
979 StringSaver Saver(A);
980 addPltEntries(Obj, AllSymbols, Saver);
981
David Majnemerfbb1c3a2015-11-18 02:49:19 +0000982 // Create a mapping from virtual address to section.
983 std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
984 for (SectionRef Sec : Obj->sections())
985 SectionAddresses.emplace_back(Sec.getAddress(), Sec);
986 array_pod_sort(SectionAddresses.begin(), SectionAddresses.end());
987
988 // Linked executables (.exe and .dll files) typically don't include a real
989 // symbol table but they might contain an export table.
990 if (const auto *COFFObj = dyn_cast<COFFObjectFile>(Obj)) {
991 for (const auto &ExportEntry : COFFObj->export_directories()) {
992 StringRef Name;
993 error(ExportEntry.getSymbolName(Name));
994 if (Name.empty())
995 continue;
996 uint32_t RVA;
997 error(ExportEntry.getExportRVA(RVA));
998
999 uint64_t VA = COFFObj->getImageBase() + RVA;
1000 auto Sec = std::upper_bound(
1001 SectionAddresses.begin(), SectionAddresses.end(), VA,
1002 [](uint64_t LHS, const std::pair<uint64_t, SectionRef> &RHS) {
1003 return LHS < RHS.first;
1004 });
1005 if (Sec != SectionAddresses.begin())
1006 --Sec;
1007 else
1008 Sec = SectionAddresses.end();
1009
1010 if (Sec != SectionAddresses.end())
Sam Koltonc05d7782016-08-17 10:17:57 +00001011 AllSymbols[Sec->second].emplace_back(VA, Name, ELF::STT_NOTYPE);
Sterling Augustinebc78b622018-06-28 18:57:13 +00001012 else
1013 AbsoluteSymbols.emplace_back(VA, Name, ELF::STT_NOTYPE);
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001014 }
1015 }
1016
1017 // Sort all the symbols, this allows us to use a simple binary search to find
1018 // a symbol near an address.
1019 for (std::pair<const SectionRef, SectionSymbolsTy> &SecSyms : AllSymbols)
1020 array_pod_sort(SecSyms.second.begin(), SecSyms.second.end());
Sterling Augustinebc78b622018-06-28 18:57:13 +00001021 array_pod_sort(AbsoluteSymbols.begin(), AbsoluteSymbols.end());
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001022
Colin LeMahieu77804be2015-07-29 15:45:39 +00001023 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Colin LeMahieuf34933e2015-07-23 20:58:49 +00001024 if (!DisassembleAll && (!Section.isText() || Section.isVirtual()))
Mark Seaborneb03ac52014-01-25 00:32:01 +00001025 continue;
Michael J. Spencer1d6167f2011-06-25 17:55:23 +00001026
Rafael Espindola80291272014-10-08 15:28:58 +00001027 uint64_t SectionAddr = Section.getAddress();
1028 uint64_t SectSize = Section.getSize();
David Majnemer185b5b12014-11-11 09:58:25 +00001029 if (!SectSize)
1030 continue;
Simon Atanasyan2b614e12014-02-24 22:12:11 +00001031
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001032 // Get the list of all the symbols in this section.
1033 SectionSymbolsTy &Symbols = AllSymbols[Section];
Davide Italianof0706882015-10-01 21:57:09 +00001034 std::vector<uint64_t> DataMappingSymsAddr;
1035 std::vector<uint64_t> TextMappingSymsAddr;
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001036 if (isArmElf(Obj)) {
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001037 for (const auto &Symb : Symbols) {
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001038 uint64_t Address = std::get<0>(Symb);
1039 StringRef Name = std::get<1>(Symb);
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001040 if (Name.startswith("$d"))
David Majnemer153722d2015-11-18 04:35:32 +00001041 DataMappingSymsAddr.push_back(Address - SectionAddr);
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001042 if (Name.startswith("$x"))
David Majnemer153722d2015-11-18 04:35:32 +00001043 TextMappingSymsAddr.push_back(Address - SectionAddr);
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001044 if (Name.startswith("$a"))
1045 TextMappingSymsAddr.push_back(Address - SectionAddr);
1046 if (Name.startswith("$t"))
1047 TextMappingSymsAddr.push_back(Address - SectionAddr);
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001048 }
1049 }
1050
Fangrui Song0cac7262018-09-27 02:13:45 +00001051 llvm::sort(DataMappingSymsAddr);
1052 llvm::sort(TextMappingSymsAddr);
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001053
Sam Kolton3381d7a2016-10-06 13:46:08 +00001054 if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
1055 // AMDGPU disassembler uses symbolizer for printing labels
1056 std::unique_ptr<MCRelocationInfo> RelInfo(
1057 TheTarget->createMCRelocationInfo(TripleName, Ctx));
1058 if (RelInfo) {
1059 std::unique_ptr<MCSymbolizer> Symbolizer(
1060 TheTarget->createMCSymbolizer(
1061 TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo)));
1062 DisAsm->setSymbolizer(std::move(Symbolizer));
1063 }
1064 }
1065
Michael J. Spencer51862b32011-10-13 22:17:18 +00001066 // Make a list of all the relocations for this section.
1067 std::vector<RelocationRef> Rels;
1068 if (InlineRelocs) {
Alexey Samsonovaa4d2952014-03-14 14:22:49 +00001069 for (const SectionRef &RelocSec : SectionRelocMap[Section]) {
1070 for (const RelocationRef &Reloc : RelocSec.relocations()) {
1071 Rels.push_back(Reloc);
1072 }
Michael J. Spencer51862b32011-10-13 22:17:18 +00001073 }
1074 }
1075
1076 // Sort relocations by address.
George Rimar73a27232019-01-15 09:19:18 +00001077 llvm::sort(Rels, isRelocAddressLess);
Michael J. Spencer51862b32011-10-13 22:17:18 +00001078
Rafael Espindolaa9f810b2012-12-21 03:47:03 +00001079 StringRef SegmentName = "";
Mark Seaborneb03ac52014-01-25 00:32:01 +00001080 if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
Alexey Samsonov48803e52014-03-13 14:37:36 +00001081 DataRefImpl DR = Section.getRawDataRefImpl();
Rafael Espindola56f976f2013-04-18 18:08:55 +00001082 SegmentName = MachO->getSectionFinalSegmentName(DR);
Rafael Espindolaa9f810b2012-12-21 03:47:03 +00001083 }
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001084 StringRef SectionName;
1085 error(Section.getName(SectionName));
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001086
Rafael Espindola7884c952015-06-04 15:01:05 +00001087 // If the section has no symbol at the start, just insert a dummy one.
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001088 if (Symbols.empty() || std::get<0>(Symbols[0]) != 0) {
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001089 Symbols.insert(
1090 Symbols.begin(),
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001091 std::make_tuple(SectionAddr, SectionName,
1092 Section.isText() ? ELF::STT_FUNC : ELF::STT_OBJECT));
Sam Koltonc05d7782016-08-17 10:17:57 +00001093 }
Alp Tokere69170a2014-06-26 22:52:05 +00001094
1095 SmallString<40> Comments;
1096 raw_svector_ostream CommentStream(Comments);
Ahmed Bougachaad1084d2013-05-24 00:39:57 +00001097
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001098 StringRef BytesStr;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001099 error(Section.getContents(BytesStr));
Aaron Ballman106fd7b2014-11-12 14:01:17 +00001100 ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
1101 BytesStr.size());
Rafael Espindola7fc5b872014-11-12 02:04:27 +00001102
Michael J. Spencer2670c252011-01-20 06:39:06 +00001103 uint64_t Size;
1104 uint64_t Index;
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001105 bool PrintedSection = false;
Michael J. Spencer2670c252011-01-20 06:39:06 +00001106
George Rimar73a27232019-01-15 09:19:18 +00001107 std::vector<RelocationRef>::const_iterator RelCur = Rels.begin();
1108 std::vector<RelocationRef>::const_iterator RelEnd = Rels.end();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001109 // Disassemble symbol by symbol.
George Rimar73a27232019-01-15 09:19:18 +00001110 for (unsigned SI = 0, SE = Symbols.size(); SI != SE; ++SI) {
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001111 uint64_t Start = std::get<0>(Symbols[SI]) - SectionAddr;
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001112 // The end is either the section end or the beginning of the next
1113 // symbol.
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001114 uint64_t End = (SI == SE - 1)
1115 ? SectSize
1116 : std::get<0>(Symbols[SI + 1]) - SectionAddr;
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001117 // Don't try to disassemble beyond the end of section contents.
1118 if (End > SectSize)
1119 End = SectSize;
Rafael Espindolae45c7402014-08-17 16:31:39 +00001120 // If this symbol has the same address as the next symbol, then skip it.
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001121 if (Start >= End)
Michael J. Spenceree84f642011-10-13 20:37:08 +00001122 continue;
1123
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001124 // Check if we need to skip symbol
1125 // Skip if the symbol's data is not between StartAddress and StopAddress
1126 if (End + SectionAddr < StartAddress ||
1127 Start + SectionAddr > StopAddress) {
1128 continue;
1129 }
1130
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001131 /// Skip if user requested specific symbols and this is not in the list
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001132 if (!DisasmFuncsSet.empty() &&
1133 !DisasmFuncsSet.count(std::get<1>(Symbols[SI])))
Rafael Aulerb0e4b912018-03-09 19:13:44 +00001134 continue;
1135
1136 if (!PrintedSection) {
1137 PrintedSection = true;
1138 outs() << "Disassembly of section ";
1139 if (!SegmentName.empty())
1140 outs() << SegmentName << ",";
1141 outs() << SectionName << ':';
1142 }
1143
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001144 // Stop disassembly at the stop address specified
1145 if (End + SectionAddr > StopAddress)
1146 End = StopAddress - SectionAddr;
1147
Valery Pykhtinde048052016-04-07 07:24:01 +00001148 if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001149 if (std::get<2>(Symbols[SI]) == ELF::STT_AMDGPU_HSA_KERNEL) {
Sam Koltonc05d7782016-08-17 10:17:57 +00001150 // skip amd_kernel_code_t at the begining of kernel symbol (256 bytes)
1151 Start += 256;
1152 }
George Rimar73a27232019-01-15 09:19:18 +00001153 if (SI == SE - 1 ||
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001154 std::get<2>(Symbols[SI + 1]) == ELF::STT_AMDGPU_HSA_KERNEL) {
Sam Koltonc05d7782016-08-17 10:17:57 +00001155 // cut trailing zeroes at the end of kernel
1156 // cut up to 256 bytes
1157 const uint64_t EndAlign = 256;
1158 const auto Limit = End - (std::min)(EndAlign, End - Start);
1159 while (End > Limit &&
1160 *reinterpret_cast<const support::ulittle32_t*>(&Bytes[End - 4]) == 0)
1161 End -= 4;
1162 }
Valery Pykhtinde048052016-04-07 07:24:01 +00001163 }
1164
George Rimar6622d412018-12-19 10:21:45 +00001165 outs() << '\n';
George Rimar3ba0f3c02019-01-09 14:43:33 +00001166 if (!NoLeadingAddr)
1167 outs() << format("%016" PRIx64 " ", SectionAddr + Start);
1168
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001169 StringRef SymbolName = std::get<1>(Symbols[SI]);
George Rimar6622d412018-12-19 10:21:45 +00001170 if (Demangle)
1171 outs() << demangle(SymbolName) << ":\n";
1172 else
1173 outs() << SymbolName << ":\n";
Michael J. Spencer2670c252011-01-20 06:39:06 +00001174
Francis Visoiu Mistrih18346822018-04-19 17:02:57 +00001175 // Don't print raw contents of a virtual section. A virtual section
1176 // doesn't have any contents in the file.
1177 if (Section.isVirtual()) {
1178 outs() << "...\n";
1179 continue;
1180 }
1181
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001182#ifndef NDEBUG
Mark Seaborneb03ac52014-01-25 00:32:01 +00001183 raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001184#else
Mark Seaborneb03ac52014-01-25 00:32:01 +00001185 raw_ostream &DebugOut = nulls();
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001186#endif
1187
Wouter van Oortmerssenf3b762a2019-01-17 18:14:09 +00001188 // Some targets (like WebAssembly) have a special prelude at the start
1189 // of each symbol.
1190 DisAsm->onSymbolStart(SymbolName, Size, Bytes.slice(Start, End - Start),
1191 SectionAddr + Start, DebugOut, CommentStream);
1192 Start += Size;
1193
Benjamin Kramer43a772e2011-09-19 17:56:04 +00001194 for (Index = Start; Index < End; Index += Size) {
1195 MCInst Inst;
Owen Andersona0c3b972011-09-15 23:38:46 +00001196
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001197 if (Index + SectionAddr < StartAddress ||
1198 Index + SectionAddr > StopAddress) {
1199 // skip byte by byte till StartAddress is reached
1200 Size = 1;
1201 continue;
1202 }
Davide Italianof0706882015-10-01 21:57:09 +00001203 // AArch64 ELF binaries can interleave data and text in the
1204 // same section. We rely on the markers introduced to
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001205 // understand what we need to dump. If the data marker is within a
1206 // function, it is denoted as a word/short etc
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001207 if (isArmElf(Obj) && std::get<2>(Symbols[SI]) != ELF::STT_OBJECT &&
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001208 !DisassembleAll) {
Davide Italianof0706882015-10-01 21:57:09 +00001209 uint64_t Stride = 0;
1210
1211 auto DAI = std::lower_bound(DataMappingSymsAddr.begin(),
1212 DataMappingSymsAddr.end(), Index);
1213 if (DAI != DataMappingSymsAddr.end() && *DAI == Index) {
1214 // Switch to data.
1215 while (Index < End) {
1216 outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1217 outs() << "\t";
1218 if (Index + 4 <= End) {
1219 Stride = 4;
1220 dumpBytes(Bytes.slice(Index, 4), outs());
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001221 outs() << "\t.word\t";
1222 uint32_t Data = 0;
1223 if (Obj->isLittleEndian()) {
1224 const auto Word =
1225 reinterpret_cast<const support::ulittle32_t *>(
1226 Bytes.data() + Index);
1227 Data = *Word;
1228 } else {
1229 const auto Word = reinterpret_cast<const support::ubig32_t *>(
1230 Bytes.data() + Index);
1231 Data = *Word;
1232 }
1233 outs() << "0x" << format("%08" PRIx32, Data);
Davide Italianof0706882015-10-01 21:57:09 +00001234 } else if (Index + 2 <= End) {
1235 Stride = 2;
1236 dumpBytes(Bytes.slice(Index, 2), outs());
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001237 outs() << "\t\t.short\t";
1238 uint16_t Data = 0;
1239 if (Obj->isLittleEndian()) {
1240 const auto Short =
1241 reinterpret_cast<const support::ulittle16_t *>(
1242 Bytes.data() + Index);
1243 Data = *Short;
1244 } else {
1245 const auto Short =
1246 reinterpret_cast<const support::ubig16_t *>(Bytes.data() +
1247 Index);
1248 Data = *Short;
1249 }
1250 outs() << "0x" << format("%04" PRIx16, Data);
Davide Italianof0706882015-10-01 21:57:09 +00001251 } else {
1252 Stride = 1;
1253 dumpBytes(Bytes.slice(Index, 1), outs());
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001254 outs() << "\t\t.byte\t";
1255 outs() << "0x" << format("%02" PRIx8, Bytes.slice(Index, 1)[0]);
Davide Italianof0706882015-10-01 21:57:09 +00001256 }
1257 Index += Stride;
1258 outs() << "\n";
1259 auto TAI = std::lower_bound(TextMappingSymsAddr.begin(),
1260 TextMappingSymsAddr.end(), Index);
1261 if (TAI != TextMappingSymsAddr.end() && *TAI == Index)
1262 break;
1263 }
1264 }
1265 }
1266
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001267 // If there is a data symbol inside an ELF text section and we are only
1268 // disassembling text (applicable all architectures),
1269 // we are in a situation where we must print the data and not
1270 // disassemble it.
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001271 if (Obj->isELF() && std::get<2>(Symbols[SI]) == ELF::STT_OBJECT &&
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001272 !DisassembleAll && Section.isText()) {
1273 // print out data up to 8 bytes at a time in hex and ascii
1274 uint8_t AsciiData[9] = {'\0'};
1275 uint8_t Byte;
1276 int NumBytes = 0;
1277
1278 for (Index = Start; Index < End; Index += 1) {
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001279 if (((SectionAddr + Index) < StartAddress) ||
1280 ((SectionAddr + Index) > StopAddress))
1281 continue;
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001282 if (NumBytes == 0) {
1283 outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1284 outs() << "\t";
1285 }
1286 Byte = Bytes.slice(Index)[0];
1287 outs() << format(" %02x", Byte);
Michael Kruse6f1da6e2018-07-26 15:31:41 +00001288 AsciiData[NumBytes] = isPrint(Byte) ? Byte : '.';
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001289
1290 uint8_t IndentOffset = 0;
1291 NumBytes++;
1292 if (Index == End - 1 || NumBytes > 8) {
1293 // Indent the space for less than 8 bytes data.
1294 // 2 spaces for byte and one for space between bytes
1295 IndentOffset = 3 * (8 - NumBytes);
1296 for (int Excess = 8 - NumBytes; Excess < 8; Excess++)
1297 AsciiData[Excess] = '\0';
1298 NumBytes = 8;
1299 }
1300 if (NumBytes == 8) {
1301 AsciiData[8] = '\0';
1302 outs() << std::string(IndentOffset, ' ') << " ";
1303 outs() << reinterpret_cast<char *>(AsciiData);
1304 outs() << '\n';
1305 NumBytes = 0;
1306 }
1307 }
1308 }
Davide Italianof0706882015-10-01 21:57:09 +00001309 if (Index >= End)
1310 break;
1311
George Rimar70d197d2019-01-10 14:55:26 +00001312 if (size_t N =
1313 countSkippableZeroBytes(Bytes.slice(Index, End - Index))) {
1314 outs() << "\t\t..." << '\n';
1315 Index += N;
1316 if (Index >= End)
1317 break;
1318 }
1319
Hemant Kulkarni5b60f632016-08-25 19:41:08 +00001320 // Disassemble a real instruction or a data when disassemble all is
1321 // provided
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001322 bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
1323 SectionAddr + Index, DebugOut,
1324 CommentStream);
1325 if (Size == 0)
1326 Size = 1;
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +00001327
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001328 PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +00001329 Bytes.slice(Index, Size), SectionAddr + Index, outs(), "",
Sid Manningd9f28732018-05-14 19:46:08 +00001330 *STI, &SP, &Rels);
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001331 outs() << CommentStream.str();
1332 Comments.clear();
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001333
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001334 // Try to resolve the target of a call, tail call, etc. to a specific
1335 // symbol.
1336 if (MIA && (MIA->isCall(Inst) || MIA->isUnconditionalBranch(Inst) ||
1337 MIA->isConditionalBranch(Inst))) {
1338 uint64_t Target;
1339 if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
1340 // In a relocatable object, the target's section must reside in
1341 // the same section as the call instruction or it is accessed
1342 // through a relocation.
1343 //
1344 // In a non-relocatable object, the target may be in any section.
1345 //
1346 // N.B. We don't walk the relocations in the relocatable case yet.
1347 auto *TargetSectionSymbols = &Symbols;
1348 if (!Obj->isRelocatableObject()) {
1349 auto SectionAddress = std::upper_bound(
1350 SectionAddresses.begin(), SectionAddresses.end(), Target,
1351 [](uint64_t LHS,
1352 const std::pair<uint64_t, SectionRef> &RHS) {
1353 return LHS < RHS.first;
1354 });
1355 if (SectionAddress != SectionAddresses.begin()) {
1356 --SectionAddress;
1357 TargetSectionSymbols = &AllSymbols[SectionAddress->second];
1358 } else {
Sterling Augustinebc78b622018-06-28 18:57:13 +00001359 TargetSectionSymbols = &AbsoluteSymbols;
David Majnemerfbb1c3a2015-11-18 02:49:19 +00001360 }
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001361 }
David Majnemer2603a8fa2015-07-09 18:11:40 +00001362
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001363 // Find the first symbol in the section whose offset is less than
Sterling Augustinebc78b622018-06-28 18:57:13 +00001364 // or equal to the target. If there isn't a section that contains
1365 // the target, find the nearest preceding absolute symbol.
1366 auto TargetSym = std::upper_bound(
1367 TargetSectionSymbols->begin(), TargetSectionSymbols->end(),
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001368 Target, [](uint64_t LHS,
1369 const std::tuple<uint64_t, StringRef, uint8_t> &RHS) {
1370 return LHS < std::get<0>(RHS);
Sterling Augustinebc78b622018-06-28 18:57:13 +00001371 });
1372 if (TargetSym == TargetSectionSymbols->begin()) {
1373 TargetSectionSymbols = &AbsoluteSymbols;
1374 TargetSym = std::upper_bound(
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001375 AbsoluteSymbols.begin(), AbsoluteSymbols.end(),
1376 Target, [](uint64_t LHS,
1377 const std::tuple<uint64_t, StringRef, uint8_t> &RHS) {
1378 return LHS < std::get<0>(RHS);
1379 });
Sterling Augustinebc78b622018-06-28 18:57:13 +00001380 }
1381 if (TargetSym != TargetSectionSymbols->begin()) {
1382 --TargetSym;
Clement Courbetd1a3bd42019-01-18 15:26:14 +00001383 uint64_t TargetAddress = std::get<0>(*TargetSym);
1384 StringRef TargetName = std::get<1>(*TargetSym);
1385 outs() << " <" << TargetName;
1386 uint64_t Disp = Target - TargetAddress;
Sterling Augustinebc78b622018-06-28 18:57:13 +00001387 if (Disp)
1388 outs() << "+0x" << Twine::utohexstr(Disp);
1389 outs() << '>';
David Majnemer81afca62015-07-07 22:06:59 +00001390 }
1391 }
Benjamin Kramere0dda9c2011-07-15 18:39:24 +00001392 }
Colin LeMahieu307a83d2016-03-18 16:26:48 +00001393 outs() << "\n";
Michael J. Spencer51862b32011-10-13 22:17:18 +00001394
Sid Manningd9f28732018-05-14 19:46:08 +00001395 // Hexagon does this in pretty printer
1396 if (Obj->getArch() != Triple::hexagon)
1397 // Print relocation for instruction.
George Rimar73a27232019-01-15 09:19:18 +00001398 while (RelCur != RelEnd) {
1399 uint64_t Addr = RelCur->getOffset();
1400 SmallString<16> Name;
1401 SmallString<32> Val;
Owen Andersonfa3e5202011-10-25 20:35:53 +00001402
Sid Manningd9f28732018-05-14 19:46:08 +00001403 // If this relocation is hidden, skip it.
George Rimar73a27232019-01-15 09:19:18 +00001404 if (getHidden(*RelCur) || ((SectionAddr + Addr) < StartAddress)) {
1405 ++RelCur;
Sid Manningd9f28732018-05-14 19:46:08 +00001406 continue;
1407 }
1408
1409 // Stop when rel_cur's address is past the current instruction.
George Rimar73a27232019-01-15 09:19:18 +00001410 if (Addr >= Index + Size)
1411 break;
1412 RelCur->getTypeName(Name);
1413 error(getRelocationValueString(*RelCur, Val));
1414 outs() << format(Fmt.data(), SectionAddr + Addr) << Name << "\t"
1415 << Val << "\n";
1416 ++RelCur;
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001417 }
Benjamin Kramer87ee76c2011-07-20 19:37:35 +00001418 }
Michael J. Spencer2670c252011-01-20 06:39:06 +00001419 }
1420 }
1421}
1422
George Rimar73a27232019-01-15 09:19:18 +00001423void llvm::printRelocations(const ObjectFile *Obj) {
Greg Fitzgerald18432272014-03-20 22:55:15 +00001424 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
1425 "%08" PRIx64;
Rafael Espindola9219fe72016-03-21 20:59:15 +00001426 // Regular objdump doesn't print relocations in non-relocatable object
1427 // files.
1428 if (!Obj->isRelocatableObject())
1429 return;
Rafael Espindolac66d7612014-08-17 19:09:37 +00001430
Colin LeMahieu77804be2015-07-29 15:45:39 +00001431 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Alexey Samsonov48803e52014-03-13 14:37:36 +00001432 if (Section.relocation_begin() == Section.relocation_end())
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001433 continue;
George Rimar73a27232019-01-15 09:19:18 +00001434 StringRef SecName;
1435 error(Section.getName(SecName));
1436 outs() << "RELOCATION RECORDS FOR [" << SecName << "]:\n";
Alexey Samsonovaa4d2952014-03-14 14:22:49 +00001437 for (const RelocationRef &Reloc : Section.relocations()) {
George Rimar73a27232019-01-15 09:19:18 +00001438 uint64_t Address = Reloc.getOffset();
1439 SmallString<32> RelocName;
1440 SmallString<32> ValueStr;
1441 if (Address < StartAddress || Address > StopAddress || getHidden(Reloc))
Alexey Samsonovaa4d2952014-03-14 14:22:49 +00001442 continue;
George Rimar73a27232019-01-15 09:19:18 +00001443 Reloc.getTypeName(RelocName);
1444 error(getRelocationValueString(Reloc, ValueStr));
1445 outs() << format(Fmt.data(), Address) << " " << RelocName << " "
1446 << ValueStr << "\n";
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001447 }
1448 outs() << "\n";
1449 }
1450}
1451
George Rimar73a27232019-01-15 09:19:18 +00001452void llvm::printDynamicRelocations(const ObjectFile *Obj) {
Paul Semelcb0f0432018-06-07 13:30:55 +00001453 // For the moment, this option is for ELF only
1454 if (!Obj->isELF())
1455 return;
1456
1457 const auto *Elf = dyn_cast<ELFObjectFileBase>(Obj);
Paul Semelcb0f0432018-06-07 13:30:55 +00001458 if (!Elf || Elf->getEType() != ELF::ET_DYN) {
1459 error("not a dynamic object");
1460 return;
1461 }
1462
Paul Semelcb0f0432018-06-07 13:30:55 +00001463 std::vector<SectionRef> DynRelSec = Obj->dynamic_relocation_sections();
1464 if (DynRelSec.empty())
1465 return;
1466
1467 outs() << "DYNAMIC RELOCATION RECORDS\n";
George Rimar73a27232019-01-15 09:19:18 +00001468 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
Paul Semelcb0f0432018-06-07 13:30:55 +00001469 for (const SectionRef &Section : DynRelSec) {
1470 if (Section.relocation_begin() == Section.relocation_end())
1471 continue;
1472 for (const RelocationRef &Reloc : Section.relocations()) {
George Rimar73a27232019-01-15 09:19:18 +00001473 uint64_t Address = Reloc.getOffset();
1474 SmallString<32> RelocName;
1475 SmallString<32> ValueStr;
1476 Reloc.getTypeName(RelocName);
1477 error(getRelocationValueString(Reloc, ValueStr));
1478 outs() << format(Fmt.data(), Address) << " " << RelocName << " "
1479 << ValueStr << "\n";
Paul Semelcb0f0432018-06-07 13:30:55 +00001480 }
1481 }
1482}
1483
George Rimar73a27232019-01-15 09:19:18 +00001484void llvm::printSectionHeaders(const ObjectFile *Obj) {
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001485 outs() << "Sections:\n"
1486 "Idx Name Size Address Type\n";
Colin LeMahieu77804be2015-07-29 15:45:39 +00001487 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001488 StringRef Name;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001489 error(Section.getName(Name));
Rafael Espindola80291272014-10-08 15:28:58 +00001490 uint64_t Address = Section.getAddress();
1491 uint64_t Size = Section.getSize();
1492 bool Text = Section.isText();
1493 bool Data = Section.isData();
1494 bool BSS = Section.isBSS();
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001495 std::string Type = (std::string(Text ? "TEXT " : "") +
Michael J. Spencer8f67d472011-10-13 20:37:20 +00001496 (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
George Rimare35e6442018-07-18 08:34:35 +00001497 outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
George Rimarc1090da2018-07-18 09:25:36 +00001498 (unsigned)Section.getIndex(), Name.str().c_str(), Size,
1499 Address, Type.c_str());
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001500 }
Xing GUO785edea2018-11-17 08:12:48 +00001501 outs() << "\n";
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001502}
1503
George Rimar73a27232019-01-15 09:19:18 +00001504void llvm::printSectionContents(const ObjectFile *Obj) {
Rafael Espindola4453e42942014-06-13 03:07:50 +00001505 std::error_code EC;
Colin LeMahieu77804be2015-07-29 15:45:39 +00001506 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001507 StringRef Name;
1508 StringRef Contents;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001509 error(Section.getName(Name));
Rafael Espindola80291272014-10-08 15:28:58 +00001510 uint64_t BaseAddr = Section.getAddress();
David Majnemer185b5b12014-11-11 09:58:25 +00001511 uint64_t Size = Section.getSize();
1512 if (!Size)
1513 continue;
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001514
1515 outs() << "Contents of section " << Name << ":\n";
David Majnemer185b5b12014-11-11 09:58:25 +00001516 if (Section.isBSS()) {
Alexey Samsonov209095c2013-04-16 10:53:11 +00001517 outs() << format("<skipping contents of bss section at [%04" PRIx64
David Majnemer8f6b04c2014-07-14 16:20:14 +00001518 ", %04" PRIx64 ")>\n",
1519 BaseAddr, BaseAddr + Size);
Alexey Samsonov209095c2013-04-16 10:53:11 +00001520 continue;
1521 }
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001522
Davide Italianoccd53fe2015-08-05 07:18:31 +00001523 error(Section.getContents(Contents));
David Majnemer8f6b04c2014-07-14 16:20:14 +00001524
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001525 // Dump out the content as hex and printable ascii characters.
George Rimar73a27232019-01-15 09:19:18 +00001526 for (std::size_t Addr = 0, End = Contents.size(); Addr < End; Addr += 16) {
1527 outs() << format(" %04" PRIx64 " ", BaseAddr + Addr);
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001528 // Dump line of hex.
George Rimar73a27232019-01-15 09:19:18 +00001529 for (std::size_t I = 0; I < 16; ++I) {
1530 if (I != 0 && I % 4 == 0)
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001531 outs() << ' ';
George Rimar73a27232019-01-15 09:19:18 +00001532 if (Addr + I < End)
1533 outs() << hexdigit((Contents[Addr + I] >> 4) & 0xF, true)
1534 << hexdigit(Contents[Addr + I] & 0xF, true);
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001535 else
1536 outs() << " ";
1537 }
1538 // Print ascii.
1539 outs() << " ";
George Rimar73a27232019-01-15 09:19:18 +00001540 for (std::size_t I = 0; I < 16 && Addr + I < End; ++I) {
1541 if (isPrint(static_cast<unsigned char>(Contents[Addr + I]) & 0xFF))
1542 outs() << Contents[Addr + I];
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001543 else
1544 outs() << ".";
1545 }
1546 outs() << "\n";
1547 }
1548 }
1549}
1550
George Rimar73a27232019-01-15 09:19:18 +00001551void llvm::printSymbolTable(const ObjectFile *O, StringRef ArchiveName,
Kevin Enderby9acb1092016-05-31 20:35:34 +00001552 StringRef ArchitectureName) {
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001553 outs() << "SYMBOL TABLE:\n";
1554
George Rimar73a27232019-01-15 09:19:18 +00001555 if (const COFFObjectFile *Coff = dyn_cast<const COFFObjectFile>(O)) {
1556 printCOFFSymbolTable(Coff);
Rui Ueyama4e39f712014-03-18 18:58:51 +00001557 return;
1558 }
George Rimar8e0a70b2019-01-10 16:24:10 +00001559
George Rimar73a27232019-01-15 09:19:18 +00001560 for (auto I = O->symbol_begin(), E = O->symbol_end(); I != E; ++I) {
George Rimar8e0a70b2019-01-10 16:24:10 +00001561 // Skip printing the special zero symbol when dumping an ELF file.
1562 // This makes the output consistent with the GNU objdump.
George Rimar73a27232019-01-15 09:19:18 +00001563 if (I == O->symbol_begin() && isa<ELFObjectFileBase>(O))
George Rimar8e0a70b2019-01-10 16:24:10 +00001564 continue;
1565
1566 const SymbolRef &Symbol = *I;
Kevin Enderby931cb652016-06-24 18:24:42 +00001567 Expected<uint64_t> AddressOrError = Symbol.getAddress();
1568 if (!AddressOrError)
George Rimar73a27232019-01-15 09:19:18 +00001569 report_error(ArchiveName, O->getFileName(), AddressOrError.takeError(),
Kevin Enderby7fa40c92016-11-16 22:17:38 +00001570 ArchitectureName);
Rafael Espindolaed067c42015-07-03 18:19:00 +00001571 uint64_t Address = *AddressOrError;
Hemant Kulkarniaecf9d02016-09-12 17:08:22 +00001572 if ((Address < StartAddress) || (Address > StopAddress))
1573 continue;
Kevin Enderby7bd8d992016-05-02 20:28:12 +00001574 Expected<SymbolRef::Type> TypeOrError = Symbol.getType();
1575 if (!TypeOrError)
George Rimar73a27232019-01-15 09:19:18 +00001576 report_error(ArchiveName, O->getFileName(), TypeOrError.takeError(),
Kevin Enderby7fa40c92016-11-16 22:17:38 +00001577 ArchitectureName);
Kevin Enderby5afbc1c2016-03-23 20:27:00 +00001578 SymbolRef::Type Type = *TypeOrError;
Rui Ueyama4e39f712014-03-18 18:58:51 +00001579 uint32_t Flags = Symbol.getFlags();
Kevin Enderby7bd8d992016-05-02 20:28:12 +00001580 Expected<section_iterator> SectionOrErr = Symbol.getSection();
Kevin Enderby7fa40c92016-11-16 22:17:38 +00001581 if (!SectionOrErr)
George Rimar73a27232019-01-15 09:19:18 +00001582 report_error(ArchiveName, O->getFileName(), SectionOrErr.takeError(),
Kevin Enderby7fa40c92016-11-16 22:17:38 +00001583 ArchitectureName);
Rafael Espindola8bab8892015-08-07 23:27:14 +00001584 section_iterator Section = *SectionOrErr;
Rafael Espindola75d5b542015-06-03 05:14:22 +00001585 StringRef Name;
George Rimar73a27232019-01-15 09:19:18 +00001586 if (Type == SymbolRef::ST_Debug && Section != O->section_end()) {
Rafael Espindola75d5b542015-06-03 05:14:22 +00001587 Section->getName(Name);
Rafael Espindola5d0c2ff2015-07-02 20:55:21 +00001588 } else {
Kevin Enderby81e8b7d2016-04-20 21:24:34 +00001589 Expected<StringRef> NameOrErr = Symbol.getName();
1590 if (!NameOrErr)
George Rimar73a27232019-01-15 09:19:18 +00001591 report_error(ArchiveName, O->getFileName(), NameOrErr.takeError(),
Kevin Enderby9acb1092016-05-31 20:35:34 +00001592 ArchitectureName);
Rafael Espindola5d0c2ff2015-07-02 20:55:21 +00001593 Name = *NameOrErr;
Rafael Espindola75d5b542015-06-03 05:14:22 +00001594 }
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001595
Rui Ueyama4e39f712014-03-18 18:58:51 +00001596 bool Global = Flags & SymbolRef::SF_Global;
1597 bool Weak = Flags & SymbolRef::SF_Weak;
1598 bool Absolute = Flags & SymbolRef::SF_Absolute;
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001599 bool Common = Flags & SymbolRef::SF_Common;
Davide Italianocd2514d2015-04-30 23:08:53 +00001600 bool Hidden = Flags & SymbolRef::SF_Hidden;
David Meyer1df4b842012-02-28 23:47:53 +00001601
Rui Ueyama4e39f712014-03-18 18:58:51 +00001602 char GlobLoc = ' ';
1603 if (Type != SymbolRef::ST_Unknown)
1604 GlobLoc = Global ? 'g' : 'l';
1605 char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
1606 ? 'd' : ' ';
1607 char FileFunc = ' ';
1608 if (Type == SymbolRef::ST_File)
1609 FileFunc = 'f';
1610 else if (Type == SymbolRef::ST_Function)
1611 FileFunc = 'F';
Kristina Brooks0674f9d2018-11-11 17:47:13 +00001612 else if (Type == SymbolRef::ST_Data)
1613 FileFunc = 'O';
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001614
George Rimar73a27232019-01-15 09:19:18 +00001615 const char *Fmt = O->getBytesInAddress() > 4 ? "%016" PRIx64 :
Rui Ueyama4e39f712014-03-18 18:58:51 +00001616 "%08" PRIx64;
Michael J. Spencerd857c1c2013-01-10 22:40:50 +00001617
Rui Ueyama4e39f712014-03-18 18:58:51 +00001618 outs() << format(Fmt, Address) << " "
1619 << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
1620 << (Weak ? 'w' : ' ') // Weak?
1621 << ' ' // Constructor. Not supported yet.
1622 << ' ' // Warning. Not supported yet.
1623 << ' ' // Indirect reference to another symbol.
1624 << Debug // Debugging (d) or dynamic (D) symbol.
1625 << FileFunc // Name of function (F), file (f) or object (O).
1626 << ' ';
1627 if (Absolute) {
1628 outs() << "*ABS*";
Colin LeMahieubc2f47a2015-01-23 20:06:24 +00001629 } else if (Common) {
1630 outs() << "*COM*";
George Rimar73a27232019-01-15 09:19:18 +00001631 } else if (Section == O->section_end()) {
Rui Ueyama4e39f712014-03-18 18:58:51 +00001632 outs() << "*UND*";
1633 } else {
1634 if (const MachOObjectFile *MachO =
George Rimar73a27232019-01-15 09:19:18 +00001635 dyn_cast<const MachOObjectFile>(O)) {
Rui Ueyama4e39f712014-03-18 18:58:51 +00001636 DataRefImpl DR = Section->getRawDataRefImpl();
1637 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
1638 outs() << SegmentName << ",";
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001639 }
Rui Ueyama4e39f712014-03-18 18:58:51 +00001640 StringRef SectionName;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001641 error(Section->getName(SectionName));
Rui Ueyama4e39f712014-03-18 18:58:51 +00001642 outs() << SectionName;
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001643 }
Rafael Espindola5f7ade22015-06-23 15:45:38 +00001644
1645 outs() << '\t';
George Rimar73a27232019-01-15 09:19:18 +00001646 if (Common || isa<ELFObjectFileBase>(O)) {
Rafael Espindoladbb6bd32015-06-25 22:10:04 +00001647 uint64_t Val =
1648 Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
Rafael Espindolaae3ac082015-06-23 18:34:25 +00001649 outs() << format("\t %08" PRIx64 " ", Val);
1650 }
Rafael Espindola5f7ade22015-06-23 15:45:38 +00001651
George Rimar73a27232019-01-15 09:19:18 +00001652 if (Hidden)
Davide Italianocd2514d2015-04-30 23:08:53 +00001653 outs() << ".hidden ";
George Rimar6622d412018-12-19 10:21:45 +00001654
1655 if (Demangle)
1656 outs() << demangle(Name) << '\n';
1657 else
1658 outs() << Name << '\n';
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001659 }
1660}
1661
George Rimar73a27232019-01-15 09:19:18 +00001662static void printUnwindInfo(const ObjectFile *O) {
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001663 outs() << "Unwind info:\n\n";
1664
George Rimar73a27232019-01-15 09:19:18 +00001665 if (const COFFObjectFile *Coff = dyn_cast<COFFObjectFile>(O))
1666 printCOFFUnwindInfo(Coff);
1667 else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O))
Tim Northover4bd286a2014-08-01 13:07:19 +00001668 printMachOUnwindInfo(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001669 else
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001670 // TODO: Extract DWARF dump tool to objdump.
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001671 WithColor::error(errs(), ToolName)
1672 << "This operation is only currently supported "
1673 "for COFF and MachO object files.\n";
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001674}
1675
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001676void llvm::printExportsTrie(const ObjectFile *o) {
Nick Kledzikd04bc352014-08-30 00:20:14 +00001677 outs() << "Exports trie:\n";
1678 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
1679 printMachOExportsTrie(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001680 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001681 WithColor::error(errs(), ToolName)
1682 << "This operation is only currently supported "
1683 "for Mach-O executable files.\n";
Nick Kledzikd04bc352014-08-30 00:20:14 +00001684}
1685
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001686void llvm::printRebaseTable(ObjectFile *o) {
Nick Kledzikac431442014-09-12 21:34:15 +00001687 outs() << "Rebase table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001688 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzikac431442014-09-12 21:34:15 +00001689 printMachORebaseTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001690 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001691 WithColor::error(errs(), ToolName)
1692 << "This operation is only currently supported "
1693 "for Mach-O executable files.\n";
Nick Kledzikac431442014-09-12 21:34:15 +00001694}
1695
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001696void llvm::printBindTable(ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001697 outs() << "Bind table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001698 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzik56ebef42014-09-16 01:41:51 +00001699 printMachOBindTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001700 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001701 WithColor::error(errs(), ToolName)
1702 << "This operation is only currently supported "
1703 "for Mach-O executable files.\n";
Nick Kledzik56ebef42014-09-16 01:41:51 +00001704}
1705
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001706void llvm::printLazyBindTable(ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001707 outs() << "Lazy bind table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001708 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzik56ebef42014-09-16 01:41:51 +00001709 printMachOLazyBindTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001710 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001711 WithColor::error(errs(), ToolName)
1712 << "This operation is only currently supported "
1713 "for Mach-O executable files.\n";
Nick Kledzik56ebef42014-09-16 01:41:51 +00001714}
1715
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001716void llvm::printWeakBindTable(ObjectFile *o) {
Nick Kledzik56ebef42014-09-16 01:41:51 +00001717 outs() << "Weak bind table:\n";
Kevin Enderbya8d256c2017-03-20 19:46:55 +00001718 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
Nick Kledzik56ebef42014-09-16 01:41:51 +00001719 printMachOWeakBindTable(MachO);
George Rimar73a27232019-01-15 09:19:18 +00001720 else
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001721 WithColor::error(errs(), ToolName)
1722 << "This operation is only currently supported "
1723 "for Mach-O executable files.\n";
Nick Kledzik56ebef42014-09-16 01:41:51 +00001724}
Nick Kledzikac431442014-09-12 21:34:15 +00001725
Adrian Prantl437105a2015-07-08 02:04:15 +00001726/// Dump the raw contents of the __clangast section so the output can be piped
1727/// into llvm-bcanalyzer.
1728void llvm::printRawClangAST(const ObjectFile *Obj) {
1729 if (outs().is_displayed()) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001730 WithColor::error(errs(), ToolName)
1731 << "The -raw-clang-ast option will dump the raw binary contents of "
1732 "the clang ast section.\n"
1733 "Please redirect the output to a file or another program such as "
1734 "llvm-bcanalyzer.\n";
Adrian Prantl437105a2015-07-08 02:04:15 +00001735 return;
1736 }
1737
1738 StringRef ClangASTSectionName("__clangast");
1739 if (isa<COFFObjectFile>(Obj)) {
1740 ClangASTSectionName = "clangast";
1741 }
1742
1743 Optional<object::SectionRef> ClangASTSection;
Colin LeMahieu77804be2015-07-29 15:45:39 +00001744 for (auto Sec : ToolSectionFilter(*Obj)) {
Adrian Prantl437105a2015-07-08 02:04:15 +00001745 StringRef Name;
1746 Sec.getName(Name);
1747 if (Name == ClangASTSectionName) {
1748 ClangASTSection = Sec;
1749 break;
1750 }
1751 }
1752 if (!ClangASTSection)
1753 return;
1754
1755 StringRef ClangASTContents;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001756 error(ClangASTSection.getValue().getContents(ClangASTContents));
Adrian Prantl437105a2015-07-08 02:04:15 +00001757 outs().write(ClangASTContents.data(), ClangASTContents.size());
1758}
1759
Sanjoy Das6f567a42015-06-22 18:03:02 +00001760static void printFaultMaps(const ObjectFile *Obj) {
George Rimar73a27232019-01-15 09:19:18 +00001761 StringRef FaultMapSectionName;
Sanjoy Das6f567a42015-06-22 18:03:02 +00001762
1763 if (isa<ELFObjectFileBase>(Obj)) {
1764 FaultMapSectionName = ".llvm_faultmaps";
1765 } else if (isa<MachOObjectFile>(Obj)) {
1766 FaultMapSectionName = "__llvm_faultmaps";
1767 } else {
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001768 WithColor::error(errs(), ToolName)
1769 << "This operation is only currently supported "
1770 "for ELF and Mach-O executable files.\n";
Sanjoy Das6f567a42015-06-22 18:03:02 +00001771 return;
1772 }
1773
1774 Optional<object::SectionRef> FaultMapSection;
1775
Colin LeMahieu77804be2015-07-29 15:45:39 +00001776 for (auto Sec : ToolSectionFilter(*Obj)) {
Sanjoy Das6f567a42015-06-22 18:03:02 +00001777 StringRef Name;
1778 Sec.getName(Name);
1779 if (Name == FaultMapSectionName) {
1780 FaultMapSection = Sec;
1781 break;
1782 }
1783 }
1784
1785 outs() << "FaultMap table:\n";
1786
1787 if (!FaultMapSection.hasValue()) {
1788 outs() << "<not found>\n";
1789 return;
1790 }
1791
1792 StringRef FaultMapContents;
Davide Italianoccd53fe2015-08-05 07:18:31 +00001793 error(FaultMapSection.getValue().getContents(FaultMapContents));
Sanjoy Das6f567a42015-06-22 18:03:02 +00001794
1795 FaultMapParser FMP(FaultMapContents.bytes_begin(),
1796 FaultMapContents.bytes_end());
1797
1798 outs() << FMP;
1799}
1800
George Rimar73a27232019-01-15 09:19:18 +00001801static void printPrivateFileHeaders(const ObjectFile *O, bool OnlyFirst) {
1802 if (O->isELF()) {
1803 printELFFileHeader(O);
1804 return printELFDynamicSection(O);
Paul Semel0913dcd2018-07-25 11:09:20 +00001805 }
George Rimar73a27232019-01-15 09:19:18 +00001806 if (O->isCOFF())
1807 return printCOFFFileHeader(O);
1808 if (O->isWasm())
1809 return printWasmFileHeader(O);
1810 if (O->isMachO()) {
1811 printMachOFileHeader(O);
1812 if (!OnlyFirst)
1813 printMachOLoadCommands(O);
Davide Italiano1bdaa202016-09-18 04:39:15 +00001814 return;
1815 }
George Rimar73a27232019-01-15 09:19:18 +00001816 report_error(O->getFileName(), "Invalid/Unsupported object file format");
Rui Ueyamac2bed422013-09-27 21:04:00 +00001817}
1818
George Rimar73a27232019-01-15 09:19:18 +00001819static void printFileHeaders(const ObjectFile *O) {
1820 if (!O->isELF() && !O->isCOFF())
1821 report_error(O->getFileName(), "Invalid/Unsupported object file format");
Paul Semeld2af4d62018-07-04 15:25:03 +00001822
George Rimar73a27232019-01-15 09:19:18 +00001823 Triple::ArchType AT = O->getArch();
Paul Semeld2af4d62018-07-04 15:25:03 +00001824 outs() << "architecture: " << Triple::getArchTypeName(AT) << "\n";
George Rimar73a27232019-01-15 09:19:18 +00001825 Expected<uint64_t> StartAddrOrErr = O->getStartAddress();
Paul Semeld2af4d62018-07-04 15:25:03 +00001826 if (!StartAddrOrErr)
George Rimar73a27232019-01-15 09:19:18 +00001827 report_error(O->getFileName(), StartAddrOrErr.takeError());
Petar Jovanovic8d947ba2018-10-19 22:16:49 +00001828
George Rimar73a27232019-01-15 09:19:18 +00001829 StringRef Fmt = O->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
Petar Jovanovic8d947ba2018-10-19 22:16:49 +00001830 uint64_t Address = StartAddrOrErr.get();
Paul Semeld2af4d62018-07-04 15:25:03 +00001831 outs() << "start address: "
George Rimar9b6fe7e2019-01-12 12:17:24 +00001832 << "0x" << format(Fmt.data(), Address) << "\n\n";
Paul Semeld2af4d62018-07-04 15:25:03 +00001833}
1834
Paul Semel0dc92f62018-07-05 14:43:29 +00001835static void printArchiveChild(StringRef Filename, const Archive::Child &C) {
1836 Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
1837 if (!ModeOrErr) {
Jonas Devliegheree787efd2018-11-11 22:12:04 +00001838 WithColor::error(errs(), ToolName) << "ill-formed archive entry.\n";
Paul Semel0dc92f62018-07-05 14:43:29 +00001839 consumeError(ModeOrErr.takeError());
1840 return;
1841 }
1842 sys::fs::perms Mode = ModeOrErr.get();
1843 outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
1844 outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
1845 outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
1846 outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
1847 outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
1848 outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
1849 outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
1850 outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
1851 outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
1852
1853 outs() << " ";
1854
1855 Expected<unsigned> UIDOrErr = C.getUID();
1856 if (!UIDOrErr)
1857 report_error(Filename, UIDOrErr.takeError());
1858 unsigned UID = UIDOrErr.get();
1859 outs() << format("%d/", UID);
1860
1861 Expected<unsigned> GIDOrErr = C.getGID();
1862 if (!GIDOrErr)
1863 report_error(Filename, GIDOrErr.takeError());
1864 unsigned GID = GIDOrErr.get();
1865 outs() << format("%-d ", GID);
1866
1867 Expected<uint64_t> Size = C.getRawSize();
1868 if (!Size)
1869 report_error(Filename, Size.takeError());
1870 outs() << format("%6" PRId64, Size.get()) << " ";
1871
1872 StringRef RawLastModified = C.getRawLastModified();
1873 unsigned Seconds;
1874 if (RawLastModified.getAsInteger(10, Seconds))
1875 outs() << "(date: \"" << RawLastModified
1876 << "\" contains non-decimal chars) ";
1877 else {
1878 // Since ctime(3) returns a 26 character string of the form:
1879 // "Sun Sep 16 01:03:52 1973\n\0"
1880 // just print 24 characters.
1881 time_t t = Seconds;
1882 outs() << format("%.24s ", ctime(&t));
1883 }
1884
1885 StringRef Name = "";
1886 Expected<StringRef> NameOrErr = C.getName();
1887 if (!NameOrErr) {
1888 consumeError(NameOrErr.takeError());
1889 Expected<StringRef> RawNameOrErr = C.getRawName();
1890 if (!RawNameOrErr)
1891 report_error(Filename, NameOrErr.takeError());
1892 Name = RawNameOrErr.get();
1893 } else {
1894 Name = NameOrErr.get();
1895 }
1896 outs() << Name << "\n";
1897}
1898
George Rimar73a27232019-01-15 09:19:18 +00001899static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
1900 const Archive::Child *C = nullptr) {
Adrian Prantl437105a2015-07-08 02:04:15 +00001901 // Avoid other output when using a raw option.
1902 if (!RawClangAST) {
1903 outs() << '\n';
George Rimar73a27232019-01-15 09:19:18 +00001904 if (A)
1905 outs() << A->getFileName() << "(" << O->getFileName() << ")";
Kevin Enderbyac9e1552016-05-17 17:10:12 +00001906 else
George Rimar73a27232019-01-15 09:19:18 +00001907 outs() << O->getFileName();
1908 outs() << ":\tfile format " << O->getFileFormatName() << "\n\n";
Adrian Prantl437105a2015-07-08 02:04:15 +00001909 }
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001910
George Rimar73a27232019-01-15 09:19:18 +00001911 StringRef ArchiveName = A ? A->getFileName() : "";
George Rimar9b6fe7e2019-01-12 12:17:24 +00001912 if (FileHeaders)
George Rimar73a27232019-01-15 09:19:18 +00001913 printFileHeaders(O);
1914 if (ArchiveHeaders && !MachOOpt && C)
1915 printArchiveChild(ArchiveName, *C);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001916 if (Disassemble)
George Rimar73a27232019-01-15 09:19:18 +00001917 disassembleObject(O, Relocations);
Michael J. Spencer51862b32011-10-13 22:17:18 +00001918 if (Relocations && !Disassemble)
George Rimar73a27232019-01-15 09:19:18 +00001919 printRelocations(O);
Paul Semelcb0f0432018-06-07 13:30:55 +00001920 if (DynamicRelocations)
George Rimar73a27232019-01-15 09:19:18 +00001921 printDynamicRelocations(O);
Nick Lewyckyfcf84622011-10-10 21:21:34 +00001922 if (SectionHeaders)
George Rimar73a27232019-01-15 09:19:18 +00001923 printSectionHeaders(O);
Michael J. Spencer4e25c022011-10-17 17:13:22 +00001924 if (SectionContents)
George Rimar73a27232019-01-15 09:19:18 +00001925 printSectionContents(O);
Michael J. Spencerbfa06782011-10-18 19:32:17 +00001926 if (SymbolTable)
George Rimar73a27232019-01-15 09:19:18 +00001927 printSymbolTable(O, ArchiveName);
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00001928 if (UnwindInfo)
George Rimar73a27232019-01-15 09:19:18 +00001929 printUnwindInfo(O);
Davide Italiano1bdaa202016-09-18 04:39:15 +00001930 if (PrivateHeaders || FirstPrivateHeader)
George Rimar73a27232019-01-15 09:19:18 +00001931 printPrivateFileHeaders(O, FirstPrivateHeader);
Nick Kledzikd04bc352014-08-30 00:20:14 +00001932 if (ExportsTrie)
George Rimar73a27232019-01-15 09:19:18 +00001933 printExportsTrie(O);
Nick Kledzikac431442014-09-12 21:34:15 +00001934 if (Rebase)
George Rimar73a27232019-01-15 09:19:18 +00001935 printRebaseTable(O);
Nick Kledzik56ebef42014-09-16 01:41:51 +00001936 if (Bind)
George Rimar73a27232019-01-15 09:19:18 +00001937 printBindTable(O);
Nick Kledzik56ebef42014-09-16 01:41:51 +00001938 if (LazyBind)
George Rimar73a27232019-01-15 09:19:18 +00001939 printLazyBindTable(O);
Nick Kledzik56ebef42014-09-16 01:41:51 +00001940 if (WeakBind)
George Rimar73a27232019-01-15 09:19:18 +00001941 printWeakBindTable(O);
Adrian Prantl437105a2015-07-08 02:04:15 +00001942 if (RawClangAST)
George Rimar73a27232019-01-15 09:19:18 +00001943 printRawClangAST(O);
Sanjoy Das6f567a42015-06-22 18:03:02 +00001944 if (PrintFaultMaps)
George Rimar73a27232019-01-15 09:19:18 +00001945 printFaultMaps(O);
Igor Laevsky03a670c2016-01-26 15:09:42 +00001946 if (DwarfDumpType != DIDT_Null) {
George Rimar73a27232019-01-15 09:19:18 +00001947 std::unique_ptr<DIContext> DICtx = DWARFContext::create(*O);
Igor Laevsky03a670c2016-01-26 15:09:42 +00001948 // Dump the complete DWARF structure.
Adrian Prantlf4bc1f72017-06-01 18:18:23 +00001949 DIDumpOptions DumpOpts;
1950 DumpOpts.DumpType = DwarfDumpType;
Adrian Prantlf4bc1f72017-06-01 18:18:23 +00001951 DICtx->dump(outs(), DumpOpts);
Igor Laevsky03a670c2016-01-26 15:09:42 +00001952 }
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001953}
1954
George Rimar73a27232019-01-15 09:19:18 +00001955static void dumpObject(const COFFImportFile *I, const Archive *A,
Paul Semel0dc92f62018-07-05 14:43:29 +00001956 const Archive::Child *C = nullptr) {
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +00001957 StringRef ArchiveName = A ? A->getFileName() : "";
1958
1959 // Avoid other output when using a raw option.
1960 if (!RawClangAST)
1961 outs() << '\n'
1962 << ArchiveName << "(" << I->getFileName() << ")"
1963 << ":\tfile format COFF-import-file"
1964 << "\n\n";
1965
James Hendersonc1608c92018-10-29 14:17:08 +00001966 if (ArchiveHeaders && !MachOOpt && C)
1967 printArchiveChild(ArchiveName, *C);
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +00001968 if (SymbolTable)
1969 printCOFFSymbolTable(I);
1970}
1971
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +00001972/// Dump each object file in \a a;
George Rimar73a27232019-01-15 09:19:18 +00001973static void dumpArchive(const Archive *A) {
Mehdi Amini41af4302016-11-11 04:28:40 +00001974 Error Err = Error::success();
George Rimar73a27232019-01-15 09:19:18 +00001975 for (auto &C : A->children(Err)) {
Kevin Enderbyac9e1552016-05-17 17:10:12 +00001976 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
1977 if (!ChildOrErr) {
1978 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
George Rimar73a27232019-01-15 09:19:18 +00001979 report_error(A->getFileName(), C, std::move(E));
Kevin Enderbyac9e1552016-05-17 17:10:12 +00001980 continue;
1981 }
George Rimar73a27232019-01-15 09:19:18 +00001982 if (ObjectFile *O = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
1983 dumpObject(O, A, &C);
Saleem Abdulrasoolc6bf5472016-08-18 16:39:19 +00001984 else if (COFFImportFile *I = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
George Rimar73a27232019-01-15 09:19:18 +00001985 dumpObject(I, A, &C);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001986 else
George Rimar73a27232019-01-15 09:19:18 +00001987 report_error(A->getFileName(), object_error::invalid_file_type);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001988 }
Lang Hamesfc209622016-07-14 02:24:01 +00001989 if (Err)
George Rimar73a27232019-01-15 09:19:18 +00001990 report_error(A->getFileName(), std::move(Err));
Michael J. Spencerba4a3622011-10-08 00:18:30 +00001991}
1992
Adrian Prantl4dfcc4a2018-05-01 16:10:38 +00001993/// Open file and figure out how to dump it.
George Rimar73a27232019-01-15 09:19:18 +00001994static void dumpInput(StringRef file) {
Kevin Enderbye2297dd2015-01-07 21:02:18 +00001995 // If we are using the Mach-O specific object file parser, then let it parse
1996 // the file and process the command line options. So the -arch flags can
1997 // be used to select specific slices, etc.
1998 if (MachOOpt) {
George Rimar73a27232019-01-15 09:19:18 +00001999 parseInputMachO(file);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002000 return;
2001 }
2002
2003 // Attempt to open the binary.
Kevin Enderby3fcdf6a2016-04-06 22:14:09 +00002004 Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
2005 if (!BinaryOrErr)
Kevin Enderbyb34e3a12016-05-05 17:43:35 +00002006 report_error(file, BinaryOrErr.takeError());
Rafael Espindola48af1c22014-08-19 18:44:46 +00002007 Binary &Binary = *BinaryOrErr.get().getBinary();
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002008
George Rimar73a27232019-01-15 09:19:18 +00002009 if (Archive *A = dyn_cast<Archive>(&Binary))
2010 dumpArchive(A);
2011 else if (ObjectFile *O = dyn_cast<ObjectFile>(&Binary))
2012 dumpObject(O);
Dave Lee3fb120f2018-08-03 00:06:38 +00002013 else if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Binary))
George Rimar73a27232019-01-15 09:19:18 +00002014 parseInputMachO(UB);
Jim Grosbachaf9aec02012-08-07 17:53:14 +00002015 else
Alexey Samsonov50d0fbd2015-06-04 18:34:11 +00002016 report_error(file, object_error::invalid_file_type);
Michael J. Spencerba4a3622011-10-08 00:18:30 +00002017}
2018
Michael J. Spencer2670c252011-01-20 06:39:06 +00002019int main(int argc, char **argv) {
Rui Ueyama197194b2018-04-13 18:26:06 +00002020 InitLLVM X(argc, argv);
Michael J. Spencer2670c252011-01-20 06:39:06 +00002021
2022 // Initialize targets and assembly printers/parsers.
2023 llvm::InitializeAllTargetInfos();
Evan Cheng8c886a42011-07-22 21:58:54 +00002024 llvm::InitializeAllTargetMCs();
Michael J. Spencer2670c252011-01-20 06:39:06 +00002025 llvm::InitializeAllDisassemblers();
2026
Pete Cooper28fb4fc2012-05-03 23:20:10 +00002027 // Register the target printer for --version.
2028 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
2029
Michael J. Spencer2670c252011-01-20 06:39:06 +00002030 cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
Michael J. Spencer2670c252011-01-20 06:39:06 +00002031
2032 ToolName = argv[0];
2033
2034 // Defaults to a.out if no filenames specified.
Jordan Rupprecht16a0de22018-12-20 00:57:06 +00002035 if (InputFilenames.empty())
Michael J. Spencer2670c252011-01-20 06:39:06 +00002036 InputFilenames.push_back("a.out");
2037
Fangrui Song8513cd42018-06-27 20:45:11 +00002038 if (AllHeaders)
George Rimar5e364332019-01-18 12:01:59 +00002039 ArchiveHeaders = FileHeaders = PrivateHeaders = Relocations =
2040 SectionHeaders = SymbolTable = true;
Fangrui Song8513cd42018-06-27 20:45:11 +00002041
Hemant Kulkarni8dfc0b52016-08-15 19:49:24 +00002042 if (DisassembleAll || PrintSource || PrintLines)
Colin LeMahieuf34933e2015-07-23 20:58:49 +00002043 Disassemble = true;
Paul Semel007dedb2018-07-18 16:39:21 +00002044
Michael J. Spencerbfa06782011-10-18 19:32:17 +00002045 if (!Disassemble
2046 && !Relocations
Paul Semelcb0f0432018-06-07 13:30:55 +00002047 && !DynamicRelocations
Michael J. Spencerbfa06782011-10-18 19:32:17 +00002048 && !SectionHeaders
2049 && !SectionContents
Michael J. Spencer0c6ec482012-12-05 20:12:35 +00002050 && !SymbolTable
Michael J. Spencer209565db2013-01-06 03:56:49 +00002051 && !UnwindInfo
Nick Kledzikd04bc352014-08-30 00:20:14 +00002052 && !PrivateHeaders
Paul Semeld2af4d62018-07-04 15:25:03 +00002053 && !FileHeaders
Kevin Enderby0ae163f2016-01-13 00:25:36 +00002054 && !FirstPrivateHeader
Nick Kledzikac431442014-09-12 21:34:15 +00002055 && !ExportsTrie
Nick Kledzik56ebef42014-09-16 01:41:51 +00002056 && !Rebase
2057 && !Bind
2058 && !LazyBind
Kevin Enderby131d1772015-01-09 19:22:37 +00002059 && !WeakBind
Adrian Prantl437105a2015-07-08 02:04:15 +00002060 && !RawClangAST
Kevin Enderby13023a12015-01-15 23:19:11 +00002061 && !(UniversalHeaders && MachOOpt)
Paul Semel0dc92f62018-07-05 14:43:29 +00002062 && !ArchiveHeaders
Kevin Enderby69fe98d2015-01-23 18:52:17 +00002063 && !(IndirectSymbols && MachOOpt)
Kevin Enderby9a509442015-01-27 21:28:24 +00002064 && !(DataInCode && MachOOpt)
Kevin Enderbyf6d25852015-01-31 00:37:11 +00002065 && !(LinkOptHints && MachOOpt)
Kevin Enderbycd66be52015-03-11 22:06:32 +00002066 && !(InfoPlist && MachOOpt)
Kevin Enderbybc847fa2015-03-16 20:08:09 +00002067 && !(DylibsUsed && MachOOpt)
2068 && !(DylibId && MachOOpt)
Kevin Enderby0fc11822015-04-01 20:57:01 +00002069 && !(ObjcMetaData && MachOOpt)
Jordan Rupprecht16a0de22018-12-20 00:57:06 +00002070 && !(!FilterSections.empty() && MachOOpt)
Igor Laevsky03a670c2016-01-26 15:09:42 +00002071 && !PrintFaultMaps
2072 && DwarfDumpType == DIDT_Null) {
Michael J. Spencer2670c252011-01-20 06:39:06 +00002073 cl::PrintHelpMessage();
Dimitry Andrice4f5d012017-12-18 19:46:56 +00002074 return 2;
2075 }
2076
Rafael Aulerb0e4b912018-03-09 19:13:44 +00002077 DisasmFuncsSet.insert(DisassembleFunctions.begin(),
2078 DisassembleFunctions.end());
2079
George Rimar73a27232019-01-15 09:19:18 +00002080 llvm::for_each(InputFilenames, dumpInput);
Dimitry Andrice4f5d012017-12-18 19:46:56 +00002081
2082 return EXIT_SUCCESS;
2083}