Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/tools/llvm-objdump/llvm-objdump.cpp
Warning:line 2066, column 33
Called C++ object pointer is null

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