1 //===-- 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 //
14 // The flags and output of this program should be near identical to those of
15 // binutils objdump.
16 //
17 //===----------------------------------------------------------------------===//
18
19 #include "llvm-objdump.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/ADT/StringSet.h"
24 #include "llvm/ADT/Triple.h"
25 #include "llvm/CodeGen/FaultMaps.h"
26 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
27 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
28 #include "llvm/Demangle/Demangle.h"
29 #include "llvm/MC/MCAsmInfo.h"
30 #include "llvm/MC/MCContext.h"
31 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
32 #include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
33 #include "llvm/MC/MCInst.h"
34 #include "llvm/MC/MCInstPrinter.h"
35 #include "llvm/MC/MCInstrAnalysis.h"
36 #include "llvm/MC/MCInstrInfo.h"
37 #include "llvm/MC/MCObjectFileInfo.h"
38 #include "llvm/MC/MCRegisterInfo.h"
39 #include "llvm/MC/MCSubtargetInfo.h"
40 #include "llvm/Object/Archive.h"
41 #include "llvm/Object/COFF.h"
42 #include "llvm/Object/COFFImportFile.h"
43 #include "llvm/Object/ELFObjectFile.h"
44 #include "llvm/Object/MachO.h"
45 #include "llvm/Object/ObjectFile.h"
46 #include "llvm/Object/Wasm.h"
47 #include "llvm/Support/Casting.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/Debug.h"
50 #include "llvm/Support/Errc.h"
51 #include "llvm/Support/FileSystem.h"
52 #include "llvm/Support/Format.h"
53 #include "llvm/Support/GraphWriter.h"
54 #include "llvm/Support/Host.h"
55 #include "llvm/Support/InitLLVM.h"
56 #include "llvm/Support/MemoryBuffer.h"
57 #include "llvm/Support/SourceMgr.h"
58 #include "llvm/Support/TargetRegistry.h"
59 #include "llvm/Support/TargetSelect.h"
60 #include "llvm/Support/raw_ostream.h"
61 #include <algorithm>
62 #include <cctype>
63 #include <cstring>
64 #include <system_error>
65 #include <unordered_map>
66 #include <utility>
67
68 using namespace llvm;
69 using namespace object;
70
71 cl::opt<bool>
72 llvm::AllHeaders("all-headers",
73 cl::desc("Display all available header information"));
74 static cl::alias AllHeadersShort("x", cl::desc("Alias for --all-headers"),
75 cl::aliasopt(AllHeaders));
76
77 static cl::list<std::string>
78 InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
79
80 cl::opt<bool>
81 llvm::Disassemble("disassemble",
82 cl::desc("Display assembler mnemonics for the machine instructions"));
83 static cl::alias
84 Disassembled("d", cl::desc("Alias for --disassemble"),
85 cl::aliasopt(Disassemble));
86
87 cl::opt<bool>
88 llvm::DisassembleAll("disassemble-all",
89 cl::desc("Display assembler mnemonics for the machine instructions"));
90 static cl::alias
91 DisassembleAlld("D", cl::desc("Alias for --disassemble-all"),
92 cl::aliasopt(DisassembleAll));
93
94 cl::opt<std::string> llvm::Demangle("demangle",
95 cl::desc("Demangle symbols names"),
96 cl::ValueOptional, cl::init("none"));
97
98 static cl::alias DemangleShort("C", cl::desc("Alias for --demangle"),
99 cl::aliasopt(Demangle));
100
101 static cl::list<std::string>
102 DisassembleFunctions("df",
103 cl::CommaSeparated,
104 cl::desc("List of functions to disassemble"));
105 static StringSet<> DisasmFuncsSet;
106
107 cl::opt<bool>
108 llvm::Relocations("r", cl::desc("Display the relocation entries in the file"));
109
110 cl::opt<bool>
111 llvm::DynamicRelocations("dynamic-reloc",
112 cl::desc("Display the dynamic relocation entries in the file"));
113 static cl::alias
114 DynamicRelocationsd("R", cl::desc("Alias for --dynamic-reloc"),
115 cl::aliasopt(DynamicRelocations));
116
117 cl::opt<bool>
118 llvm::SectionContents("s", cl::desc("Display the content of each section"));
119
120 cl::opt<bool>
121 llvm::SymbolTable("t", cl::desc("Display the symbol table"));
122
123 cl::opt<bool>
124 llvm::ExportsTrie("exports-trie", cl::desc("Display mach-o exported symbols"));
125
126 cl::opt<bool>
127 llvm::Rebase("rebase", cl::desc("Display mach-o rebasing info"));
128
129 cl::opt<bool>
130 llvm::Bind("bind", cl::desc("Display mach-o binding info"));
131
132 cl::opt<bool>
133 llvm::LazyBind("lazy-bind", cl::desc("Display mach-o lazy binding info"));
134
135 cl::opt<bool>
136 llvm::WeakBind("weak-bind", cl::desc("Display mach-o weak binding info"));
137
138 cl::opt<bool>
139 llvm::RawClangAST("raw-clang-ast",
140 cl::desc("Dump the raw binary contents of the clang AST section"));
141
142 static cl::opt<bool>
143 MachOOpt("macho", cl::desc("Use MachO specific object file parser"));
144 static cl::alias
145 MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt));
146
147 cl::opt<std::string>
148 llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
149 "see -version for available targets"));
150
151 cl::opt<std::string>
152 llvm::MCPU("mcpu",
153 cl::desc("Target a specific cpu type (-mcpu=help for details)"),
154 cl::value_desc("cpu-name"),
155 cl::init(""));
156
157 cl::opt<std::string>
158 llvm::ArchName("arch-name", cl::desc("Target arch to disassemble for, "
159 "see -version for available targets"));
160
161 cl::opt<bool>
162 llvm::SectionHeaders("section-headers", cl::desc("Display summaries of the "
163 "headers for each section."));
164 static cl::alias
165 SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
166 cl::aliasopt(SectionHeaders));
167 static cl::alias
168 SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
169 cl::aliasopt(SectionHeaders));
170
171 cl::list<std::string>
172 llvm::FilterSections("section", cl::desc("Operate on the specified sections only. "
173 "With -macho dump segment,section"));
174 cl::alias
175 static FilterSectionsj("j", cl::desc("Alias for --section"),
176 cl::aliasopt(llvm::FilterSections));
177
178 cl::list<std::string>
179 llvm::MAttrs("mattr",
180 cl::CommaSeparated,
181 cl::desc("Target specific attributes"),
182 cl::value_desc("a1,+a2,-a3,..."));
183
184 cl::opt<bool>
185 llvm::NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling "
186 "instructions, do not print "
187 "the instruction bytes."));
188 cl::opt<bool>
189 llvm::NoLeadingAddr("no-leading-addr", cl::desc("Print no leading address"));
190
191 cl::opt<bool>
192 llvm::UnwindInfo("unwind-info", cl::desc("Display unwind information"));
193
194 static cl::alias
195 UnwindInfoShort("u", cl::desc("Alias for --unwind-info"),
196 cl::aliasopt(UnwindInfo));
197
198 cl::opt<bool>
199 llvm::PrivateHeaders("private-headers",
200 cl::desc("Display format specific file headers"));
201
202 cl::opt<bool>
203 llvm::FirstPrivateHeader("private-header",
204 cl::desc("Display only the first format specific file "
205 "header"));
206
207 static cl::alias
208 PrivateHeadersShort("p", cl::desc("Alias for --private-headers"),
209 cl::aliasopt(PrivateHeaders));
210
211 cl::opt<bool> llvm::FileHeaders(
212 "file-headers",
213 cl::desc("Display the contents of the overall file header"));
214
215 static cl::alias FileHeadersShort("f", cl::desc("Alias for --file-headers"),
216 cl::aliasopt(FileHeaders));
217
218 cl::opt<bool>
219 llvm::ArchiveHeaders("archive-headers",
220 cl::desc("Display archive header information"));
221
222 cl::alias
223 ArchiveHeadersShort("a", cl::desc("Alias for --archive-headers"),
224 cl::aliasopt(ArchiveHeaders));
225
226 cl::opt<bool>
227 llvm::PrintImmHex("print-imm-hex",
228 cl::desc("Use hex format for immediate values"));
229
230 cl::opt<bool> PrintFaultMaps("fault-map-section",
231 cl::desc("Display contents of faultmap section"));
232
233 cl::opt<DIDumpType> llvm::DwarfDumpType(
234 "dwarf", cl::init(DIDT_Null), cl::desc("Dump of dwarf debug sections:"),
235 cl::values(clEnumValN(DIDT_DebugFrame, "frames", ".debug_frame")));
236
237 cl::opt<bool> PrintSource(
238 "source",
239 cl::desc(
240 "Display source inlined with disassembly. Implies disassemble object"));
241
242 cl::alias PrintSourceShort("S", cl::desc("Alias for -source"),
243 cl::aliasopt(PrintSource));
244
245 cl::opt<bool> PrintLines("line-numbers",
246 cl::desc("Display source line numbers with "
247 "disassembly. Implies disassemble object"));
248
249 cl::alias PrintLinesShort("l", cl::desc("Alias for -line-numbers"),
250 cl::aliasopt(PrintLines));
251
252 cl::opt<unsigned long long>
253 StartAddress("start-address", cl::desc("Disassemble beginning at address"),
254 cl::value_desc("address"), cl::init(0));
255 cl::opt<unsigned long long>
256 StopAddress("stop-address", cl::desc("Stop disassembly at address"),
257 cl::value_desc("address"), cl::init(UINT64_MAX));
258 static StringRef ToolName;
259
260 typedef std::vector<std::tuple<uint64_t, StringRef, uint8_t>> SectionSymbolsTy;
261
262 namespace {
263 typedef std::function<bool(llvm::object::SectionRef const &)> FilterPredicate;
264
265 class SectionFilterIterator {
266 public:
SectionFilterIterator(FilterPredicate P,llvm::object::section_iterator const & I,llvm::object::section_iterator const & E)267 SectionFilterIterator(FilterPredicate P,
268 llvm::object::section_iterator const &I,
269 llvm::object::section_iterator const &E)
270 : Predicate(std::move(P)), Iterator(I), End(E) {
271 ScanPredicate();
272 }
operator *() const273 const llvm::object::SectionRef &operator*() const { return *Iterator; }
operator ++()274 SectionFilterIterator &operator++() {
275 ++Iterator;
276 ScanPredicate();
277 return *this;
278 }
operator !=(SectionFilterIterator const & Other) const279 bool operator!=(SectionFilterIterator const &Other) const {
280 return Iterator != Other.Iterator;
281 }
282
283 private:
ScanPredicate()284 void ScanPredicate() {
285 while (Iterator != End && !Predicate(*Iterator)) {
286 ++Iterator;
287 }
288 }
289 FilterPredicate Predicate;
290 llvm::object::section_iterator Iterator;
291 llvm::object::section_iterator End;
292 };
293
294 class SectionFilter {
295 public:
SectionFilter(FilterPredicate P,llvm::object::ObjectFile const & O)296 SectionFilter(FilterPredicate P, llvm::object::ObjectFile const &O)
297 : Predicate(std::move(P)), Object(O) {}
begin()298 SectionFilterIterator begin() {
299 return SectionFilterIterator(Predicate, Object.section_begin(),
300 Object.section_end());
301 }
end()302 SectionFilterIterator end() {
303 return SectionFilterIterator(Predicate, Object.section_end(),
304 Object.section_end());
305 }
306
307 private:
308 FilterPredicate Predicate;
309 llvm::object::ObjectFile const &Object;
310 };
ToolSectionFilter(llvm::object::ObjectFile const & O)311 SectionFilter ToolSectionFilter(llvm::object::ObjectFile const &O) {
312 return SectionFilter(
313 [](llvm::object::SectionRef const &S) {
314 if (FilterSections.empty())
315 return true;
316 llvm::StringRef String;
317 std::error_code error = S.getName(String);
318 if (error)
319 return false;
320 return is_contained(FilterSections, String);
321 },
322 O);
323 }
324 }
325
error(std::error_code EC)326 void llvm::error(std::error_code EC) {
327 if (!EC)
328 return;
329
330 errs() << ToolName << ": error reading file: " << EC.message() << ".\n";
331 errs().flush();
332 exit(1);
333 }
334
error(Twine Message)335 LLVM_ATTRIBUTE_NORETURN void llvm::error(Twine Message) {
336 errs() << ToolName << ": " << Message << ".\n";
337 errs().flush();
338 exit(1);
339 }
340
warn(StringRef Message)341 void llvm::warn(StringRef Message) {
342 errs() << ToolName << ": warning: " << Message << ".\n";
343 errs().flush();
344 }
345
report_error(StringRef File,Twine Message)346 LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
347 Twine Message) {
348 errs() << ToolName << ": '" << File << "': " << Message << ".\n";
349 exit(1);
350 }
351
report_error(StringRef File,std::error_code EC)352 LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
353 std::error_code EC) {
354 assert(EC);
355 errs() << ToolName << ": '" << File << "': " << EC.message() << ".\n";
356 exit(1);
357 }
358
report_error(StringRef File,llvm::Error E)359 LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef File,
360 llvm::Error E) {
361 assert(E);
362 std::string Buf;
363 raw_string_ostream OS(Buf);
364 logAllUnhandledErrors(std::move(E), OS, "");
365 OS.flush();
366 errs() << ToolName << ": '" << File << "': " << Buf;
367 exit(1);
368 }
369
report_error(StringRef ArchiveName,StringRef FileName,llvm::Error E,StringRef ArchitectureName)370 LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
371 StringRef FileName,
372 llvm::Error E,
373 StringRef ArchitectureName) {
374 assert(E);
375 errs() << ToolName << ": ";
376 if (ArchiveName != "")
377 errs() << ArchiveName << "(" << FileName << ")";
378 else
379 errs() << "'" << FileName << "'";
380 if (!ArchitectureName.empty())
381 errs() << " (for architecture " << ArchitectureName << ")";
382 std::string Buf;
383 raw_string_ostream OS(Buf);
384 logAllUnhandledErrors(std::move(E), OS, "");
385 OS.flush();
386 errs() << ": " << Buf;
387 exit(1);
388 }
389
report_error(StringRef ArchiveName,const object::Archive::Child & C,llvm::Error E,StringRef ArchitectureName)390 LLVM_ATTRIBUTE_NORETURN void llvm::report_error(StringRef ArchiveName,
391 const object::Archive::Child &C,
392 llvm::Error E,
393 StringRef ArchitectureName) {
394 Expected<StringRef> NameOrErr = C.getName();
395 // TODO: if we have a error getting the name then it would be nice to print
396 // the index of which archive member this is and or its offset in the
397 // archive instead of "???" as the name.
398 if (!NameOrErr) {
399 consumeError(NameOrErr.takeError());
400 llvm::report_error(ArchiveName, "???", std::move(E), ArchitectureName);
401 } else
402 llvm::report_error(ArchiveName, NameOrErr.get(), std::move(E),
403 ArchitectureName);
404 }
405
getTarget(const ObjectFile * Obj=nullptr)406 static const Target *getTarget(const ObjectFile *Obj = nullptr) {
407 // Figure out the target triple.
408 llvm::Triple TheTriple("unknown-unknown-unknown");
409 if (TripleName.empty()) {
410 if (Obj) {
411 TheTriple = Obj->makeTriple();
412 }
413 } else {
414 TheTriple.setTriple(Triple::normalize(TripleName));
415
416 // Use the triple, but also try to combine with ARM build attributes.
417 if (Obj) {
418 auto Arch = Obj->getArch();
419 if (Arch == Triple::arm || Arch == Triple::armeb) {
420 Obj->setARMSubArch(TheTriple);
421 }
422 }
423 }
424
425 // Get the target specific parser.
426 std::string Error;
427 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
428 Error);
429 if (!TheTarget) {
430 if (Obj)
431 report_error(Obj->getFileName(), "can't find target: " + Error);
432 else
433 error("can't find target: " + Error);
434 }
435
436 // Update the triple name and return the found target.
437 TripleName = TheTriple.getTriple();
438 return TheTarget;
439 }
440
RelocAddressLess(RelocationRef a,RelocationRef b)441 bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
442 return a.getOffset() < b.getOffset();
443 }
444
445 template <class ELFT>
getRelocationValueString(const ELFObjectFile<ELFT> * Obj,const RelocationRef & RelRef,SmallVectorImpl<char> & Result)446 static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
447 const RelocationRef &RelRef,
448 SmallVectorImpl<char> &Result) {
449 DataRefImpl Rel = RelRef.getRawDataRefImpl();
450
451 typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
452 typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
453 typedef typename ELFObjectFile<ELFT>::Elf_Rela Elf_Rela;
454
455 const ELFFile<ELFT> &EF = *Obj->getELFFile();
456
457 auto SecOrErr = EF.getSection(Rel.d.a);
458 if (!SecOrErr)
459 return errorToErrorCode(SecOrErr.takeError());
460 const Elf_Shdr *Sec = *SecOrErr;
461 auto SymTabOrErr = EF.getSection(Sec->sh_link);
462 if (!SymTabOrErr)
463 return errorToErrorCode(SymTabOrErr.takeError());
464 const Elf_Shdr *SymTab = *SymTabOrErr;
465 assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
466 SymTab->sh_type == ELF::SHT_DYNSYM);
467 auto StrTabSec = EF.getSection(SymTab->sh_link);
468 if (!StrTabSec)
469 return errorToErrorCode(StrTabSec.takeError());
470 auto StrTabOrErr = EF.getStringTable(*StrTabSec);
471 if (!StrTabOrErr)
472 return errorToErrorCode(StrTabOrErr.takeError());
473 StringRef StrTab = *StrTabOrErr;
474 int64_t addend = 0;
475 // If there is no Symbol associated with the relocation, we set the undef
476 // boolean value to 'true'. This will prevent us from calling functions that
477 // requires the relocation to be associated with a symbol.
478 bool undef = false;
479 switch (Sec->sh_type) {
480 default:
481 return object_error::parse_failed;
482 case ELF::SHT_REL: {
483 // TODO: Read implicit addend from section data.
484 break;
485 }
486 case ELF::SHT_RELA: {
487 const Elf_Rela *ERela = Obj->getRela(Rel);
488 addend = ERela->r_addend;
489 undef = ERela->getSymbol(false) == 0;
490 break;
491 }
492 }
493 StringRef Target;
494 if (!undef) {
495 symbol_iterator SI = RelRef.getSymbol();
496 const Elf_Sym *symb = Obj->getSymbol(SI->getRawDataRefImpl());
497 if (symb->getType() == ELF::STT_SECTION) {
498 Expected<section_iterator> SymSI = SI->getSection();
499 if (!SymSI)
500 return errorToErrorCode(SymSI.takeError());
501 const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
502 auto SecName = EF.getSectionName(SymSec);
503 if (!SecName)
504 return errorToErrorCode(SecName.takeError());
505 Target = *SecName;
506 } else {
507 Expected<StringRef> SymName = symb->getName(StrTab);
508 if (!SymName)
509 return errorToErrorCode(SymName.takeError());
510 Target = *SymName;
511 }
512 } else
513 Target = "*ABS*";
514
515 // Default scheme is to print Target, as well as "+ <addend>" for nonzero
516 // addend. Should be acceptable for all normal purposes.
517 std::string fmtbuf;
518 raw_string_ostream fmt(fmtbuf);
519 fmt << Target;
520 if (addend != 0)
521 fmt << (addend < 0 ? "" : "+") << addend;
522 fmt.flush();
523 Result.append(fmtbuf.begin(), fmtbuf.end());
524 return std::error_code();
525 }
526
getRelocationValueString(const ELFObjectFileBase * Obj,const RelocationRef & Rel,SmallVectorImpl<char> & Result)527 static std::error_code getRelocationValueString(const ELFObjectFileBase *Obj,
528 const RelocationRef &Rel,
529 SmallVectorImpl<char> &Result) {
530 if (auto *ELF32LE = dyn_cast<ELF32LEObjectFile>(Obj))
531 return getRelocationValueString(ELF32LE, Rel, Result);
532 if (auto *ELF64LE = dyn_cast<ELF64LEObjectFile>(Obj))
533 return getRelocationValueString(ELF64LE, Rel, Result);
534 if (auto *ELF32BE = dyn_cast<ELF32BEObjectFile>(Obj))
535 return getRelocationValueString(ELF32BE, Rel, Result);
536 auto *ELF64BE = cast<ELF64BEObjectFile>(Obj);
537 return getRelocationValueString(ELF64BE, Rel, Result);
538 }
539
getRelocationValueString(const COFFObjectFile * Obj,const RelocationRef & Rel,SmallVectorImpl<char> & Result)540 static std::error_code getRelocationValueString(const COFFObjectFile *Obj,
541 const RelocationRef &Rel,
542 SmallVectorImpl<char> &Result) {
543 symbol_iterator SymI = Rel.getSymbol();
544 Expected<StringRef> SymNameOrErr = SymI->getName();
545 if (!SymNameOrErr)
546 return errorToErrorCode(SymNameOrErr.takeError());
547 StringRef SymName = *SymNameOrErr;
548 Result.append(SymName.begin(), SymName.end());
549 return std::error_code();
550 }
551
printRelocationTargetName(const MachOObjectFile * O,const MachO::any_relocation_info & RE,raw_string_ostream & fmt)552 static void printRelocationTargetName(const MachOObjectFile *O,
553 const MachO::any_relocation_info &RE,
554 raw_string_ostream &fmt) {
555 bool IsScattered = O->isRelocationScattered(RE);
556
557 // Target of a scattered relocation is an address. In the interest of
558 // generating pretty output, scan through the symbol table looking for a
559 // symbol that aligns with that address. If we find one, print it.
560 // Otherwise, we just print the hex address of the target.
561 if (IsScattered) {
562 uint32_t Val = O->getPlainRelocationSymbolNum(RE);
563
564 for (const SymbolRef &Symbol : O->symbols()) {
565 std::error_code ec;
566 Expected<uint64_t> Addr = Symbol.getAddress();
567 if (!Addr)
568 report_error(O->getFileName(), Addr.takeError());
569 if (*Addr != Val)
570 continue;
571 Expected<StringRef> Name = Symbol.getName();
572 if (!Name)
573 report_error(O->getFileName(), Name.takeError());
574 fmt << *Name;
575 return;
576 }
577
578 // If we couldn't find a symbol that this relocation refers to, try
579 // to find a section beginning instead.
580 for (const SectionRef &Section : ToolSectionFilter(*O)) {
581 std::error_code ec;
582
583 StringRef Name;
584 uint64_t Addr = Section.getAddress();
585 if (Addr != Val)
586 continue;
587 if ((ec = Section.getName(Name)))
588 report_error(O->getFileName(), ec);
589 fmt << Name;
590 return;
591 }
592
593 fmt << format("0x%x", Val);
594 return;
595 }
596
597 StringRef S;
598 bool isExtern = O->getPlainRelocationExternal(RE);
599 uint64_t Val = O->getPlainRelocationSymbolNum(RE);
600
601 if (O->getAnyRelocationType(RE) == MachO::ARM64_RELOC_ADDEND) {
602 fmt << format("0x%0" PRIx64, Val);
603 return;
604 } else if (isExtern) {
605 symbol_iterator SI = O->symbol_begin();
606 advance(SI, Val);
607 Expected<StringRef> SOrErr = SI->getName();
608 if (!SOrErr)
609 report_error(O->getFileName(), SOrErr.takeError());
610 S = *SOrErr;
611 } else {
612 section_iterator SI = O->section_begin();
613 // Adjust for the fact that sections are 1-indexed.
614 if (Val == 0) {
615 fmt << "0 (?,?)";
616 return;
617 }
618 uint32_t i = Val - 1;
619 while (i != 0 && SI != O->section_end()) {
620 i--;
621 advance(SI, 1);
622 }
623 if (SI == O->section_end())
624 fmt << Val << " (?,?)";
625 else
626 SI->getName(S);
627 }
628
629 fmt << S;
630 }
631
getRelocationValueString(const WasmObjectFile * Obj,const RelocationRef & RelRef,SmallVectorImpl<char> & Result)632 static std::error_code getRelocationValueString(const WasmObjectFile *Obj,
633 const RelocationRef &RelRef,
634 SmallVectorImpl<char> &Result) {
635 const wasm::WasmRelocation& Rel = Obj->getWasmRelocation(RelRef);
636 symbol_iterator SI = RelRef.getSymbol();
637 std::string fmtbuf;
638 raw_string_ostream fmt(fmtbuf);
639 if (SI == Obj->symbol_end()) {
640 // Not all wasm relocations have symbols associated with them.
641 // In particular R_WEBASSEMBLY_TYPE_INDEX_LEB.
642 fmt << Rel.Index;
643 } else {
644 Expected<StringRef> SymNameOrErr = SI->getName();
645 if (!SymNameOrErr)
646 return errorToErrorCode(SymNameOrErr.takeError());
647 StringRef SymName = *SymNameOrErr;
648 Result.append(SymName.begin(), SymName.end());
649 }
650 fmt << (Rel.Addend < 0 ? "" : "+") << Rel.Addend;
651 fmt.flush();
652 Result.append(fmtbuf.begin(), fmtbuf.end());
653 return std::error_code();
654 }
655
getRelocationValueString(const MachOObjectFile * Obj,const RelocationRef & RelRef,SmallVectorImpl<char> & Result)656 static std::error_code getRelocationValueString(const MachOObjectFile *Obj,
657 const RelocationRef &RelRef,
658 SmallVectorImpl<char> &Result) {
659 DataRefImpl Rel = RelRef.getRawDataRefImpl();
660 MachO::any_relocation_info RE = Obj->getRelocation(Rel);
661
662 unsigned Arch = Obj->getArch();
663
664 std::string fmtbuf;
665 raw_string_ostream fmt(fmtbuf);
666 unsigned Type = Obj->getAnyRelocationType(RE);
667 bool IsPCRel = Obj->getAnyRelocationPCRel(RE);
668
669 // Determine any addends that should be displayed with the relocation.
670 // These require decoding the relocation type, which is triple-specific.
671
672 // X86_64 has entirely custom relocation types.
673 if (Arch == Triple::x86_64) {
674 bool isPCRel = Obj->getAnyRelocationPCRel(RE);
675
676 switch (Type) {
677 case MachO::X86_64_RELOC_GOT_LOAD:
678 case MachO::X86_64_RELOC_GOT: {
679 printRelocationTargetName(Obj, RE, fmt);
680 fmt << "@GOT";
681 if (isPCRel)
682 fmt << "PCREL";
683 break;
684 }
685 case MachO::X86_64_RELOC_SUBTRACTOR: {
686 DataRefImpl RelNext = Rel;
687 Obj->moveRelocationNext(RelNext);
688 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
689
690 // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
691 // X86_64_RELOC_UNSIGNED.
692 // NOTE: Scattered relocations don't exist on x86_64.
693 unsigned RType = Obj->getAnyRelocationType(RENext);
694 if (RType != MachO::X86_64_RELOC_UNSIGNED)
695 report_error(Obj->getFileName(), "Expected X86_64_RELOC_UNSIGNED after "
696 "X86_64_RELOC_SUBTRACTOR.");
697
698 // The X86_64_RELOC_UNSIGNED contains the minuend symbol;
699 // X86_64_RELOC_SUBTRACTOR contains the subtrahend.
700 printRelocationTargetName(Obj, RENext, fmt);
701 fmt << "-";
702 printRelocationTargetName(Obj, RE, fmt);
703 break;
704 }
705 case MachO::X86_64_RELOC_TLV:
706 printRelocationTargetName(Obj, RE, fmt);
707 fmt << "@TLV";
708 if (isPCRel)
709 fmt << "P";
710 break;
711 case MachO::X86_64_RELOC_SIGNED_1:
712 printRelocationTargetName(Obj, RE, fmt);
713 fmt << "-1";
714 break;
715 case MachO::X86_64_RELOC_SIGNED_2:
716 printRelocationTargetName(Obj, RE, fmt);
717 fmt << "-2";
718 break;
719 case MachO::X86_64_RELOC_SIGNED_4:
720 printRelocationTargetName(Obj, RE, fmt);
721 fmt << "-4";
722 break;
723 default:
724 printRelocationTargetName(Obj, RE, fmt);
725 break;
726 }
727 // X86 and ARM share some relocation types in common.
728 } else if (Arch == Triple::x86 || Arch == Triple::arm ||
729 Arch == Triple::ppc) {
730 // Generic relocation types...
731 switch (Type) {
732 case MachO::GENERIC_RELOC_PAIR: // prints no info
733 return std::error_code();
734 case MachO::GENERIC_RELOC_SECTDIFF: {
735 DataRefImpl RelNext = Rel;
736 Obj->moveRelocationNext(RelNext);
737 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
738
739 // X86 sect diff's must be followed by a relocation of type
740 // GENERIC_RELOC_PAIR.
741 unsigned RType = Obj->getAnyRelocationType(RENext);
742
743 if (RType != MachO::GENERIC_RELOC_PAIR)
744 report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
745 "GENERIC_RELOC_SECTDIFF.");
746
747 printRelocationTargetName(Obj, RE, fmt);
748 fmt << "-";
749 printRelocationTargetName(Obj, RENext, fmt);
750 break;
751 }
752 }
753
754 if (Arch == Triple::x86 || Arch == Triple::ppc) {
755 switch (Type) {
756 case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
757 DataRefImpl RelNext = Rel;
758 Obj->moveRelocationNext(RelNext);
759 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
760
761 // X86 sect diff's must be followed by a relocation of type
762 // GENERIC_RELOC_PAIR.
763 unsigned RType = Obj->getAnyRelocationType(RENext);
764 if (RType != MachO::GENERIC_RELOC_PAIR)
765 report_error(Obj->getFileName(), "Expected GENERIC_RELOC_PAIR after "
766 "GENERIC_RELOC_LOCAL_SECTDIFF.");
767
768 printRelocationTargetName(Obj, RE, fmt);
769 fmt << "-";
770 printRelocationTargetName(Obj, RENext, fmt);
771 break;
772 }
773 case MachO::GENERIC_RELOC_TLV: {
774 printRelocationTargetName(Obj, RE, fmt);
775 fmt << "@TLV";
776 if (IsPCRel)
777 fmt << "P";
778 break;
779 }
780 default:
781 printRelocationTargetName(Obj, RE, fmt);
782 }
783 } else { // ARM-specific relocations
784 switch (Type) {
785 case MachO::ARM_RELOC_HALF:
786 case MachO::ARM_RELOC_HALF_SECTDIFF: {
787 // Half relocations steal a bit from the length field to encode
788 // whether this is an upper16 or a lower16 relocation.
789 bool isUpper = (Obj->getAnyRelocationLength(RE) & 0x1) == 1;
790
791 if (isUpper)
792 fmt << ":upper16:(";
793 else
794 fmt << ":lower16:(";
795 printRelocationTargetName(Obj, RE, fmt);
796
797 DataRefImpl RelNext = Rel;
798 Obj->moveRelocationNext(RelNext);
799 MachO::any_relocation_info RENext = Obj->getRelocation(RelNext);
800
801 // ARM half relocs must be followed by a relocation of type
802 // ARM_RELOC_PAIR.
803 unsigned RType = Obj->getAnyRelocationType(RENext);
804 if (RType != MachO::ARM_RELOC_PAIR)
805 report_error(Obj->getFileName(), "Expected ARM_RELOC_PAIR after "
806 "ARM_RELOC_HALF");
807
808 // NOTE: The half of the target virtual address is stashed in the
809 // address field of the secondary relocation, but we can't reverse
810 // engineer the constant offset from it without decoding the movw/movt
811 // instruction to find the other half in its immediate field.
812
813 // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
814 // symbol/section pointer of the follow-on relocation.
815 if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
816 fmt << "-";
817 printRelocationTargetName(Obj, RENext, fmt);
818 }
819
820 fmt << ")";
821 break;
822 }
823 default: { printRelocationTargetName(Obj, RE, fmt); }
824 }
825 }
826 } else
827 printRelocationTargetName(Obj, RE, fmt);
828
829 fmt.flush();
830 Result.append(fmtbuf.begin(), fmtbuf.end());
831 return std::error_code();
832 }
833
getRelocationValueString(const RelocationRef & Rel,SmallVectorImpl<char> & Result)834 static std::error_code getRelocationValueString(const RelocationRef &Rel,
835 SmallVectorImpl<char> &Result) {
836 const ObjectFile *Obj = Rel.getObject();
837 if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
838 return getRelocationValueString(ELF, Rel, Result);
839 if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
840 return getRelocationValueString(COFF, Rel, Result);
841 if (auto *Wasm = dyn_cast<WasmObjectFile>(Obj))
842 return getRelocationValueString(Wasm, Rel, Result);
843 if (auto *MachO = dyn_cast<MachOObjectFile>(Obj))
844 return getRelocationValueString(MachO, Rel, Result);
845 llvm_unreachable("unknown object file format");
846 }
847
848 /// Indicates whether this relocation should hidden when listing
849 /// relocations, usually because it is the trailing part of a multipart
850 /// relocation that will be printed as part of the leading relocation.
getHidden(RelocationRef RelRef)851 static bool getHidden(RelocationRef RelRef) {
852 const ObjectFile *Obj = RelRef.getObject();
853 auto *MachO = dyn_cast<MachOObjectFile>(Obj);
854 if (!MachO)
855 return false;
856
857 unsigned Arch = MachO->getArch();
858 DataRefImpl Rel = RelRef.getRawDataRefImpl();
859 uint64_t Type = MachO->getRelocationType(Rel);
860
861 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
862 // is always hidden.
863 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) {
864 if (Type == MachO::GENERIC_RELOC_PAIR)
865 return true;
866 } else if (Arch == Triple::x86_64) {
867 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
868 // an X86_64_RELOC_SUBTRACTOR.
869 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
870 DataRefImpl RelPrev = Rel;
871 RelPrev.d.a--;
872 uint64_t PrevType = MachO->getRelocationType(RelPrev);
873 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
874 return true;
875 }
876 }
877
878 return false;
879 }
880
881 namespace {
882 class SourcePrinter {
883 protected:
884 DILineInfo OldLineInfo;
885 const ObjectFile *Obj = nullptr;
886 std::unique_ptr<symbolize::LLVMSymbolizer> Symbolizer;
887 // File name to file contents of source
888 std::unordered_map<std::string, std::unique_ptr<MemoryBuffer>> SourceCache;
889 // Mark the line endings of the cached source
890 std::unordered_map<std::string, std::vector<StringRef>> LineCache;
891
892 private:
893 bool cacheSource(const DILineInfo& LineInfoFile);
894
895 public:
896 SourcePrinter() = default;
SourcePrinter(const ObjectFile * Obj,StringRef DefaultArch)897 SourcePrinter(const ObjectFile *Obj, StringRef DefaultArch) : Obj(Obj) {
898 symbolize::LLVMSymbolizer::Options SymbolizerOpts(
899 DILineInfoSpecifier::FunctionNameKind::None, true, false, false,
900 DefaultArch);
901 Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts));
902 }
903 virtual ~SourcePrinter() = default;
904 virtual void printSourceLine(raw_ostream &OS, uint64_t Address,
905 StringRef Delimiter = "; ");
906 };
907
cacheSource(const DILineInfo & LineInfo)908 bool SourcePrinter::cacheSource(const DILineInfo &LineInfo) {
909 std::unique_ptr<MemoryBuffer> Buffer;
910 if (LineInfo.Source) {
911 Buffer = MemoryBuffer::getMemBuffer(*LineInfo.Source);
912 } else {
913 auto BufferOrError = MemoryBuffer::getFile(LineInfo.FileName);
914 if (!BufferOrError)
915 return false;
916 Buffer = std::move(*BufferOrError);
917 }
918 // Chomp the file to get lines
919 size_t BufferSize = Buffer->getBufferSize();
920 const char *BufferStart = Buffer->getBufferStart();
921 for (const char *Start = BufferStart, *End = BufferStart;
922 End < BufferStart + BufferSize; End++)
923 if (*End == '\n' || End == BufferStart + BufferSize - 1 ||
924 (*End == '\r' && *(End + 1) == '\n')) {
925 LineCache[LineInfo.FileName].push_back(StringRef(Start, End - Start));
926 if (*End == '\r')
927 End++;
928 Start = End + 1;
929 }
930 SourceCache[LineInfo.FileName] = std::move(Buffer);
931 return true;
932 }
933
printSourceLine(raw_ostream & OS,uint64_t Address,StringRef Delimiter)934 void SourcePrinter::printSourceLine(raw_ostream &OS, uint64_t Address,
935 StringRef Delimiter) {
936 if (!Symbolizer)
937 return;
938 DILineInfo LineInfo = DILineInfo();
939 auto ExpectecLineInfo =
940 Symbolizer->symbolizeCode(Obj->getFileName(), Address);
941 if (!ExpectecLineInfo)
942 consumeError(ExpectecLineInfo.takeError());
943 else
944 LineInfo = *ExpectecLineInfo;
945
946 if ((LineInfo.FileName == "<invalid>") || OldLineInfo.Line == LineInfo.Line ||
947 LineInfo.Line == 0)
948 return;
949
950 if (PrintLines)
951 OS << Delimiter << LineInfo.FileName << ":" << LineInfo.Line << "\n";
952 if (PrintSource) {
953 if (SourceCache.find(LineInfo.FileName) == SourceCache.end())
954 if (!cacheSource(LineInfo))
955 return;
956 auto FileBuffer = SourceCache.find(LineInfo.FileName);
957 if (FileBuffer != SourceCache.end()) {
958 auto LineBuffer = LineCache.find(LineInfo.FileName);
959 if (LineBuffer != LineCache.end()) {
960 if (LineInfo.Line > LineBuffer->second.size())
961 return;
962 // Vector begins at 0, line numbers are non-zero
963 OS << Delimiter << LineBuffer->second[LineInfo.Line - 1].ltrim()
964 << "\n";
965 }
966 }
967 }
968 OldLineInfo = LineInfo;
969 }
970
isArmElf(const ObjectFile * Obj)971 static bool isArmElf(const ObjectFile *Obj) {
972 return (Obj->isELF() &&
973 (Obj->getArch() == Triple::aarch64 ||
974 Obj->getArch() == Triple::aarch64_be ||
975 Obj->getArch() == Triple::arm || Obj->getArch() == Triple::armeb ||
976 Obj->getArch() == Triple::thumb ||
977 Obj->getArch() == Triple::thumbeb));
978 }
979
980 class PrettyPrinter {
981 public:
982 virtual ~PrettyPrinter() = default;
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,std::vector<RelocationRef> * Rels=nullptr)983 virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
984 ArrayRef<uint8_t> Bytes, uint64_t Address,
985 raw_ostream &OS, StringRef Annot,
986 MCSubtargetInfo const &STI, SourcePrinter *SP,
987 std::vector<RelocationRef> *Rels = nullptr) {
988 if (SP && (PrintSource || PrintLines))
989 SP->printSourceLine(OS, Address);
990 if (!NoLeadingAddr)
991 OS << format("%8" PRIx64 ":", Address);
992 if (!NoShowRawInsn) {
993 OS << "\t";
994 dumpBytes(Bytes, OS);
995 }
996 if (MI)
997 IP.printInst(MI, OS, "", STI);
998 else
999 OS << " <unknown>";
1000 }
1001 };
1002 PrettyPrinter PrettyPrinterInst;
1003 class HexagonPrettyPrinter : public PrettyPrinter {
1004 public:
printLead(ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS)1005 void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
1006 raw_ostream &OS) {
1007 uint32_t opcode =
1008 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
1009 if (!NoLeadingAddr)
1010 OS << format("%8" PRIx64 ":", Address);
1011 if (!NoShowRawInsn) {
1012 OS << "\t";
1013 dumpBytes(Bytes.slice(0, 4), OS);
1014 OS << format("%08" PRIx32, opcode);
1015 }
1016 }
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,std::vector<RelocationRef> * Rels)1017 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
1018 uint64_t Address, raw_ostream &OS, StringRef Annot,
1019 MCSubtargetInfo const &STI, SourcePrinter *SP,
1020 std::vector<RelocationRef> *Rels) override {
1021 if (SP && (PrintSource || PrintLines))
1022 SP->printSourceLine(OS, Address, "");
1023 if (!MI) {
1024 printLead(Bytes, Address, OS);
1025 OS << " <unknown>";
1026 return;
1027 }
1028 std::string Buffer;
1029 {
1030 raw_string_ostream TempStream(Buffer);
1031 IP.printInst(MI, TempStream, "", STI);
1032 }
1033 StringRef Contents(Buffer);
1034 // Split off bundle attributes
1035 auto PacketBundle = Contents.rsplit('\n');
1036 // Split off first instruction from the rest
1037 auto HeadTail = PacketBundle.first.split('\n');
1038 auto Preamble = " { ";
1039 auto Separator = "";
1040 StringRef Fmt = "\t\t\t%08" PRIx64 ": ";
1041 std::vector<RelocationRef>::const_iterator rel_cur = Rels->begin();
1042 std::vector<RelocationRef>::const_iterator rel_end = Rels->end();
1043
1044 // Hexagon's packets require relocations to be inline rather than
1045 // clustered at the end of the packet.
1046 auto PrintReloc = [&]() -> void {
1047 while ((rel_cur != rel_end) && (rel_cur->getOffset() <= Address)) {
1048 if (rel_cur->getOffset() == Address) {
1049 SmallString<16> name;
1050 SmallString<32> val;
1051 rel_cur->getTypeName(name);
1052 error(getRelocationValueString(*rel_cur, val));
1053 OS << Separator << format(Fmt.data(), Address) << name << "\t" << val
1054 << "\n";
1055 return;
1056 }
1057 rel_cur++;
1058 }
1059 };
1060
1061 while(!HeadTail.first.empty()) {
1062 OS << Separator;
1063 Separator = "\n";
1064 if (SP && (PrintSource || PrintLines))
1065 SP->printSourceLine(OS, Address, "");
1066 printLead(Bytes, Address, OS);
1067 OS << Preamble;
1068 Preamble = " ";
1069 StringRef Inst;
1070 auto Duplex = HeadTail.first.split('\v');
1071 if(!Duplex.second.empty()){
1072 OS << Duplex.first;
1073 OS << "; ";
1074 Inst = Duplex.second;
1075 }
1076 else
1077 Inst = HeadTail.first;
1078 OS << Inst;
1079 HeadTail = HeadTail.second.split('\n');
1080 if (HeadTail.first.empty())
1081 OS << " } " << PacketBundle.second;
1082 PrintReloc();
1083 Bytes = Bytes.slice(4);
1084 Address += 4;
1085 }
1086 }
1087 };
1088 HexagonPrettyPrinter HexagonPrettyPrinterInst;
1089
1090 class AMDGCNPrettyPrinter : public PrettyPrinter {
1091 public:
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,std::vector<RelocationRef> * Rels)1092 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
1093 uint64_t Address, raw_ostream &OS, StringRef Annot,
1094 MCSubtargetInfo const &STI, SourcePrinter *SP,
1095 std::vector<RelocationRef> *Rels) override {
1096 if (SP && (PrintSource || PrintLines))
1097 SP->printSourceLine(OS, Address);
1098
1099 typedef support::ulittle32_t U32;
1100
1101 if (MI) {
1102 SmallString<40> InstStr;
1103 raw_svector_ostream IS(InstStr);
1104
1105 IP.printInst(MI, IS, "", STI);
1106
1107 OS << left_justify(IS.str(), 60);
1108 } else {
1109 // an unrecognized encoding - this is probably data so represent it
1110 // using the .long directive, or .byte directive if fewer than 4 bytes
1111 // remaining
1112 if (Bytes.size() >= 4) {
1113 OS << format("\t.long 0x%08" PRIx32 " ",
1114 static_cast<uint32_t>(*reinterpret_cast<const U32*>(Bytes.data())));
1115 OS.indent(42);
1116 } else {
1117 OS << format("\t.byte 0x%02" PRIx8, Bytes[0]);
1118 for (unsigned int i = 1; i < Bytes.size(); i++)
1119 OS << format(", 0x%02" PRIx8, Bytes[i]);
1120 OS.indent(55 - (6 * Bytes.size()));
1121 }
1122 }
1123
1124 OS << format("// %012" PRIX64 ": ", Address);
1125 if (Bytes.size() >=4) {
1126 for (auto D : makeArrayRef(reinterpret_cast<const U32*>(Bytes.data()),
1127 Bytes.size() / sizeof(U32)))
1128 // D should be explicitly casted to uint32_t here as it is passed
1129 // by format to snprintf as vararg.
1130 OS << format("%08" PRIX32 " ", static_cast<uint32_t>(D));
1131 } else {
1132 for (unsigned int i = 0; i < Bytes.size(); i++)
1133 OS << format("%02" PRIX8 " ", Bytes[i]);
1134 }
1135
1136 if (!Annot.empty())
1137 OS << "// " << Annot;
1138 }
1139 };
1140 AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
1141
1142 class BPFPrettyPrinter : public PrettyPrinter {
1143 public:
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,std::vector<RelocationRef> * Rels)1144 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
1145 uint64_t Address, raw_ostream &OS, StringRef Annot,
1146 MCSubtargetInfo const &STI, SourcePrinter *SP,
1147 std::vector<RelocationRef> *Rels) override {
1148 if (SP && (PrintSource || PrintLines))
1149 SP->printSourceLine(OS, Address);
1150 if (!NoLeadingAddr)
1151 OS << format("%8" PRId64 ":", Address / 8);
1152 if (!NoShowRawInsn) {
1153 OS << "\t";
1154 dumpBytes(Bytes, OS);
1155 }
1156 if (MI)
1157 IP.printInst(MI, OS, "", STI);
1158 else
1159 OS << " <unknown>";
1160 }
1161 };
1162 BPFPrettyPrinter BPFPrettyPrinterInst;
1163
selectPrettyPrinter(Triple const & Triple)1164 PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
1165 switch(Triple.getArch()) {
1166 default:
1167 return PrettyPrinterInst;
1168 case Triple::hexagon:
1169 return HexagonPrettyPrinterInst;
1170 case Triple::amdgcn:
1171 return AMDGCNPrettyPrinterInst;
1172 case Triple::bpfel:
1173 case Triple::bpfeb:
1174 return BPFPrettyPrinterInst;
1175 }
1176 }
1177 }
1178
getElfSymbolType(const ObjectFile * Obj,const SymbolRef & Sym)1179 static uint8_t getElfSymbolType(const ObjectFile *Obj, const SymbolRef &Sym) {
1180 assert(Obj->isELF());
1181 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
1182 return Elf32LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
1183 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
1184 return Elf64LEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
1185 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
1186 return Elf32BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
1187 if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
1188 return Elf64BEObj->getSymbol(Sym.getRawDataRefImpl())->getType();
1189 llvm_unreachable("Unsupported binary format");
1190 }
1191
1192 template <class ELFT> static void
addDynamicElfSymbols(const ELFObjectFile<ELFT> * Obj,std::map<SectionRef,SectionSymbolsTy> & AllSymbols)1193 addDynamicElfSymbols(const ELFObjectFile<ELFT> *Obj,
1194 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
1195 for (auto Symbol : Obj->getDynamicSymbolIterators()) {
1196 uint8_t SymbolType = Symbol.getELFType();
1197 if (SymbolType != ELF::STT_FUNC || Symbol.getSize() == 0)
1198 continue;
1199
1200 Expected<uint64_t> AddressOrErr = Symbol.getAddress();
1201 if (!AddressOrErr)
1202 report_error(Obj->getFileName(), AddressOrErr.takeError());
1203 uint64_t Address = *AddressOrErr;
1204
1205 Expected<StringRef> Name = Symbol.getName();
1206 if (!Name)
1207 report_error(Obj->getFileName(), Name.takeError());
1208 if (Name->empty())
1209 continue;
1210
1211 Expected<section_iterator> SectionOrErr = Symbol.getSection();
1212 if (!SectionOrErr)
1213 report_error(Obj->getFileName(), SectionOrErr.takeError());
1214 section_iterator SecI = *SectionOrErr;
1215 if (SecI == Obj->section_end())
1216 continue;
1217
1218 AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType);
1219 }
1220 }
1221
1222 static void
addDynamicElfSymbols(const ObjectFile * Obj,std::map<SectionRef,SectionSymbolsTy> & AllSymbols)1223 addDynamicElfSymbols(const ObjectFile *Obj,
1224 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
1225 assert(Obj->isELF());
1226 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(Obj))
1227 addDynamicElfSymbols(Elf32LEObj, AllSymbols);
1228 else if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(Obj))
1229 addDynamicElfSymbols(Elf64LEObj, AllSymbols);
1230 else if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(Obj))
1231 addDynamicElfSymbols(Elf32BEObj, AllSymbols);
1232 else if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(Obj))
1233 addDynamicElfSymbols(Elf64BEObj, AllSymbols);
1234 else
1235 llvm_unreachable("Unsupported binary format");
1236 }
1237
DisassembleObject(const ObjectFile * Obj,bool InlineRelocs)1238 static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
1239 if (StartAddress > StopAddress)
1240 error("Start address should be less than stop address");
1241
1242 const Target *TheTarget = getTarget(Obj);
1243
1244 // Package up features to be passed to target/subtarget
1245 SubtargetFeatures Features = Obj->getFeatures();
1246 if (MAttrs.size()) {
1247 for (unsigned i = 0; i != MAttrs.size(); ++i)
1248 Features.AddFeature(MAttrs[i]);
1249 }
1250
1251 std::unique_ptr<const MCRegisterInfo> MRI(
1252 TheTarget->createMCRegInfo(TripleName));
1253 if (!MRI)
1254 report_error(Obj->getFileName(), "no register info for target " +
1255 TripleName);
1256
1257 // Set up disassembler.
1258 std::unique_ptr<const MCAsmInfo> AsmInfo(
1259 TheTarget->createMCAsmInfo(*MRI, TripleName));
1260 if (!AsmInfo)
1261 report_error(Obj->getFileName(), "no assembly info for target " +
1262 TripleName);
1263 std::unique_ptr<const MCSubtargetInfo> STI(
1264 TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
1265 if (!STI)
1266 report_error(Obj->getFileName(), "no subtarget info for target " +
1267 TripleName);
1268 std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
1269 if (!MII)
1270 report_error(Obj->getFileName(), "no instruction info for target " +
1271 TripleName);
1272 MCObjectFileInfo MOFI;
1273 MCContext Ctx(AsmInfo.get(), MRI.get(), &MOFI);
1274 // FIXME: for now initialize MCObjectFileInfo with default values
1275 MOFI.InitMCObjectFileInfo(Triple(TripleName), false, Ctx);
1276
1277 std::unique_ptr<MCDisassembler> DisAsm(
1278 TheTarget->createMCDisassembler(*STI, Ctx));
1279 if (!DisAsm)
1280 report_error(Obj->getFileName(), "no disassembler for target " +
1281 TripleName);
1282
1283 std::unique_ptr<const MCInstrAnalysis> MIA(
1284 TheTarget->createMCInstrAnalysis(MII.get()));
1285
1286 int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
1287 std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
1288 Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
1289 if (!IP)
1290 report_error(Obj->getFileName(), "no instruction printer for target " +
1291 TripleName);
1292 IP->setPrintImmHex(PrintImmHex);
1293 PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
1294
1295 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "\t\t%016" PRIx64 ": " :
1296 "\t\t\t%08" PRIx64 ": ";
1297
1298 SourcePrinter SP(Obj, TheTarget->getName());
1299
1300 // Create a mapping, RelocSecs = SectionRelocMap[S], where sections
1301 // in RelocSecs contain the relocations for section S.
1302 std::error_code EC;
1303 std::map<SectionRef, SmallVector<SectionRef, 1>> SectionRelocMap;
1304 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1305 section_iterator Sec2 = Section.getRelocatedSection();
1306 if (Sec2 != Obj->section_end())
1307 SectionRelocMap[*Sec2].push_back(Section);
1308 }
1309
1310 // Create a mapping from virtual address to symbol name. This is used to
1311 // pretty print the symbols while disassembling.
1312 std::map<SectionRef, SectionSymbolsTy> AllSymbols;
1313 SectionSymbolsTy AbsoluteSymbols;
1314 for (const SymbolRef &Symbol : Obj->symbols()) {
1315 Expected<uint64_t> AddressOrErr = Symbol.getAddress();
1316 if (!AddressOrErr)
1317 report_error(Obj->getFileName(), AddressOrErr.takeError());
1318 uint64_t Address = *AddressOrErr;
1319
1320 Expected<StringRef> Name = Symbol.getName();
1321 if (!Name)
1322 report_error(Obj->getFileName(), Name.takeError());
1323 if (Name->empty())
1324 continue;
1325
1326 Expected<section_iterator> SectionOrErr = Symbol.getSection();
1327 if (!SectionOrErr)
1328 report_error(Obj->getFileName(), SectionOrErr.takeError());
1329
1330 uint8_t SymbolType = ELF::STT_NOTYPE;
1331 if (Obj->isELF())
1332 SymbolType = getElfSymbolType(Obj, Symbol);
1333
1334 section_iterator SecI = *SectionOrErr;
1335 if (SecI != Obj->section_end())
1336 AllSymbols[*SecI].emplace_back(Address, *Name, SymbolType);
1337 else
1338 AbsoluteSymbols.emplace_back(Address, *Name, SymbolType);
1339
1340
1341 }
1342 if (AllSymbols.empty() && Obj->isELF())
1343 addDynamicElfSymbols(Obj, AllSymbols);
1344
1345 // Create a mapping from virtual address to section.
1346 std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
1347 for (SectionRef Sec : Obj->sections())
1348 SectionAddresses.emplace_back(Sec.getAddress(), Sec);
1349 array_pod_sort(SectionAddresses.begin(), SectionAddresses.end());
1350
1351 // Linked executables (.exe and .dll files) typically don't include a real
1352 // symbol table but they might contain an export table.
1353 if (const auto *COFFObj = dyn_cast<COFFObjectFile>(Obj)) {
1354 for (const auto &ExportEntry : COFFObj->export_directories()) {
1355 StringRef Name;
1356 error(ExportEntry.getSymbolName(Name));
1357 if (Name.empty())
1358 continue;
1359 uint32_t RVA;
1360 error(ExportEntry.getExportRVA(RVA));
1361
1362 uint64_t VA = COFFObj->getImageBase() + RVA;
1363 auto Sec = std::upper_bound(
1364 SectionAddresses.begin(), SectionAddresses.end(), VA,
1365 [](uint64_t LHS, const std::pair<uint64_t, SectionRef> &RHS) {
1366 return LHS < RHS.first;
1367 });
1368 if (Sec != SectionAddresses.begin())
1369 --Sec;
1370 else
1371 Sec = SectionAddresses.end();
1372
1373 if (Sec != SectionAddresses.end())
1374 AllSymbols[Sec->second].emplace_back(VA, Name, ELF::STT_NOTYPE);
1375 else
1376 AbsoluteSymbols.emplace_back(VA, Name, ELF::STT_NOTYPE);
1377 }
1378 }
1379
1380 // Sort all the symbols, this allows us to use a simple binary search to find
1381 // a symbol near an address.
1382 for (std::pair<const SectionRef, SectionSymbolsTy> &SecSyms : AllSymbols)
1383 array_pod_sort(SecSyms.second.begin(), SecSyms.second.end());
1384 array_pod_sort(AbsoluteSymbols.begin(), AbsoluteSymbols.end());
1385
1386 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1387 if (!DisassembleAll && (!Section.isText() || Section.isVirtual()))
1388 continue;
1389
1390 uint64_t SectionAddr = Section.getAddress();
1391 uint64_t SectSize = Section.getSize();
1392 if (!SectSize)
1393 continue;
1394
1395 // Get the list of all the symbols in this section.
1396 SectionSymbolsTy &Symbols = AllSymbols[Section];
1397 std::vector<uint64_t> DataMappingSymsAddr;
1398 std::vector<uint64_t> TextMappingSymsAddr;
1399 if (isArmElf(Obj)) {
1400 for (const auto &Symb : Symbols) {
1401 uint64_t Address = std::get<0>(Symb);
1402 StringRef Name = std::get<1>(Symb);
1403 if (Name.startswith("$d"))
1404 DataMappingSymsAddr.push_back(Address - SectionAddr);
1405 if (Name.startswith("$x"))
1406 TextMappingSymsAddr.push_back(Address - SectionAddr);
1407 if (Name.startswith("$a"))
1408 TextMappingSymsAddr.push_back(Address - SectionAddr);
1409 if (Name.startswith("$t"))
1410 TextMappingSymsAddr.push_back(Address - SectionAddr);
1411 }
1412 }
1413
1414 llvm::sort(DataMappingSymsAddr.begin(), DataMappingSymsAddr.end());
1415 llvm::sort(TextMappingSymsAddr.begin(), TextMappingSymsAddr.end());
1416
1417 if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
1418 // AMDGPU disassembler uses symbolizer for printing labels
1419 std::unique_ptr<MCRelocationInfo> RelInfo(
1420 TheTarget->createMCRelocationInfo(TripleName, Ctx));
1421 if (RelInfo) {
1422 std::unique_ptr<MCSymbolizer> Symbolizer(
1423 TheTarget->createMCSymbolizer(
1424 TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo)));
1425 DisAsm->setSymbolizer(std::move(Symbolizer));
1426 }
1427 }
1428
1429 // Make a list of all the relocations for this section.
1430 std::vector<RelocationRef> Rels;
1431 if (InlineRelocs) {
1432 for (const SectionRef &RelocSec : SectionRelocMap[Section]) {
1433 for (const RelocationRef &Reloc : RelocSec.relocations()) {
1434 Rels.push_back(Reloc);
1435 }
1436 }
1437 }
1438
1439 // Sort relocations by address.
1440 llvm::sort(Rels.begin(), Rels.end(), RelocAddressLess);
1441
1442 StringRef SegmentName = "";
1443 if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) {
1444 DataRefImpl DR = Section.getRawDataRefImpl();
1445 SegmentName = MachO->getSectionFinalSegmentName(DR);
1446 }
1447 StringRef SectionName;
1448 error(Section.getName(SectionName));
1449
1450 // If the section has no symbol at the start, just insert a dummy one.
1451 if (Symbols.empty() || std::get<0>(Symbols[0]) != 0) {
1452 Symbols.insert(
1453 Symbols.begin(),
1454 std::make_tuple(SectionAddr, SectionName,
1455 Section.isText() ? ELF::STT_FUNC : ELF::STT_OBJECT));
1456 }
1457
1458 SmallString<40> Comments;
1459 raw_svector_ostream CommentStream(Comments);
1460
1461 StringRef BytesStr;
1462 error(Section.getContents(BytesStr));
1463 ArrayRef<uint8_t> Bytes(reinterpret_cast<const uint8_t *>(BytesStr.data()),
1464 BytesStr.size());
1465
1466 uint64_t Size;
1467 uint64_t Index;
1468 bool PrintedSection = false;
1469
1470 std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
1471 std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
1472 // Disassemble symbol by symbol.
1473 for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
1474 uint64_t Start = std::get<0>(Symbols[si]) - SectionAddr;
1475 // The end is either the section end or the beginning of the next
1476 // symbol.
1477 uint64_t End =
1478 (si == se - 1) ? SectSize : std::get<0>(Symbols[si + 1]) - SectionAddr;
1479 // Don't try to disassemble beyond the end of section contents.
1480 if (End > SectSize)
1481 End = SectSize;
1482 // If this symbol has the same address as the next symbol, then skip it.
1483 if (Start >= End)
1484 continue;
1485
1486 // Check if we need to skip symbol
1487 // Skip if the symbol's data is not between StartAddress and StopAddress
1488 if (End + SectionAddr < StartAddress ||
1489 Start + SectionAddr > StopAddress) {
1490 continue;
1491 }
1492
1493 /// Skip if user requested specific symbols and this is not in the list
1494 if (!DisasmFuncsSet.empty() &&
1495 !DisasmFuncsSet.count(std::get<1>(Symbols[si])))
1496 continue;
1497
1498 if (!PrintedSection) {
1499 PrintedSection = true;
1500 outs() << "Disassembly of section ";
1501 if (!SegmentName.empty())
1502 outs() << SegmentName << ",";
1503 outs() << SectionName << ':';
1504 }
1505
1506 // Stop disassembly at the stop address specified
1507 if (End + SectionAddr > StopAddress)
1508 End = StopAddress - SectionAddr;
1509
1510 if (Obj->isELF() && Obj->getArch() == Triple::amdgcn) {
1511 if (std::get<2>(Symbols[si]) == ELF::STT_AMDGPU_HSA_KERNEL) {
1512 // skip amd_kernel_code_t at the begining of kernel symbol (256 bytes)
1513 Start += 256;
1514 }
1515 if (si == se - 1 ||
1516 std::get<2>(Symbols[si + 1]) == ELF::STT_AMDGPU_HSA_KERNEL) {
1517 // cut trailing zeroes at the end of kernel
1518 // cut up to 256 bytes
1519 const uint64_t EndAlign = 256;
1520 const auto Limit = End - (std::min)(EndAlign, End - Start);
1521 while (End > Limit &&
1522 *reinterpret_cast<const support::ulittle32_t*>(&Bytes[End - 4]) == 0)
1523 End -= 4;
1524 }
1525 }
1526
1527 auto PrintSymbol = [](StringRef Name) {
1528 outs() << '\n' << Name << ":\n";
1529 };
1530 StringRef SymbolName = std::get<1>(Symbols[si]);
1531 if (Demangle.getValue() == "" || Demangle.getValue() == "itanium") {
1532 char *DemangledSymbol = nullptr;
1533 size_t Size = 0;
1534 int Status;
1535 DemangledSymbol =
1536 itaniumDemangle(SymbolName.data(), DemangledSymbol, &Size, &Status);
1537 if (Status == 0)
1538 PrintSymbol(StringRef(DemangledSymbol));
1539 else
1540 PrintSymbol(SymbolName);
1541
1542 if (Size != 0)
1543 free(DemangledSymbol);
1544 } else
1545 PrintSymbol(SymbolName);
1546
1547 // Don't print raw contents of a virtual section. A virtual section
1548 // doesn't have any contents in the file.
1549 if (Section.isVirtual()) {
1550 outs() << "...\n";
1551 continue;
1552 }
1553
1554 #ifndef NDEBUG
1555 raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
1556 #else
1557 raw_ostream &DebugOut = nulls();
1558 #endif
1559
1560 for (Index = Start; Index < End; Index += Size) {
1561 MCInst Inst;
1562
1563 if (Index + SectionAddr < StartAddress ||
1564 Index + SectionAddr > StopAddress) {
1565 // skip byte by byte till StartAddress is reached
1566 Size = 1;
1567 continue;
1568 }
1569 // AArch64 ELF binaries can interleave data and text in the
1570 // same section. We rely on the markers introduced to
1571 // understand what we need to dump. If the data marker is within a
1572 // function, it is denoted as a word/short etc
1573 if (isArmElf(Obj) && std::get<2>(Symbols[si]) != ELF::STT_OBJECT &&
1574 !DisassembleAll) {
1575 uint64_t Stride = 0;
1576
1577 auto DAI = std::lower_bound(DataMappingSymsAddr.begin(),
1578 DataMappingSymsAddr.end(), Index);
1579 if (DAI != DataMappingSymsAddr.end() && *DAI == Index) {
1580 // Switch to data.
1581 while (Index < End) {
1582 outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1583 outs() << "\t";
1584 if (Index + 4 <= End) {
1585 Stride = 4;
1586 dumpBytes(Bytes.slice(Index, 4), outs());
1587 outs() << "\t.word\t";
1588 uint32_t Data = 0;
1589 if (Obj->isLittleEndian()) {
1590 const auto Word =
1591 reinterpret_cast<const support::ulittle32_t *>(
1592 Bytes.data() + Index);
1593 Data = *Word;
1594 } else {
1595 const auto Word = reinterpret_cast<const support::ubig32_t *>(
1596 Bytes.data() + Index);
1597 Data = *Word;
1598 }
1599 outs() << "0x" << format("%08" PRIx32, Data);
1600 } else if (Index + 2 <= End) {
1601 Stride = 2;
1602 dumpBytes(Bytes.slice(Index, 2), outs());
1603 outs() << "\t\t.short\t";
1604 uint16_t Data = 0;
1605 if (Obj->isLittleEndian()) {
1606 const auto Short =
1607 reinterpret_cast<const support::ulittle16_t *>(
1608 Bytes.data() + Index);
1609 Data = *Short;
1610 } else {
1611 const auto Short =
1612 reinterpret_cast<const support::ubig16_t *>(Bytes.data() +
1613 Index);
1614 Data = *Short;
1615 }
1616 outs() << "0x" << format("%04" PRIx16, Data);
1617 } else {
1618 Stride = 1;
1619 dumpBytes(Bytes.slice(Index, 1), outs());
1620 outs() << "\t\t.byte\t";
1621 outs() << "0x" << format("%02" PRIx8, Bytes.slice(Index, 1)[0]);
1622 }
1623 Index += Stride;
1624 outs() << "\n";
1625 auto TAI = std::lower_bound(TextMappingSymsAddr.begin(),
1626 TextMappingSymsAddr.end(), Index);
1627 if (TAI != TextMappingSymsAddr.end() && *TAI == Index)
1628 break;
1629 }
1630 }
1631 }
1632
1633 // If there is a data symbol inside an ELF text section and we are only
1634 // disassembling text (applicable all architectures),
1635 // we are in a situation where we must print the data and not
1636 // disassemble it.
1637 if (Obj->isELF() && std::get<2>(Symbols[si]) == ELF::STT_OBJECT &&
1638 !DisassembleAll && Section.isText()) {
1639 // print out data up to 8 bytes at a time in hex and ascii
1640 uint8_t AsciiData[9] = {'\0'};
1641 uint8_t Byte;
1642 int NumBytes = 0;
1643
1644 for (Index = Start; Index < End; Index += 1) {
1645 if (((SectionAddr + Index) < StartAddress) ||
1646 ((SectionAddr + Index) > StopAddress))
1647 continue;
1648 if (NumBytes == 0) {
1649 outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1650 outs() << "\t";
1651 }
1652 Byte = Bytes.slice(Index)[0];
1653 outs() << format(" %02x", Byte);
1654 AsciiData[NumBytes] = isPrint(Byte) ? Byte : '.';
1655
1656 uint8_t IndentOffset = 0;
1657 NumBytes++;
1658 if (Index == End - 1 || NumBytes > 8) {
1659 // Indent the space for less than 8 bytes data.
1660 // 2 spaces for byte and one for space between bytes
1661 IndentOffset = 3 * (8 - NumBytes);
1662 for (int Excess = 8 - NumBytes; Excess < 8; Excess++)
1663 AsciiData[Excess] = '\0';
1664 NumBytes = 8;
1665 }
1666 if (NumBytes == 8) {
1667 AsciiData[8] = '\0';
1668 outs() << std::string(IndentOffset, ' ') << " ";
1669 outs() << reinterpret_cast<char *>(AsciiData);
1670 outs() << '\n';
1671 NumBytes = 0;
1672 }
1673 }
1674 }
1675 if (Index >= End)
1676 break;
1677
1678 // Disassemble a real instruction or a data when disassemble all is
1679 // provided
1680 bool Disassembled = DisAsm->getInstruction(Inst, Size, Bytes.slice(Index),
1681 SectionAddr + Index, DebugOut,
1682 CommentStream);
1683 if (Size == 0)
1684 Size = 1;
1685
1686 PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
1687 Bytes.slice(Index, Size), SectionAddr + Index, outs(), "",
1688 *STI, &SP, &Rels);
1689 outs() << CommentStream.str();
1690 Comments.clear();
1691
1692 // Try to resolve the target of a call, tail call, etc. to a specific
1693 // symbol.
1694 if (MIA && (MIA->isCall(Inst) || MIA->isUnconditionalBranch(Inst) ||
1695 MIA->isConditionalBranch(Inst))) {
1696 uint64_t Target;
1697 if (MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target)) {
1698 // In a relocatable object, the target's section must reside in
1699 // the same section as the call instruction or it is accessed
1700 // through a relocation.
1701 //
1702 // In a non-relocatable object, the target may be in any section.
1703 //
1704 // N.B. We don't walk the relocations in the relocatable case yet.
1705 auto *TargetSectionSymbols = &Symbols;
1706 if (!Obj->isRelocatableObject()) {
1707 auto SectionAddress = std::upper_bound(
1708 SectionAddresses.begin(), SectionAddresses.end(), Target,
1709 [](uint64_t LHS,
1710 const std::pair<uint64_t, SectionRef> &RHS) {
1711 return LHS < RHS.first;
1712 });
1713 if (SectionAddress != SectionAddresses.begin()) {
1714 --SectionAddress;
1715 TargetSectionSymbols = &AllSymbols[SectionAddress->second];
1716 } else {
1717 TargetSectionSymbols = &AbsoluteSymbols;
1718 }
1719 }
1720
1721 // Find the first symbol in the section whose offset is less than
1722 // or equal to the target. If there isn't a section that contains
1723 // the target, find the nearest preceding absolute symbol.
1724 auto TargetSym = std::upper_bound(
1725 TargetSectionSymbols->begin(), TargetSectionSymbols->end(),
1726 Target, [](uint64_t LHS,
1727 const std::tuple<uint64_t, StringRef, uint8_t> &RHS) {
1728 return LHS < std::get<0>(RHS);
1729 });
1730 if (TargetSym == TargetSectionSymbols->begin()) {
1731 TargetSectionSymbols = &AbsoluteSymbols;
1732 TargetSym = std::upper_bound(
1733 AbsoluteSymbols.begin(), AbsoluteSymbols.end(),
1734 Target, [](uint64_t LHS,
1735 const std::tuple<uint64_t, StringRef, uint8_t> &RHS) {
1736 return LHS < std::get<0>(RHS);
1737 });
1738 }
1739 if (TargetSym != TargetSectionSymbols->begin()) {
1740 --TargetSym;
1741 uint64_t TargetAddress = std::get<0>(*TargetSym);
1742 StringRef TargetName = std::get<1>(*TargetSym);
1743 outs() << " <" << TargetName;
1744 uint64_t Disp = Target - TargetAddress;
1745 if (Disp)
1746 outs() << "+0x" << Twine::utohexstr(Disp);
1747 outs() << '>';
1748 }
1749 }
1750 }
1751 outs() << "\n";
1752
1753 // Hexagon does this in pretty printer
1754 if (Obj->getArch() != Triple::hexagon)
1755 // Print relocation for instruction.
1756 while (rel_cur != rel_end) {
1757 bool hidden = getHidden(*rel_cur);
1758 uint64_t addr = rel_cur->getOffset();
1759 SmallString<16> name;
1760 SmallString<32> val;
1761
1762 // If this relocation is hidden, skip it.
1763 if (hidden || ((SectionAddr + addr) < StartAddress)) {
1764 ++rel_cur;
1765 continue;
1766 }
1767
1768 // Stop when rel_cur's address is past the current instruction.
1769 if (addr >= Index + Size) break;
1770 rel_cur->getTypeName(name);
1771 error(getRelocationValueString(*rel_cur, val));
1772 outs() << format(Fmt.data(), SectionAddr + addr) << name
1773 << "\t" << val << "\n";
1774 ++rel_cur;
1775 }
1776 }
1777 }
1778 }
1779 }
1780
PrintRelocations(const ObjectFile * Obj)1781 void llvm::PrintRelocations(const ObjectFile *Obj) {
1782 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
1783 "%08" PRIx64;
1784 // Regular objdump doesn't print relocations in non-relocatable object
1785 // files.
1786 if (!Obj->isRelocatableObject())
1787 return;
1788
1789 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1790 if (Section.relocation_begin() == Section.relocation_end())
1791 continue;
1792 StringRef secname;
1793 error(Section.getName(secname));
1794 outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
1795 for (const RelocationRef &Reloc : Section.relocations()) {
1796 bool hidden = getHidden(Reloc);
1797 uint64_t address = Reloc.getOffset();
1798 SmallString<32> relocname;
1799 SmallString<32> valuestr;
1800 if (address < StartAddress || address > StopAddress || hidden)
1801 continue;
1802 Reloc.getTypeName(relocname);
1803 error(getRelocationValueString(Reloc, valuestr));
1804 outs() << format(Fmt.data(), address) << " " << relocname << " "
1805 << valuestr << "\n";
1806 }
1807 outs() << "\n";
1808 }
1809 }
1810
PrintDynamicRelocations(const ObjectFile * Obj)1811 void llvm::PrintDynamicRelocations(const ObjectFile *Obj) {
1812
1813 // For the moment, this option is for ELF only
1814 if (!Obj->isELF())
1815 return;
1816
1817 const auto *Elf = dyn_cast<ELFObjectFileBase>(Obj);
1818
1819 if (!Elf || Elf->getEType() != ELF::ET_DYN) {
1820 error("not a dynamic object");
1821 return;
1822 }
1823
1824 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
1825
1826 std::vector<SectionRef> DynRelSec = Obj->dynamic_relocation_sections();
1827 if (DynRelSec.empty())
1828 return;
1829
1830 outs() << "DYNAMIC RELOCATION RECORDS\n";
1831 for (const SectionRef &Section : DynRelSec) {
1832 if (Section.relocation_begin() == Section.relocation_end())
1833 continue;
1834 for (const RelocationRef &Reloc : Section.relocations()) {
1835 uint64_t address = Reloc.getOffset();
1836 SmallString<32> relocname;
1837 SmallString<32> valuestr;
1838 Reloc.getTypeName(relocname);
1839 error(getRelocationValueString(Reloc, valuestr));
1840 outs() << format(Fmt.data(), address) << " " << relocname << " "
1841 << valuestr << "\n";
1842 }
1843 }
1844 }
1845
PrintSectionHeaders(const ObjectFile * Obj)1846 void llvm::PrintSectionHeaders(const ObjectFile *Obj) {
1847 outs() << "Sections:\n"
1848 "Idx Name Size Address Type\n";
1849 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1850 StringRef Name;
1851 error(Section.getName(Name));
1852 uint64_t Address = Section.getAddress();
1853 uint64_t Size = Section.getSize();
1854 bool Text = Section.isText();
1855 bool Data = Section.isData();
1856 bool BSS = Section.isBSS();
1857 std::string Type = (std::string(Text ? "TEXT " : "") +
1858 (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
1859 outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n",
1860 (unsigned)Section.getIndex(), Name.str().c_str(), Size,
1861 Address, Type.c_str());
1862 }
1863 }
1864
PrintSectionContents(const ObjectFile * Obj)1865 void llvm::PrintSectionContents(const ObjectFile *Obj) {
1866 std::error_code EC;
1867 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
1868 StringRef Name;
1869 StringRef Contents;
1870 error(Section.getName(Name));
1871 uint64_t BaseAddr = Section.getAddress();
1872 uint64_t Size = Section.getSize();
1873 if (!Size)
1874 continue;
1875
1876 outs() << "Contents of section " << Name << ":\n";
1877 if (Section.isBSS()) {
1878 outs() << format("<skipping contents of bss section at [%04" PRIx64
1879 ", %04" PRIx64 ")>\n",
1880 BaseAddr, BaseAddr + Size);
1881 continue;
1882 }
1883
1884 error(Section.getContents(Contents));
1885
1886 // Dump out the content as hex and printable ascii characters.
1887 for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) {
1888 outs() << format(" %04" PRIx64 " ", BaseAddr + addr);
1889 // Dump line of hex.
1890 for (std::size_t i = 0; i < 16; ++i) {
1891 if (i != 0 && i % 4 == 0)
1892 outs() << ' ';
1893 if (addr + i < end)
1894 outs() << hexdigit((Contents[addr + i] >> 4) & 0xF, true)
1895 << hexdigit(Contents[addr + i] & 0xF, true);
1896 else
1897 outs() << " ";
1898 }
1899 // Print ascii.
1900 outs() << " ";
1901 for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
1902 if (isPrint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF))
1903 outs() << Contents[addr + i];
1904 else
1905 outs() << ".";
1906 }
1907 outs() << "\n";
1908 }
1909 }
1910 }
1911
PrintSymbolTable(const ObjectFile * o,StringRef ArchiveName,StringRef ArchitectureName)1912 void llvm::PrintSymbolTable(const ObjectFile *o, StringRef ArchiveName,
1913 StringRef ArchitectureName) {
1914 outs() << "SYMBOL TABLE:\n";
1915
1916 if (const COFFObjectFile *coff = dyn_cast<const COFFObjectFile>(o)) {
1917 printCOFFSymbolTable(coff);
1918 return;
1919 }
1920 for (const SymbolRef &Symbol : o->symbols()) {
1921 Expected<uint64_t> AddressOrError = Symbol.getAddress();
1922 if (!AddressOrError)
1923 report_error(ArchiveName, o->getFileName(), AddressOrError.takeError(),
1924 ArchitectureName);
1925 uint64_t Address = *AddressOrError;
1926 if ((Address < StartAddress) || (Address > StopAddress))
1927 continue;
1928 Expected<SymbolRef::Type> TypeOrError = Symbol.getType();
1929 if (!TypeOrError)
1930 report_error(ArchiveName, o->getFileName(), TypeOrError.takeError(),
1931 ArchitectureName);
1932 SymbolRef::Type Type = *TypeOrError;
1933 uint32_t Flags = Symbol.getFlags();
1934 Expected<section_iterator> SectionOrErr = Symbol.getSection();
1935 if (!SectionOrErr)
1936 report_error(ArchiveName, o->getFileName(), SectionOrErr.takeError(),
1937 ArchitectureName);
1938 section_iterator Section = *SectionOrErr;
1939 StringRef Name;
1940 if (Type == SymbolRef::ST_Debug && Section != o->section_end()) {
1941 Section->getName(Name);
1942 } else {
1943 Expected<StringRef> NameOrErr = Symbol.getName();
1944 if (!NameOrErr)
1945 report_error(ArchiveName, o->getFileName(), NameOrErr.takeError(),
1946 ArchitectureName);
1947 Name = *NameOrErr;
1948 }
1949
1950 bool Global = Flags & SymbolRef::SF_Global;
1951 bool Weak = Flags & SymbolRef::SF_Weak;
1952 bool Absolute = Flags & SymbolRef::SF_Absolute;
1953 bool Common = Flags & SymbolRef::SF_Common;
1954 bool Hidden = Flags & SymbolRef::SF_Hidden;
1955
1956 char GlobLoc = ' ';
1957 if (Type != SymbolRef::ST_Unknown)
1958 GlobLoc = Global ? 'g' : 'l';
1959 char Debug = (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
1960 ? 'd' : ' ';
1961 char FileFunc = ' ';
1962 if (Type == SymbolRef::ST_File)
1963 FileFunc = 'f';
1964 else if (Type == SymbolRef::ST_Function)
1965 FileFunc = 'F';
1966
1967 const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 :
1968 "%08" PRIx64;
1969
1970 outs() << format(Fmt, Address) << " "
1971 << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
1972 << (Weak ? 'w' : ' ') // Weak?
1973 << ' ' // Constructor. Not supported yet.
1974 << ' ' // Warning. Not supported yet.
1975 << ' ' // Indirect reference to another symbol.
1976 << Debug // Debugging (d) or dynamic (D) symbol.
1977 << FileFunc // Name of function (F), file (f) or object (O).
1978 << ' ';
1979 if (Absolute) {
1980 outs() << "*ABS*";
1981 } else if (Common) {
1982 outs() << "*COM*";
1983 } else if (Section == o->section_end()) {
1984 outs() << "*UND*";
1985 } else {
1986 if (const MachOObjectFile *MachO =
1987 dyn_cast<const MachOObjectFile>(o)) {
1988 DataRefImpl DR = Section->getRawDataRefImpl();
1989 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
1990 outs() << SegmentName << ",";
1991 }
1992 StringRef SectionName;
1993 error(Section->getName(SectionName));
1994 outs() << SectionName;
1995 }
1996
1997 outs() << '\t';
1998 if (Common || isa<ELFObjectFileBase>(o)) {
1999 uint64_t Val =
2000 Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
2001 outs() << format("\t %08" PRIx64 " ", Val);
2002 }
2003
2004 if (Hidden) {
2005 outs() << ".hidden ";
2006 }
2007 outs() << Name
2008 << '\n';
2009 }
2010 }
2011
PrintUnwindInfo(const ObjectFile * o)2012 static void PrintUnwindInfo(const ObjectFile *o) {
2013 outs() << "Unwind info:\n\n";
2014
2015 if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) {
2016 printCOFFUnwindInfo(coff);
2017 } else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
2018 printMachOUnwindInfo(MachO);
2019 else {
2020 // TODO: Extract DWARF dump tool to objdump.
2021 errs() << "This operation is only currently supported "
2022 "for COFF and MachO object files.\n";
2023 return;
2024 }
2025 }
2026
printExportsTrie(const ObjectFile * o)2027 void llvm::printExportsTrie(const ObjectFile *o) {
2028 outs() << "Exports trie:\n";
2029 if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
2030 printMachOExportsTrie(MachO);
2031 else {
2032 errs() << "This operation is only currently supported "
2033 "for Mach-O executable files.\n";
2034 return;
2035 }
2036 }
2037
printRebaseTable(ObjectFile * o)2038 void llvm::printRebaseTable(ObjectFile *o) {
2039 outs() << "Rebase table:\n";
2040 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
2041 printMachORebaseTable(MachO);
2042 else {
2043 errs() << "This operation is only currently supported "
2044 "for Mach-O executable files.\n";
2045 return;
2046 }
2047 }
2048
printBindTable(ObjectFile * o)2049 void llvm::printBindTable(ObjectFile *o) {
2050 outs() << "Bind table:\n";
2051 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
2052 printMachOBindTable(MachO);
2053 else {
2054 errs() << "This operation is only currently supported "
2055 "for Mach-O executable files.\n";
2056 return;
2057 }
2058 }
2059
printLazyBindTable(ObjectFile * o)2060 void llvm::printLazyBindTable(ObjectFile *o) {
2061 outs() << "Lazy bind table:\n";
2062 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
2063 printMachOLazyBindTable(MachO);
2064 else {
2065 errs() << "This operation is only currently supported "
2066 "for Mach-O executable files.\n";
2067 return;
2068 }
2069 }
2070
printWeakBindTable(ObjectFile * o)2071 void llvm::printWeakBindTable(ObjectFile *o) {
2072 outs() << "Weak bind table:\n";
2073 if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(o))
2074 printMachOWeakBindTable(MachO);
2075 else {
2076 errs() << "This operation is only currently supported "
2077 "for Mach-O executable files.\n";
2078 return;
2079 }
2080 }
2081
2082 /// Dump the raw contents of the __clangast section so the output can be piped
2083 /// into llvm-bcanalyzer.
printRawClangAST(const ObjectFile * Obj)2084 void llvm::printRawClangAST(const ObjectFile *Obj) {
2085 if (outs().is_displayed()) {
2086 errs() << "The -raw-clang-ast option will dump the raw binary contents of "
2087 "the clang ast section.\n"
2088 "Please redirect the output to a file or another program such as "
2089 "llvm-bcanalyzer.\n";
2090 return;
2091 }
2092
2093 StringRef ClangASTSectionName("__clangast");
2094 if (isa<COFFObjectFile>(Obj)) {
2095 ClangASTSectionName = "clangast";
2096 }
2097
2098 Optional<object::SectionRef> ClangASTSection;
2099 for (auto Sec : ToolSectionFilter(*Obj)) {
2100 StringRef Name;
2101 Sec.getName(Name);
2102 if (Name == ClangASTSectionName) {
2103 ClangASTSection = Sec;
2104 break;
2105 }
2106 }
2107 if (!ClangASTSection)
2108 return;
2109
2110 StringRef ClangASTContents;
2111 error(ClangASTSection.getValue().getContents(ClangASTContents));
2112 outs().write(ClangASTContents.data(), ClangASTContents.size());
2113 }
2114
printFaultMaps(const ObjectFile * Obj)2115 static void printFaultMaps(const ObjectFile *Obj) {
2116 const char *FaultMapSectionName = nullptr;
2117
2118 if (isa<ELFObjectFileBase>(Obj)) {
2119 FaultMapSectionName = ".llvm_faultmaps";
2120 } else if (isa<MachOObjectFile>(Obj)) {
2121 FaultMapSectionName = "__llvm_faultmaps";
2122 } else {
2123 errs() << "This operation is only currently supported "
2124 "for ELF and Mach-O executable files.\n";
2125 return;
2126 }
2127
2128 Optional<object::SectionRef> FaultMapSection;
2129
2130 for (auto Sec : ToolSectionFilter(*Obj)) {
2131 StringRef Name;
2132 Sec.getName(Name);
2133 if (Name == FaultMapSectionName) {
2134 FaultMapSection = Sec;
2135 break;
2136 }
2137 }
2138
2139 outs() << "FaultMap table:\n";
2140
2141 if (!FaultMapSection.hasValue()) {
2142 outs() << "<not found>\n";
2143 return;
2144 }
2145
2146 StringRef FaultMapContents;
2147 error(FaultMapSection.getValue().getContents(FaultMapContents));
2148
2149 FaultMapParser FMP(FaultMapContents.bytes_begin(),
2150 FaultMapContents.bytes_end());
2151
2152 outs() << FMP;
2153 }
2154
printPrivateFileHeaders(const ObjectFile * o,bool onlyFirst)2155 static void printPrivateFileHeaders(const ObjectFile *o, bool onlyFirst) {
2156 if (o->isELF()) {
2157 printELFFileHeader(o);
2158 return printELFDynamicSection(o);
2159 }
2160 if (o->isCOFF())
2161 return printCOFFFileHeader(o);
2162 if (o->isWasm())
2163 return printWasmFileHeader(o);
2164 if (o->isMachO()) {
2165 printMachOFileHeader(o);
2166 if (!onlyFirst)
2167 printMachOLoadCommands(o);
2168 return;
2169 }
2170 report_error(o->getFileName(), "Invalid/Unsupported object file format");
2171 }
2172
printFileHeaders(const ObjectFile * o)2173 static void printFileHeaders(const ObjectFile *o) {
2174 if (!o->isELF() && !o->isCOFF())
2175 report_error(o->getFileName(), "Invalid/Unsupported object file format");
2176
2177 Triple::ArchType AT = o->getArch();
2178 outs() << "architecture: " << Triple::getArchTypeName(AT) << "\n";
2179 Expected<uint64_t> StartAddrOrErr = o->getStartAddress();
2180 if (!StartAddrOrErr)
2181 report_error(o->getFileName(), StartAddrOrErr.takeError());
2182 outs() << "start address: "
2183 << format("0x%0*x", o->getBytesInAddress(), StartAddrOrErr.get())
2184 << "\n";
2185 }
2186
printArchiveChild(StringRef Filename,const Archive::Child & C)2187 static void printArchiveChild(StringRef Filename, const Archive::Child &C) {
2188 Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
2189 if (!ModeOrErr) {
2190 errs() << "ill-formed archive entry.\n";
2191 consumeError(ModeOrErr.takeError());
2192 return;
2193 }
2194 sys::fs::perms Mode = ModeOrErr.get();
2195 outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
2196 outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
2197 outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
2198 outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
2199 outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
2200 outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
2201 outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
2202 outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
2203 outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
2204
2205 outs() << " ";
2206
2207 Expected<unsigned> UIDOrErr = C.getUID();
2208 if (!UIDOrErr)
2209 report_error(Filename, UIDOrErr.takeError());
2210 unsigned UID = UIDOrErr.get();
2211 outs() << format("%d/", UID);
2212
2213 Expected<unsigned> GIDOrErr = C.getGID();
2214 if (!GIDOrErr)
2215 report_error(Filename, GIDOrErr.takeError());
2216 unsigned GID = GIDOrErr.get();
2217 outs() << format("%-d ", GID);
2218
2219 Expected<uint64_t> Size = C.getRawSize();
2220 if (!Size)
2221 report_error(Filename, Size.takeError());
2222 outs() << format("%6" PRId64, Size.get()) << " ";
2223
2224 StringRef RawLastModified = C.getRawLastModified();
2225 unsigned Seconds;
2226 if (RawLastModified.getAsInteger(10, Seconds))
2227 outs() << "(date: \"" << RawLastModified
2228 << "\" contains non-decimal chars) ";
2229 else {
2230 // Since ctime(3) returns a 26 character string of the form:
2231 // "Sun Sep 16 01:03:52 1973\n\0"
2232 // just print 24 characters.
2233 time_t t = Seconds;
2234 outs() << format("%.24s ", ctime(&t));
2235 }
2236
2237 StringRef Name = "";
2238 Expected<StringRef> NameOrErr = C.getName();
2239 if (!NameOrErr) {
2240 consumeError(NameOrErr.takeError());
2241 Expected<StringRef> RawNameOrErr = C.getRawName();
2242 if (!RawNameOrErr)
2243 report_error(Filename, NameOrErr.takeError());
2244 Name = RawNameOrErr.get();
2245 } else {
2246 Name = NameOrErr.get();
2247 }
2248 outs() << Name << "\n";
2249 }
2250
DumpObject(ObjectFile * o,const Archive * a=nullptr,const Archive::Child * c=nullptr)2251 static void DumpObject(ObjectFile *o, const Archive *a = nullptr,
2252 const Archive::Child *c = nullptr) {
2253 StringRef ArchiveName = a != nullptr ? a->getFileName() : "";
2254 // Avoid other output when using a raw option.
2255 if (!RawClangAST) {
2256 outs() << '\n';
2257 if (a)
2258 outs() << a->getFileName() << "(" << o->getFileName() << ")";
2259 else
2260 outs() << o->getFileName();
2261 outs() << ":\tfile format " << o->getFileFormatName() << "\n\n";
2262 }
2263
2264 if (ArchiveHeaders && !MachOOpt)
2265 printArchiveChild(a->getFileName(), *c);
2266 if (Disassemble)
2267 DisassembleObject(o, Relocations);
2268 if (Relocations && !Disassemble)
2269 PrintRelocations(o);
2270 if (DynamicRelocations)
2271 PrintDynamicRelocations(o);
2272 if (SectionHeaders)
2273 PrintSectionHeaders(o);
2274 if (SectionContents)
2275 PrintSectionContents(o);
2276 if (SymbolTable)
2277 PrintSymbolTable(o, ArchiveName);
2278 if (UnwindInfo)
2279 PrintUnwindInfo(o);
2280 if (PrivateHeaders || FirstPrivateHeader)
2281 printPrivateFileHeaders(o, FirstPrivateHeader);
2282 if (FileHeaders)
2283 printFileHeaders(o);
2284 if (ExportsTrie)
2285 printExportsTrie(o);
2286 if (Rebase)
2287 printRebaseTable(o);
2288 if (Bind)
2289 printBindTable(o);
2290 if (LazyBind)
2291 printLazyBindTable(o);
2292 if (WeakBind)
2293 printWeakBindTable(o);
2294 if (RawClangAST)
2295 printRawClangAST(o);
2296 if (PrintFaultMaps)
2297 printFaultMaps(o);
2298 if (DwarfDumpType != DIDT_Null) {
2299 std::unique_ptr<DIContext> DICtx = DWARFContext::create(*o);
2300 // Dump the complete DWARF structure.
2301 DIDumpOptions DumpOpts;
2302 DumpOpts.DumpType = DwarfDumpType;
2303 DICtx->dump(outs(), DumpOpts);
2304 }
2305 }
2306
DumpObject(const COFFImportFile * I,const Archive * A,const Archive::Child * C=nullptr)2307 static void DumpObject(const COFFImportFile *I, const Archive *A,
2308 const Archive::Child *C = nullptr) {
2309 StringRef ArchiveName = A ? A->getFileName() : "";
2310
2311 // Avoid other output when using a raw option.
2312 if (!RawClangAST)
2313 outs() << '\n'
2314 << ArchiveName << "(" << I->getFileName() << ")"
2315 << ":\tfile format COFF-import-file"
2316 << "\n\n";
2317
2318 if (ArchiveHeaders && !MachOOpt)
2319 printArchiveChild(A->getFileName(), *C);
2320 if (SymbolTable)
2321 printCOFFSymbolTable(I);
2322 }
2323
2324 /// Dump each object file in \a a;
DumpArchive(const Archive * a)2325 static void DumpArchive(const Archive *a) {
2326 Error Err = Error::success();
2327 for (auto &C : a->children(Err)) {
2328 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2329 if (!ChildOrErr) {
2330 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2331 report_error(a->getFileName(), C, std::move(E));
2332 continue;
2333 }
2334 if (ObjectFile *o = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
2335 DumpObject(o, a, &C);
2336 else if (COFFImportFile *I = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
2337 DumpObject(I, a, &C);
2338 else
2339 report_error(a->getFileName(), object_error::invalid_file_type);
2340 }
2341 if (Err)
2342 report_error(a->getFileName(), std::move(Err));
2343 }
2344
2345 /// Open file and figure out how to dump it.
DumpInput(StringRef file)2346 static void DumpInput(StringRef file) {
2347
2348 // If we are using the Mach-O specific object file parser, then let it parse
2349 // the file and process the command line options. So the -arch flags can
2350 // be used to select specific slices, etc.
2351 if (MachOOpt) {
2352 ParseInputMachO(file);
2353 return;
2354 }
2355
2356 // Attempt to open the binary.
2357 Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
2358 if (!BinaryOrErr)
2359 report_error(file, BinaryOrErr.takeError());
2360 Binary &Binary = *BinaryOrErr.get().getBinary();
2361
2362 if (Archive *a = dyn_cast<Archive>(&Binary))
2363 DumpArchive(a);
2364 else if (ObjectFile *o = dyn_cast<ObjectFile>(&Binary))
2365 DumpObject(o);
2366 else
2367 report_error(file, object_error::invalid_file_type);
2368 }
2369
main(int argc,char ** argv)2370 int main(int argc, char **argv) {
2371 InitLLVM X(argc, argv);
2372
2373 // Initialize targets and assembly printers/parsers.
2374 llvm::InitializeAllTargetInfos();
2375 llvm::InitializeAllTargetMCs();
2376 llvm::InitializeAllDisassemblers();
2377
2378 // Register the target printer for --version.
2379 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
2380
2381 cl::ParseCommandLineOptions(argc, argv, "llvm object file dumper\n");
2382 TripleName = Triple::normalize(TripleName);
2383
2384 ToolName = argv[0];
2385
2386 // Defaults to a.out if no filenames specified.
2387 if (InputFilenames.size() == 0)
2388 InputFilenames.push_back("a.out");
2389
2390 if (AllHeaders)
2391 PrivateHeaders = Relocations = SectionHeaders = SymbolTable = true;
2392
2393 if (DisassembleAll || PrintSource || PrintLines)
2394 Disassemble = true;
2395
2396 if (Demangle.getValue() != "none" && Demangle.getValue() != "" &&
2397 Demangle.getValue() != "itanium")
2398 warn("Unsupported demangling style");
2399
2400 if (!Disassemble
2401 && !Relocations
2402 && !DynamicRelocations
2403 && !SectionHeaders
2404 && !SectionContents
2405 && !SymbolTable
2406 && !UnwindInfo
2407 && !PrivateHeaders
2408 && !FileHeaders
2409 && !FirstPrivateHeader
2410 && !ExportsTrie
2411 && !Rebase
2412 && !Bind
2413 && !LazyBind
2414 && !WeakBind
2415 && !RawClangAST
2416 && !(UniversalHeaders && MachOOpt)
2417 && !ArchiveHeaders
2418 && !(IndirectSymbols && MachOOpt)
2419 && !(DataInCode && MachOOpt)
2420 && !(LinkOptHints && MachOOpt)
2421 && !(InfoPlist && MachOOpt)
2422 && !(DylibsUsed && MachOOpt)
2423 && !(DylibId && MachOOpt)
2424 && !(ObjcMetaData && MachOOpt)
2425 && !(FilterSections.size() != 0 && MachOOpt)
2426 && !PrintFaultMaps
2427 && DwarfDumpType == DIDT_Null) {
2428 cl::PrintHelpMessage();
2429 return 2;
2430 }
2431
2432 DisasmFuncsSet.insert(DisassembleFunctions.begin(),
2433 DisassembleFunctions.end());
2434
2435 llvm::for_each(InputFilenames, DumpInput);
2436
2437 return EXIT_SUCCESS;
2438 }
2439