Bug Summary

File:build/llvm-toolchain-snapshot-16~++20221003111214+1fa2019828ca/llvm/tools/llvm-objdump/llvm-objdump.cpp
Warning:line 1692, column 9
Value stored to 'Index' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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