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