Bug Summary

File:llvm/tools/llvm-objdump/llvm-objdump.cpp
Warning:line 2057, 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-14~++20220125101009+ceec4383681c/build-llvm -resource-dir /usr/lib/llvm-14/lib/clang/14.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-14~++20220125101009+ceec4383681c/llvm/tools/llvm-objdump -I include -I /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/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-14/lib/clang/14.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-14~++20220125101009+ceec4383681c/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/= -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-14~++20220125101009+ceec4383681c/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/= -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-01-25-232935-20746-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/llvm/tools/llvm-objdump/llvm-objdump.cpp

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

/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/llvm/include/llvm/Object/Binary.h

1//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
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 file declares the Binary class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_OBJECT_BINARY_H
14#define LLVM_OBJECT_BINARY_H
15
16#include "llvm-c/Types.h"
17#include "llvm/ADT/Triple.h"
18#include "llvm/Object/Error.h"
19#include "llvm/Support/Error.h"
20#include "llvm/Support/MemoryBuffer.h"
21#include <algorithm>
22#include <memory>
23#include <utility>
24
25namespace llvm {
26
27class LLVMContext;
28class StringRef;
29
30namespace object {
31
32class Binary {
33private:
34 unsigned int TypeID;
35
36protected:
37 MemoryBufferRef Data;
38
39 Binary(unsigned int Type, MemoryBufferRef Source);
40
41 enum {
42 ID_Archive,
43 ID_MachOUniversalBinary,
44 ID_COFFImportFile,
45 ID_IR, // LLVM IR
46 ID_TapiUniversal, // Text-based Dynamic Library Stub file.
47 ID_TapiFile, // Text-based Dynamic Library Stub file.
48
49 ID_Minidump,
50
51 ID_WinRes, // Windows resource (.res) file.
52
53 // Object and children.
54 ID_StartObjects,
55 ID_COFF,
56
57 ID_XCOFF32, // AIX XCOFF 32-bit
58 ID_XCOFF64, // AIX XCOFF 64-bit
59
60 ID_ELF32L, // ELF 32-bit, little endian
61 ID_ELF32B, // ELF 32-bit, big endian
62 ID_ELF64L, // ELF 64-bit, little endian
63 ID_ELF64B, // ELF 64-bit, big endian
64
65 ID_MachO32L, // MachO 32-bit, little endian
66 ID_MachO32B, // MachO 32-bit, big endian
67 ID_MachO64L, // MachO 64-bit, little endian
68 ID_MachO64B, // MachO 64-bit, big endian
69
70 ID_Wasm,
71
72 ID_EndObjects
73 };
74
75 static inline unsigned int getELFType(bool isLE, bool is64Bits) {
76 if (isLE)
77 return is64Bits ? ID_ELF64L : ID_ELF32L;
78 else
79 return is64Bits ? ID_ELF64B : ID_ELF32B;
80 }
81
82 static unsigned int getMachOType(bool isLE, bool is64Bits) {
83 if (isLE)
84 return is64Bits ? ID_MachO64L : ID_MachO32L;
85 else
86 return is64Bits ? ID_MachO64B : ID_MachO32B;
87 }
88
89public:
90 Binary() = delete;
91 Binary(const Binary &other) = delete;
92 virtual ~Binary();
93
94 virtual Error initContent() { return Error::success(); };
95
96 StringRef getData() const;
97 StringRef getFileName() const;
98 MemoryBufferRef getMemoryBufferRef() const;
99
100 // Cast methods.
101 unsigned int getType() const { return TypeID; }
102
103 // Convenience methods
104 bool isObject() const {
105 return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
106 }
107
108 bool isSymbolic() const {
109 return isIR() || isObject() || isCOFFImportFile() || isTapiFile();
110 }
111
112 bool isArchive() const { return TypeID == ID_Archive; }
113
114 bool isMachOUniversalBinary() const {
115 return TypeID == ID_MachOUniversalBinary;
116 }
117
118 bool isTapiUniversal() const { return TypeID == ID_TapiUniversal; }
119
120 bool isELF() const {
121 return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
122 }
123
124 bool isMachO() const {
125 return TypeID >= ID_MachO32L && TypeID <= ID_MachO64B;
126 }
127
128 bool isCOFF() const {
129 return TypeID == ID_COFF;
130 }
131
132 bool isXCOFF() const { return TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64; }
31
Assuming field 'TypeID' is equal to ID_XCOFF32
32
Returning the value 1, which participates in a condition later
133
134 bool isWasm() const { return TypeID == ID_Wasm; }
135
136 bool isCOFFImportFile() const {
137 return TypeID == ID_COFFImportFile;
138 }
139
140 bool isIR() const {
141 return TypeID == ID_IR;
142 }
143
144 bool isMinidump() const { return TypeID == ID_Minidump; }
145
146 bool isTapiFile() const { return TypeID == ID_TapiFile; }
147
148 bool isLittleEndian() const {
149 return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
150 TypeID == ID_MachO32B || TypeID == ID_MachO64B ||
151 TypeID == ID_XCOFF32 || TypeID == ID_XCOFF64);
152 }
153
154 bool isWinRes() const { return TypeID == ID_WinRes; }
155
156 Triple::ObjectFormatType getTripleObjectFormat() const {
157 if (isCOFF())
158 return Triple::COFF;
159 if (isMachO())
160 return Triple::MachO;
161 if (isELF())
162 return Triple::ELF;
163 return Triple::UnknownObjectFormat;
164 }
165
166 static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
167 const uint64_t Size) {
168 if (Addr + Size < Addr || Addr + Size < Size ||
169 Addr + Size > reinterpret_cast<uintptr_t>(M.getBufferEnd()) ||
170 Addr < reinterpret_cast<uintptr_t>(M.getBufferStart())) {
171 return errorCodeToError(object_error::unexpected_eof);
172 }
173 return Error::success();
174 }
175};
176
177// Create wrappers for C Binding types (see CBindingWrapping.h).
178DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)inline Binary *unwrap(LLVMBinaryRef P) { return reinterpret_cast
<Binary*>(P); } inline LLVMBinaryRef wrap(const Binary *
P) { return reinterpret_cast<LLVMBinaryRef>(const_cast<
Binary*>(P)); } template<typename T> inline T *unwrap
(LLVMBinaryRef P) { return cast<T>(unwrap(P)); }
179
180/// Create a Binary from Source, autodetecting the file type.
181///
182/// @param Source The data to create the Binary from.
183Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
184 LLVMContext *Context = nullptr,
185 bool InitContent = true);
186
187template <typename T> class OwningBinary {
188 std::unique_ptr<T> Bin;
189 std::unique_ptr<MemoryBuffer> Buf;
190
191public:
192 OwningBinary();
193 OwningBinary(std::unique_ptr<T> Bin, std::unique_ptr<MemoryBuffer> Buf);
194 OwningBinary(OwningBinary<T>&& Other);
195 OwningBinary<T> &operator=(OwningBinary<T> &&Other);
196
197 std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>> takeBinary();
198
199 T* getBinary();
200 const T* getBinary() const;
201};
202
203template <typename T>
204OwningBinary<T>::OwningBinary(std::unique_ptr<T> Bin,
205 std::unique_ptr<MemoryBuffer> Buf)
206 : Bin(std::move(Bin)), Buf(std::move(Buf)) {}
207
208template <typename T> OwningBinary<T>::OwningBinary() = default;
209
210template <typename T>
211OwningBinary<T>::OwningBinary(OwningBinary &&Other)
212 : Bin(std::move(Other.Bin)), Buf(std::move(Other.Buf)) {}
213
214template <typename T>
215OwningBinary<T> &OwningBinary<T>::operator=(OwningBinary &&Other) {
216 Bin = std::move(Other.Bin);
217 Buf = std::move(Other.Buf);
218 return *this;
219}
220
221template <typename T>
222std::pair<std::unique_ptr<T>, std::unique_ptr<MemoryBuffer>>
223OwningBinary<T>::takeBinary() {
224 return std::make_pair(std::move(Bin), std::move(Buf));
225}
226
227template <typename T> T* OwningBinary<T>::getBinary() {
228 return Bin.get();
229}
230
231template <typename T> const T* OwningBinary<T>::getBinary() const {
232 return Bin.get();
233}
234
235Expected<OwningBinary<Binary>> createBinary(StringRef Path,
236 LLVMContext *Context = nullptr,
237 bool InitContent = true);
238
239} // end namespace object
240
241} // end namespace llvm
242
243#endif // LLVM_OBJECT_BINARY_H