Bug Summary

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