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