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