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