1 //===-- llvm-objdump.cpp - Object file dumping utility for llvm -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This program is a utility that works like binutils "objdump", that is, it
10 // dumps out a plethora of information about an object file depending on the
11 // flags.
12 //
13 // The flags and output of this program should be near identical to those of
14 // binutils objdump.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #include "llvm-objdump.h"
19 #include "COFFDump.h"
20 #include "ELFDump.h"
21 #include "MachODump.h"
22 #include "ObjdumpOptID.h"
23 #include "OffloadDump.h"
24 #include "SourcePrinter.h"
25 #include "WasmDump.h"
26 #include "XCOFFDump.h"
27 #include "llvm/ADT/IndexedMap.h"
28 #include "llvm/ADT/Optional.h"
29 #include "llvm/ADT/STLExtras.h"
30 #include "llvm/ADT/SetOperations.h"
31 #include "llvm/ADT/SmallSet.h"
32 #include "llvm/ADT/StringExtras.h"
33 #include "llvm/ADT/StringSet.h"
34 #include "llvm/ADT/Triple.h"
35 #include "llvm/ADT/Twine.h"
36 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
37 #include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
38 #include "llvm/DebugInfo/Symbolize/Symbolize.h"
39 #include "llvm/Demangle/Demangle.h"
40 #include "llvm/MC/MCAsmInfo.h"
41 #include "llvm/MC/MCContext.h"
42 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
43 #include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
44 #include "llvm/MC/MCInst.h"
45 #include "llvm/MC/MCInstPrinter.h"
46 #include "llvm/MC/MCInstrAnalysis.h"
47 #include "llvm/MC/MCInstrInfo.h"
48 #include "llvm/MC/MCObjectFileInfo.h"
49 #include "llvm/MC/MCRegisterInfo.h"
50 #include "llvm/MC/MCSubtargetInfo.h"
51 #include "llvm/MC/MCTargetOptions.h"
52 #include "llvm/MC/TargetRegistry.h"
53 #include "llvm/Object/Archive.h"
54 #include "llvm/Object/COFF.h"
55 #include "llvm/Object/COFFImportFile.h"
56 #include "llvm/Object/ELFObjectFile.h"
57 #include "llvm/Object/ELFTypes.h"
58 #include "llvm/Object/FaultMapParser.h"
59 #include "llvm/Object/MachO.h"
60 #include "llvm/Object/MachOUniversal.h"
61 #include "llvm/Object/ObjectFile.h"
62 #include "llvm/Object/OffloadBinary.h"
63 #include "llvm/Object/Wasm.h"
64 #include "llvm/Option/Arg.h"
65 #include "llvm/Option/ArgList.h"
66 #include "llvm/Option/Option.h"
67 #include "llvm/Support/Casting.h"
68 #include "llvm/Support/Debug.h"
69 #include "llvm/Support/Errc.h"
70 #include "llvm/Support/FileSystem.h"
71 #include "llvm/Support/Format.h"
72 #include "llvm/Support/FormatVariadic.h"
73 #include "llvm/Support/GraphWriter.h"
74 #include "llvm/Support/Host.h"
75 #include "llvm/Support/InitLLVM.h"
76 #include "llvm/Support/MemoryBuffer.h"
77 #include "llvm/Support/SourceMgr.h"
78 #include "llvm/Support/StringSaver.h"
79 #include "llvm/Support/TargetSelect.h"
80 #include "llvm/Support/WithColor.h"
81 #include "llvm/Support/raw_ostream.h"
82 #include <algorithm>
83 #include <cctype>
84 #include <cstring>
85 #include <system_error>
86 #include <unordered_map>
87 #include <utility>
88
89 using namespace llvm;
90 using namespace llvm::object;
91 using namespace llvm::objdump;
92 using namespace llvm::opt;
93
94 namespace {
95
96 class CommonOptTable : public opt::OptTable {
97 public:
CommonOptTable(ArrayRef<Info> OptionInfos,const char * Usage,const char * Description)98 CommonOptTable(ArrayRef<Info> OptionInfos, const char *Usage,
99 const char *Description)
100 : OptTable(OptionInfos), Usage(Usage), Description(Description) {
101 setGroupedShortOptions(true);
102 }
103
printHelp(StringRef Argv0,bool ShowHidden=false) const104 void printHelp(StringRef Argv0, bool ShowHidden = false) const {
105 Argv0 = sys::path::filename(Argv0);
106 opt::OptTable::printHelp(outs(), (Argv0 + Usage).str().c_str(), Description,
107 ShowHidden, ShowHidden);
108 // TODO Replace this with OptTable API once it adds extrahelp support.
109 outs() << "\nPass @FILE as argument to read options from FILE.\n";
110 }
111
112 private:
113 const char *Usage;
114 const char *Description;
115 };
116
117 // ObjdumpOptID is in ObjdumpOptID.h
118
119 #define PREFIX(NAME, VALUE) const char *const OBJDUMP_##NAME[] = VALUE;
120 #include "ObjdumpOpts.inc"
121 #undef PREFIX
122
123 static constexpr opt::OptTable::Info ObjdumpInfoTable[] = {
124 #define OBJDUMP_nullptr nullptr
125 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
126 HELPTEXT, METAVAR, VALUES) \
127 {OBJDUMP_##PREFIX, NAME, HELPTEXT, \
128 METAVAR, OBJDUMP_##ID, opt::Option::KIND##Class, \
129 PARAM, FLAGS, OBJDUMP_##GROUP, \
130 OBJDUMP_##ALIAS, ALIASARGS, VALUES},
131 #include "ObjdumpOpts.inc"
132 #undef OPTION
133 #undef OBJDUMP_nullptr
134 };
135
136 class ObjdumpOptTable : public CommonOptTable {
137 public:
ObjdumpOptTable()138 ObjdumpOptTable()
139 : CommonOptTable(ObjdumpInfoTable, " [options] <input object files>",
140 "llvm object file dumper") {}
141 };
142
143 enum OtoolOptID {
144 OTOOL_INVALID = 0, // This is not an option ID.
145 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
146 HELPTEXT, METAVAR, VALUES) \
147 OTOOL_##ID,
148 #include "OtoolOpts.inc"
149 #undef OPTION
150 };
151
152 #define PREFIX(NAME, VALUE) const char *const OTOOL_##NAME[] = VALUE;
153 #include "OtoolOpts.inc"
154 #undef PREFIX
155
156 static constexpr opt::OptTable::Info OtoolInfoTable[] = {
157 #define OTOOL_nullptr nullptr
158 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
159 HELPTEXT, METAVAR, VALUES) \
160 {OTOOL_##PREFIX, NAME, HELPTEXT, \
161 METAVAR, OTOOL_##ID, opt::Option::KIND##Class, \
162 PARAM, FLAGS, OTOOL_##GROUP, \
163 OTOOL_##ALIAS, ALIASARGS, VALUES},
164 #include "OtoolOpts.inc"
165 #undef OPTION
166 #undef OTOOL_nullptr
167 };
168
169 class OtoolOptTable : public CommonOptTable {
170 public:
OtoolOptTable()171 OtoolOptTable()
172 : CommonOptTable(OtoolInfoTable, " [option...] [file...]",
173 "Mach-O object file displaying tool") {}
174 };
175
176 } // namespace
177
178 #define DEBUG_TYPE "objdump"
179
180 static uint64_t AdjustVMA;
181 static bool AllHeaders;
182 static std::string ArchName;
183 bool objdump::ArchiveHeaders;
184 bool objdump::Demangle;
185 bool objdump::Disassemble;
186 bool objdump::DisassembleAll;
187 bool objdump::SymbolDescription;
188 static std::vector<std::string> DisassembleSymbols;
189 static bool DisassembleZeroes;
190 static std::vector<std::string> DisassemblerOptions;
191 DIDumpType objdump::DwarfDumpType;
192 static bool DynamicRelocations;
193 static bool FaultMapSection;
194 static bool FileHeaders;
195 bool objdump::SectionContents;
196 static std::vector<std::string> InputFilenames;
197 bool objdump::PrintLines;
198 static bool MachOOpt;
199 std::string objdump::MCPU;
200 std::vector<std::string> objdump::MAttrs;
201 bool objdump::ShowRawInsn;
202 bool objdump::LeadingAddr;
203 static bool Offloading;
204 static bool RawClangAST;
205 bool objdump::Relocations;
206 bool objdump::PrintImmHex;
207 bool objdump::PrivateHeaders;
208 std::vector<std::string> objdump::FilterSections;
209 bool objdump::SectionHeaders;
210 static bool ShowLMA;
211 bool objdump::PrintSource;
212
213 static uint64_t StartAddress;
214 static bool HasStartAddressFlag;
215 static uint64_t StopAddress = UINT64_MAX;
216 static bool HasStopAddressFlag;
217
218 bool objdump::SymbolTable;
219 static bool SymbolizeOperands;
220 static bool DynamicSymbolTable;
221 std::string objdump::TripleName;
222 bool objdump::UnwindInfo;
223 static bool Wide;
224 std::string objdump::Prefix;
225 uint32_t objdump::PrefixStrip;
226
227 DebugVarsFormat objdump::DbgVariables = DVDisabled;
228
229 int objdump::DbgIndent = 52;
230
231 static StringSet<> DisasmSymbolSet;
232 StringSet<> objdump::FoundSectionSet;
233 static StringRef ToolName;
234
235 namespace {
236 struct FilterResult {
237 // True if the section should not be skipped.
238 bool Keep;
239
240 // True if the index counter should be incremented, even if the section should
241 // be skipped. For example, sections may be skipped if they are not included
242 // in the --section flag, but we still want those to count toward the section
243 // count.
244 bool IncrementIndex;
245 };
246 } // namespace
247
checkSectionFilter(object::SectionRef S)248 static FilterResult checkSectionFilter(object::SectionRef S) {
249 if (FilterSections.empty())
250 return {/*Keep=*/true, /*IncrementIndex=*/true};
251
252 Expected<StringRef> SecNameOrErr = S.getName();
253 if (!SecNameOrErr) {
254 consumeError(SecNameOrErr.takeError());
255 return {/*Keep=*/false, /*IncrementIndex=*/false};
256 }
257 StringRef SecName = *SecNameOrErr;
258
259 // StringSet does not allow empty key so avoid adding sections with
260 // no name (such as the section with index 0) here.
261 if (!SecName.empty())
262 FoundSectionSet.insert(SecName);
263
264 // Only show the section if it's in the FilterSections list, but always
265 // increment so the indexing is stable.
266 return {/*Keep=*/is_contained(FilterSections, SecName),
267 /*IncrementIndex=*/true};
268 }
269
ToolSectionFilter(object::ObjectFile const & O,uint64_t * Idx)270 SectionFilter objdump::ToolSectionFilter(object::ObjectFile const &O,
271 uint64_t *Idx) {
272 // Start at UINT64_MAX so that the first index returned after an increment is
273 // zero (after the unsigned wrap).
274 if (Idx)
275 *Idx = UINT64_MAX;
276 return SectionFilter(
277 [Idx](object::SectionRef S) {
278 FilterResult Result = checkSectionFilter(S);
279 if (Idx != nullptr && Result.IncrementIndex)
280 *Idx += 1;
281 return Result.Keep;
282 },
283 O);
284 }
285
getFileNameForError(const object::Archive::Child & C,unsigned Index)286 std::string objdump::getFileNameForError(const object::Archive::Child &C,
287 unsigned Index) {
288 Expected<StringRef> NameOrErr = C.getName();
289 if (NameOrErr)
290 return std::string(NameOrErr.get());
291 // If we have an error getting the name then we print the index of the archive
292 // member. Since we are already in an error state, we just ignore this error.
293 consumeError(NameOrErr.takeError());
294 return "<file index: " + std::to_string(Index) + ">";
295 }
296
reportWarning(const Twine & Message,StringRef File)297 void objdump::reportWarning(const Twine &Message, StringRef File) {
298 // Output order between errs() and outs() matters especially for archive
299 // files where the output is per member object.
300 outs().flush();
301 WithColor::warning(errs(), ToolName)
302 << "'" << File << "': " << Message << "\n";
303 }
304
reportError(StringRef File,const Twine & Message)305 [[noreturn]] void objdump::reportError(StringRef File, const Twine &Message) {
306 outs().flush();
307 WithColor::error(errs(), ToolName) << "'" << File << "': " << Message << "\n";
308 exit(1);
309 }
310
reportError(Error E,StringRef FileName,StringRef ArchiveName,StringRef ArchitectureName)311 [[noreturn]] void objdump::reportError(Error E, StringRef FileName,
312 StringRef ArchiveName,
313 StringRef ArchitectureName) {
314 assert(E);
315 outs().flush();
316 WithColor::error(errs(), ToolName);
317 if (ArchiveName != "")
318 errs() << ArchiveName << "(" << FileName << ")";
319 else
320 errs() << "'" << FileName << "'";
321 if (!ArchitectureName.empty())
322 errs() << " (for architecture " << ArchitectureName << ")";
323 errs() << ": ";
324 logAllUnhandledErrors(std::move(E), errs());
325 exit(1);
326 }
327
reportCmdLineWarning(const Twine & Message)328 static void reportCmdLineWarning(const Twine &Message) {
329 WithColor::warning(errs(), ToolName) << Message << "\n";
330 }
331
reportCmdLineError(const Twine & Message)332 [[noreturn]] static void reportCmdLineError(const Twine &Message) {
333 WithColor::error(errs(), ToolName) << Message << "\n";
334 exit(1);
335 }
336
warnOnNoMatchForSections()337 static void warnOnNoMatchForSections() {
338 SetVector<StringRef> MissingSections;
339 for (StringRef S : FilterSections) {
340 if (FoundSectionSet.count(S))
341 return;
342 // User may specify a unnamed section. Don't warn for it.
343 if (!S.empty())
344 MissingSections.insert(S);
345 }
346
347 // Warn only if no section in FilterSections is matched.
348 for (StringRef S : MissingSections)
349 reportCmdLineWarning("section '" + S +
350 "' mentioned in a -j/--section option, but not "
351 "found in any input file");
352 }
353
getTarget(const ObjectFile * Obj)354 static const Target *getTarget(const ObjectFile *Obj) {
355 // Figure out the target triple.
356 Triple TheTriple("unknown-unknown-unknown");
357 if (TripleName.empty()) {
358 TheTriple = Obj->makeTriple();
359 } else {
360 TheTriple.setTriple(Triple::normalize(TripleName));
361 auto Arch = Obj->getArch();
362 if (Arch == Triple::arm || Arch == Triple::armeb)
363 Obj->setARMSubArch(TheTriple);
364 }
365
366 // Get the target specific parser.
367 std::string Error;
368 const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple,
369 Error);
370 if (!TheTarget)
371 reportError(Obj->getFileName(), "can't find target: " + Error);
372
373 // Update the triple name and return the found target.
374 TripleName = TheTriple.getTriple();
375 return TheTarget;
376 }
377
isRelocAddressLess(RelocationRef A,RelocationRef B)378 bool objdump::isRelocAddressLess(RelocationRef A, RelocationRef B) {
379 return A.getOffset() < B.getOffset();
380 }
381
getRelocationValueString(const RelocationRef & Rel,SmallVectorImpl<char> & Result)382 static Error getRelocationValueString(const RelocationRef &Rel,
383 SmallVectorImpl<char> &Result) {
384 const ObjectFile *Obj = Rel.getObject();
385 if (auto *ELF = dyn_cast<ELFObjectFileBase>(Obj))
386 return getELFRelocationValueString(ELF, Rel, Result);
387 if (auto *COFF = dyn_cast<COFFObjectFile>(Obj))
388 return getCOFFRelocationValueString(COFF, Rel, Result);
389 if (auto *Wasm = dyn_cast<WasmObjectFile>(Obj))
390 return getWasmRelocationValueString(Wasm, Rel, Result);
391 if (auto *MachO = dyn_cast<MachOObjectFile>(Obj))
392 return getMachORelocationValueString(MachO, Rel, Result);
393 if (auto *XCOFF = dyn_cast<XCOFFObjectFile>(Obj))
394 return getXCOFFRelocationValueString(*XCOFF, Rel, Result);
395 llvm_unreachable("unknown object file format");
396 }
397
398 /// Indicates whether this relocation should hidden when listing
399 /// relocations, usually because it is the trailing part of a multipart
400 /// relocation that will be printed as part of the leading relocation.
getHidden(RelocationRef RelRef)401 static bool getHidden(RelocationRef RelRef) {
402 auto *MachO = dyn_cast<MachOObjectFile>(RelRef.getObject());
403 if (!MachO)
404 return false;
405
406 unsigned Arch = MachO->getArch();
407 DataRefImpl Rel = RelRef.getRawDataRefImpl();
408 uint64_t Type = MachO->getRelocationType(Rel);
409
410 // On arches that use the generic relocations, GENERIC_RELOC_PAIR
411 // is always hidden.
412 if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc)
413 return Type == MachO::GENERIC_RELOC_PAIR;
414
415 if (Arch == Triple::x86_64) {
416 // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
417 // an X86_64_RELOC_SUBTRACTOR.
418 if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) {
419 DataRefImpl RelPrev = Rel;
420 RelPrev.d.a--;
421 uint64_t PrevType = MachO->getRelocationType(RelPrev);
422 if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR)
423 return true;
424 }
425 }
426
427 return false;
428 }
429
430 namespace {
431
432 /// Get the column at which we want to start printing the instruction
433 /// disassembly, taking into account anything which appears to the left of it.
getInstStartColumn(const MCSubtargetInfo & STI)434 unsigned getInstStartColumn(const MCSubtargetInfo &STI) {
435 return !ShowRawInsn ? 16 : STI.getTargetTriple().isX86() ? 40 : 24;
436 }
437
isAArch64Elf(const ObjectFile & Obj)438 static bool isAArch64Elf(const ObjectFile &Obj) {
439 const auto *Elf = dyn_cast<ELFObjectFileBase>(&Obj);
440 return Elf && Elf->getEMachine() == ELF::EM_AARCH64;
441 }
442
isArmElf(const ObjectFile & Obj)443 static bool isArmElf(const ObjectFile &Obj) {
444 const auto *Elf = dyn_cast<ELFObjectFileBase>(&Obj);
445 return Elf && Elf->getEMachine() == ELF::EM_ARM;
446 }
447
isCSKYElf(const ObjectFile & Obj)448 static bool isCSKYElf(const ObjectFile &Obj) {
449 const auto *Elf = dyn_cast<ELFObjectFileBase>(&Obj);
450 return Elf && Elf->getEMachine() == ELF::EM_CSKY;
451 }
452
hasMappingSymbols(const ObjectFile & Obj)453 static bool hasMappingSymbols(const ObjectFile &Obj) {
454 return isArmElf(Obj) || isAArch64Elf(Obj) || isCSKYElf(Obj) ;
455 }
456
printRelocation(formatted_raw_ostream & OS,StringRef FileName,const RelocationRef & Rel,uint64_t Address,bool Is64Bits)457 static void printRelocation(formatted_raw_ostream &OS, StringRef FileName,
458 const RelocationRef &Rel, uint64_t Address,
459 bool Is64Bits) {
460 StringRef Fmt = Is64Bits ? "\t\t%016" PRIx64 ": " : "\t\t\t%08" PRIx64 ": ";
461 SmallString<16> Name;
462 SmallString<32> Val;
463 Rel.getTypeName(Name);
464 if (Error E = getRelocationValueString(Rel, Val))
465 reportError(std::move(E), FileName);
466 OS << format(Fmt.data(), Address) << Name << "\t" << Val;
467 }
468
AlignToInstStartColumn(size_t Start,const MCSubtargetInfo & STI,raw_ostream & OS)469 static void AlignToInstStartColumn(size_t Start, const MCSubtargetInfo &STI,
470 raw_ostream &OS) {
471 // The output of printInst starts with a tab. Print some spaces so that
472 // the tab has 1 column and advances to the target tab stop.
473 unsigned TabStop = getInstStartColumn(STI);
474 unsigned Column = OS.tell() - Start;
475 OS.indent(Column < TabStop - 1 ? TabStop - 1 - Column : 7 - Column % 8);
476 }
477
478 class PrettyPrinter {
479 public:
480 virtual ~PrettyPrinter() = default;
481 virtual void
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,object::SectionedAddress Address,formatted_raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,StringRef ObjectFilename,std::vector<RelocationRef> * Rels,LiveVariablePrinter & LVP)482 printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
483 object::SectionedAddress Address, formatted_raw_ostream &OS,
484 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
485 StringRef ObjectFilename, std::vector<RelocationRef> *Rels,
486 LiveVariablePrinter &LVP) {
487 if (SP && (PrintSource || PrintLines))
488 SP->printSourceLine(OS, Address, ObjectFilename, LVP);
489 LVP.printBetweenInsts(OS, false);
490
491 size_t Start = OS.tell();
492 if (LeadingAddr)
493 OS << format("%8" PRIx64 ":", Address.Address);
494 if (ShowRawInsn) {
495 OS << ' ';
496 dumpBytes(Bytes, OS);
497 }
498
499 AlignToInstStartColumn(Start, STI, OS);
500
501 if (MI) {
502 // See MCInstPrinter::printInst. On targets where a PC relative immediate
503 // is relative to the next instruction and the length of a MCInst is
504 // difficult to measure (x86), this is the address of the next
505 // instruction.
506 uint64_t Addr =
507 Address.Address + (STI.getTargetTriple().isX86() ? Bytes.size() : 0);
508 IP.printInst(MI, Addr, "", STI, OS);
509 } else
510 OS << "\t<unknown>";
511 }
512 };
513 PrettyPrinter PrettyPrinterInst;
514
515 class HexagonPrettyPrinter : public PrettyPrinter {
516 public:
printLead(ArrayRef<uint8_t> Bytes,uint64_t Address,formatted_raw_ostream & OS)517 void printLead(ArrayRef<uint8_t> Bytes, uint64_t Address,
518 formatted_raw_ostream &OS) {
519 uint32_t opcode =
520 (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | Bytes[0];
521 if (LeadingAddr)
522 OS << format("%8" PRIx64 ":", Address);
523 if (ShowRawInsn) {
524 OS << "\t";
525 dumpBytes(Bytes.slice(0, 4), OS);
526 OS << format("\t%08" PRIx32, opcode);
527 }
528 }
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,object::SectionedAddress Address,formatted_raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,StringRef ObjectFilename,std::vector<RelocationRef> * Rels,LiveVariablePrinter & LVP)529 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
530 object::SectionedAddress Address, formatted_raw_ostream &OS,
531 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
532 StringRef ObjectFilename, std::vector<RelocationRef> *Rels,
533 LiveVariablePrinter &LVP) override {
534 if (SP && (PrintSource || PrintLines))
535 SP->printSourceLine(OS, Address, ObjectFilename, LVP, "");
536 if (!MI) {
537 printLead(Bytes, Address.Address, OS);
538 OS << " <unknown>";
539 return;
540 }
541 std::string Buffer;
542 {
543 raw_string_ostream TempStream(Buffer);
544 IP.printInst(MI, Address.Address, "", STI, TempStream);
545 }
546 StringRef Contents(Buffer);
547 // Split off bundle attributes
548 auto PacketBundle = Contents.rsplit('\n');
549 // Split off first instruction from the rest
550 auto HeadTail = PacketBundle.first.split('\n');
551 auto Preamble = " { ";
552 auto Separator = "";
553
554 // Hexagon's packets require relocations to be inline rather than
555 // clustered at the end of the packet.
556 std::vector<RelocationRef>::const_iterator RelCur = Rels->begin();
557 std::vector<RelocationRef>::const_iterator RelEnd = Rels->end();
558 auto PrintReloc = [&]() -> void {
559 while ((RelCur != RelEnd) && (RelCur->getOffset() <= Address.Address)) {
560 if (RelCur->getOffset() == Address.Address) {
561 printRelocation(OS, ObjectFilename, *RelCur, Address.Address, false);
562 return;
563 }
564 ++RelCur;
565 }
566 };
567
568 while (!HeadTail.first.empty()) {
569 OS << Separator;
570 Separator = "\n";
571 if (SP && (PrintSource || PrintLines))
572 SP->printSourceLine(OS, Address, ObjectFilename, LVP, "");
573 printLead(Bytes, Address.Address, OS);
574 OS << Preamble;
575 Preamble = " ";
576 StringRef Inst;
577 auto Duplex = HeadTail.first.split('\v');
578 if (!Duplex.second.empty()) {
579 OS << Duplex.first;
580 OS << "; ";
581 Inst = Duplex.second;
582 }
583 else
584 Inst = HeadTail.first;
585 OS << Inst;
586 HeadTail = HeadTail.second.split('\n');
587 if (HeadTail.first.empty())
588 OS << " } " << PacketBundle.second;
589 PrintReloc();
590 Bytes = Bytes.slice(4);
591 Address.Address += 4;
592 }
593 }
594 };
595 HexagonPrettyPrinter HexagonPrettyPrinterInst;
596
597 class AMDGCNPrettyPrinter : public PrettyPrinter {
598 public:
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,object::SectionedAddress Address,formatted_raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,StringRef ObjectFilename,std::vector<RelocationRef> * Rels,LiveVariablePrinter & LVP)599 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
600 object::SectionedAddress Address, formatted_raw_ostream &OS,
601 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
602 StringRef ObjectFilename, std::vector<RelocationRef> *Rels,
603 LiveVariablePrinter &LVP) override {
604 if (SP && (PrintSource || PrintLines))
605 SP->printSourceLine(OS, Address, ObjectFilename, LVP);
606
607 if (MI) {
608 SmallString<40> InstStr;
609 raw_svector_ostream IS(InstStr);
610
611 IP.printInst(MI, Address.Address, "", STI, IS);
612
613 OS << left_justify(IS.str(), 60);
614 } else {
615 // an unrecognized encoding - this is probably data so represent it
616 // using the .long directive, or .byte directive if fewer than 4 bytes
617 // remaining
618 if (Bytes.size() >= 4) {
619 OS << format("\t.long 0x%08" PRIx32 " ",
620 support::endian::read32<support::little>(Bytes.data()));
621 OS.indent(42);
622 } else {
623 OS << format("\t.byte 0x%02" PRIx8, Bytes[0]);
624 for (unsigned int i = 1; i < Bytes.size(); i++)
625 OS << format(", 0x%02" PRIx8, Bytes[i]);
626 OS.indent(55 - (6 * Bytes.size()));
627 }
628 }
629
630 OS << format("// %012" PRIX64 ":", Address.Address);
631 if (Bytes.size() >= 4) {
632 // D should be casted to uint32_t here as it is passed by format to
633 // snprintf as vararg.
634 for (uint32_t D : makeArrayRef(
635 reinterpret_cast<const support::little32_t *>(Bytes.data()),
636 Bytes.size() / 4))
637 OS << format(" %08" PRIX32, D);
638 } else {
639 for (unsigned char B : Bytes)
640 OS << format(" %02" PRIX8, B);
641 }
642
643 if (!Annot.empty())
644 OS << " // " << Annot;
645 }
646 };
647 AMDGCNPrettyPrinter AMDGCNPrettyPrinterInst;
648
649 class BPFPrettyPrinter : public PrettyPrinter {
650 public:
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,object::SectionedAddress Address,formatted_raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,StringRef ObjectFilename,std::vector<RelocationRef> * Rels,LiveVariablePrinter & LVP)651 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
652 object::SectionedAddress Address, formatted_raw_ostream &OS,
653 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
654 StringRef ObjectFilename, std::vector<RelocationRef> *Rels,
655 LiveVariablePrinter &LVP) override {
656 if (SP && (PrintSource || PrintLines))
657 SP->printSourceLine(OS, Address, ObjectFilename, LVP);
658 if (LeadingAddr)
659 OS << format("%8" PRId64 ":", Address.Address / 8);
660 if (ShowRawInsn) {
661 OS << "\t";
662 dumpBytes(Bytes, OS);
663 }
664 if (MI)
665 IP.printInst(MI, Address.Address, "", STI, OS);
666 else
667 OS << "\t<unknown>";
668 }
669 };
670 BPFPrettyPrinter BPFPrettyPrinterInst;
671
672 class ARMPrettyPrinter : public PrettyPrinter {
673 public:
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,object::SectionedAddress Address,formatted_raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,StringRef ObjectFilename,std::vector<RelocationRef> * Rels,LiveVariablePrinter & LVP)674 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
675 object::SectionedAddress Address, formatted_raw_ostream &OS,
676 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
677 StringRef ObjectFilename, std::vector<RelocationRef> *Rels,
678 LiveVariablePrinter &LVP) override {
679 if (SP && (PrintSource || PrintLines))
680 SP->printSourceLine(OS, Address, ObjectFilename, LVP);
681 LVP.printBetweenInsts(OS, false);
682
683 size_t Start = OS.tell();
684 if (LeadingAddr)
685 OS << format("%8" PRIx64 ":", Address.Address);
686 if (ShowRawInsn) {
687 size_t Pos = 0, End = Bytes.size();
688 if (STI.checkFeatures("+thumb-mode")) {
689 for (; Pos + 2 <= End; Pos += 2)
690 OS << ' '
691 << format_hex_no_prefix(
692 llvm::support::endian::read<uint16_t>(
693 Bytes.data() + Pos, llvm::support::little),
694 4);
695 } else {
696 for (; Pos + 4 <= End; Pos += 4)
697 OS << ' '
698 << format_hex_no_prefix(
699 llvm::support::endian::read<uint32_t>(
700 Bytes.data() + Pos, llvm::support::little),
701 8);
702 }
703 if (Pos < End) {
704 OS << ' ';
705 dumpBytes(Bytes.slice(Pos), OS);
706 }
707 }
708
709 AlignToInstStartColumn(Start, STI, OS);
710
711 if (MI) {
712 IP.printInst(MI, Address.Address, "", STI, OS);
713 } else
714 OS << "\t<unknown>";
715 }
716 };
717 ARMPrettyPrinter ARMPrettyPrinterInst;
718
719 class AArch64PrettyPrinter : public PrettyPrinter {
720 public:
printInst(MCInstPrinter & IP,const MCInst * MI,ArrayRef<uint8_t> Bytes,object::SectionedAddress Address,formatted_raw_ostream & OS,StringRef Annot,MCSubtargetInfo const & STI,SourcePrinter * SP,StringRef ObjectFilename,std::vector<RelocationRef> * Rels,LiveVariablePrinter & LVP)721 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef<uint8_t> Bytes,
722 object::SectionedAddress Address, formatted_raw_ostream &OS,
723 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
724 StringRef ObjectFilename, std::vector<RelocationRef> *Rels,
725 LiveVariablePrinter &LVP) override {
726 if (SP && (PrintSource || PrintLines))
727 SP->printSourceLine(OS, Address, ObjectFilename, LVP);
728 LVP.printBetweenInsts(OS, false);
729
730 size_t Start = OS.tell();
731 if (LeadingAddr)
732 OS << format("%8" PRIx64 ":", Address.Address);
733 if (ShowRawInsn) {
734 size_t Pos = 0, End = Bytes.size();
735 for (; Pos + 4 <= End; Pos += 4)
736 OS << ' '
737 << format_hex_no_prefix(
738 llvm::support::endian::read<uint32_t>(Bytes.data() + Pos,
739 llvm::support::little),
740 8);
741 if (Pos < End) {
742 OS << ' ';
743 dumpBytes(Bytes.slice(Pos), OS);
744 }
745 }
746
747 AlignToInstStartColumn(Start, STI, OS);
748
749 if (MI) {
750 IP.printInst(MI, Address.Address, "", STI, OS);
751 } else
752 OS << "\t<unknown>";
753 }
754 };
755 AArch64PrettyPrinter AArch64PrettyPrinterInst;
756
selectPrettyPrinter(Triple const & Triple)757 PrettyPrinter &selectPrettyPrinter(Triple const &Triple) {
758 switch(Triple.getArch()) {
759 default:
760 return PrettyPrinterInst;
761 case Triple::hexagon:
762 return HexagonPrettyPrinterInst;
763 case Triple::amdgcn:
764 return AMDGCNPrettyPrinterInst;
765 case Triple::bpfel:
766 case Triple::bpfeb:
767 return BPFPrettyPrinterInst;
768 case Triple::arm:
769 case Triple::armeb:
770 case Triple::thumb:
771 case Triple::thumbeb:
772 return ARMPrettyPrinterInst;
773 case Triple::aarch64:
774 case Triple::aarch64_be:
775 case Triple::aarch64_32:
776 return AArch64PrettyPrinterInst;
777 }
778 }
779 }
780
getElfSymbolType(const ObjectFile & Obj,const SymbolRef & Sym)781 static uint8_t getElfSymbolType(const ObjectFile &Obj, const SymbolRef &Sym) {
782 assert(Obj.isELF());
783 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(&Obj))
784 return unwrapOrError(Elf32LEObj->getSymbol(Sym.getRawDataRefImpl()),
785 Obj.getFileName())
786 ->getType();
787 if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(&Obj))
788 return unwrapOrError(Elf64LEObj->getSymbol(Sym.getRawDataRefImpl()),
789 Obj.getFileName())
790 ->getType();
791 if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(&Obj))
792 return unwrapOrError(Elf32BEObj->getSymbol(Sym.getRawDataRefImpl()),
793 Obj.getFileName())
794 ->getType();
795 if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(&Obj))
796 return unwrapOrError(Elf64BEObj->getSymbol(Sym.getRawDataRefImpl()),
797 Obj.getFileName())
798 ->getType();
799 llvm_unreachable("Unsupported binary format");
800 }
801
802 template <class ELFT>
803 static void
addDynamicElfSymbols(const ELFObjectFile<ELFT> & Obj,std::map<SectionRef,SectionSymbolsTy> & AllSymbols)804 addDynamicElfSymbols(const ELFObjectFile<ELFT> &Obj,
805 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
806 for (auto Symbol : Obj.getDynamicSymbolIterators()) {
807 uint8_t SymbolType = Symbol.getELFType();
808 if (SymbolType == ELF::STT_SECTION)
809 continue;
810
811 uint64_t Address = unwrapOrError(Symbol.getAddress(), Obj.getFileName());
812 // ELFSymbolRef::getAddress() returns size instead of value for common
813 // symbols which is not desirable for disassembly output. Overriding.
814 if (SymbolType == ELF::STT_COMMON)
815 Address = unwrapOrError(Obj.getSymbol(Symbol.getRawDataRefImpl()),
816 Obj.getFileName())
817 ->st_value;
818
819 StringRef Name = unwrapOrError(Symbol.getName(), Obj.getFileName());
820 if (Name.empty())
821 continue;
822
823 section_iterator SecI =
824 unwrapOrError(Symbol.getSection(), Obj.getFileName());
825 if (SecI == Obj.section_end())
826 continue;
827
828 AllSymbols[*SecI].emplace_back(Address, Name, SymbolType);
829 }
830 }
831
832 static void
addDynamicElfSymbols(const ELFObjectFileBase & Obj,std::map<SectionRef,SectionSymbolsTy> & AllSymbols)833 addDynamicElfSymbols(const ELFObjectFileBase &Obj,
834 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
835 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(&Obj))
836 addDynamicElfSymbols(*Elf32LEObj, AllSymbols);
837 else if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(&Obj))
838 addDynamicElfSymbols(*Elf64LEObj, AllSymbols);
839 else if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(&Obj))
840 addDynamicElfSymbols(*Elf32BEObj, AllSymbols);
841 else if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(&Obj))
842 addDynamicElfSymbols(*Elf64BEObj, AllSymbols);
843 else
844 llvm_unreachable("Unsupported binary format");
845 }
846
getWasmCodeSection(const WasmObjectFile & Obj)847 static Optional<SectionRef> getWasmCodeSection(const WasmObjectFile &Obj) {
848 for (auto SecI : Obj.sections()) {
849 const WasmSection &Section = Obj.getWasmSection(SecI);
850 if (Section.Type == wasm::WASM_SEC_CODE)
851 return SecI;
852 }
853 return None;
854 }
855
856 static void
addMissingWasmCodeSymbols(const WasmObjectFile & Obj,std::map<SectionRef,SectionSymbolsTy> & AllSymbols)857 addMissingWasmCodeSymbols(const WasmObjectFile &Obj,
858 std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
859 Optional<SectionRef> Section = getWasmCodeSection(Obj);
860 if (!Section)
861 return;
862 SectionSymbolsTy &Symbols = AllSymbols[*Section];
863
864 std::set<uint64_t> SymbolAddresses;
865 for (const auto &Sym : Symbols)
866 SymbolAddresses.insert(Sym.Addr);
867
868 for (const wasm::WasmFunction &Function : Obj.functions()) {
869 uint64_t Address = Function.CodeSectionOffset;
870 // Only add fallback symbols for functions not already present in the symbol
871 // table.
872 if (SymbolAddresses.count(Address))
873 continue;
874 // This function has no symbol, so it should have no SymbolName.
875 assert(Function.SymbolName.empty());
876 // We use DebugName for the name, though it may be empty if there is no
877 // "name" custom section, or that section is missing a name for this
878 // function.
879 StringRef Name = Function.DebugName;
880 Symbols.emplace_back(Address, Name, ELF::STT_NOTYPE);
881 }
882 }
883
addPltEntries(const ObjectFile & Obj,std::map<SectionRef,SectionSymbolsTy> & AllSymbols,StringSaver & Saver)884 static void addPltEntries(const ObjectFile &Obj,
885 std::map<SectionRef, SectionSymbolsTy> &AllSymbols,
886 StringSaver &Saver) {
887 Optional<SectionRef> Plt = None;
888 for (const SectionRef &Section : Obj.sections()) {
889 Expected<StringRef> SecNameOrErr = Section.getName();
890 if (!SecNameOrErr) {
891 consumeError(SecNameOrErr.takeError());
892 continue;
893 }
894 if (*SecNameOrErr == ".plt")
895 Plt = Section;
896 }
897 if (!Plt)
898 return;
899 if (auto *ElfObj = dyn_cast<ELFObjectFileBase>(&Obj)) {
900 for (auto PltEntry : ElfObj->getPltAddresses()) {
901 if (PltEntry.first) {
902 SymbolRef Symbol(*PltEntry.first, ElfObj);
903 uint8_t SymbolType = getElfSymbolType(Obj, Symbol);
904 if (Expected<StringRef> NameOrErr = Symbol.getName()) {
905 if (!NameOrErr->empty())
906 AllSymbols[*Plt].emplace_back(
907 PltEntry.second, Saver.save((*NameOrErr + "@plt").str()),
908 SymbolType);
909 continue;
910 } else {
911 // The warning has been reported in disassembleObject().
912 consumeError(NameOrErr.takeError());
913 }
914 }
915 reportWarning("PLT entry at 0x" + Twine::utohexstr(PltEntry.second) +
916 " references an invalid symbol",
917 Obj.getFileName());
918 }
919 }
920 }
921
922 // Normally the disassembly output will skip blocks of zeroes. This function
923 // returns the number of zero bytes that can be skipped when dumping the
924 // disassembly of the instructions in Buf.
countSkippableZeroBytes(ArrayRef<uint8_t> Buf)925 static size_t countSkippableZeroBytes(ArrayRef<uint8_t> Buf) {
926 // Find the number of leading zeroes.
927 size_t N = 0;
928 while (N < Buf.size() && !Buf[N])
929 ++N;
930
931 // We may want to skip blocks of zero bytes, but unless we see
932 // at least 8 of them in a row.
933 if (N < 8)
934 return 0;
935
936 // We skip zeroes in multiples of 4 because do not want to truncate an
937 // instruction if it starts with a zero byte.
938 return N & ~0x3;
939 }
940
941 // Returns a map from sections to their relocations.
942 static std::map<SectionRef, std::vector<RelocationRef>>
getRelocsMap(object::ObjectFile const & Obj)943 getRelocsMap(object::ObjectFile const &Obj) {
944 std::map<SectionRef, std::vector<RelocationRef>> Ret;
945 uint64_t I = (uint64_t)-1;
946 for (SectionRef Sec : Obj.sections()) {
947 ++I;
948 Expected<section_iterator> RelocatedOrErr = Sec.getRelocatedSection();
949 if (!RelocatedOrErr)
950 reportError(Obj.getFileName(),
951 "section (" + Twine(I) +
952 "): failed to get a relocated section: " +
953 toString(RelocatedOrErr.takeError()));
954
955 section_iterator Relocated = *RelocatedOrErr;
956 if (Relocated == Obj.section_end() || !checkSectionFilter(*Relocated).Keep)
957 continue;
958 std::vector<RelocationRef> &V = Ret[*Relocated];
959 append_range(V, Sec.relocations());
960 // Sort relocations by address.
961 llvm::stable_sort(V, isRelocAddressLess);
962 }
963 return Ret;
964 }
965
966 // Used for --adjust-vma to check if address should be adjusted by the
967 // specified value for a given section.
968 // For ELF we do not adjust non-allocatable sections like debug ones,
969 // because they are not loadable.
970 // TODO: implement for other file formats.
shouldAdjustVA(const SectionRef & Section)971 static bool shouldAdjustVA(const SectionRef &Section) {
972 const ObjectFile *Obj = Section.getObject();
973 if (Obj->isELF())
974 return ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC;
975 return false;
976 }
977
978
979 typedef std::pair<uint64_t, char> MappingSymbolPair;
getMappingSymbolKind(ArrayRef<MappingSymbolPair> MappingSymbols,uint64_t Address)980 static char getMappingSymbolKind(ArrayRef<MappingSymbolPair> MappingSymbols,
981 uint64_t Address) {
982 auto It =
983 partition_point(MappingSymbols, [Address](const MappingSymbolPair &Val) {
984 return Val.first <= Address;
985 });
986 // Return zero for any address before the first mapping symbol; this means
987 // we should use the default disassembly mode, depending on the target.
988 if (It == MappingSymbols.begin())
989 return '\x00';
990 return (It - 1)->second;
991 }
992
dumpARMELFData(uint64_t SectionAddr,uint64_t Index,uint64_t End,const ObjectFile & Obj,ArrayRef<uint8_t> Bytes,ArrayRef<MappingSymbolPair> MappingSymbols,const MCSubtargetInfo & STI,raw_ostream & OS)993 static uint64_t dumpARMELFData(uint64_t SectionAddr, uint64_t Index,
994 uint64_t End, const ObjectFile &Obj,
995 ArrayRef<uint8_t> Bytes,
996 ArrayRef<MappingSymbolPair> MappingSymbols,
997 const MCSubtargetInfo &STI, raw_ostream &OS) {
998 support::endianness Endian =
999 Obj.isLittleEndian() ? support::little : support::big;
1000 size_t Start = OS.tell();
1001 OS << format("%8" PRIx64 ": ", SectionAddr + Index);
1002 if (Index + 4 <= End) {
1003 dumpBytes(Bytes.slice(Index, 4), OS);
1004 AlignToInstStartColumn(Start, STI, OS);
1005 OS << "\t.word\t"
1006 << format_hex(support::endian::read32(Bytes.data() + Index, Endian),
1007 10);
1008 return 4;
1009 }
1010 if (Index + 2 <= End) {
1011 dumpBytes(Bytes.slice(Index, 2), OS);
1012 AlignToInstStartColumn(Start, STI, OS);
1013 OS << "\t.short\t"
1014 << format_hex(support::endian::read16(Bytes.data() + Index, Endian), 6);
1015 return 2;
1016 }
1017 dumpBytes(Bytes.slice(Index, 1), OS);
1018 AlignToInstStartColumn(Start, STI, OS);
1019 OS << "\t.byte\t" << format_hex(Bytes[Index], 4);
1020 return 1;
1021 }
1022
dumpELFData(uint64_t SectionAddr,uint64_t Index,uint64_t End,ArrayRef<uint8_t> Bytes)1023 static void dumpELFData(uint64_t SectionAddr, uint64_t Index, uint64_t End,
1024 ArrayRef<uint8_t> Bytes) {
1025 // print out data up to 8 bytes at a time in hex and ascii
1026 uint8_t AsciiData[9] = {'\0'};
1027 uint8_t Byte;
1028 int NumBytes = 0;
1029
1030 for (; Index < End; ++Index) {
1031 if (NumBytes == 0)
1032 outs() << format("%8" PRIx64 ":", SectionAddr + Index);
1033 Byte = Bytes.slice(Index)[0];
1034 outs() << format(" %02x", Byte);
1035 AsciiData[NumBytes] = isPrint(Byte) ? Byte : '.';
1036
1037 uint8_t IndentOffset = 0;
1038 NumBytes++;
1039 if (Index == End - 1 || NumBytes > 8) {
1040 // Indent the space for less than 8 bytes data.
1041 // 2 spaces for byte and one for space between bytes
1042 IndentOffset = 3 * (8 - NumBytes);
1043 for (int Excess = NumBytes; Excess < 8; Excess++)
1044 AsciiData[Excess] = '\0';
1045 NumBytes = 8;
1046 }
1047 if (NumBytes == 8) {
1048 AsciiData[8] = '\0';
1049 outs() << std::string(IndentOffset, ' ') << " ";
1050 outs() << reinterpret_cast<char *>(AsciiData);
1051 outs() << '\n';
1052 NumBytes = 0;
1053 }
1054 }
1055 }
1056
createSymbolInfo(const ObjectFile & Obj,const SymbolRef & Symbol)1057 SymbolInfoTy objdump::createSymbolInfo(const ObjectFile &Obj,
1058 const SymbolRef &Symbol) {
1059 const StringRef FileName = Obj.getFileName();
1060 const uint64_t Addr = unwrapOrError(Symbol.getAddress(), FileName);
1061 const StringRef Name = unwrapOrError(Symbol.getName(), FileName);
1062
1063 if (Obj.isXCOFF() && SymbolDescription) {
1064 const auto &XCOFFObj = cast<XCOFFObjectFile>(Obj);
1065 DataRefImpl SymbolDRI = Symbol.getRawDataRefImpl();
1066
1067 const uint32_t SymbolIndex = XCOFFObj.getSymbolIndex(SymbolDRI.p);
1068 Optional<XCOFF::StorageMappingClass> Smc =
1069 getXCOFFSymbolCsectSMC(XCOFFObj, Symbol);
1070 return SymbolInfoTy(Addr, Name, Smc, SymbolIndex,
1071 isLabel(XCOFFObj, Symbol));
1072 } else if (Obj.isXCOFF()) {
1073 const SymbolRef::Type SymType = unwrapOrError(Symbol.getType(), FileName);
1074 return SymbolInfoTy(Addr, Name, SymType, true);
1075 } else
1076 return SymbolInfoTy(Addr, Name,
1077 Obj.isELF() ? getElfSymbolType(Obj, Symbol)
1078 : (uint8_t)ELF::STT_NOTYPE);
1079 }
1080
createDummySymbolInfo(const ObjectFile & Obj,const uint64_t Addr,StringRef & Name,uint8_t Type)1081 static SymbolInfoTy createDummySymbolInfo(const ObjectFile &Obj,
1082 const uint64_t Addr, StringRef &Name,
1083 uint8_t Type) {
1084 if (Obj.isXCOFF() && SymbolDescription)
1085 return SymbolInfoTy(Addr, Name, None, None, false);
1086 else
1087 return SymbolInfoTy(Addr, Name, Type);
1088 }
1089
1090 static void
collectBBAddrMapLabels(const std::unordered_map<uint64_t,BBAddrMap> & AddrToBBAddrMap,uint64_t SectionAddr,uint64_t Start,uint64_t End,std::unordered_map<uint64_t,std::vector<std::string>> & Labels)1091 collectBBAddrMapLabels(const std::unordered_map<uint64_t, BBAddrMap> &AddrToBBAddrMap,
1092 uint64_t SectionAddr, uint64_t Start, uint64_t End,
1093 std::unordered_map<uint64_t, std::vector<std::string>> &Labels) {
1094 if (AddrToBBAddrMap.empty())
1095 return;
1096 Labels.clear();
1097 uint64_t StartAddress = SectionAddr + Start;
1098 uint64_t EndAddress = SectionAddr + End;
1099 auto Iter = AddrToBBAddrMap.find(StartAddress);
1100 if (Iter == AddrToBBAddrMap.end())
1101 return;
1102 for (unsigned I = 0, Size = Iter->second.BBEntries.size(); I < Size; ++I) {
1103 uint64_t BBAddress = Iter->second.BBEntries[I].Offset + Iter->second.Addr;
1104 if (BBAddress >= EndAddress)
1105 continue;
1106 Labels[BBAddress].push_back(("BB" + Twine(I)).str());
1107 }
1108 }
1109
collectLocalBranchTargets(ArrayRef<uint8_t> Bytes,const MCInstrAnalysis * MIA,MCDisassembler * DisAsm,MCInstPrinter * IP,const MCSubtargetInfo * STI,uint64_t SectionAddr,uint64_t Start,uint64_t End,std::unordered_map<uint64_t,std::string> & Labels)1110 static void collectLocalBranchTargets(
1111 ArrayRef<uint8_t> Bytes, const MCInstrAnalysis *MIA, MCDisassembler *DisAsm,
1112 MCInstPrinter *IP, const MCSubtargetInfo *STI, uint64_t SectionAddr,
1113 uint64_t Start, uint64_t End, std::unordered_map<uint64_t, std::string> &Labels) {
1114 // So far only supports PowerPC and X86.
1115 if (!STI->getTargetTriple().isPPC() && !STI->getTargetTriple().isX86())
1116 return;
1117
1118 Labels.clear();
1119 unsigned LabelCount = 0;
1120 Start += SectionAddr;
1121 End += SectionAddr;
1122 uint64_t Index = Start;
1123 while (Index < End) {
1124 // Disassemble a real instruction and record function-local branch labels.
1125 MCInst Inst;
1126 uint64_t Size;
1127 ArrayRef<uint8_t> ThisBytes = Bytes.slice(Index - SectionAddr);
1128 bool Disassembled =
1129 DisAsm->getInstruction(Inst, Size, ThisBytes, Index, nulls());
1130 if (Size == 0)
1131 Size = std::min<uint64_t>(ThisBytes.size(),
1132 DisAsm->suggestBytesToSkip(ThisBytes, Index));
1133
1134 if (Disassembled && MIA) {
1135 uint64_t Target;
1136 bool TargetKnown = MIA->evaluateBranch(Inst, Index, Size, Target);
1137 // On PowerPC, if the address of a branch is the same as the target, it
1138 // means that it's a function call. Do not mark the label for this case.
1139 if (TargetKnown && (Target >= Start && Target < End) &&
1140 !Labels.count(Target) &&
1141 !(STI->getTargetTriple().isPPC() && Target == Index))
1142 Labels[Target] = ("L" + Twine(LabelCount++)).str();
1143 }
1144 Index += Size;
1145 }
1146 }
1147
1148 // Create an MCSymbolizer for the target and add it to the MCDisassembler.
1149 // This is currently only used on AMDGPU, and assumes the format of the
1150 // void * argument passed to AMDGPU's createMCSymbolizer.
addSymbolizer(MCContext & Ctx,const Target * Target,StringRef TripleName,MCDisassembler * DisAsm,uint64_t SectionAddr,ArrayRef<uint8_t> Bytes,SectionSymbolsTy & Symbols,std::vector<std::unique_ptr<std::string>> & SynthesizedLabelNames)1151 static void addSymbolizer(
1152 MCContext &Ctx, const Target *Target, StringRef TripleName,
1153 MCDisassembler *DisAsm, uint64_t SectionAddr, ArrayRef<uint8_t> Bytes,
1154 SectionSymbolsTy &Symbols,
1155 std::vector<std::unique_ptr<std::string>> &SynthesizedLabelNames) {
1156
1157 std::unique_ptr<MCRelocationInfo> RelInfo(
1158 Target->createMCRelocationInfo(TripleName, Ctx));
1159 if (!RelInfo)
1160 return;
1161 std::unique_ptr<MCSymbolizer> Symbolizer(Target->createMCSymbolizer(
1162 TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo)));
1163 MCSymbolizer *SymbolizerPtr = &*Symbolizer;
1164 DisAsm->setSymbolizer(std::move(Symbolizer));
1165
1166 if (!SymbolizeOperands)
1167 return;
1168
1169 // Synthesize labels referenced by branch instructions by
1170 // disassembling, discarding the output, and collecting the referenced
1171 // addresses from the symbolizer.
1172 for (size_t Index = 0; Index != Bytes.size();) {
1173 MCInst Inst;
1174 uint64_t Size;
1175 ArrayRef<uint8_t> ThisBytes = Bytes.slice(Index - SectionAddr);
1176 DisAsm->getInstruction(Inst, Size, ThisBytes, Index, nulls());
1177 if (Size == 0)
1178 Size = std::min<uint64_t>(ThisBytes.size(),
1179 DisAsm->suggestBytesToSkip(ThisBytes, Index));
1180 Index += Size;
1181 }
1182 ArrayRef<uint64_t> LabelAddrsRef = SymbolizerPtr->getReferencedAddresses();
1183 // Copy and sort to remove duplicates.
1184 std::vector<uint64_t> LabelAddrs;
1185 LabelAddrs.insert(LabelAddrs.end(), LabelAddrsRef.begin(),
1186 LabelAddrsRef.end());
1187 llvm::sort(LabelAddrs);
1188 LabelAddrs.resize(std::unique(LabelAddrs.begin(), LabelAddrs.end()) -
1189 LabelAddrs.begin());
1190 // Add the labels.
1191 for (unsigned LabelNum = 0; LabelNum != LabelAddrs.size(); ++LabelNum) {
1192 auto Name = std::make_unique<std::string>();
1193 *Name = (Twine("L") + Twine(LabelNum)).str();
1194 SynthesizedLabelNames.push_back(std::move(Name));
1195 Symbols.push_back(SymbolInfoTy(
1196 LabelAddrs[LabelNum], *SynthesizedLabelNames.back(), ELF::STT_NOTYPE));
1197 }
1198 llvm::stable_sort(Symbols);
1199 // Recreate the symbolizer with the new symbols list.
1200 RelInfo.reset(Target->createMCRelocationInfo(TripleName, Ctx));
1201 Symbolizer.reset(Target->createMCSymbolizer(
1202 TripleName, nullptr, nullptr, &Symbols, &Ctx, std::move(RelInfo)));
1203 DisAsm->setSymbolizer(std::move(Symbolizer));
1204 }
1205
getSegmentName(const MachOObjectFile * MachO,const SectionRef & Section)1206 static StringRef getSegmentName(const MachOObjectFile *MachO,
1207 const SectionRef &Section) {
1208 if (MachO) {
1209 DataRefImpl DR = Section.getRawDataRefImpl();
1210 StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
1211 return SegmentName;
1212 }
1213 return "";
1214 }
1215
emitPostInstructionInfo(formatted_raw_ostream & FOS,const MCAsmInfo & MAI,const MCSubtargetInfo & STI,StringRef Comments,LiveVariablePrinter & LVP)1216 static void emitPostInstructionInfo(formatted_raw_ostream &FOS,
1217 const MCAsmInfo &MAI,
1218 const MCSubtargetInfo &STI,
1219 StringRef Comments,
1220 LiveVariablePrinter &LVP) {
1221 do {
1222 if (!Comments.empty()) {
1223 // Emit a line of comments.
1224 StringRef Comment;
1225 std::tie(Comment, Comments) = Comments.split('\n');
1226 // MAI.getCommentColumn() assumes that instructions are printed at the
1227 // position of 8, while getInstStartColumn() returns the actual position.
1228 unsigned CommentColumn =
1229 MAI.getCommentColumn() - 8 + getInstStartColumn(STI);
1230 FOS.PadToColumn(CommentColumn);
1231 FOS << MAI.getCommentString() << ' ' << Comment;
1232 }
1233 LVP.printAfterInst(FOS);
1234 FOS << '\n';
1235 } while (!Comments.empty());
1236 FOS.flush();
1237 }
1238
createFakeELFSections(ObjectFile & Obj)1239 static void createFakeELFSections(ObjectFile &Obj) {
1240 assert(Obj.isELF());
1241 if (auto *Elf32LEObj = dyn_cast<ELF32LEObjectFile>(&Obj))
1242 Elf32LEObj->createFakeSections();
1243 else if (auto *Elf64LEObj = dyn_cast<ELF64LEObjectFile>(&Obj))
1244 Elf64LEObj->createFakeSections();
1245 else if (auto *Elf32BEObj = dyn_cast<ELF32BEObjectFile>(&Obj))
1246 Elf32BEObj->createFakeSections();
1247 else if (auto *Elf64BEObj = cast<ELF64BEObjectFile>(&Obj))
1248 Elf64BEObj->createFakeSections();
1249 else
1250 llvm_unreachable("Unsupported binary format");
1251 }
1252
disassembleObject(const Target * TheTarget,ObjectFile & Obj,MCContext & Ctx,MCDisassembler * PrimaryDisAsm,MCDisassembler * SecondaryDisAsm,const MCInstrAnalysis * MIA,MCInstPrinter * IP,const MCSubtargetInfo * PrimarySTI,const MCSubtargetInfo * SecondarySTI,PrettyPrinter & PIP,SourcePrinter & SP,bool InlineRelocs)1253 static void disassembleObject(const Target *TheTarget, ObjectFile &Obj,
1254 MCContext &Ctx, MCDisassembler *PrimaryDisAsm,
1255 MCDisassembler *SecondaryDisAsm,
1256 const MCInstrAnalysis *MIA, MCInstPrinter *IP,
1257 const MCSubtargetInfo *PrimarySTI,
1258 const MCSubtargetInfo *SecondarySTI,
1259 PrettyPrinter &PIP, SourcePrinter &SP,
1260 bool InlineRelocs) {
1261 const MCSubtargetInfo *STI = PrimarySTI;
1262 MCDisassembler *DisAsm = PrimaryDisAsm;
1263 bool PrimaryIsThumb = false;
1264 if (isArmElf(Obj))
1265 PrimaryIsThumb = STI->checkFeatures("+thumb-mode");
1266
1267 std::map<SectionRef, std::vector<RelocationRef>> RelocMap;
1268 if (InlineRelocs)
1269 RelocMap = getRelocsMap(Obj);
1270 bool Is64Bits = Obj.getBytesInAddress() > 4;
1271
1272 // Create a mapping from virtual address to symbol name. This is used to
1273 // pretty print the symbols while disassembling.
1274 std::map<SectionRef, SectionSymbolsTy> AllSymbols;
1275 SectionSymbolsTy AbsoluteSymbols;
1276 const StringRef FileName = Obj.getFileName();
1277 const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(&Obj);
1278 for (const SymbolRef &Symbol : Obj.symbols()) {
1279 Expected<StringRef> NameOrErr = Symbol.getName();
1280 if (!NameOrErr) {
1281 reportWarning(toString(NameOrErr.takeError()), FileName);
1282 continue;
1283 }
1284 if (NameOrErr->empty() && !(Obj.isXCOFF() && SymbolDescription))
1285 continue;
1286
1287 if (Obj.isELF() && getElfSymbolType(Obj, Symbol) == ELF::STT_SECTION)
1288 continue;
1289
1290 if (MachO) {
1291 // __mh_(execute|dylib|dylinker|bundle|preload|object)_header are special
1292 // symbols that support MachO header introspection. They do not bind to
1293 // code locations and are irrelevant for disassembly.
1294 if (NameOrErr->startswith("__mh_") && NameOrErr->endswith("_header"))
1295 continue;
1296 // Don't ask a Mach-O STAB symbol for its section unless you know that
1297 // STAB symbol's section field refers to a valid section index. Otherwise
1298 // the symbol may error trying to load a section that does not exist.
1299 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
1300 uint8_t NType = (MachO->is64Bit() ?
1301 MachO->getSymbol64TableEntry(SymDRI).n_type:
1302 MachO->getSymbolTableEntry(SymDRI).n_type);
1303 if (NType & MachO::N_STAB)
1304 continue;
1305 }
1306
1307 section_iterator SecI = unwrapOrError(Symbol.getSection(), FileName);
1308 if (SecI != Obj.section_end())
1309 AllSymbols[*SecI].push_back(createSymbolInfo(Obj, Symbol));
1310 else
1311 AbsoluteSymbols.push_back(createSymbolInfo(Obj, Symbol));
1312 }
1313
1314 if (AllSymbols.empty() && Obj.isELF())
1315 addDynamicElfSymbols(cast<ELFObjectFileBase>(Obj), AllSymbols);
1316
1317 if (Obj.isWasm())
1318 addMissingWasmCodeSymbols(cast<WasmObjectFile>(Obj), AllSymbols);
1319
1320 if (Obj.isELF() && Obj.sections().empty())
1321 createFakeELFSections(Obj);
1322
1323 BumpPtrAllocator A;
1324 StringSaver Saver(A);
1325 addPltEntries(Obj, AllSymbols, Saver);
1326
1327 // Create a mapping from virtual address to section. An empty section can
1328 // cause more than one section at the same address. Sort such sections to be
1329 // before same-addressed non-empty sections so that symbol lookups prefer the
1330 // non-empty section.
1331 std::vector<std::pair<uint64_t, SectionRef>> SectionAddresses;
1332 for (SectionRef Sec : Obj.sections())
1333 SectionAddresses.emplace_back(Sec.getAddress(), Sec);
1334 llvm::stable_sort(SectionAddresses, [](const auto &LHS, const auto &RHS) {
1335 if (LHS.first != RHS.first)
1336 return LHS.first < RHS.first;
1337 return LHS.second.getSize() < RHS.second.getSize();
1338 });
1339
1340 // Linked executables (.exe and .dll files) typically don't include a real
1341 // symbol table but they might contain an export table.
1342 if (const auto *COFFObj = dyn_cast<COFFObjectFile>(&Obj)) {
1343 for (const auto &ExportEntry : COFFObj->export_directories()) {
1344 StringRef Name;
1345 if (Error E = ExportEntry.getSymbolName(Name))
1346 reportError(std::move(E), Obj.getFileName());
1347 if (Name.empty())
1348 continue;
1349
1350 uint32_t RVA;
1351 if (Error E = ExportEntry.getExportRVA(RVA))
1352 reportError(std::move(E), Obj.getFileName());
1353
1354 uint64_t VA = COFFObj->getImageBase() + RVA;
1355 auto Sec = partition_point(
1356 SectionAddresses, [VA](const std::pair<uint64_t, SectionRef> &O) {
1357 return O.first <= VA;
1358 });
1359 if (Sec != SectionAddresses.begin()) {
1360 --Sec;
1361 AllSymbols[Sec->second].emplace_back(VA, Name, ELF::STT_NOTYPE);
1362 } else
1363 AbsoluteSymbols.emplace_back(VA, Name, ELF::STT_NOTYPE);
1364 }
1365 }
1366
1367 // Sort all the symbols, this allows us to use a simple binary search to find
1368 // Multiple symbols can have the same address. Use a stable sort to stabilize
1369 // the output.
1370 StringSet<> FoundDisasmSymbolSet;
1371 for (std::pair<const SectionRef, SectionSymbolsTy> &SecSyms : AllSymbols)
1372 llvm::stable_sort(SecSyms.second);
1373 llvm::stable_sort(AbsoluteSymbols);
1374
1375 std::unique_ptr<DWARFContext> DICtx;
1376 LiveVariablePrinter LVP(*Ctx.getRegisterInfo(), *STI);
1377
1378 if (DbgVariables != DVDisabled) {
1379 DICtx = DWARFContext::create(Obj);
1380 for (const std::unique_ptr<DWARFUnit> &CU : DICtx->compile_units())
1381 LVP.addCompileUnit(CU->getUnitDIE(false));
1382 }
1383
1384 LLVM_DEBUG(LVP.dump());
1385
1386 std::unordered_map<uint64_t, BBAddrMap> AddrToBBAddrMap;
1387 auto ReadBBAddrMap = [&](Optional<unsigned> SectionIndex = None) {
1388 AddrToBBAddrMap.clear();
1389 if (const auto *Elf = dyn_cast<ELFObjectFileBase>(&Obj)) {
1390 auto BBAddrMapsOrErr = Elf->readBBAddrMap(SectionIndex);
1391 if (!BBAddrMapsOrErr)
1392 reportWarning(toString(BBAddrMapsOrErr.takeError()),
1393 Obj.getFileName());
1394 for (auto &FunctionBBAddrMap : *BBAddrMapsOrErr)
1395 AddrToBBAddrMap.emplace(FunctionBBAddrMap.Addr,
1396 std::move(FunctionBBAddrMap));
1397 }
1398 };
1399
1400 // For non-relocatable objects, Read all LLVM_BB_ADDR_MAP sections into a
1401 // single mapping, since they don't have any conflicts.
1402 if (SymbolizeOperands && !Obj.isRelocatableObject())
1403 ReadBBAddrMap();
1404
1405 for (const SectionRef &Section : ToolSectionFilter(Obj)) {
1406 if (FilterSections.empty() && !DisassembleAll &&
1407 (!Section.isText() || Section.isVirtual()))
1408 continue;
1409
1410 uint64_t SectionAddr = Section.getAddress();
1411 uint64_t SectSize = Section.getSize();
1412 if (!SectSize)
1413 continue;
1414
1415 // For relocatable object files, read the LLVM_BB_ADDR_MAP section
1416 // corresponding to this section, if present.
1417 if (SymbolizeOperands && Obj.isRelocatableObject())
1418 ReadBBAddrMap(Section.getIndex());
1419
1420 // Get the list of all the symbols in this section.
1421 SectionSymbolsTy &Symbols = AllSymbols[Section];
1422 std::vector<MappingSymbolPair> MappingSymbols;
1423 if (hasMappingSymbols(Obj)) {
1424 for (const auto &Symb : Symbols) {
1425 uint64_t Address = Symb.Addr;
1426 StringRef Name = Symb.Name;
1427 if (Name.startswith("$d"))
1428 MappingSymbols.emplace_back(Address - SectionAddr, 'd');
1429 if (Name.startswith("$x"))
1430 MappingSymbols.emplace_back(Address - SectionAddr, 'x');
1431 if (Name.startswith("$a"))
1432 MappingSymbols.emplace_back(Address - SectionAddr, 'a');
1433 if (Name.startswith("$t"))
1434 MappingSymbols.emplace_back(Address - SectionAddr, 't');
1435 }
1436 }
1437
1438 llvm::sort(MappingSymbols);
1439
1440 ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(
1441 unwrapOrError(Section.getContents(), Obj.getFileName()));
1442
1443 std::vector<std::unique_ptr<std::string>> SynthesizedLabelNames;
1444 if (Obj.isELF() && Obj.getArch() == Triple::amdgcn) {
1445 // AMDGPU disassembler uses symbolizer for printing labels
1446 addSymbolizer(Ctx, TheTarget, TripleName, DisAsm, SectionAddr, Bytes,
1447 Symbols, SynthesizedLabelNames);
1448 }
1449
1450 StringRef SegmentName = getSegmentName(MachO, Section);
1451 StringRef SectionName = unwrapOrError(Section.getName(), Obj.getFileName());
1452 // If the section has no symbol at the start, just insert a dummy one.
1453 if (Symbols.empty() || Symbols[0].Addr != 0) {
1454 Symbols.insert(Symbols.begin(),
1455 createDummySymbolInfo(Obj, SectionAddr, SectionName,
1456 Section.isText() ? ELF::STT_FUNC
1457 : ELF::STT_OBJECT));
1458 }
1459
1460 SmallString<40> Comments;
1461 raw_svector_ostream CommentStream(Comments);
1462
1463 uint64_t VMAAdjustment = 0;
1464 if (shouldAdjustVA(Section))
1465 VMAAdjustment = AdjustVMA;
1466
1467 // In executable and shared objects, r_offset holds a virtual address.
1468 // Subtract SectionAddr from the r_offset field of a relocation to get
1469 // the section offset.
1470 uint64_t RelAdjustment = Obj.isRelocatableObject() ? 0 : SectionAddr;
1471 uint64_t Size;
1472 uint64_t Index;
1473 bool PrintedSection = false;
1474 std::vector<RelocationRef> Rels = RelocMap[Section];
1475 std::vector<RelocationRef>::const_iterator RelCur = Rels.begin();
1476 std::vector<RelocationRef>::const_iterator RelEnd = Rels.end();
1477 // Disassemble symbol by symbol.
1478 for (unsigned SI = 0, SE = Symbols.size(); SI != SE; ++SI) {
1479 std::string SymbolName = Symbols[SI].Name.str();
1480 if (Demangle)
1481 SymbolName = demangle(SymbolName);
1482
1483 // Skip if --disassemble-symbols is not empty and the symbol is not in
1484 // the list.
1485 if (!DisasmSymbolSet.empty() && !DisasmSymbolSet.count(SymbolName))
1486 continue;
1487
1488 uint64_t Start = Symbols[SI].Addr;
1489 if (Start < SectionAddr || StopAddress <= Start)
1490 continue;
1491 else
1492 FoundDisasmSymbolSet.insert(SymbolName);
1493
1494 // The end is the section end, the beginning of the next symbol, or
1495 // --stop-address.
1496 uint64_t End = std::min<uint64_t>(SectionAddr + SectSize, StopAddress);
1497 if (SI + 1 < SE)
1498 End = std::min(End, Symbols[SI + 1].Addr);
1499 if (Start >= End || End <= StartAddress)
1500 continue;
1501 Start -= SectionAddr;
1502 End -= SectionAddr;
1503
1504 if (!PrintedSection) {
1505 PrintedSection = true;
1506 outs() << "\nDisassembly of section ";
1507 if (!SegmentName.empty())
1508 outs() << SegmentName << ",";
1509 outs() << SectionName << ":\n";
1510 }
1511
1512 outs() << '\n';
1513 if (LeadingAddr)
1514 outs() << format(Is64Bits ? "%016" PRIx64 " " : "%08" PRIx64 " ",
1515 SectionAddr + Start + VMAAdjustment);
1516 if (Obj.isXCOFF() && SymbolDescription) {
1517 outs() << getXCOFFSymbolDescription(Symbols[SI], SymbolName) << ":\n";
1518 } else
1519 outs() << '<' << SymbolName << ">:\n";
1520
1521 // Don't print raw contents of a virtual section. A virtual section
1522 // doesn't have any contents in the file.
1523 if (Section.isVirtual()) {
1524 outs() << "...\n";
1525 continue;
1526 }
1527
1528 auto Status = DisAsm->onSymbolStart(Symbols[SI], Size,
1529 Bytes.slice(Start, End - Start),
1530 SectionAddr + Start, CommentStream);
1531 // To have round trippable disassembly, we fall back to decoding the
1532 // remaining bytes as instructions.
1533 //
1534 // If there is a failure, we disassemble the failed region as bytes before
1535 // falling back. The target is expected to print nothing in this case.
1536 //
1537 // If there is Success or SoftFail i.e no 'real' failure, we go ahead by
1538 // Size bytes before falling back.
1539 // So if the entire symbol is 'eaten' by the target:
1540 // Start += Size // Now Start = End and we will never decode as
1541 // // instructions
1542 //
1543 // Right now, most targets return None i.e ignore to treat a symbol
1544 // separately. But WebAssembly decodes preludes for some symbols.
1545 //
1546 if (Status) {
1547 if (Status.value() == MCDisassembler::Fail) {
1548 outs() << "// Error in decoding " << SymbolName
1549 << " : Decoding failed region as bytes.\n";
1550 for (uint64_t I = 0; I < Size; ++I) {
1551 outs() << "\t.byte\t " << format_hex(Bytes[I], 1, /*Upper=*/true)
1552 << "\n";
1553 }
1554 }
1555 } else {
1556 Size = 0;
1557 }
1558
1559 Start += Size;
1560
1561 Index = Start;
1562 if (SectionAddr < StartAddress)
1563 Index = std::max<uint64_t>(Index, StartAddress - SectionAddr);
1564
1565 // If there is a data/common symbol inside an ELF text section and we are
1566 // only disassembling text (applicable all architectures), we are in a
1567 // situation where we must print the data and not disassemble it.
1568 if (Obj.isELF() && !DisassembleAll && Section.isText()) {
1569 uint8_t SymTy = Symbols[SI].Type;
1570 if (SymTy == ELF::STT_OBJECT || SymTy == ELF::STT_COMMON) {
1571 dumpELFData(SectionAddr, Index, End, Bytes);
1572 Index = End;
1573 }
1574 }
1575
1576 bool CheckARMELFData = hasMappingSymbols(Obj) &&
1577 Symbols[SI].Type != ELF::STT_OBJECT &&
1578 !DisassembleAll;
1579 bool DumpARMELFData = false;
1580 formatted_raw_ostream FOS(outs());
1581
1582 std::unordered_map<uint64_t, std::string> AllLabels;
1583 std::unordered_map<uint64_t, std::vector<std::string>> BBAddrMapLabels;
1584 if (SymbolizeOperands) {
1585 collectLocalBranchTargets(Bytes, MIA, DisAsm, IP, PrimarySTI,
1586 SectionAddr, Index, End, AllLabels);
1587 collectBBAddrMapLabels(AddrToBBAddrMap, SectionAddr, Index, End,
1588 BBAddrMapLabels);
1589 }
1590
1591 while (Index < End) {
1592 // ARM and AArch64 ELF binaries can interleave data and text in the
1593 // same section. We rely on the markers introduced to understand what
1594 // we need to dump. If the data marker is within a function, it is
1595 // denoted as a word/short etc.
1596 if (CheckARMELFData) {
1597 char Kind = getMappingSymbolKind(MappingSymbols, Index);
1598 DumpARMELFData = Kind == 'd';
1599 if (SecondarySTI) {
1600 if (Kind == 'a') {
1601 STI = PrimaryIsThumb ? SecondarySTI : PrimarySTI;
1602 DisAsm = PrimaryIsThumb ? SecondaryDisAsm : PrimaryDisAsm;
1603 } else if (Kind == 't') {
1604 STI = PrimaryIsThumb ? PrimarySTI : SecondarySTI;
1605 DisAsm = PrimaryIsThumb ? PrimaryDisAsm : SecondaryDisAsm;
1606 }
1607 }
1608 }
1609
1610 if (DumpARMELFData) {
1611 Size = dumpARMELFData(SectionAddr, Index, End, Obj, Bytes,
1612 MappingSymbols, *STI, FOS);
1613 } else {
1614 // When -z or --disassemble-zeroes are given we always dissasemble
1615 // them. Otherwise we might want to skip zero bytes we see.
1616 if (!DisassembleZeroes) {
1617 uint64_t MaxOffset = End - Index;
1618 // For --reloc: print zero blocks patched by relocations, so that
1619 // relocations can be shown in the dump.
1620 if (RelCur != RelEnd)
1621 MaxOffset = std::min(RelCur->getOffset() - RelAdjustment - Index,
1622 MaxOffset);
1623
1624 if (size_t N =
1625 countSkippableZeroBytes(Bytes.slice(Index, MaxOffset))) {
1626 FOS << "\t\t..." << '\n';
1627 Index += N;
1628 continue;
1629 }
1630 }
1631
1632 // Print local label if there's any.
1633 auto Iter1 = BBAddrMapLabels.find(SectionAddr + Index);
1634 if (Iter1 != BBAddrMapLabels.end()) {
1635 for (StringRef Label : Iter1->second)
1636 FOS << "<" << Label << ">:\n";
1637 } else {
1638 auto Iter2 = AllLabels.find(SectionAddr + Index);
1639 if (Iter2 != AllLabels.end())
1640 FOS << "<" << Iter2->second << ">:\n";
1641 }
1642
1643 // Disassemble a real instruction or a data when disassemble all is
1644 // provided
1645 MCInst Inst;
1646 ArrayRef<uint8_t> ThisBytes = Bytes.slice(Index);
1647 uint64_t ThisAddr = SectionAddr + Index;
1648 bool Disassembled = DisAsm->getInstruction(Inst, Size, ThisBytes,
1649 ThisAddr, CommentStream);
1650 if (Size == 0)
1651 Size = std::min<uint64_t>(
1652 ThisBytes.size(),
1653 DisAsm->suggestBytesToSkip(ThisBytes, ThisAddr));
1654
1655 LVP.update({Index, Section.getIndex()},
1656 {Index + Size, Section.getIndex()}, Index + Size != End);
1657
1658 IP->setCommentStream(CommentStream);
1659
1660 PIP.printInst(
1661 *IP, Disassembled ? &Inst : nullptr, Bytes.slice(Index, Size),
1662 {SectionAddr + Index + VMAAdjustment, Section.getIndex()}, FOS,
1663 "", *STI, &SP, Obj.getFileName(), &Rels, LVP);
1664
1665 IP->setCommentStream(llvm::nulls());
1666
1667 // If disassembly has failed, avoid analysing invalid/incomplete
1668 // instruction information. Otherwise, try to resolve the target
1669 // address (jump target or memory operand address) and print it on the
1670 // right of the instruction.
1671 if (Disassembled && MIA) {
1672 // Branch targets are printed just after the instructions.
1673 llvm::raw_ostream *TargetOS = &FOS;
1674 uint64_t Target;
1675 bool PrintTarget =
1676 MIA->evaluateBranch(Inst, SectionAddr + Index, Size, Target);
1677 if (!PrintTarget)
1678 if (Optional<uint64_t> MaybeTarget =
1679 MIA->evaluateMemoryOperandAddress(
1680 Inst, STI, SectionAddr + Index, Size)) {
1681 Target = *MaybeTarget;
1682 PrintTarget = true;
1683 // Do not print real address when symbolizing.
1684 if (!SymbolizeOperands) {
1685 // Memory operand addresses are printed as comments.
1686 TargetOS = &CommentStream;
1687 *TargetOS << "0x" << Twine::utohexstr(Target);
1688 }
1689 }
1690 if (PrintTarget) {
1691 // In a relocatable object, the target's section must reside in
1692 // the same section as the call instruction or it is accessed
1693 // through a relocation.
1694 //
1695 // In a non-relocatable object, the target may be in any section.
1696 // In that case, locate the section(s) containing the target
1697 // address and find the symbol in one of those, if possible.
1698 //
1699 // N.B. We don't walk the relocations in the relocatable case yet.
1700 std::vector<const SectionSymbolsTy *> TargetSectionSymbols;
1701 if (!Obj.isRelocatableObject()) {
1702 auto It = llvm::partition_point(
1703 SectionAddresses,
1704 [=](const std::pair<uint64_t, SectionRef> &O) {
1705 return O.first <= Target;
1706 });
1707 uint64_t TargetSecAddr = 0;
1708 while (It != SectionAddresses.begin()) {
1709 --It;
1710 if (TargetSecAddr == 0)
1711 TargetSecAddr = It->first;
1712 if (It->first != TargetSecAddr)
1713 break;
1714 TargetSectionSymbols.push_back(&AllSymbols[It->second]);
1715 }
1716 } else {
1717 TargetSectionSymbols.push_back(&Symbols);
1718 }
1719 TargetSectionSymbols.push_back(&AbsoluteSymbols);
1720
1721 // Find the last symbol in the first candidate section whose
1722 // offset is less than or equal to the target. If there are no
1723 // such symbols, try in the next section and so on, before finally
1724 // using the nearest preceding absolute symbol (if any), if there
1725 // are no other valid symbols.
1726 const SymbolInfoTy *TargetSym = nullptr;
1727 for (const SectionSymbolsTy *TargetSymbols :
1728 TargetSectionSymbols) {
1729 auto It = llvm::partition_point(
1730 *TargetSymbols,
1731 [=](const SymbolInfoTy &O) { return O.Addr <= Target; });
1732 if (It != TargetSymbols->begin()) {
1733 TargetSym = &*(It - 1);
1734 break;
1735 }
1736 }
1737
1738 // Print the labels corresponding to the target if there's any.
1739 bool BBAddrMapLabelAvailable = BBAddrMapLabels.count(Target);
1740 bool LabelAvailable = AllLabels.count(Target);
1741 if (TargetSym != nullptr) {
1742 uint64_t TargetAddress = TargetSym->Addr;
1743 uint64_t Disp = Target - TargetAddress;
1744 std::string TargetName = TargetSym->Name.str();
1745 if (Demangle)
1746 TargetName = demangle(TargetName);
1747
1748 *TargetOS << " <";
1749 if (!Disp) {
1750 // Always Print the binary symbol precisely corresponding to
1751 // the target address.
1752 *TargetOS << TargetName;
1753 } else if (BBAddrMapLabelAvailable) {
1754 *TargetOS << BBAddrMapLabels[Target].front();
1755 } else if (LabelAvailable) {
1756 *TargetOS << AllLabels[Target];
1757 } else {
1758 // Always Print the binary symbol plus an offset if there's no
1759 // local label corresponding to the target address.
1760 *TargetOS << TargetName << "+0x" << Twine::utohexstr(Disp);
1761 }
1762 *TargetOS << ">";
1763 } else if (BBAddrMapLabelAvailable) {
1764 *TargetOS << " <" << BBAddrMapLabels[Target].front() << ">";
1765 } else if (LabelAvailable) {
1766 *TargetOS << " <" << AllLabels[Target] << ">";
1767 }
1768 // By convention, each record in the comment stream should be
1769 // terminated.
1770 if (TargetOS == &CommentStream)
1771 *TargetOS << "\n";
1772 }
1773 }
1774 }
1775
1776 assert(Ctx.getAsmInfo());
1777 emitPostInstructionInfo(FOS, *Ctx.getAsmInfo(), *STI,
1778 CommentStream.str(), LVP);
1779 Comments.clear();
1780
1781 // Hexagon does this in pretty printer
1782 if (Obj.getArch() != Triple::hexagon) {
1783 // Print relocation for instruction and data.
1784 while (RelCur != RelEnd) {
1785 uint64_t Offset = RelCur->getOffset() - RelAdjustment;
1786 // If this relocation is hidden, skip it.
1787 if (getHidden(*RelCur) || SectionAddr + Offset < StartAddress) {
1788 ++RelCur;
1789 continue;
1790 }
1791
1792 // Stop when RelCur's offset is past the disassembled
1793 // instruction/data. Note that it's possible the disassembled data
1794 // is not the complete data: we might see the relocation printed in
1795 // the middle of the data, but this matches the binutils objdump
1796 // output.
1797 if (Offset >= Index + Size)
1798 break;
1799
1800 // When --adjust-vma is used, update the address printed.
1801 if (RelCur->getSymbol() != Obj.symbol_end()) {
1802 Expected<section_iterator> SymSI =
1803 RelCur->getSymbol()->getSection();
1804 if (SymSI && *SymSI != Obj.section_end() &&
1805 shouldAdjustVA(**SymSI))
1806 Offset += AdjustVMA;
1807 }
1808
1809 printRelocation(FOS, Obj.getFileName(), *RelCur,
1810 SectionAddr + Offset, Is64Bits);
1811 LVP.printAfterOtherLine(FOS, true);
1812 ++RelCur;
1813 }
1814 }
1815
1816 Index += Size;
1817 }
1818 }
1819 }
1820 StringSet<> MissingDisasmSymbolSet =
1821 set_difference(DisasmSymbolSet, FoundDisasmSymbolSet);
1822 for (StringRef Sym : MissingDisasmSymbolSet.keys())
1823 reportWarning("failed to disassemble missing symbol " + Sym, FileName);
1824 }
1825
disassembleObject(ObjectFile * Obj,bool InlineRelocs)1826 static void disassembleObject(ObjectFile *Obj, bool InlineRelocs) {
1827 const Target *TheTarget = getTarget(Obj);
1828
1829 // Package up features to be passed to target/subtarget
1830 SubtargetFeatures Features = Obj->getFeatures();
1831 if (!MAttrs.empty()) {
1832 for (unsigned I = 0; I != MAttrs.size(); ++I)
1833 Features.AddFeature(MAttrs[I]);
1834 } else if (MCPU.empty() && Obj->getArch() == llvm::Triple::aarch64) {
1835 Features.AddFeature("+all");
1836 }
1837
1838 std::unique_ptr<const MCRegisterInfo> MRI(
1839 TheTarget->createMCRegInfo(TripleName));
1840 if (!MRI)
1841 reportError(Obj->getFileName(),
1842 "no register info for target " + TripleName);
1843
1844 // Set up disassembler.
1845 MCTargetOptions MCOptions;
1846 std::unique_ptr<const MCAsmInfo> AsmInfo(
1847 TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
1848 if (!AsmInfo)
1849 reportError(Obj->getFileName(),
1850 "no assembly info for target " + TripleName);
1851
1852 if (MCPU.empty())
1853 MCPU = Obj->tryGetCPUName().value_or("").str();
1854
1855 std::unique_ptr<const MCSubtargetInfo> STI(
1856 TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString()));
1857 if (!STI)
1858 reportError(Obj->getFileName(),
1859 "no subtarget info for target " + TripleName);
1860 std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
1861 if (!MII)
1862 reportError(Obj->getFileName(),
1863 "no instruction info for target " + TripleName);
1864 MCContext Ctx(Triple(TripleName), AsmInfo.get(), MRI.get(), STI.get());
1865 // FIXME: for now initialize MCObjectFileInfo with default values
1866 std::unique_ptr<MCObjectFileInfo> MOFI(
1867 TheTarget->createMCObjectFileInfo(Ctx, /*PIC=*/false));
1868 Ctx.setObjectFileInfo(MOFI.get());
1869
1870 std::unique_ptr<MCDisassembler> DisAsm(
1871 TheTarget->createMCDisassembler(*STI, Ctx));
1872 if (!DisAsm)
1873 reportError(Obj->getFileName(), "no disassembler for target " + TripleName);
1874
1875 // If we have an ARM object file, we need a second disassembler, because
1876 // ARM CPUs have two different instruction sets: ARM mode, and Thumb mode.
1877 // We use mapping symbols to switch between the two assemblers, where
1878 // appropriate.
1879 std::unique_ptr<MCDisassembler> SecondaryDisAsm;
1880 std::unique_ptr<const MCSubtargetInfo> SecondarySTI;
1881 if (isArmElf(*Obj) && !STI->checkFeatures("+mclass")) {
1882 if (STI->checkFeatures("+thumb-mode"))
1883 Features.AddFeature("-thumb-mode");
1884 else
1885 Features.AddFeature("+thumb-mode");
1886 SecondarySTI.reset(TheTarget->createMCSubtargetInfo(TripleName, MCPU,
1887 Features.getString()));
1888 SecondaryDisAsm.reset(TheTarget->createMCDisassembler(*SecondarySTI, Ctx));
1889 }
1890
1891 std::unique_ptr<const MCInstrAnalysis> MIA(
1892 TheTarget->createMCInstrAnalysis(MII.get()));
1893
1894 int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
1895 std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
1896 Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI));
1897 if (!IP)
1898 reportError(Obj->getFileName(),
1899 "no instruction printer for target " + TripleName);
1900 IP->setPrintImmHex(PrintImmHex);
1901 IP->setPrintBranchImmAsAddress(true);
1902 IP->setSymbolizeOperands(SymbolizeOperands);
1903 IP->setMCInstrAnalysis(MIA.get());
1904
1905 PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName));
1906 SourcePrinter SP(Obj, TheTarget->getName());
1907
1908 for (StringRef Opt : DisassemblerOptions)
1909 if (!IP->applyTargetSpecificCLOption(Opt))
1910 reportError(Obj->getFileName(),
1911 "Unrecognized disassembler option: " + Opt);
1912
1913 disassembleObject(TheTarget, *Obj, Ctx, DisAsm.get(), SecondaryDisAsm.get(),
1914 MIA.get(), IP.get(), STI.get(), SecondarySTI.get(), PIP, SP,
1915 InlineRelocs);
1916 }
1917
printRelocations(const ObjectFile * Obj)1918 void objdump::printRelocations(const ObjectFile *Obj) {
1919 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
1920 "%08" PRIx64;
1921
1922 // Build a mapping from relocation target to a vector of relocation
1923 // sections. Usually, there is an only one relocation section for
1924 // each relocated section.
1925 MapVector<SectionRef, std::vector<SectionRef>> SecToRelSec;
1926 uint64_t Ndx;
1927 for (const SectionRef &Section : ToolSectionFilter(*Obj, &Ndx)) {
1928 if (Obj->isELF() && (ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC))
1929 continue;
1930 if (Section.relocation_begin() == Section.relocation_end())
1931 continue;
1932 Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
1933 if (!SecOrErr)
1934 reportError(Obj->getFileName(),
1935 "section (" + Twine(Ndx) +
1936 "): unable to get a relocation target: " +
1937 toString(SecOrErr.takeError()));
1938 SecToRelSec[**SecOrErr].push_back(Section);
1939 }
1940
1941 for (std::pair<SectionRef, std::vector<SectionRef>> &P : SecToRelSec) {
1942 StringRef SecName = unwrapOrError(P.first.getName(), Obj->getFileName());
1943 outs() << "\nRELOCATION RECORDS FOR [" << SecName << "]:\n";
1944 uint32_t OffsetPadding = (Obj->getBytesInAddress() > 4 ? 16 : 8);
1945 uint32_t TypePadding = 24;
1946 outs() << left_justify("OFFSET", OffsetPadding) << " "
1947 << left_justify("TYPE", TypePadding) << " "
1948 << "VALUE\n";
1949
1950 for (SectionRef Section : P.second) {
1951 for (const RelocationRef &Reloc : Section.relocations()) {
1952 uint64_t Address = Reloc.getOffset();
1953 SmallString<32> RelocName;
1954 SmallString<32> ValueStr;
1955 if (Address < StartAddress || Address > StopAddress || getHidden(Reloc))
1956 continue;
1957 Reloc.getTypeName(RelocName);
1958 if (Error E = getRelocationValueString(Reloc, ValueStr))
1959 reportError(std::move(E), Obj->getFileName());
1960
1961 outs() << format(Fmt.data(), Address) << " "
1962 << left_justify(RelocName, TypePadding) << " " << ValueStr
1963 << "\n";
1964 }
1965 }
1966 }
1967 }
1968
printDynamicRelocations(const ObjectFile * Obj)1969 void objdump::printDynamicRelocations(const ObjectFile *Obj) {
1970 // For the moment, this option is for ELF only
1971 if (!Obj->isELF())
1972 return;
1973
1974 const auto *Elf = dyn_cast<ELFObjectFileBase>(Obj);
1975 if (!Elf || !any_of(Elf->sections(), [](const ELFSectionRef Sec) {
1976 return Sec.getType() == ELF::SHT_DYNAMIC;
1977 })) {
1978 reportError(Obj->getFileName(), "not a dynamic object");
1979 return;
1980 }
1981
1982 std::vector<SectionRef> DynRelSec = Obj->dynamic_relocation_sections();
1983 if (DynRelSec.empty())
1984 return;
1985
1986 outs() << "\nDYNAMIC RELOCATION RECORDS\n";
1987 const uint32_t OffsetPadding = (Obj->getBytesInAddress() > 4 ? 16 : 8);
1988 const uint32_t TypePadding = 24;
1989 outs() << left_justify("OFFSET", OffsetPadding) << ' '
1990 << left_justify("TYPE", TypePadding) << " VALUE\n";
1991
1992 StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
1993 for (const SectionRef &Section : DynRelSec)
1994 for (const RelocationRef &Reloc : Section.relocations()) {
1995 uint64_t Address = Reloc.getOffset();
1996 SmallString<32> RelocName;
1997 SmallString<32> ValueStr;
1998 Reloc.getTypeName(RelocName);
1999 if (Error E = getRelocationValueString(Reloc, ValueStr))
2000 reportError(std::move(E), Obj->getFileName());
2001 outs() << format(Fmt.data(), Address) << ' '
2002 << left_justify(RelocName, TypePadding) << ' ' << ValueStr << '\n';
2003 }
2004 }
2005
2006 // Returns true if we need to show LMA column when dumping section headers. We
2007 // show it only when the platform is ELF and either we have at least one section
2008 // whose VMA and LMA are different and/or when --show-lma flag is used.
shouldDisplayLMA(const ObjectFile & Obj)2009 static bool shouldDisplayLMA(const ObjectFile &Obj) {
2010 if (!Obj.isELF())
2011 return false;
2012 for (const SectionRef &S : ToolSectionFilter(Obj))
2013 if (S.getAddress() != getELFSectionLMA(S))
2014 return true;
2015 return ShowLMA;
2016 }
2017
getMaxSectionNameWidth(const ObjectFile & Obj)2018 static size_t getMaxSectionNameWidth(const ObjectFile &Obj) {
2019 // Default column width for names is 13 even if no names are that long.
2020 size_t MaxWidth = 13;
2021 for (const SectionRef &Section : ToolSectionFilter(Obj)) {
2022 StringRef Name = unwrapOrError(Section.getName(), Obj.getFileName());
2023 MaxWidth = std::max(MaxWidth, Name.size());
2024 }
2025 return MaxWidth;
2026 }
2027
printSectionHeaders(ObjectFile & Obj)2028 void objdump::printSectionHeaders(ObjectFile &Obj) {
2029 size_t NameWidth = getMaxSectionNameWidth(Obj);
2030 size_t AddressWidth = 2 * Obj.getBytesInAddress();
2031 bool HasLMAColumn = shouldDisplayLMA(Obj);
2032 outs() << "\nSections:\n";
2033 if (HasLMAColumn)
2034 outs() << "Idx " << left_justify("Name", NameWidth) << " Size "
2035 << left_justify("VMA", AddressWidth) << " "
2036 << left_justify("LMA", AddressWidth) << " Type\n";
2037 else
2038 outs() << "Idx " << left_justify("Name", NameWidth) << " Size "
2039 << left_justify("VMA", AddressWidth) << " Type\n";
2040
2041 if (Obj.isELF() && Obj.sections().empty())
2042 createFakeELFSections(Obj);
2043
2044 uint64_t Idx;
2045 for (const SectionRef &Section : ToolSectionFilter(Obj, &Idx)) {
2046 StringRef Name = unwrapOrError(Section.getName(), Obj.getFileName());
2047 uint64_t VMA = Section.getAddress();
2048 if (shouldAdjustVA(Section))
2049 VMA += AdjustVMA;
2050
2051 uint64_t Size = Section.getSize();
2052
2053 std::string Type = Section.isText() ? "TEXT" : "";
2054 if (Section.isData())
2055 Type += Type.empty() ? "DATA" : ", DATA";
2056 if (Section.isBSS())
2057 Type += Type.empty() ? "BSS" : ", BSS";
2058 if (Section.isDebugSection())
2059 Type += Type.empty() ? "DEBUG" : ", DEBUG";
2060
2061 if (HasLMAColumn)
2062 outs() << format("%3" PRIu64 " %-*s %08" PRIx64 " ", Idx, NameWidth,
2063 Name.str().c_str(), Size)
2064 << format_hex_no_prefix(VMA, AddressWidth) << " "
2065 << format_hex_no_prefix(getELFSectionLMA(Section), AddressWidth)
2066 << " " << Type << "\n";
2067 else
2068 outs() << format("%3" PRIu64 " %-*s %08" PRIx64 " ", Idx, NameWidth,
2069 Name.str().c_str(), Size)
2070 << format_hex_no_prefix(VMA, AddressWidth) << " " << Type << "\n";
2071 }
2072 }
2073
printSectionContents(const ObjectFile * Obj)2074 void objdump::printSectionContents(const ObjectFile *Obj) {
2075 const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj);
2076
2077 for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
2078 StringRef Name = unwrapOrError(Section.getName(), Obj->getFileName());
2079 uint64_t BaseAddr = Section.getAddress();
2080 uint64_t Size = Section.getSize();
2081 if (!Size)
2082 continue;
2083
2084 outs() << "Contents of section ";
2085 StringRef SegmentName = getSegmentName(MachO, Section);
2086 if (!SegmentName.empty())
2087 outs() << SegmentName << ",";
2088 outs() << Name << ":\n";
2089 if (Section.isBSS()) {
2090 outs() << format("<skipping contents of bss section at [%04" PRIx64
2091 ", %04" PRIx64 ")>\n",
2092 BaseAddr, BaseAddr + Size);
2093 continue;
2094 }
2095
2096 StringRef Contents = unwrapOrError(Section.getContents(), Obj->getFileName());
2097
2098 // Dump out the content as hex and printable ascii characters.
2099 for (std::size_t Addr = 0, End = Contents.size(); Addr < End; Addr += 16) {
2100 outs() << format(" %04" PRIx64 " ", BaseAddr + Addr);
2101 // Dump line of hex.
2102 for (std::size_t I = 0; I < 16; ++I) {
2103 if (I != 0 && I % 4 == 0)
2104 outs() << ' ';
2105 if (Addr + I < End)
2106 outs() << hexdigit((Contents[Addr + I] >> 4) & 0xF, true)
2107 << hexdigit(Contents[Addr + I] & 0xF, true);
2108 else
2109 outs() << " ";
2110 }
2111 // Print ascii.
2112 outs() << " ";
2113 for (std::size_t I = 0; I < 16 && Addr + I < End; ++I) {
2114 if (isPrint(static_cast<unsigned char>(Contents[Addr + I]) & 0xFF))
2115 outs() << Contents[Addr + I];
2116 else
2117 outs() << ".";
2118 }
2119 outs() << "\n";
2120 }
2121 }
2122 }
2123
printSymbolTable(const ObjectFile & O,StringRef ArchiveName,StringRef ArchitectureName,bool DumpDynamic)2124 void objdump::printSymbolTable(const ObjectFile &O, StringRef ArchiveName,
2125 StringRef ArchitectureName, bool DumpDynamic) {
2126 if (O.isCOFF() && !DumpDynamic) {
2127 outs() << "\nSYMBOL TABLE:\n";
2128 printCOFFSymbolTable(cast<const COFFObjectFile>(O));
2129 return;
2130 }
2131
2132 const StringRef FileName = O.getFileName();
2133
2134 if (!DumpDynamic) {
2135 outs() << "\nSYMBOL TABLE:\n";
2136 for (auto I = O.symbol_begin(); I != O.symbol_end(); ++I)
2137 printSymbol(O, *I, {}, FileName, ArchiveName, ArchitectureName,
2138 DumpDynamic);
2139 return;
2140 }
2141
2142 outs() << "\nDYNAMIC SYMBOL TABLE:\n";
2143 if (!O.isELF()) {
2144 reportWarning(
2145 "this operation is not currently supported for this file format",
2146 FileName);
2147 return;
2148 }
2149
2150 const ELFObjectFileBase *ELF = cast<const ELFObjectFileBase>(&O);
2151 auto Symbols = ELF->getDynamicSymbolIterators();
2152 Expected<std::vector<VersionEntry>> SymbolVersionsOrErr =
2153 ELF->readDynsymVersions();
2154 if (!SymbolVersionsOrErr) {
2155 reportWarning(toString(SymbolVersionsOrErr.takeError()), FileName);
2156 SymbolVersionsOrErr = std::vector<VersionEntry>();
2157 (void)!SymbolVersionsOrErr;
2158 }
2159 for (auto &Sym : Symbols)
2160 printSymbol(O, Sym, *SymbolVersionsOrErr, FileName, ArchiveName,
2161 ArchitectureName, DumpDynamic);
2162 }
2163
printSymbol(const ObjectFile & O,const SymbolRef & Symbol,ArrayRef<VersionEntry> SymbolVersions,StringRef FileName,StringRef ArchiveName,StringRef ArchitectureName,bool DumpDynamic)2164 void objdump::printSymbol(const ObjectFile &O, const SymbolRef &Symbol,
2165 ArrayRef<VersionEntry> SymbolVersions,
2166 StringRef FileName, StringRef ArchiveName,
2167 StringRef ArchitectureName, bool DumpDynamic) {
2168 const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(&O);
2169 uint64_t Address = unwrapOrError(Symbol.getAddress(), FileName, ArchiveName,
2170 ArchitectureName);
2171 if ((Address < StartAddress) || (Address > StopAddress))
2172 return;
2173 SymbolRef::Type Type =
2174 unwrapOrError(Symbol.getType(), FileName, ArchiveName, ArchitectureName);
2175 uint32_t Flags =
2176 unwrapOrError(Symbol.getFlags(), FileName, ArchiveName, ArchitectureName);
2177
2178 // Don't ask a Mach-O STAB symbol for its section unless you know that
2179 // STAB symbol's section field refers to a valid section index. Otherwise
2180 // the symbol may error trying to load a section that does not exist.
2181 bool IsSTAB = false;
2182 if (MachO) {
2183 DataRefImpl SymDRI = Symbol.getRawDataRefImpl();
2184 uint8_t NType =
2185 (MachO->is64Bit() ? MachO->getSymbol64TableEntry(SymDRI).n_type
2186 : MachO->getSymbolTableEntry(SymDRI).n_type);
2187 if (NType & MachO::N_STAB)
2188 IsSTAB = true;
2189 }
2190 section_iterator Section = IsSTAB
2191 ? O.section_end()
2192 : unwrapOrError(Symbol.getSection(), FileName,
2193 ArchiveName, ArchitectureName);
2194
2195 StringRef Name;
2196 if (Type == SymbolRef::ST_Debug && Section != O.section_end()) {
2197 if (Expected<StringRef> NameOrErr = Section->getName())
2198 Name = *NameOrErr;
2199 else
2200 consumeError(NameOrErr.takeError());
2201
2202 } else {
2203 Name = unwrapOrError(Symbol.getName(), FileName, ArchiveName,
2204 ArchitectureName);
2205 }
2206
2207 bool Global = Flags & SymbolRef::SF_Global;
2208 bool Weak = Flags & SymbolRef::SF_Weak;
2209 bool Absolute = Flags & SymbolRef::SF_Absolute;
2210 bool Common = Flags & SymbolRef::SF_Common;
2211 bool Hidden = Flags & SymbolRef::SF_Hidden;
2212
2213 char GlobLoc = ' ';
2214 if ((Section != O.section_end() || Absolute) && !Weak)
2215 GlobLoc = Global ? 'g' : 'l';
2216 char IFunc = ' ';
2217 if (O.isELF()) {
2218 if (ELFSymbolRef(Symbol).getELFType() == ELF::STT_GNU_IFUNC)
2219 IFunc = 'i';
2220 if (ELFSymbolRef(Symbol).getBinding() == ELF::STB_GNU_UNIQUE)
2221 GlobLoc = 'u';
2222 }
2223
2224 char Debug = ' ';
2225 if (DumpDynamic)
2226 Debug = 'D';
2227 else if (Type == SymbolRef::ST_Debug || Type == SymbolRef::ST_File)
2228 Debug = 'd';
2229
2230 char FileFunc = ' ';
2231 if (Type == SymbolRef::ST_File)
2232 FileFunc = 'f';
2233 else if (Type == SymbolRef::ST_Function)
2234 FileFunc = 'F';
2235 else if (Type == SymbolRef::ST_Data)
2236 FileFunc = 'O';
2237
2238 const char *Fmt = O.getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
2239
2240 outs() << format(Fmt, Address) << " "
2241 << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' '
2242 << (Weak ? 'w' : ' ') // Weak?
2243 << ' ' // Constructor. Not supported yet.
2244 << ' ' // Warning. Not supported yet.
2245 << IFunc // Indirect reference to another symbol.
2246 << Debug // Debugging (d) or dynamic (D) symbol.
2247 << FileFunc // Name of function (F), file (f) or object (O).
2248 << ' ';
2249 if (Absolute) {
2250 outs() << "*ABS*";
2251 } else if (Common) {
2252 outs() << "*COM*";
2253 } else if (Section == O.section_end()) {
2254 if (O.isXCOFF()) {
2255 XCOFFSymbolRef XCOFFSym = cast<const XCOFFObjectFile>(O).toSymbolRef(
2256 Symbol.getRawDataRefImpl());
2257 if (XCOFF::N_DEBUG == XCOFFSym.getSectionNumber())
2258 outs() << "*DEBUG*";
2259 else
2260 outs() << "*UND*";
2261 } else
2262 outs() << "*UND*";
2263 } else {
2264 StringRef SegmentName = getSegmentName(MachO, *Section);
2265 if (!SegmentName.empty())
2266 outs() << SegmentName << ",";
2267 StringRef SectionName = unwrapOrError(Section->getName(), FileName);
2268 outs() << SectionName;
2269 if (O.isXCOFF()) {
2270 Optional<SymbolRef> SymRef =
2271 getXCOFFSymbolContainingSymbolRef(cast<XCOFFObjectFile>(O), Symbol);
2272 if (SymRef) {
2273
2274 Expected<StringRef> NameOrErr = SymRef->getName();
2275
2276 if (NameOrErr) {
2277 outs() << " (csect:";
2278 std::string SymName(NameOrErr.get());
2279
2280 if (Demangle)
2281 SymName = demangle(SymName);
2282
2283 if (SymbolDescription)
2284 SymName = getXCOFFSymbolDescription(
2285 createSymbolInfo(O, SymRef.value()), SymName);
2286
2287 outs() << ' ' << SymName;
2288 outs() << ") ";
2289 } else
2290 reportWarning(toString(NameOrErr.takeError()), FileName);
2291 }
2292 }
2293 }
2294
2295 if (Common)
2296 outs() << '\t' << format(Fmt, static_cast<uint64_t>(Symbol.getAlignment()));
2297 else if (O.isXCOFF())
2298 outs() << '\t'
2299 << format(Fmt, cast<XCOFFObjectFile>(O).getSymbolSize(
2300 Symbol.getRawDataRefImpl()));
2301 else if (O.isELF())
2302 outs() << '\t' << format(Fmt, ELFSymbolRef(Symbol).getSize());
2303
2304 if (O.isELF()) {
2305 if (!SymbolVersions.empty()) {
2306 const VersionEntry &Ver =
2307 SymbolVersions[Symbol.getRawDataRefImpl().d.b - 1];
2308 std::string Str;
2309 if (!Ver.Name.empty())
2310 Str = Ver.IsVerDef ? ' ' + Ver.Name : '(' + Ver.Name + ')';
2311 outs() << ' ' << left_justify(Str, 12);
2312 }
2313
2314 uint8_t Other = ELFSymbolRef(Symbol).getOther();
2315 switch (Other) {
2316 case ELF::STV_DEFAULT:
2317 break;
2318 case ELF::STV_INTERNAL:
2319 outs() << " .internal";
2320 break;
2321 case ELF::STV_HIDDEN:
2322 outs() << " .hidden";
2323 break;
2324 case ELF::STV_PROTECTED:
2325 outs() << " .protected";
2326 break;
2327 default:
2328 outs() << format(" 0x%02x", Other);
2329 break;
2330 }
2331 } else if (Hidden) {
2332 outs() << " .hidden";
2333 }
2334
2335 std::string SymName(Name);
2336 if (Demangle)
2337 SymName = demangle(SymName);
2338
2339 if (O.isXCOFF() && SymbolDescription)
2340 SymName = getXCOFFSymbolDescription(createSymbolInfo(O, Symbol), SymName);
2341
2342 outs() << ' ' << SymName << '\n';
2343 }
2344
printUnwindInfo(const ObjectFile * O)2345 static void printUnwindInfo(const ObjectFile *O) {
2346 outs() << "Unwind info:\n\n";
2347
2348 if (const COFFObjectFile *Coff = dyn_cast<COFFObjectFile>(O))
2349 printCOFFUnwindInfo(Coff);
2350 else if (const MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(O))
2351 printMachOUnwindInfo(MachO);
2352 else
2353 // TODO: Extract DWARF dump tool to objdump.
2354 WithColor::error(errs(), ToolName)
2355 << "This operation is only currently supported "
2356 "for COFF and MachO object files.\n";
2357 }
2358
2359 /// Dump the raw contents of the __clangast section so the output can be piped
2360 /// into llvm-bcanalyzer.
printRawClangAST(const ObjectFile * Obj)2361 static void printRawClangAST(const ObjectFile *Obj) {
2362 if (outs().is_displayed()) {
2363 WithColor::error(errs(), ToolName)
2364 << "The -raw-clang-ast option will dump the raw binary contents of "
2365 "the clang ast section.\n"
2366 "Please redirect the output to a file or another program such as "
2367 "llvm-bcanalyzer.\n";
2368 return;
2369 }
2370
2371 StringRef ClangASTSectionName("__clangast");
2372 if (Obj->isCOFF()) {
2373 ClangASTSectionName = "clangast";
2374 }
2375
2376 Optional<object::SectionRef> ClangASTSection;
2377 for (auto Sec : ToolSectionFilter(*Obj)) {
2378 StringRef Name;
2379 if (Expected<StringRef> NameOrErr = Sec.getName())
2380 Name = *NameOrErr;
2381 else
2382 consumeError(NameOrErr.takeError());
2383
2384 if (Name == ClangASTSectionName) {
2385 ClangASTSection = Sec;
2386 break;
2387 }
2388 }
2389 if (!ClangASTSection)
2390 return;
2391
2392 StringRef ClangASTContents =
2393 unwrapOrError(ClangASTSection.value().getContents(), Obj->getFileName());
2394 outs().write(ClangASTContents.data(), ClangASTContents.size());
2395 }
2396
printFaultMaps(const ObjectFile * Obj)2397 static void printFaultMaps(const ObjectFile *Obj) {
2398 StringRef FaultMapSectionName;
2399
2400 if (Obj->isELF()) {
2401 FaultMapSectionName = ".llvm_faultmaps";
2402 } else if (Obj->isMachO()) {
2403 FaultMapSectionName = "__llvm_faultmaps";
2404 } else {
2405 WithColor::error(errs(), ToolName)
2406 << "This operation is only currently supported "
2407 "for ELF and Mach-O executable files.\n";
2408 return;
2409 }
2410
2411 Optional<object::SectionRef> FaultMapSection;
2412
2413 for (auto Sec : ToolSectionFilter(*Obj)) {
2414 StringRef Name;
2415 if (Expected<StringRef> NameOrErr = Sec.getName())
2416 Name = *NameOrErr;
2417 else
2418 consumeError(NameOrErr.takeError());
2419
2420 if (Name == FaultMapSectionName) {
2421 FaultMapSection = Sec;
2422 break;
2423 }
2424 }
2425
2426 outs() << "FaultMap table:\n";
2427
2428 if (!FaultMapSection) {
2429 outs() << "<not found>\n";
2430 return;
2431 }
2432
2433 StringRef FaultMapContents =
2434 unwrapOrError(FaultMapSection->getContents(), Obj->getFileName());
2435 FaultMapParser FMP(FaultMapContents.bytes_begin(),
2436 FaultMapContents.bytes_end());
2437
2438 outs() << FMP;
2439 }
2440
printPrivateFileHeaders(const ObjectFile * O,bool OnlyFirst)2441 static void printPrivateFileHeaders(const ObjectFile *O, bool OnlyFirst) {
2442 if (O->isELF()) {
2443 printELFFileHeader(O);
2444 printELFDynamicSection(O);
2445 printELFSymbolVersionInfo(O);
2446 return;
2447 }
2448 if (O->isCOFF())
2449 return printCOFFFileHeader(cast<object::COFFObjectFile>(*O));
2450 if (O->isWasm())
2451 return printWasmFileHeader(O);
2452 if (O->isMachO()) {
2453 printMachOFileHeader(O);
2454 if (!OnlyFirst)
2455 printMachOLoadCommands(O);
2456 return;
2457 }
2458 reportError(O->getFileName(), "Invalid/Unsupported object file format");
2459 }
2460
printFileHeaders(const ObjectFile * O)2461 static void printFileHeaders(const ObjectFile *O) {
2462 if (!O->isELF() && !O->isCOFF())
2463 reportError(O->getFileName(), "Invalid/Unsupported object file format");
2464
2465 Triple::ArchType AT = O->getArch();
2466 outs() << "architecture: " << Triple::getArchTypeName(AT) << "\n";
2467 uint64_t Address = unwrapOrError(O->getStartAddress(), O->getFileName());
2468
2469 StringRef Fmt = O->getBytesInAddress() > 4 ? "%016" PRIx64 : "%08" PRIx64;
2470 outs() << "start address: "
2471 << "0x" << format(Fmt.data(), Address) << "\n";
2472 }
2473
printArchiveChild(StringRef Filename,const Archive::Child & C)2474 static void printArchiveChild(StringRef Filename, const Archive::Child &C) {
2475 Expected<sys::fs::perms> ModeOrErr = C.getAccessMode();
2476 if (!ModeOrErr) {
2477 WithColor::error(errs(), ToolName) << "ill-formed archive entry.\n";
2478 consumeError(ModeOrErr.takeError());
2479 return;
2480 }
2481 sys::fs::perms Mode = ModeOrErr.get();
2482 outs() << ((Mode & sys::fs::owner_read) ? "r" : "-");
2483 outs() << ((Mode & sys::fs::owner_write) ? "w" : "-");
2484 outs() << ((Mode & sys::fs::owner_exe) ? "x" : "-");
2485 outs() << ((Mode & sys::fs::group_read) ? "r" : "-");
2486 outs() << ((Mode & sys::fs::group_write) ? "w" : "-");
2487 outs() << ((Mode & sys::fs::group_exe) ? "x" : "-");
2488 outs() << ((Mode & sys::fs::others_read) ? "r" : "-");
2489 outs() << ((Mode & sys::fs::others_write) ? "w" : "-");
2490 outs() << ((Mode & sys::fs::others_exe) ? "x" : "-");
2491
2492 outs() << " ";
2493
2494 outs() << format("%d/%d %6" PRId64 " ", unwrapOrError(C.getUID(), Filename),
2495 unwrapOrError(C.getGID(), Filename),
2496 unwrapOrError(C.getRawSize(), Filename));
2497
2498 StringRef RawLastModified = C.getRawLastModified();
2499 unsigned Seconds;
2500 if (RawLastModified.getAsInteger(10, Seconds))
2501 outs() << "(date: \"" << RawLastModified
2502 << "\" contains non-decimal chars) ";
2503 else {
2504 // Since ctime(3) returns a 26 character string of the form:
2505 // "Sun Sep 16 01:03:52 1973\n\0"
2506 // just print 24 characters.
2507 time_t t = Seconds;
2508 outs() << format("%.24s ", ctime(&t));
2509 }
2510
2511 StringRef Name = "";
2512 Expected<StringRef> NameOrErr = C.getName();
2513 if (!NameOrErr) {
2514 consumeError(NameOrErr.takeError());
2515 Name = unwrapOrError(C.getRawName(), Filename);
2516 } else {
2517 Name = NameOrErr.get();
2518 }
2519 outs() << Name << "\n";
2520 }
2521
2522 // For ELF only now.
shouldWarnForInvalidStartStopAddress(ObjectFile * Obj)2523 static bool shouldWarnForInvalidStartStopAddress(ObjectFile *Obj) {
2524 if (const auto *Elf = dyn_cast<ELFObjectFileBase>(Obj)) {
2525 if (Elf->getEType() != ELF::ET_REL)
2526 return true;
2527 }
2528 return false;
2529 }
2530
checkForInvalidStartStopAddress(ObjectFile * Obj,uint64_t Start,uint64_t Stop)2531 static void checkForInvalidStartStopAddress(ObjectFile *Obj,
2532 uint64_t Start, uint64_t Stop) {
2533 if (!shouldWarnForInvalidStartStopAddress(Obj))
2534 return;
2535
2536 for (const SectionRef &Section : Obj->sections())
2537 if (ELFSectionRef(Section).getFlags() & ELF::SHF_ALLOC) {
2538 uint64_t BaseAddr = Section.getAddress();
2539 uint64_t Size = Section.getSize();
2540 if ((Start < BaseAddr + Size) && Stop > BaseAddr)
2541 return;
2542 }
2543
2544 if (!HasStartAddressFlag)
2545 reportWarning("no section has address less than 0x" +
2546 Twine::utohexstr(Stop) + " specified by --stop-address",
2547 Obj->getFileName());
2548 else if (!HasStopAddressFlag)
2549 reportWarning("no section has address greater than or equal to 0x" +
2550 Twine::utohexstr(Start) + " specified by --start-address",
2551 Obj->getFileName());
2552 else
2553 reportWarning("no section overlaps the range [0x" +
2554 Twine::utohexstr(Start) + ",0x" + Twine::utohexstr(Stop) +
2555 ") specified by --start-address/--stop-address",
2556 Obj->getFileName());
2557 }
2558
dumpObject(ObjectFile * O,const Archive * A=nullptr,const Archive::Child * C=nullptr)2559 static void dumpObject(ObjectFile *O, const Archive *A = nullptr,
2560 const Archive::Child *C = nullptr) {
2561 // Avoid other output when using a raw option.
2562 if (!RawClangAST) {
2563 outs() << '\n';
2564 if (A)
2565 outs() << A->getFileName() << "(" << O->getFileName() << ")";
2566 else
2567 outs() << O->getFileName();
2568 outs() << ":\tfile format " << O->getFileFormatName().lower() << "\n";
2569 }
2570
2571 if (HasStartAddressFlag || HasStopAddressFlag)
2572 checkForInvalidStartStopAddress(O, StartAddress, StopAddress);
2573
2574 // Note: the order here matches GNU objdump for compatability.
2575 StringRef ArchiveName = A ? A->getFileName() : "";
2576 if (ArchiveHeaders && !MachOOpt && C)
2577 printArchiveChild(ArchiveName, *C);
2578 if (FileHeaders)
2579 printFileHeaders(O);
2580 if (PrivateHeaders || FirstPrivateHeader)
2581 printPrivateFileHeaders(O, FirstPrivateHeader);
2582 if (SectionHeaders)
2583 printSectionHeaders(*O);
2584 if (SymbolTable)
2585 printSymbolTable(*O, ArchiveName);
2586 if (DynamicSymbolTable)
2587 printSymbolTable(*O, ArchiveName, /*ArchitectureName=*/"",
2588 /*DumpDynamic=*/true);
2589 if (DwarfDumpType != DIDT_Null) {
2590 std::unique_ptr<DIContext> DICtx = DWARFContext::create(*O);
2591 // Dump the complete DWARF structure.
2592 DIDumpOptions DumpOpts;
2593 DumpOpts.DumpType = DwarfDumpType;
2594 DICtx->dump(outs(), DumpOpts);
2595 }
2596 if (Relocations && !Disassemble)
2597 printRelocations(O);
2598 if (DynamicRelocations)
2599 printDynamicRelocations(O);
2600 if (SectionContents)
2601 printSectionContents(O);
2602 if (Disassemble)
2603 disassembleObject(O, Relocations);
2604 if (UnwindInfo)
2605 printUnwindInfo(O);
2606
2607 // Mach-O specific options:
2608 if (ExportsTrie)
2609 printExportsTrie(O);
2610 if (Rebase)
2611 printRebaseTable(O);
2612 if (Bind)
2613 printBindTable(O);
2614 if (LazyBind)
2615 printLazyBindTable(O);
2616 if (WeakBind)
2617 printWeakBindTable(O);
2618
2619 // Other special sections:
2620 if (RawClangAST)
2621 printRawClangAST(O);
2622 if (FaultMapSection)
2623 printFaultMaps(O);
2624 if (Offloading)
2625 dumpOffloadBinary(*O);
2626 }
2627
dumpObject(const COFFImportFile * I,const Archive * A,const Archive::Child * C=nullptr)2628 static void dumpObject(const COFFImportFile *I, const Archive *A,
2629 const Archive::Child *C = nullptr) {
2630 StringRef ArchiveName = A ? A->getFileName() : "";
2631
2632 // Avoid other output when using a raw option.
2633 if (!RawClangAST)
2634 outs() << '\n'
2635 << ArchiveName << "(" << I->getFileName() << ")"
2636 << ":\tfile format COFF-import-file"
2637 << "\n\n";
2638
2639 if (ArchiveHeaders && !MachOOpt && C)
2640 printArchiveChild(ArchiveName, *C);
2641 if (SymbolTable)
2642 printCOFFSymbolTable(*I);
2643 }
2644
2645 /// Dump each object file in \a a;
dumpArchive(const Archive * A)2646 static void dumpArchive(const Archive *A) {
2647 Error Err = Error::success();
2648 unsigned I = -1;
2649 for (auto &C : A->children(Err)) {
2650 ++I;
2651 Expected<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary();
2652 if (!ChildOrErr) {
2653 if (auto E = isNotObjectErrorInvalidFileType(ChildOrErr.takeError()))
2654 reportError(std::move(E), getFileNameForError(C, I), A->getFileName());
2655 continue;
2656 }
2657 if (ObjectFile *O = dyn_cast<ObjectFile>(&*ChildOrErr.get()))
2658 dumpObject(O, A, &C);
2659 else if (COFFImportFile *I = dyn_cast<COFFImportFile>(&*ChildOrErr.get()))
2660 dumpObject(I, A, &C);
2661 else
2662 reportError(errorCodeToError(object_error::invalid_file_type),
2663 A->getFileName());
2664 }
2665 if (Err)
2666 reportError(std::move(Err), A->getFileName());
2667 }
2668
2669 /// Open file and figure out how to dump it.
dumpInput(StringRef file)2670 static void dumpInput(StringRef file) {
2671 // If we are using the Mach-O specific object file parser, then let it parse
2672 // the file and process the command line options. So the -arch flags can
2673 // be used to select specific slices, etc.
2674 if (MachOOpt) {
2675 parseInputMachO(file);
2676 return;
2677 }
2678
2679 // Attempt to open the binary.
2680 OwningBinary<Binary> OBinary = unwrapOrError(createBinary(file), file);
2681 Binary &Binary = *OBinary.getBinary();
2682
2683 if (Archive *A = dyn_cast<Archive>(&Binary))
2684 dumpArchive(A);
2685 else if (ObjectFile *O = dyn_cast<ObjectFile>(&Binary))
2686 dumpObject(O);
2687 else if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Binary))
2688 parseInputMachO(UB);
2689 else if (OffloadBinary *OB = dyn_cast<OffloadBinary>(&Binary))
2690 dumpOffloadSections(*OB);
2691 else
2692 reportError(errorCodeToError(object_error::invalid_file_type), file);
2693 }
2694
2695 template <typename T>
parseIntArg(const llvm::opt::InputArgList & InputArgs,int ID,T & Value)2696 static void parseIntArg(const llvm::opt::InputArgList &InputArgs, int ID,
2697 T &Value) {
2698 if (const opt::Arg *A = InputArgs.getLastArg(ID)) {
2699 StringRef V(A->getValue());
2700 if (!llvm::to_integer(V, Value, 0)) {
2701 reportCmdLineError(A->getSpelling() +
2702 ": expected a non-negative integer, but got '" + V +
2703 "'");
2704 }
2705 }
2706 }
2707
invalidArgValue(const opt::Arg * A)2708 static void invalidArgValue(const opt::Arg *A) {
2709 reportCmdLineError("'" + StringRef(A->getValue()) +
2710 "' is not a valid value for '" + A->getSpelling() + "'");
2711 }
2712
2713 static std::vector<std::string>
commaSeparatedValues(const llvm::opt::InputArgList & InputArgs,int ID)2714 commaSeparatedValues(const llvm::opt::InputArgList &InputArgs, int ID) {
2715 std::vector<std::string> Values;
2716 for (StringRef Value : InputArgs.getAllArgValues(ID)) {
2717 llvm::SmallVector<StringRef, 2> SplitValues;
2718 llvm::SplitString(Value, SplitValues, ",");
2719 for (StringRef SplitValue : SplitValues)
2720 Values.push_back(SplitValue.str());
2721 }
2722 return Values;
2723 }
2724
parseOtoolOptions(const llvm::opt::InputArgList & InputArgs)2725 static void parseOtoolOptions(const llvm::opt::InputArgList &InputArgs) {
2726 MachOOpt = true;
2727 FullLeadingAddr = true;
2728 PrintImmHex = true;
2729
2730 ArchName = InputArgs.getLastArgValue(OTOOL_arch).str();
2731 LinkOptHints = InputArgs.hasArg(OTOOL_C);
2732 if (InputArgs.hasArg(OTOOL_d))
2733 FilterSections.push_back("__DATA,__data");
2734 DylibId = InputArgs.hasArg(OTOOL_D);
2735 UniversalHeaders = InputArgs.hasArg(OTOOL_f);
2736 DataInCode = InputArgs.hasArg(OTOOL_G);
2737 FirstPrivateHeader = InputArgs.hasArg(OTOOL_h);
2738 IndirectSymbols = InputArgs.hasArg(OTOOL_I);
2739 ShowRawInsn = InputArgs.hasArg(OTOOL_j);
2740 PrivateHeaders = InputArgs.hasArg(OTOOL_l);
2741 DylibsUsed = InputArgs.hasArg(OTOOL_L);
2742 MCPU = InputArgs.getLastArgValue(OTOOL_mcpu_EQ).str();
2743 ObjcMetaData = InputArgs.hasArg(OTOOL_o);
2744 DisSymName = InputArgs.getLastArgValue(OTOOL_p).str();
2745 InfoPlist = InputArgs.hasArg(OTOOL_P);
2746 Relocations = InputArgs.hasArg(OTOOL_r);
2747 if (const Arg *A = InputArgs.getLastArg(OTOOL_s)) {
2748 auto Filter = (A->getValue(0) + StringRef(",") + A->getValue(1)).str();
2749 FilterSections.push_back(Filter);
2750 }
2751 if (InputArgs.hasArg(OTOOL_t))
2752 FilterSections.push_back("__TEXT,__text");
2753 Verbose = InputArgs.hasArg(OTOOL_v) || InputArgs.hasArg(OTOOL_V) ||
2754 InputArgs.hasArg(OTOOL_o);
2755 SymbolicOperands = InputArgs.hasArg(OTOOL_V);
2756 if (InputArgs.hasArg(OTOOL_x))
2757 FilterSections.push_back(",__text");
2758 LeadingAddr = LeadingHeaders = !InputArgs.hasArg(OTOOL_X);
2759
2760 InputFilenames = InputArgs.getAllArgValues(OTOOL_INPUT);
2761 if (InputFilenames.empty())
2762 reportCmdLineError("no input file");
2763
2764 for (const Arg *A : InputArgs) {
2765 const Option &O = A->getOption();
2766 if (O.getGroup().isValid() && O.getGroup().getID() == OTOOL_grp_obsolete) {
2767 reportCmdLineWarning(O.getPrefixedName() +
2768 " is obsolete and not implemented");
2769 }
2770 }
2771 }
2772
parseObjdumpOptions(const llvm::opt::InputArgList & InputArgs)2773 static void parseObjdumpOptions(const llvm::opt::InputArgList &InputArgs) {
2774 parseIntArg(InputArgs, OBJDUMP_adjust_vma_EQ, AdjustVMA);
2775 AllHeaders = InputArgs.hasArg(OBJDUMP_all_headers);
2776 ArchName = InputArgs.getLastArgValue(OBJDUMP_arch_name_EQ).str();
2777 ArchiveHeaders = InputArgs.hasArg(OBJDUMP_archive_headers);
2778 Demangle = InputArgs.hasArg(OBJDUMP_demangle);
2779 Disassemble = InputArgs.hasArg(OBJDUMP_disassemble);
2780 DisassembleAll = InputArgs.hasArg(OBJDUMP_disassemble_all);
2781 SymbolDescription = InputArgs.hasArg(OBJDUMP_symbol_description);
2782 DisassembleSymbols =
2783 commaSeparatedValues(InputArgs, OBJDUMP_disassemble_symbols_EQ);
2784 DisassembleZeroes = InputArgs.hasArg(OBJDUMP_disassemble_zeroes);
2785 if (const opt::Arg *A = InputArgs.getLastArg(OBJDUMP_dwarf_EQ)) {
2786 DwarfDumpType = StringSwitch<DIDumpType>(A->getValue())
2787 .Case("frames", DIDT_DebugFrame)
2788 .Default(DIDT_Null);
2789 if (DwarfDumpType == DIDT_Null)
2790 invalidArgValue(A);
2791 }
2792 DynamicRelocations = InputArgs.hasArg(OBJDUMP_dynamic_reloc);
2793 FaultMapSection = InputArgs.hasArg(OBJDUMP_fault_map_section);
2794 Offloading = InputArgs.hasArg(OBJDUMP_offloading);
2795 FileHeaders = InputArgs.hasArg(OBJDUMP_file_headers);
2796 SectionContents = InputArgs.hasArg(OBJDUMP_full_contents);
2797 PrintLines = InputArgs.hasArg(OBJDUMP_line_numbers);
2798 InputFilenames = InputArgs.getAllArgValues(OBJDUMP_INPUT);
2799 MachOOpt = InputArgs.hasArg(OBJDUMP_macho);
2800 MCPU = InputArgs.getLastArgValue(OBJDUMP_mcpu_EQ).str();
2801 MAttrs = commaSeparatedValues(InputArgs, OBJDUMP_mattr_EQ);
2802 ShowRawInsn = !InputArgs.hasArg(OBJDUMP_no_show_raw_insn);
2803 LeadingAddr = !InputArgs.hasArg(OBJDUMP_no_leading_addr);
2804 RawClangAST = InputArgs.hasArg(OBJDUMP_raw_clang_ast);
2805 Relocations = InputArgs.hasArg(OBJDUMP_reloc);
2806 PrintImmHex =
2807 InputArgs.hasFlag(OBJDUMP_print_imm_hex, OBJDUMP_no_print_imm_hex, false);
2808 PrivateHeaders = InputArgs.hasArg(OBJDUMP_private_headers);
2809 FilterSections = InputArgs.getAllArgValues(OBJDUMP_section_EQ);
2810 SectionHeaders = InputArgs.hasArg(OBJDUMP_section_headers);
2811 ShowLMA = InputArgs.hasArg(OBJDUMP_show_lma);
2812 PrintSource = InputArgs.hasArg(OBJDUMP_source);
2813 parseIntArg(InputArgs, OBJDUMP_start_address_EQ, StartAddress);
2814 HasStartAddressFlag = InputArgs.hasArg(OBJDUMP_start_address_EQ);
2815 parseIntArg(InputArgs, OBJDUMP_stop_address_EQ, StopAddress);
2816 HasStopAddressFlag = InputArgs.hasArg(OBJDUMP_stop_address_EQ);
2817 SymbolTable = InputArgs.hasArg(OBJDUMP_syms);
2818 SymbolizeOperands = InputArgs.hasArg(OBJDUMP_symbolize_operands);
2819 DynamicSymbolTable = InputArgs.hasArg(OBJDUMP_dynamic_syms);
2820 TripleName = InputArgs.getLastArgValue(OBJDUMP_triple_EQ).str();
2821 UnwindInfo = InputArgs.hasArg(OBJDUMP_unwind_info);
2822 Wide = InputArgs.hasArg(OBJDUMP_wide);
2823 Prefix = InputArgs.getLastArgValue(OBJDUMP_prefix).str();
2824 parseIntArg(InputArgs, OBJDUMP_prefix_strip, PrefixStrip);
2825 if (const opt::Arg *A = InputArgs.getLastArg(OBJDUMP_debug_vars_EQ)) {
2826 DbgVariables = StringSwitch<DebugVarsFormat>(A->getValue())
2827 .Case("ascii", DVASCII)
2828 .Case("unicode", DVUnicode)
2829 .Default(DVInvalid);
2830 if (DbgVariables == DVInvalid)
2831 invalidArgValue(A);
2832 }
2833 parseIntArg(InputArgs, OBJDUMP_debug_vars_indent_EQ, DbgIndent);
2834
2835 parseMachOOptions(InputArgs);
2836
2837 // Parse -M (--disassembler-options) and deprecated
2838 // --x86-asm-syntax={att,intel}.
2839 //
2840 // Note, for x86, the asm dialect (AssemblerDialect) is initialized when the
2841 // MCAsmInfo is constructed. MCInstPrinter::applyTargetSpecificCLOption is
2842 // called too late. For now we have to use the internal cl::opt option.
2843 const char *AsmSyntax = nullptr;
2844 for (const auto *A : InputArgs.filtered(OBJDUMP_disassembler_options_EQ,
2845 OBJDUMP_x86_asm_syntax_att,
2846 OBJDUMP_x86_asm_syntax_intel)) {
2847 switch (A->getOption().getID()) {
2848 case OBJDUMP_x86_asm_syntax_att:
2849 AsmSyntax = "--x86-asm-syntax=att";
2850 continue;
2851 case OBJDUMP_x86_asm_syntax_intel:
2852 AsmSyntax = "--x86-asm-syntax=intel";
2853 continue;
2854 }
2855
2856 SmallVector<StringRef, 2> Values;
2857 llvm::SplitString(A->getValue(), Values, ",");
2858 for (StringRef V : Values) {
2859 if (V == "att")
2860 AsmSyntax = "--x86-asm-syntax=att";
2861 else if (V == "intel")
2862 AsmSyntax = "--x86-asm-syntax=intel";
2863 else
2864 DisassemblerOptions.push_back(V.str());
2865 }
2866 }
2867 if (AsmSyntax) {
2868 const char *Argv[] = {"llvm-objdump", AsmSyntax};
2869 llvm::cl::ParseCommandLineOptions(2, Argv);
2870 }
2871
2872 // objdump defaults to a.out if no filenames specified.
2873 if (InputFilenames.empty())
2874 InputFilenames.push_back("a.out");
2875 }
2876
main(int argc,char ** argv)2877 int main(int argc, char **argv) {
2878 using namespace llvm;
2879 InitLLVM X(argc, argv);
2880
2881 ToolName = argv[0];
2882 std::unique_ptr<CommonOptTable> T;
2883 OptSpecifier Unknown, HelpFlag, HelpHiddenFlag, VersionFlag;
2884
2885 StringRef Stem = sys::path::stem(ToolName);
2886 auto Is = [=](StringRef Tool) {
2887 // We need to recognize the following filenames:
2888 //
2889 // llvm-objdump -> objdump
2890 // llvm-otool-10.exe -> otool
2891 // powerpc64-unknown-freebsd13-objdump -> objdump
2892 auto I = Stem.rfind_insensitive(Tool);
2893 return I != StringRef::npos &&
2894 (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()]));
2895 };
2896 if (Is("otool")) {
2897 T = std::make_unique<OtoolOptTable>();
2898 Unknown = OTOOL_UNKNOWN;
2899 HelpFlag = OTOOL_help;
2900 HelpHiddenFlag = OTOOL_help_hidden;
2901 VersionFlag = OTOOL_version;
2902 } else {
2903 T = std::make_unique<ObjdumpOptTable>();
2904 Unknown = OBJDUMP_UNKNOWN;
2905 HelpFlag = OBJDUMP_help;
2906 HelpHiddenFlag = OBJDUMP_help_hidden;
2907 VersionFlag = OBJDUMP_version;
2908 }
2909
2910 BumpPtrAllocator A;
2911 StringSaver Saver(A);
2912 opt::InputArgList InputArgs =
2913 T->parseArgs(argc, argv, Unknown, Saver,
2914 [&](StringRef Msg) { reportCmdLineError(Msg); });
2915
2916 if (InputArgs.size() == 0 || InputArgs.hasArg(HelpFlag)) {
2917 T->printHelp(ToolName);
2918 return 0;
2919 }
2920 if (InputArgs.hasArg(HelpHiddenFlag)) {
2921 T->printHelp(ToolName, /*ShowHidden=*/true);
2922 return 0;
2923 }
2924
2925 // Initialize targets and assembly printers/parsers.
2926 InitializeAllTargetInfos();
2927 InitializeAllTargetMCs();
2928 InitializeAllDisassemblers();
2929
2930 if (InputArgs.hasArg(VersionFlag)) {
2931 cl::PrintVersionMessage();
2932 if (!Is("otool")) {
2933 outs() << '\n';
2934 TargetRegistry::printRegisteredTargetsForVersion(outs());
2935 }
2936 return 0;
2937 }
2938
2939 if (Is("otool"))
2940 parseOtoolOptions(InputArgs);
2941 else
2942 parseObjdumpOptions(InputArgs);
2943
2944 if (StartAddress >= StopAddress)
2945 reportCmdLineError("start address should be less than stop address");
2946
2947 // Removes trailing separators from prefix.
2948 while (!Prefix.empty() && sys::path::is_separator(Prefix.back()))
2949 Prefix.pop_back();
2950
2951 if (AllHeaders)
2952 ArchiveHeaders = FileHeaders = PrivateHeaders = Relocations =
2953 SectionHeaders = SymbolTable = true;
2954
2955 if (DisassembleAll || PrintSource || PrintLines ||
2956 !DisassembleSymbols.empty())
2957 Disassemble = true;
2958
2959 if (!ArchiveHeaders && !Disassemble && DwarfDumpType == DIDT_Null &&
2960 !DynamicRelocations && !FileHeaders && !PrivateHeaders && !RawClangAST &&
2961 !Relocations && !SectionHeaders && !SectionContents && !SymbolTable &&
2962 !DynamicSymbolTable && !UnwindInfo && !FaultMapSection && !Offloading &&
2963 !(MachOOpt && (Bind || DataInCode || DyldInfo || DylibId || DylibsUsed ||
2964 ExportsTrie || FirstPrivateHeader || FunctionStarts ||
2965 IndirectSymbols || InfoPlist || LazyBind || LinkOptHints ||
2966 ObjcMetaData || Rebase || Rpaths || UniversalHeaders ||
2967 WeakBind || !FilterSections.empty()))) {
2968 T->printHelp(ToolName);
2969 return 2;
2970 }
2971
2972 DisasmSymbolSet.insert(DisassembleSymbols.begin(), DisassembleSymbols.end());
2973
2974 llvm::for_each(InputFilenames, dumpInput);
2975
2976 warnOnNoMatchForSections();
2977
2978 return EXIT_SUCCESS;
2979 }
2980