1 //===- ELFDumper.cpp - ELF-specific dumper --------------------------------===// 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 /// \file 10 /// This file implements the ELF-specific dumper for llvm-readobj. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMEHABIPrinter.h" 15 #include "DwarfCFIEHPrinter.h" 16 #include "ObjDumper.h" 17 #include "StackMapPrinter.h" 18 #include "llvm-readobj.h" 19 #include "llvm/ADT/ArrayRef.h" 20 #include "llvm/ADT/BitVector.h" 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/ADT/DenseSet.h" 23 #include "llvm/ADT/MapVector.h" 24 #include "llvm/ADT/STLExtras.h" 25 #include "llvm/ADT/SmallString.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/ADT/StringRef.h" 29 #include "llvm/ADT/Twine.h" 30 #include "llvm/BinaryFormat/AMDGPUMetadataVerifier.h" 31 #include "llvm/BinaryFormat/ELF.h" 32 #include "llvm/BinaryFormat/MsgPackDocument.h" 33 #include "llvm/Demangle/Demangle.h" 34 #include "llvm/Object/Archive.h" 35 #include "llvm/Object/ELF.h" 36 #include "llvm/Object/ELFObjectFile.h" 37 #include "llvm/Object/ELFTypes.h" 38 #include "llvm/Object/Error.h" 39 #include "llvm/Object/ObjectFile.h" 40 #include "llvm/Object/RelocationResolver.h" 41 #include "llvm/Object/StackMapParser.h" 42 #include "llvm/Support/AArch64AttributeParser.h" 43 #include "llvm/Support/AMDGPUMetadata.h" 44 #include "llvm/Support/ARMAttributeParser.h" 45 #include "llvm/Support/ARMBuildAttributes.h" 46 #include "llvm/Support/Casting.h" 47 #include "llvm/Support/Compiler.h" 48 #include "llvm/Support/Endian.h" 49 #include "llvm/Support/ErrorHandling.h" 50 #include "llvm/Support/Format.h" 51 #include "llvm/Support/FormatVariadic.h" 52 #include "llvm/Support/FormattedStream.h" 53 #include "llvm/Support/HexagonAttributeParser.h" 54 #include "llvm/Support/LEB128.h" 55 #include "llvm/Support/MSP430AttributeParser.h" 56 #include "llvm/Support/MSP430Attributes.h" 57 #include "llvm/Support/MathExtras.h" 58 #include "llvm/Support/MipsABIFlags.h" 59 #include "llvm/Support/RISCVAttributeParser.h" 60 #include "llvm/Support/RISCVAttributes.h" 61 #include "llvm/Support/ScopedPrinter.h" 62 #include "llvm/Support/SystemZ/zOSSupport.h" 63 #include "llvm/Support/raw_ostream.h" 64 #include <algorithm> 65 #include <array> 66 #include <cinttypes> 67 #include <cstddef> 68 #include <cstdint> 69 #include <cstdlib> 70 #include <iterator> 71 #include <memory> 72 #include <optional> 73 #include <string> 74 #include <system_error> 75 #include <vector> 76 77 using namespace llvm; 78 using namespace llvm::object; 79 using namespace llvm::support; 80 using namespace ELF; 81 82 #define LLVM_READOBJ_ENUM_CASE(ns, enum) \ 83 case ns::enum: \ 84 return #enum; 85 86 #define ENUM_ENT(enum, altName) \ 87 { #enum, altName, ELF::enum } 88 89 #define ENUM_ENT_1(enum) \ 90 { #enum, #enum, ELF::enum } 91 92 namespace { 93 94 template <class ELFT> struct RelSymbol { 95 RelSymbol(const typename ELFT::Sym *S, StringRef N) 96 : Sym(S), Name(N.str()) {} 97 const typename ELFT::Sym *Sym; 98 std::string Name; 99 }; 100 101 /// Represents a contiguous uniform range in the file. We cannot just create a 102 /// range directly because when creating one of these from the .dynamic table 103 /// the size, entity size and virtual address are different entries in arbitrary 104 /// order (DT_REL, DT_RELSZ, DT_RELENT for example). 105 struct DynRegionInfo { 106 DynRegionInfo(const Binary &Owner, const ObjDumper &D) 107 : Obj(&Owner), Dumper(&D) {} 108 DynRegionInfo(const Binary &Owner, const ObjDumper &D, const uint8_t *A, 109 uint64_t S, uint64_t ES) 110 : Addr(A), Size(S), EntSize(ES), Obj(&Owner), Dumper(&D) {} 111 112 /// Address in current address space. 113 const uint8_t *Addr = nullptr; 114 /// Size in bytes of the region. 115 uint64_t Size = 0; 116 /// Size of each entity in the region. 117 uint64_t EntSize = 0; 118 119 /// Owner object. Used for error reporting. 120 const Binary *Obj; 121 /// Dumper used for error reporting. 122 const ObjDumper *Dumper; 123 /// Error prefix. Used for error reporting to provide more information. 124 std::string Context; 125 /// Region size name. Used for error reporting. 126 StringRef SizePrintName = "size"; 127 /// Entry size name. Used for error reporting. If this field is empty, errors 128 /// will not mention the entry size. 129 StringRef EntSizePrintName = "entry size"; 130 131 template <typename Type> ArrayRef<Type> getAsArrayRef() const { 132 const Type *Start = reinterpret_cast<const Type *>(Addr); 133 if (!Start) 134 return {Start, Start}; 135 136 const uint64_t Offset = 137 Addr - (const uint8_t *)Obj->getMemoryBufferRef().getBufferStart(); 138 const uint64_t ObjSize = Obj->getMemoryBufferRef().getBufferSize(); 139 140 if (Size > ObjSize - Offset) { 141 Dumper->reportUniqueWarning( 142 "unable to read data at 0x" + Twine::utohexstr(Offset) + 143 " of size 0x" + Twine::utohexstr(Size) + " (" + SizePrintName + 144 "): it goes past the end of the file of size 0x" + 145 Twine::utohexstr(ObjSize)); 146 return {Start, Start}; 147 } 148 149 if (EntSize == sizeof(Type) && (Size % EntSize == 0)) 150 return {Start, Start + (Size / EntSize)}; 151 152 std::string Msg; 153 if (!Context.empty()) 154 Msg += Context + " has "; 155 156 Msg += ("invalid " + SizePrintName + " (0x" + Twine::utohexstr(Size) + ")") 157 .str(); 158 if (!EntSizePrintName.empty()) 159 Msg += 160 (" or " + EntSizePrintName + " (0x" + Twine::utohexstr(EntSize) + ")") 161 .str(); 162 163 Dumper->reportUniqueWarning(Msg); 164 return {Start, Start}; 165 } 166 }; 167 168 struct GroupMember { 169 StringRef Name; 170 uint64_t Index; 171 }; 172 173 struct GroupSection { 174 StringRef Name; 175 std::string Signature; 176 uint64_t ShName; 177 uint64_t Index; 178 uint32_t Link; 179 uint32_t Info; 180 uint32_t Type; 181 std::vector<GroupMember> Members; 182 }; 183 184 namespace { 185 186 struct NoteType { 187 uint32_t ID; 188 StringRef Name; 189 }; 190 191 } // namespace 192 193 template <class ELFT> class Relocation { 194 public: 195 Relocation(const typename ELFT::Rel &R, bool IsMips64EL) 196 : Type(R.getType(IsMips64EL)), Symbol(R.getSymbol(IsMips64EL)), 197 Offset(R.r_offset), Info(R.r_info) {} 198 199 Relocation(const typename ELFT::Rela &R, bool IsMips64EL) 200 : Relocation((const typename ELFT::Rel &)R, IsMips64EL) { 201 Addend = R.r_addend; 202 } 203 204 uint32_t Type; 205 uint32_t Symbol; 206 typename ELFT::uint Offset; 207 typename ELFT::uint Info; 208 std::optional<int64_t> Addend; 209 }; 210 211 template <class ELFT> class MipsGOTParser; 212 213 template <typename ELFT> class ELFDumper : public ObjDumper { 214 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 215 216 public: 217 ELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer); 218 219 void printUnwindInfo() override; 220 void printNeededLibraries() override; 221 void printHashTable() override; 222 void printGnuHashTable() override; 223 void printLoadName() override; 224 void printVersionInfo() override; 225 void printArchSpecificInfo() override; 226 void printStackMap() const override; 227 void printMemtag() override; 228 ArrayRef<uint8_t> getMemtagGlobalsSectionContents(uint64_t ExpectedAddr); 229 230 // Hash histogram shows statistics of how efficient the hash was for the 231 // dynamic symbol table. The table shows the number of hash buckets for 232 // different lengths of chains as an absolute number and percentage of the 233 // total buckets, and the cumulative coverage of symbols for each set of 234 // buckets. 235 void printHashHistograms() override; 236 237 const object::ELFObjectFile<ELFT> &getElfObject() const { return ObjF; }; 238 239 std::string describe(const Elf_Shdr &Sec) const; 240 241 unsigned getHashTableEntSize() const { 242 // EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH 243 // sections. This violates the ELF specification. 244 if (Obj.getHeader().e_machine == ELF::EM_S390 || 245 Obj.getHeader().e_machine == ELF::EM_ALPHA) 246 return 8; 247 return 4; 248 } 249 250 std::vector<EnumEntry<unsigned>> 251 getOtherFlagsFromSymbol(const Elf_Ehdr &Header, const Elf_Sym &Symbol) const; 252 253 Elf_Dyn_Range dynamic_table() const { 254 // A valid .dynamic section contains an array of entries terminated 255 // with a DT_NULL entry. However, sometimes the section content may 256 // continue past the DT_NULL entry, so to dump the section correctly, 257 // we first find the end of the entries by iterating over them. 258 Elf_Dyn_Range Table = DynamicTable.template getAsArrayRef<Elf_Dyn>(); 259 260 size_t Size = 0; 261 while (Size < Table.size()) 262 if (Table[Size++].getTag() == DT_NULL) 263 break; 264 265 return Table.slice(0, Size); 266 } 267 268 Elf_Sym_Range dynamic_symbols() const { 269 if (!DynSymRegion) 270 return Elf_Sym_Range(); 271 return DynSymRegion->template getAsArrayRef<Elf_Sym>(); 272 } 273 274 const Elf_Shdr *findSectionByName(StringRef Name) const; 275 276 StringRef getDynamicStringTable() const { return DynamicStringTable; } 277 278 protected: 279 virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0; 280 virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0; 281 virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0; 282 283 void 284 printDependentLibsHelper(function_ref<void(const Elf_Shdr &)> OnSectionStart, 285 function_ref<void(StringRef, uint64_t)> OnLibEntry); 286 287 virtual void printRelRelaReloc(const Relocation<ELFT> &R, 288 const RelSymbol<ELFT> &RelSym) = 0; 289 virtual void printDynamicRelocHeader(unsigned Type, StringRef Name, 290 const DynRegionInfo &Reg) {} 291 void printReloc(const Relocation<ELFT> &R, unsigned RelIndex, 292 const Elf_Shdr &Sec, const Elf_Shdr *SymTab); 293 void printDynamicReloc(const Relocation<ELFT> &R); 294 void printDynamicRelocationsHelper(); 295 void printRelocationsHelper(const Elf_Shdr &Sec); 296 void forEachRelocationDo( 297 const Elf_Shdr &Sec, 298 llvm::function_ref<void(const Relocation<ELFT> &, unsigned, 299 const Elf_Shdr &, const Elf_Shdr *)> 300 RelRelaFn); 301 302 virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset, 303 bool NonVisibilityBitsUsed, 304 bool ExtraSymInfo) const {}; 305 virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, 306 DataRegion<Elf_Word> ShndxTable, 307 std::optional<StringRef> StrTable, bool IsDynamic, 308 bool NonVisibilityBitsUsed, 309 bool ExtraSymInfo) const = 0; 310 311 virtual void printMipsABIFlags() = 0; 312 virtual void printMipsGOT(const MipsGOTParser<ELFT> &Parser) = 0; 313 virtual void printMipsPLT(const MipsGOTParser<ELFT> &Parser) = 0; 314 315 virtual void printMemtag( 316 const ArrayRef<std::pair<std::string, std::string>> DynamicEntries, 317 const ArrayRef<uint8_t> AndroidNoteDesc, 318 const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) = 0; 319 320 virtual void printHashHistogram(const Elf_Hash &HashTable) const; 321 virtual void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable) const; 322 virtual void printHashHistogramStats(size_t NBucket, size_t MaxChain, 323 size_t TotalSyms, ArrayRef<size_t> Count, 324 bool IsGnu) const = 0; 325 326 Expected<ArrayRef<Elf_Versym>> 327 getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab, 328 StringRef *StrTab, const Elf_Shdr **SymTabSec) const; 329 StringRef getPrintableSectionName(const Elf_Shdr &Sec) const; 330 331 std::vector<GroupSection> getGroups(); 332 333 // Returns the function symbol index for the given address. Matches the 334 // symbol's section with FunctionSec when specified. 335 // Returns std::nullopt if no function symbol can be found for the address or 336 // in case it is not defined in the specified section. 337 SmallVector<uint32_t> getSymbolIndexesForFunctionAddress( 338 uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec); 339 bool printFunctionStackSize(uint64_t SymValue, 340 std::optional<const Elf_Shdr *> FunctionSec, 341 const Elf_Shdr &StackSizeSec, DataExtractor Data, 342 uint64_t *Offset); 343 void printStackSize(const Relocation<ELFT> &R, const Elf_Shdr &RelocSec, 344 unsigned Ndx, const Elf_Shdr *SymTab, 345 const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec, 346 const RelocationResolver &Resolver, DataExtractor Data); 347 virtual void printStackSizeEntry(uint64_t Size, 348 ArrayRef<std::string> FuncNames) = 0; 349 350 void printRelocatableStackSizes(std::function<void()> PrintHeader); 351 void printNonRelocatableStackSizes(std::function<void()> PrintHeader); 352 353 const object::ELFObjectFile<ELFT> &ObjF; 354 const ELFFile<ELFT> &Obj; 355 StringRef FileName; 356 357 Expected<DynRegionInfo> createDRI(uint64_t Offset, uint64_t Size, 358 uint64_t EntSize) { 359 if (Offset + Size < Offset || Offset + Size > Obj.getBufSize()) 360 return createError("offset (0x" + Twine::utohexstr(Offset) + 361 ") + size (0x" + Twine::utohexstr(Size) + 362 ") is greater than the file size (0x" + 363 Twine::utohexstr(Obj.getBufSize()) + ")"); 364 return DynRegionInfo(ObjF, *this, Obj.base() + Offset, Size, EntSize); 365 } 366 367 void printAttributes(unsigned, std::unique_ptr<ELFAttributeParser>, 368 llvm::endianness); 369 void printMipsReginfo(); 370 void printMipsOptions(); 371 372 std::pair<const Elf_Phdr *, const Elf_Shdr *> findDynamic(); 373 void loadDynamicTable(); 374 void parseDynamicTable(); 375 376 Expected<StringRef> getSymbolVersion(const Elf_Sym &Sym, 377 bool &IsDefault) const; 378 Expected<SmallVector<std::optional<VersionEntry>, 0> *> getVersionMap() const; 379 380 DynRegionInfo DynRelRegion; 381 DynRegionInfo DynRelaRegion; 382 DynRegionInfo DynCrelRegion; 383 DynRegionInfo DynRelrRegion; 384 DynRegionInfo DynPLTRelRegion; 385 std::optional<DynRegionInfo> DynSymRegion; 386 DynRegionInfo DynSymTabShndxRegion; 387 DynRegionInfo DynamicTable; 388 StringRef DynamicStringTable; 389 const Elf_Hash *HashTable = nullptr; 390 const Elf_GnuHash *GnuHashTable = nullptr; 391 const Elf_Shdr *DotSymtabSec = nullptr; 392 const Elf_Shdr *DotDynsymSec = nullptr; 393 const Elf_Shdr *DotAddrsigSec = nullptr; 394 DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables; 395 std::optional<uint64_t> SONameOffset; 396 std::optional<DenseMap<uint64_t, std::vector<uint32_t>>> AddressToIndexMap; 397 398 const Elf_Shdr *SymbolVersionSection = nullptr; // .gnu.version 399 const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r 400 const Elf_Shdr *SymbolVersionDefSection = nullptr; // .gnu.version_d 401 402 std::string getFullSymbolName(const Elf_Sym &Symbol, unsigned SymIndex, 403 DataRegion<Elf_Word> ShndxTable, 404 std::optional<StringRef> StrTable, 405 bool IsDynamic) const; 406 Expected<unsigned> 407 getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex, 408 DataRegion<Elf_Word> ShndxTable) const; 409 Expected<StringRef> getSymbolSectionName(const Elf_Sym &Symbol, 410 unsigned SectionIndex) const; 411 std::string getStaticSymbolName(uint32_t Index) const; 412 StringRef getDynamicString(uint64_t Value) const; 413 414 std::pair<Elf_Sym_Range, std::optional<StringRef>> getSymtabAndStrtab() const; 415 void printSymbolsHelper(bool IsDynamic, bool ExtraSymInfo) const; 416 std::string getDynamicEntry(uint64_t Type, uint64_t Value) const; 417 418 Expected<RelSymbol<ELFT>> getRelocationTarget(const Relocation<ELFT> &R, 419 const Elf_Shdr *SymTab) const; 420 421 ArrayRef<Elf_Word> getShndxTable(const Elf_Shdr *Symtab) const; 422 423 private: 424 mutable SmallVector<std::optional<VersionEntry>, 0> VersionMap; 425 }; 426 427 template <class ELFT> 428 std::string ELFDumper<ELFT>::describe(const Elf_Shdr &Sec) const { 429 return ::describe(Obj, Sec); 430 } 431 432 namespace { 433 434 template <class ELFT> struct SymtabLink { 435 typename ELFT::SymRange Symbols; 436 StringRef StringTable; 437 const typename ELFT::Shdr *SymTab; 438 }; 439 440 // Returns the linked symbol table, symbols and associated string table for a 441 // given section. 442 template <class ELFT> 443 Expected<SymtabLink<ELFT>> getLinkAsSymtab(const ELFFile<ELFT> &Obj, 444 const typename ELFT::Shdr &Sec, 445 unsigned ExpectedType) { 446 Expected<const typename ELFT::Shdr *> SymtabOrErr = 447 Obj.getSection(Sec.sh_link); 448 if (!SymtabOrErr) 449 return createError("invalid section linked to " + describe(Obj, Sec) + 450 ": " + toString(SymtabOrErr.takeError())); 451 452 if ((*SymtabOrErr)->sh_type != ExpectedType) 453 return createError( 454 "invalid section linked to " + describe(Obj, Sec) + ": expected " + 455 object::getELFSectionTypeName(Obj.getHeader().e_machine, ExpectedType) + 456 ", but got " + 457 object::getELFSectionTypeName(Obj.getHeader().e_machine, 458 (*SymtabOrErr)->sh_type)); 459 460 Expected<StringRef> StrTabOrErr = Obj.getLinkAsStrtab(**SymtabOrErr); 461 if (!StrTabOrErr) 462 return createError( 463 "can't get a string table for the symbol table linked to " + 464 describe(Obj, Sec) + ": " + toString(StrTabOrErr.takeError())); 465 466 Expected<typename ELFT::SymRange> SymsOrErr = Obj.symbols(*SymtabOrErr); 467 if (!SymsOrErr) 468 return createError("unable to read symbols from the " + describe(Obj, Sec) + 469 ": " + toString(SymsOrErr.takeError())); 470 471 return SymtabLink<ELFT>{*SymsOrErr, *StrTabOrErr, *SymtabOrErr}; 472 } 473 474 } // namespace 475 476 template <class ELFT> 477 Expected<ArrayRef<typename ELFT::Versym>> 478 ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab, 479 StringRef *StrTab, 480 const Elf_Shdr **SymTabSec) const { 481 assert((!SymTab && !StrTab && !SymTabSec) || (SymTab && StrTab && SymTabSec)); 482 if (reinterpret_cast<uintptr_t>(Obj.base() + Sec.sh_offset) % 483 sizeof(uint16_t) != 484 0) 485 return createError("the " + describe(Sec) + " is misaligned"); 486 487 Expected<ArrayRef<Elf_Versym>> VersionsOrErr = 488 Obj.template getSectionContentsAsArray<Elf_Versym>(Sec); 489 if (!VersionsOrErr) 490 return createError("cannot read content of " + describe(Sec) + ": " + 491 toString(VersionsOrErr.takeError())); 492 493 Expected<SymtabLink<ELFT>> SymTabOrErr = 494 getLinkAsSymtab(Obj, Sec, SHT_DYNSYM); 495 if (!SymTabOrErr) { 496 reportUniqueWarning(SymTabOrErr.takeError()); 497 return *VersionsOrErr; 498 } 499 500 if (SymTabOrErr->Symbols.size() != VersionsOrErr->size()) 501 reportUniqueWarning(describe(Sec) + ": the number of entries (" + 502 Twine(VersionsOrErr->size()) + 503 ") does not match the number of symbols (" + 504 Twine(SymTabOrErr->Symbols.size()) + 505 ") in the symbol table with index " + 506 Twine(Sec.sh_link)); 507 508 if (SymTab) { 509 *SymTab = SymTabOrErr->Symbols; 510 *StrTab = SymTabOrErr->StringTable; 511 *SymTabSec = SymTabOrErr->SymTab; 512 } 513 return *VersionsOrErr; 514 } 515 516 template <class ELFT> 517 std::pair<typename ELFDumper<ELFT>::Elf_Sym_Range, std::optional<StringRef>> 518 ELFDumper<ELFT>::getSymtabAndStrtab() const { 519 assert(DotSymtabSec); 520 Elf_Sym_Range Syms(nullptr, nullptr); 521 std::optional<StringRef> StrTable; 522 if (Expected<StringRef> StrTableOrErr = 523 Obj.getStringTableForSymtab(*DotSymtabSec)) 524 StrTable = *StrTableOrErr; 525 else 526 reportUniqueWarning( 527 "unable to get the string table for the SHT_SYMTAB section: " + 528 toString(StrTableOrErr.takeError())); 529 530 if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec)) 531 Syms = *SymsOrErr; 532 else 533 reportUniqueWarning("unable to read symbols from the SHT_SYMTAB section: " + 534 toString(SymsOrErr.takeError())); 535 return {Syms, StrTable}; 536 } 537 538 template <class ELFT> 539 void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic, 540 bool ExtraSymInfo) const { 541 std::optional<StringRef> StrTable; 542 size_t Entries = 0; 543 Elf_Sym_Range Syms(nullptr, nullptr); 544 const Elf_Shdr *SymtabSec = IsDynamic ? DotDynsymSec : DotSymtabSec; 545 546 if (IsDynamic) { 547 StrTable = DynamicStringTable; 548 Syms = dynamic_symbols(); 549 Entries = Syms.size(); 550 } else if (DotSymtabSec) { 551 std::tie(Syms, StrTable) = getSymtabAndStrtab(); 552 Entries = DotSymtabSec->getEntityCount(); 553 } 554 if (Syms.empty()) 555 return; 556 557 // The st_other field has 2 logical parts. The first two bits hold the symbol 558 // visibility (STV_*) and the remainder hold other platform-specific values. 559 bool NonVisibilityBitsUsed = 560 llvm::any_of(Syms, [](const Elf_Sym &S) { return S.st_other & ~0x3; }); 561 562 DataRegion<Elf_Word> ShndxTable = 563 IsDynamic ? DataRegion<Elf_Word>( 564 (const Elf_Word *)this->DynSymTabShndxRegion.Addr, 565 this->getElfObject().getELFFile().end()) 566 : DataRegion<Elf_Word>(this->getShndxTable(SymtabSec)); 567 568 printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed, ExtraSymInfo); 569 for (const Elf_Sym &Sym : Syms) 570 printSymbol(Sym, &Sym - Syms.begin(), ShndxTable, StrTable, IsDynamic, 571 NonVisibilityBitsUsed, ExtraSymInfo); 572 } 573 574 template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> { 575 formatted_raw_ostream &OS; 576 577 public: 578 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 579 580 GNUELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer) 581 : ELFDumper<ELFT>(ObjF, Writer), 582 OS(static_cast<formatted_raw_ostream &>(Writer.getOStream())) { 583 assert(&this->W.getOStream() == &llvm::fouts()); 584 } 585 586 void printFileSummary(StringRef FileStr, ObjectFile &Obj, 587 ArrayRef<std::string> InputFilenames, 588 const Archive *A) override; 589 void printFileHeaders() override; 590 void printGroupSections() override; 591 void printRelocations() override; 592 void printSectionHeaders() override; 593 void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols, 594 bool ExtraSymInfo) override; 595 void printHashSymbols() override; 596 void printSectionDetails() override; 597 void printDependentLibs() override; 598 void printDynamicTable() override; 599 void printDynamicRelocations() override; 600 void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset, 601 bool NonVisibilityBitsUsed, 602 bool ExtraSymInfo) const override; 603 void printProgramHeaders(bool PrintProgramHeaders, 604 cl::boolOrDefault PrintSectionMapping) override; 605 void printVersionSymbolSection(const Elf_Shdr *Sec) override; 606 void printVersionDefinitionSection(const Elf_Shdr *Sec) override; 607 void printVersionDependencySection(const Elf_Shdr *Sec) override; 608 void printCGProfile() override; 609 void printBBAddrMaps(bool PrettyPGOAnalysis) override; 610 void printAddrsig() override; 611 void printNotes() override; 612 void printELFLinkerOptions() override; 613 void printStackSizes() override; 614 void printMemtag( 615 const ArrayRef<std::pair<std::string, std::string>> DynamicEntries, 616 const ArrayRef<uint8_t> AndroidNoteDesc, 617 const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) override; 618 void printHashHistogramStats(size_t NBucket, size_t MaxChain, 619 size_t TotalSyms, ArrayRef<size_t> Count, 620 bool IsGnu) const override; 621 622 private: 623 void printHashTableSymbols(const Elf_Hash &HashTable); 624 void printGnuHashTableSymbols(const Elf_GnuHash &GnuHashTable); 625 626 struct Field { 627 std::string Str; 628 unsigned Column; 629 630 Field(StringRef S, unsigned Col) : Str(std::string(S)), Column(Col) {} 631 Field(unsigned Col) : Column(Col) {} 632 }; 633 634 template <typename T, typename TEnum> 635 std::string printFlags(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues, 636 TEnum EnumMask1 = {}, TEnum EnumMask2 = {}, 637 TEnum EnumMask3 = {}) const { 638 std::string Str; 639 for (const EnumEntry<TEnum> &Flag : EnumValues) { 640 if (Flag.Value == 0) 641 continue; 642 643 TEnum EnumMask{}; 644 if (Flag.Value & EnumMask1) 645 EnumMask = EnumMask1; 646 else if (Flag.Value & EnumMask2) 647 EnumMask = EnumMask2; 648 else if (Flag.Value & EnumMask3) 649 EnumMask = EnumMask3; 650 bool IsEnum = (Flag.Value & EnumMask) != 0; 651 if ((!IsEnum && (Value & Flag.Value) == Flag.Value) || 652 (IsEnum && (Value & EnumMask) == Flag.Value)) { 653 if (!Str.empty()) 654 Str += ", "; 655 Str += Flag.AltName; 656 } 657 } 658 return Str; 659 } 660 661 formatted_raw_ostream &printField(struct Field F) const { 662 if (F.Column != 0) 663 OS.PadToColumn(F.Column); 664 OS << F.Str; 665 OS.flush(); 666 return OS; 667 } 668 void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex, 669 DataRegion<Elf_Word> ShndxTable, StringRef StrTable, 670 uint32_t Bucket); 671 void printRelr(const Elf_Shdr &Sec); 672 void printRelRelaReloc(const Relocation<ELFT> &R, 673 const RelSymbol<ELFT> &RelSym) override; 674 void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, 675 DataRegion<Elf_Word> ShndxTable, 676 std::optional<StringRef> StrTable, bool IsDynamic, 677 bool NonVisibilityBitsUsed, 678 bool ExtraSymInfo) const override; 679 void printDynamicRelocHeader(unsigned Type, StringRef Name, 680 const DynRegionInfo &Reg) override; 681 682 std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex, 683 DataRegion<Elf_Word> ShndxTable, 684 bool ExtraSymInfo = false) const; 685 void printProgramHeaders() override; 686 void printSectionMapping() override; 687 void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec, 688 const Twine &Label, unsigned EntriesNum); 689 690 void printStackSizeEntry(uint64_t Size, 691 ArrayRef<std::string> FuncNames) override; 692 693 void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override; 694 void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override; 695 void printMipsABIFlags() override; 696 }; 697 698 template <typename ELFT> class LLVMELFDumper : public ELFDumper<ELFT> { 699 public: 700 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 701 702 LLVMELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer) 703 : ELFDumper<ELFT>(ObjF, Writer), W(Writer) {} 704 705 void printFileHeaders() override; 706 void printGroupSections() override; 707 void printRelocations() override; 708 void printSectionHeaders() override; 709 void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols, 710 bool ExtraSymInfo) override; 711 void printDependentLibs() override; 712 void printDynamicTable() override; 713 void printDynamicRelocations() override; 714 void printProgramHeaders(bool PrintProgramHeaders, 715 cl::boolOrDefault PrintSectionMapping) override; 716 void printVersionSymbolSection(const Elf_Shdr *Sec) override; 717 void printVersionDefinitionSection(const Elf_Shdr *Sec) override; 718 void printVersionDependencySection(const Elf_Shdr *Sec) override; 719 void printCGProfile() override; 720 void printBBAddrMaps(bool PrettyPGOAnalysis) override; 721 void printAddrsig() override; 722 void printNotes() override; 723 void printELFLinkerOptions() override; 724 void printStackSizes() override; 725 void printMemtag( 726 const ArrayRef<std::pair<std::string, std::string>> DynamicEntries, 727 const ArrayRef<uint8_t> AndroidNoteDesc, 728 const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) override; 729 void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex, 730 DataRegion<Elf_Word> ShndxTable) const; 731 void printHashHistogramStats(size_t NBucket, size_t MaxChain, 732 size_t TotalSyms, ArrayRef<size_t> Count, 733 bool IsGnu) const override; 734 735 private: 736 void printRelRelaReloc(const Relocation<ELFT> &R, 737 const RelSymbol<ELFT> &RelSym) override; 738 739 void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, 740 DataRegion<Elf_Word> ShndxTable, 741 std::optional<StringRef> StrTable, bool IsDynamic, 742 bool /*NonVisibilityBitsUsed*/, 743 bool /*ExtraSymInfo*/) const override; 744 void printProgramHeaders() override; 745 void printSectionMapping() override {} 746 void printStackSizeEntry(uint64_t Size, 747 ArrayRef<std::string> FuncNames) override; 748 749 void printMipsGOT(const MipsGOTParser<ELFT> &Parser) override; 750 void printMipsPLT(const MipsGOTParser<ELFT> &Parser) override; 751 void printMipsABIFlags() override; 752 virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const; 753 754 protected: 755 virtual std::string getGroupSectionHeaderName() const; 756 void printSymbolOtherField(const Elf_Sym &Symbol) const; 757 virtual void printExpandedRelRelaReloc(const Relocation<ELFT> &R, 758 StringRef SymbolName, 759 StringRef RelocName); 760 virtual void printDefaultRelRelaReloc(const Relocation<ELFT> &R, 761 StringRef SymbolName, 762 StringRef RelocName); 763 virtual void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name, 764 const unsigned SecNdx); 765 virtual void printSectionGroupMembers(StringRef Name, uint64_t Idx) const; 766 virtual void printEmptyGroupMessage() const; 767 768 ScopedPrinter &W; 769 }; 770 771 // JSONELFDumper shares most of the same implementation as LLVMELFDumper except 772 // it uses a JSONScopedPrinter. 773 template <typename ELFT> class JSONELFDumper : public LLVMELFDumper<ELFT> { 774 public: 775 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 776 777 JSONELFDumper(const object::ELFObjectFile<ELFT> &ObjF, ScopedPrinter &Writer) 778 : LLVMELFDumper<ELFT>(ObjF, Writer) {} 779 780 std::string getGroupSectionHeaderName() const override; 781 782 void printFileSummary(StringRef FileStr, ObjectFile &Obj, 783 ArrayRef<std::string> InputFilenames, 784 const Archive *A) override; 785 virtual void printZeroSymbolOtherField(const Elf_Sym &Symbol) const override; 786 787 void printDefaultRelRelaReloc(const Relocation<ELFT> &R, 788 StringRef SymbolName, 789 StringRef RelocName) override; 790 791 void printRelocationSectionInfo(const Elf_Shdr &Sec, StringRef Name, 792 const unsigned SecNdx) override; 793 794 void printSectionGroupMembers(StringRef Name, uint64_t Idx) const override; 795 796 void printEmptyGroupMessage() const override; 797 798 void printDynamicTable() override; 799 800 private: 801 void printAuxillaryDynamicTableEntryInfo(const Elf_Dyn &Entry); 802 803 std::unique_ptr<DictScope> FileScope; 804 }; 805 806 } // end anonymous namespace 807 808 namespace llvm { 809 810 template <class ELFT> 811 static std::unique_ptr<ObjDumper> 812 createELFDumper(const ELFObjectFile<ELFT> &Obj, ScopedPrinter &Writer) { 813 if (opts::Output == opts::GNU) 814 return std::make_unique<GNUELFDumper<ELFT>>(Obj, Writer); 815 else if (opts::Output == opts::JSON) 816 return std::make_unique<JSONELFDumper<ELFT>>(Obj, Writer); 817 return std::make_unique<LLVMELFDumper<ELFT>>(Obj, Writer); 818 } 819 820 std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj, 821 ScopedPrinter &Writer) { 822 // Little-endian 32-bit 823 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(&Obj)) 824 return createELFDumper(*ELFObj, Writer); 825 826 // Big-endian 32-bit 827 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(&Obj)) 828 return createELFDumper(*ELFObj, Writer); 829 830 // Little-endian 64-bit 831 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(&Obj)) 832 return createELFDumper(*ELFObj, Writer); 833 834 // Big-endian 64-bit 835 return createELFDumper(*cast<ELF64BEObjectFile>(&Obj), Writer); 836 } 837 838 } // end namespace llvm 839 840 template <class ELFT> 841 Expected<SmallVector<std::optional<VersionEntry>, 0> *> 842 ELFDumper<ELFT>::getVersionMap() const { 843 // If the VersionMap has already been loaded or if there is no dynamic symtab 844 // or version table, there is nothing to do. 845 if (!VersionMap.empty() || !DynSymRegion || !SymbolVersionSection) 846 return &VersionMap; 847 848 Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr = 849 Obj.loadVersionMap(SymbolVersionNeedSection, SymbolVersionDefSection); 850 if (MapOrErr) 851 VersionMap = *MapOrErr; 852 else 853 return MapOrErr.takeError(); 854 855 return &VersionMap; 856 } 857 858 template <typename ELFT> 859 Expected<StringRef> ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym &Sym, 860 bool &IsDefault) const { 861 // This is a dynamic symbol. Look in the GNU symbol version table. 862 if (!SymbolVersionSection) { 863 // No version table. 864 IsDefault = false; 865 return ""; 866 } 867 868 assert(DynSymRegion && "DynSymRegion has not been initialised"); 869 // Determine the position in the symbol table of this entry. 870 size_t EntryIndex = (reinterpret_cast<uintptr_t>(&Sym) - 871 reinterpret_cast<uintptr_t>(DynSymRegion->Addr)) / 872 sizeof(Elf_Sym); 873 874 // Get the corresponding version index entry. 875 Expected<const Elf_Versym *> EntryOrErr = 876 Obj.template getEntry<Elf_Versym>(*SymbolVersionSection, EntryIndex); 877 if (!EntryOrErr) 878 return EntryOrErr.takeError(); 879 880 unsigned Version = (*EntryOrErr)->vs_index; 881 if (Version == VER_NDX_LOCAL || Version == VER_NDX_GLOBAL) { 882 IsDefault = false; 883 return ""; 884 } 885 886 Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr = 887 getVersionMap(); 888 if (!MapOrErr) 889 return MapOrErr.takeError(); 890 891 return Obj.getSymbolVersionByIndex(Version, IsDefault, **MapOrErr, 892 Sym.st_shndx == ELF::SHN_UNDEF); 893 } 894 895 template <typename ELFT> 896 Expected<RelSymbol<ELFT>> 897 ELFDumper<ELFT>::getRelocationTarget(const Relocation<ELFT> &R, 898 const Elf_Shdr *SymTab) const { 899 if (R.Symbol == 0) 900 return RelSymbol<ELFT>(nullptr, ""); 901 902 Expected<const Elf_Sym *> SymOrErr = 903 Obj.template getEntry<Elf_Sym>(*SymTab, R.Symbol); 904 if (!SymOrErr) 905 return createError("unable to read an entry with index " + Twine(R.Symbol) + 906 " from " + describe(*SymTab) + ": " + 907 toString(SymOrErr.takeError())); 908 const Elf_Sym *Sym = *SymOrErr; 909 if (!Sym) 910 return RelSymbol<ELFT>(nullptr, ""); 911 912 Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*SymTab); 913 if (!StrTableOrErr) 914 return StrTableOrErr.takeError(); 915 916 const Elf_Sym *FirstSym = 917 cantFail(Obj.template getEntry<Elf_Sym>(*SymTab, 0)); 918 std::string SymbolName = 919 getFullSymbolName(*Sym, Sym - FirstSym, getShndxTable(SymTab), 920 *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM); 921 return RelSymbol<ELFT>(Sym, SymbolName); 922 } 923 924 template <typename ELFT> 925 ArrayRef<typename ELFT::Word> 926 ELFDumper<ELFT>::getShndxTable(const Elf_Shdr *Symtab) const { 927 if (Symtab) { 928 auto It = ShndxTables.find(Symtab); 929 if (It != ShndxTables.end()) 930 return It->second; 931 } 932 return {}; 933 } 934 935 static std::string maybeDemangle(StringRef Name) { 936 return opts::Demangle ? demangle(Name) : Name.str(); 937 } 938 939 template <typename ELFT> 940 std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const { 941 auto Warn = [&](Error E) -> std::string { 942 reportUniqueWarning("unable to read the name of symbol with index " + 943 Twine(Index) + ": " + toString(std::move(E))); 944 return "<?>"; 945 }; 946 947 Expected<const typename ELFT::Sym *> SymOrErr = 948 Obj.getSymbol(DotSymtabSec, Index); 949 if (!SymOrErr) 950 return Warn(SymOrErr.takeError()); 951 952 Expected<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*DotSymtabSec); 953 if (!StrTabOrErr) 954 return Warn(StrTabOrErr.takeError()); 955 956 Expected<StringRef> NameOrErr = (*SymOrErr)->getName(*StrTabOrErr); 957 if (!NameOrErr) 958 return Warn(NameOrErr.takeError()); 959 return maybeDemangle(*NameOrErr); 960 } 961 962 template <typename ELFT> 963 std::string ELFDumper<ELFT>::getFullSymbolName( 964 const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, 965 std::optional<StringRef> StrTable, bool IsDynamic) const { 966 if (!StrTable) 967 return "<?>"; 968 969 std::string SymbolName; 970 if (Expected<StringRef> NameOrErr = Symbol.getName(*StrTable)) { 971 SymbolName = maybeDemangle(*NameOrErr); 972 } else { 973 reportUniqueWarning(NameOrErr.takeError()); 974 return "<?>"; 975 } 976 977 if (SymbolName.empty() && Symbol.getType() == ELF::STT_SECTION) { 978 Expected<unsigned> SectionIndex = 979 getSymbolSectionIndex(Symbol, SymIndex, ShndxTable); 980 if (!SectionIndex) { 981 reportUniqueWarning(SectionIndex.takeError()); 982 return "<?>"; 983 } 984 Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex); 985 if (!NameOrErr) { 986 reportUniqueWarning(NameOrErr.takeError()); 987 return ("<section " + Twine(*SectionIndex) + ">").str(); 988 } 989 return std::string(*NameOrErr); 990 } 991 992 if (!IsDynamic) 993 return SymbolName; 994 995 bool IsDefault; 996 Expected<StringRef> VersionOrErr = getSymbolVersion(Symbol, IsDefault); 997 if (!VersionOrErr) { 998 reportUniqueWarning(VersionOrErr.takeError()); 999 return SymbolName + "@<corrupt>"; 1000 } 1001 1002 if (!VersionOrErr->empty()) { 1003 SymbolName += (IsDefault ? "@@" : "@"); 1004 SymbolName += *VersionOrErr; 1005 } 1006 return SymbolName; 1007 } 1008 1009 template <typename ELFT> 1010 Expected<unsigned> 1011 ELFDumper<ELFT>::getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex, 1012 DataRegion<Elf_Word> ShndxTable) const { 1013 unsigned Ndx = Symbol.st_shndx; 1014 if (Ndx == SHN_XINDEX) 1015 return object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex, 1016 ShndxTable); 1017 if (Ndx != SHN_UNDEF && Ndx < SHN_LORESERVE) 1018 return Ndx; 1019 1020 auto CreateErr = [&](const Twine &Name, 1021 std::optional<unsigned> Offset = std::nullopt) { 1022 std::string Desc; 1023 if (Offset) 1024 Desc = (Name + "+0x" + Twine::utohexstr(*Offset)).str(); 1025 else 1026 Desc = Name.str(); 1027 return createError( 1028 "unable to get section index for symbol with st_shndx = 0x" + 1029 Twine::utohexstr(Ndx) + " (" + Desc + ")"); 1030 }; 1031 1032 if (Ndx >= ELF::SHN_LOPROC && Ndx <= ELF::SHN_HIPROC) 1033 return CreateErr("SHN_LOPROC", Ndx - ELF::SHN_LOPROC); 1034 if (Ndx >= ELF::SHN_LOOS && Ndx <= ELF::SHN_HIOS) 1035 return CreateErr("SHN_LOOS", Ndx - ELF::SHN_LOOS); 1036 if (Ndx == ELF::SHN_UNDEF) 1037 return CreateErr("SHN_UNDEF"); 1038 if (Ndx == ELF::SHN_ABS) 1039 return CreateErr("SHN_ABS"); 1040 if (Ndx == ELF::SHN_COMMON) 1041 return CreateErr("SHN_COMMON"); 1042 return CreateErr("SHN_LORESERVE", Ndx - SHN_LORESERVE); 1043 } 1044 1045 template <typename ELFT> 1046 Expected<StringRef> 1047 ELFDumper<ELFT>::getSymbolSectionName(const Elf_Sym &Symbol, 1048 unsigned SectionIndex) const { 1049 Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(SectionIndex); 1050 if (!SecOrErr) 1051 return SecOrErr.takeError(); 1052 return Obj.getSectionName(**SecOrErr); 1053 } 1054 1055 template <class ELFO> 1056 static const typename ELFO::Elf_Shdr * 1057 findNotEmptySectionByAddress(const ELFO &Obj, StringRef FileName, 1058 uint64_t Addr) { 1059 for (const typename ELFO::Elf_Shdr &Shdr : cantFail(Obj.sections())) 1060 if (Shdr.sh_addr == Addr && Shdr.sh_size > 0) 1061 return &Shdr; 1062 return nullptr; 1063 } 1064 1065 const EnumEntry<unsigned> ElfClass[] = { 1066 {"None", "none", ELF::ELFCLASSNONE}, 1067 {"32-bit", "ELF32", ELF::ELFCLASS32}, 1068 {"64-bit", "ELF64", ELF::ELFCLASS64}, 1069 }; 1070 1071 const EnumEntry<unsigned> ElfDataEncoding[] = { 1072 {"None", "none", ELF::ELFDATANONE}, 1073 {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB}, 1074 {"BigEndian", "2's complement, big endian", ELF::ELFDATA2MSB}, 1075 }; 1076 1077 const EnumEntry<unsigned> ElfObjectFileType[] = { 1078 {"None", "NONE (none)", ELF::ET_NONE}, 1079 {"Relocatable", "REL (Relocatable file)", ELF::ET_REL}, 1080 {"Executable", "EXEC (Executable file)", ELF::ET_EXEC}, 1081 {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN}, 1082 {"Core", "CORE (Core file)", ELF::ET_CORE}, 1083 }; 1084 1085 const EnumEntry<unsigned> ElfOSABI[] = { 1086 {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE}, 1087 {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX}, 1088 {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD}, 1089 {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX}, 1090 {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD}, 1091 {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS}, 1092 {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX}, 1093 {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX}, 1094 {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD}, 1095 {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64}, 1096 {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO}, 1097 {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD}, 1098 {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS}, 1099 {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK}, 1100 {"AROS", "AROS", ELF::ELFOSABI_AROS}, 1101 {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS}, 1102 {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI}, 1103 {"CUDA", "NVIDIA - CUDA", ELF::ELFOSABI_CUDA}, 1104 {"CUDA", "NVIDIA - CUDA", ELF::ELFOSABI_CUDA_V2}, 1105 {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE}}; 1106 1107 const EnumEntry<unsigned> AMDGPUElfOSABI[] = { 1108 {"AMDGPU_HSA", "AMDGPU - HSA", ELF::ELFOSABI_AMDGPU_HSA}, 1109 {"AMDGPU_PAL", "AMDGPU - PAL", ELF::ELFOSABI_AMDGPU_PAL}, 1110 {"AMDGPU_MESA3D", "AMDGPU - MESA3D", ELF::ELFOSABI_AMDGPU_MESA3D} 1111 }; 1112 1113 const EnumEntry<unsigned> ARMElfOSABI[] = { 1114 {"ARM", "ARM", ELF::ELFOSABI_ARM}, 1115 {"ARM FDPIC", "ARM FDPIC", ELF::ELFOSABI_ARM_FDPIC}, 1116 }; 1117 1118 const EnumEntry<unsigned> C6000ElfOSABI[] = { 1119 {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI}, 1120 {"C6000_LINUX", "Linux C6000", ELF::ELFOSABI_C6000_LINUX} 1121 }; 1122 1123 const EnumEntry<unsigned> ElfMachineType[] = { 1124 ENUM_ENT(EM_NONE, "None"), 1125 ENUM_ENT(EM_M32, "WE32100"), 1126 ENUM_ENT(EM_SPARC, "Sparc"), 1127 ENUM_ENT(EM_386, "Intel 80386"), 1128 ENUM_ENT(EM_68K, "MC68000"), 1129 ENUM_ENT(EM_88K, "MC88000"), 1130 ENUM_ENT(EM_IAMCU, "EM_IAMCU"), 1131 ENUM_ENT(EM_860, "Intel 80860"), 1132 ENUM_ENT(EM_MIPS, "MIPS R3000"), 1133 ENUM_ENT(EM_S370, "IBM System/370"), 1134 ENUM_ENT(EM_MIPS_RS3_LE, "MIPS R3000 little-endian"), 1135 ENUM_ENT(EM_PARISC, "HPPA"), 1136 ENUM_ENT(EM_VPP500, "Fujitsu VPP500"), 1137 ENUM_ENT(EM_SPARC32PLUS, "Sparc v8+"), 1138 ENUM_ENT(EM_960, "Intel 80960"), 1139 ENUM_ENT(EM_PPC, "PowerPC"), 1140 ENUM_ENT(EM_PPC64, "PowerPC64"), 1141 ENUM_ENT(EM_S390, "IBM S/390"), 1142 ENUM_ENT(EM_SPU, "SPU"), 1143 ENUM_ENT(EM_V800, "NEC V800 series"), 1144 ENUM_ENT(EM_FR20, "Fujistsu FR20"), 1145 ENUM_ENT(EM_RH32, "TRW RH-32"), 1146 ENUM_ENT(EM_RCE, "Motorola RCE"), 1147 ENUM_ENT(EM_ARM, "ARM"), 1148 ENUM_ENT(EM_ALPHA, "EM_ALPHA"), 1149 ENUM_ENT(EM_SH, "Hitachi SH"), 1150 ENUM_ENT(EM_SPARCV9, "Sparc v9"), 1151 ENUM_ENT(EM_TRICORE, "Siemens Tricore"), 1152 ENUM_ENT(EM_ARC, "ARC"), 1153 ENUM_ENT(EM_H8_300, "Hitachi H8/300"), 1154 ENUM_ENT(EM_H8_300H, "Hitachi H8/300H"), 1155 ENUM_ENT(EM_H8S, "Hitachi H8S"), 1156 ENUM_ENT(EM_H8_500, "Hitachi H8/500"), 1157 ENUM_ENT(EM_IA_64, "Intel IA-64"), 1158 ENUM_ENT(EM_MIPS_X, "Stanford MIPS-X"), 1159 ENUM_ENT(EM_COLDFIRE, "Motorola Coldfire"), 1160 ENUM_ENT(EM_68HC12, "Motorola MC68HC12 Microcontroller"), 1161 ENUM_ENT(EM_MMA, "Fujitsu Multimedia Accelerator"), 1162 ENUM_ENT(EM_PCP, "Siemens PCP"), 1163 ENUM_ENT(EM_NCPU, "Sony nCPU embedded RISC processor"), 1164 ENUM_ENT(EM_NDR1, "Denso NDR1 microprocesspr"), 1165 ENUM_ENT(EM_STARCORE, "Motorola Star*Core processor"), 1166 ENUM_ENT(EM_ME16, "Toyota ME16 processor"), 1167 ENUM_ENT(EM_ST100, "STMicroelectronics ST100 processor"), 1168 ENUM_ENT(EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor"), 1169 ENUM_ENT(EM_X86_64, "Advanced Micro Devices X86-64"), 1170 ENUM_ENT(EM_PDSP, "Sony DSP processor"), 1171 ENUM_ENT(EM_PDP10, "Digital Equipment Corp. PDP-10"), 1172 ENUM_ENT(EM_PDP11, "Digital Equipment Corp. PDP-11"), 1173 ENUM_ENT(EM_FX66, "Siemens FX66 microcontroller"), 1174 ENUM_ENT(EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller"), 1175 ENUM_ENT(EM_ST7, "STMicroelectronics ST7 8-bit microcontroller"), 1176 ENUM_ENT(EM_68HC16, "Motorola MC68HC16 Microcontroller"), 1177 ENUM_ENT(EM_68HC11, "Motorola MC68HC11 Microcontroller"), 1178 ENUM_ENT(EM_68HC08, "Motorola MC68HC08 Microcontroller"), 1179 ENUM_ENT(EM_68HC05, "Motorola MC68HC05 Microcontroller"), 1180 ENUM_ENT(EM_SVX, "Silicon Graphics SVx"), 1181 ENUM_ENT(EM_ST19, "STMicroelectronics ST19 8-bit microcontroller"), 1182 ENUM_ENT(EM_VAX, "Digital VAX"), 1183 ENUM_ENT(EM_CRIS, "Axis Communications 32-bit embedded processor"), 1184 ENUM_ENT(EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu"), 1185 ENUM_ENT(EM_FIREPATH, "Element 14 64-bit DSP processor"), 1186 ENUM_ENT(EM_ZSP, "LSI Logic's 16-bit DSP processor"), 1187 ENUM_ENT(EM_MMIX, "Donald Knuth's educational 64-bit processor"), 1188 ENUM_ENT(EM_HUANY, "Harvard Universitys's machine-independent object format"), 1189 ENUM_ENT(EM_PRISM, "Vitesse Prism"), 1190 ENUM_ENT(EM_AVR, "Atmel AVR 8-bit microcontroller"), 1191 ENUM_ENT(EM_FR30, "Fujitsu FR30"), 1192 ENUM_ENT(EM_D10V, "Mitsubishi D10V"), 1193 ENUM_ENT(EM_D30V, "Mitsubishi D30V"), 1194 ENUM_ENT(EM_V850, "NEC v850"), 1195 ENUM_ENT(EM_M32R, "Renesas M32R (formerly Mitsubishi M32r)"), 1196 ENUM_ENT(EM_MN10300, "Matsushita MN10300"), 1197 ENUM_ENT(EM_MN10200, "Matsushita MN10200"), 1198 ENUM_ENT(EM_PJ, "picoJava"), 1199 ENUM_ENT(EM_OPENRISC, "OpenRISC 32-bit embedded processor"), 1200 ENUM_ENT(EM_ARC_COMPACT, "EM_ARC_COMPACT"), 1201 ENUM_ENT(EM_XTENSA, "Tensilica Xtensa Processor"), 1202 ENUM_ENT(EM_VIDEOCORE, "Alphamosaic VideoCore processor"), 1203 ENUM_ENT(EM_TMM_GPP, "Thompson Multimedia General Purpose Processor"), 1204 ENUM_ENT(EM_NS32K, "National Semiconductor 32000 series"), 1205 ENUM_ENT(EM_TPC, "Tenor Network TPC processor"), 1206 ENUM_ENT(EM_SNP1K, "EM_SNP1K"), 1207 ENUM_ENT(EM_ST200, "STMicroelectronics ST200 microcontroller"), 1208 ENUM_ENT(EM_IP2K, "Ubicom IP2xxx 8-bit microcontrollers"), 1209 ENUM_ENT(EM_MAX, "MAX Processor"), 1210 ENUM_ENT(EM_CR, "National Semiconductor CompactRISC"), 1211 ENUM_ENT(EM_F2MC16, "Fujitsu F2MC16"), 1212 ENUM_ENT(EM_MSP430, "Texas Instruments msp430 microcontroller"), 1213 ENUM_ENT(EM_BLACKFIN, "Analog Devices Blackfin"), 1214 ENUM_ENT(EM_SE_C33, "S1C33 Family of Seiko Epson processors"), 1215 ENUM_ENT(EM_SEP, "Sharp embedded microprocessor"), 1216 ENUM_ENT(EM_ARCA, "Arca RISC microprocessor"), 1217 ENUM_ENT(EM_UNICORE, "Unicore"), 1218 ENUM_ENT(EM_EXCESS, "eXcess 16/32/64-bit configurable embedded CPU"), 1219 ENUM_ENT(EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor"), 1220 ENUM_ENT(EM_ALTERA_NIOS2, "Altera Nios"), 1221 ENUM_ENT(EM_CRX, "National Semiconductor CRX microprocessor"), 1222 ENUM_ENT(EM_XGATE, "Motorola XGATE embedded processor"), 1223 ENUM_ENT(EM_C166, "Infineon Technologies xc16x"), 1224 ENUM_ENT(EM_M16C, "Renesas M16C"), 1225 ENUM_ENT(EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller"), 1226 ENUM_ENT(EM_CE, "Freescale Communication Engine RISC core"), 1227 ENUM_ENT(EM_M32C, "Renesas M32C"), 1228 ENUM_ENT(EM_TSK3000, "Altium TSK3000 core"), 1229 ENUM_ENT(EM_RS08, "Freescale RS08 embedded processor"), 1230 ENUM_ENT(EM_SHARC, "EM_SHARC"), 1231 ENUM_ENT(EM_ECOG2, "Cyan Technology eCOG2 microprocessor"), 1232 ENUM_ENT(EM_SCORE7, "SUNPLUS S+Core"), 1233 ENUM_ENT(EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor"), 1234 ENUM_ENT(EM_VIDEOCORE3, "Broadcom VideoCore III processor"), 1235 ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"), 1236 ENUM_ENT(EM_SE_C17, "Seiko Epson C17 family"), 1237 ENUM_ENT(EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family"), 1238 ENUM_ENT(EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family"), 1239 ENUM_ENT(EM_TI_C5500, "Texas Instruments TMS320C55x DSP family"), 1240 ENUM_ENT(EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor"), 1241 ENUM_ENT(EM_CYPRESS_M8C, "Cypress M8C microprocessor"), 1242 ENUM_ENT(EM_R32C, "Renesas R32C series microprocessors"), 1243 ENUM_ENT(EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family"), 1244 ENUM_ENT(EM_HEXAGON, "Qualcomm Hexagon"), 1245 ENUM_ENT(EM_8051, "Intel 8051 and variants"), 1246 ENUM_ENT(EM_STXP7X, "STMicroelectronics STxP7x family"), 1247 ENUM_ENT(EM_NDS32, "Andes Technology compact code size embedded RISC processor family"), 1248 ENUM_ENT(EM_ECOG1, "Cyan Technology eCOG1 microprocessor"), 1249 // FIXME: Following EM_ECOG1X definitions is dead code since EM_ECOG1X has 1250 // an identical number to EM_ECOG1. 1251 ENUM_ENT(EM_ECOG1X, "Cyan Technology eCOG1X family"), 1252 ENUM_ENT(EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core microcontrollers"), 1253 ENUM_ENT(EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor"), 1254 ENUM_ENT(EM_MANIK, "M2000 Reconfigurable RISC Microprocessor"), 1255 ENUM_ENT(EM_CRAYNV2, "Cray Inc. NV2 vector architecture"), 1256 ENUM_ENT(EM_RX, "Renesas RX"), 1257 ENUM_ENT(EM_METAG, "Imagination Technologies Meta processor architecture"), 1258 ENUM_ENT(EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture"), 1259 ENUM_ENT(EM_ECOG16, "Cyan Technology eCOG16 family"), 1260 ENUM_ENT(EM_CR16, "National Semiconductor CompactRISC 16-bit processor"), 1261 ENUM_ENT(EM_ETPU, "Freescale Extended Time Processing Unit"), 1262 ENUM_ENT(EM_SLE9X, "Infineon Technologies SLE9X core"), 1263 ENUM_ENT(EM_L10M, "EM_L10M"), 1264 ENUM_ENT(EM_K10M, "EM_K10M"), 1265 ENUM_ENT(EM_AARCH64, "AArch64"), 1266 ENUM_ENT(EM_AVR32, "Atmel Corporation 32-bit microprocessor family"), 1267 ENUM_ENT(EM_STM8, "STMicroeletronics STM8 8-bit microcontroller"), 1268 ENUM_ENT(EM_TILE64, "Tilera TILE64 multicore architecture family"), 1269 ENUM_ENT(EM_TILEPRO, "Tilera TILEPro multicore architecture family"), 1270 ENUM_ENT(EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core"), 1271 ENUM_ENT(EM_CUDA, "NVIDIA CUDA architecture"), 1272 ENUM_ENT(EM_TILEGX, "Tilera TILE-Gx multicore architecture family"), 1273 ENUM_ENT(EM_CLOUDSHIELD, "EM_CLOUDSHIELD"), 1274 ENUM_ENT(EM_COREA_1ST, "EM_COREA_1ST"), 1275 ENUM_ENT(EM_COREA_2ND, "EM_COREA_2ND"), 1276 ENUM_ENT(EM_ARC_COMPACT2, "EM_ARC_COMPACT2"), 1277 ENUM_ENT(EM_OPEN8, "EM_OPEN8"), 1278 ENUM_ENT(EM_RL78, "Renesas RL78"), 1279 ENUM_ENT(EM_VIDEOCORE5, "Broadcom VideoCore V processor"), 1280 ENUM_ENT(EM_78KOR, "EM_78KOR"), 1281 ENUM_ENT(EM_56800EX, "EM_56800EX"), 1282 ENUM_ENT(EM_AMDGPU, "EM_AMDGPU"), 1283 ENUM_ENT(EM_RISCV, "RISC-V"), 1284 ENUM_ENT(EM_LANAI, "EM_LANAI"), 1285 ENUM_ENT(EM_BPF, "EM_BPF"), 1286 ENUM_ENT(EM_VE, "NEC SX-Aurora Vector Engine"), 1287 ENUM_ENT(EM_LOONGARCH, "LoongArch"), 1288 }; 1289 1290 const EnumEntry<unsigned> ElfSymbolBindings[] = { 1291 {"Local", "LOCAL", ELF::STB_LOCAL}, 1292 {"Global", "GLOBAL", ELF::STB_GLOBAL}, 1293 {"Weak", "WEAK", ELF::STB_WEAK}, 1294 {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}}; 1295 1296 const EnumEntry<unsigned> ElfSymbolVisibilities[] = { 1297 {"DEFAULT", "DEFAULT", ELF::STV_DEFAULT}, 1298 {"INTERNAL", "INTERNAL", ELF::STV_INTERNAL}, 1299 {"HIDDEN", "HIDDEN", ELF::STV_HIDDEN}, 1300 {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}}; 1301 1302 const EnumEntry<unsigned> AMDGPUSymbolTypes[] = { 1303 { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL } 1304 }; 1305 1306 static const char *getGroupType(uint32_t Flag) { 1307 if (Flag & ELF::GRP_COMDAT) 1308 return "COMDAT"; 1309 else 1310 return "(unknown)"; 1311 } 1312 1313 const EnumEntry<unsigned> ElfSectionFlags[] = { 1314 ENUM_ENT(SHF_WRITE, "W"), 1315 ENUM_ENT(SHF_ALLOC, "A"), 1316 ENUM_ENT(SHF_EXECINSTR, "X"), 1317 ENUM_ENT(SHF_MERGE, "M"), 1318 ENUM_ENT(SHF_STRINGS, "S"), 1319 ENUM_ENT(SHF_INFO_LINK, "I"), 1320 ENUM_ENT(SHF_LINK_ORDER, "L"), 1321 ENUM_ENT(SHF_OS_NONCONFORMING, "O"), 1322 ENUM_ENT(SHF_GROUP, "G"), 1323 ENUM_ENT(SHF_TLS, "T"), 1324 ENUM_ENT(SHF_COMPRESSED, "C"), 1325 ENUM_ENT(SHF_EXCLUDE, "E"), 1326 }; 1327 1328 const EnumEntry<unsigned> ElfGNUSectionFlags[] = { 1329 ENUM_ENT(SHF_GNU_RETAIN, "R") 1330 }; 1331 1332 const EnumEntry<unsigned> ElfSolarisSectionFlags[] = { 1333 ENUM_ENT(SHF_SUNW_NODISCARD, "R") 1334 }; 1335 1336 const EnumEntry<unsigned> ElfXCoreSectionFlags[] = { 1337 ENUM_ENT(XCORE_SHF_CP_SECTION, ""), 1338 ENUM_ENT(XCORE_SHF_DP_SECTION, "") 1339 }; 1340 1341 const EnumEntry<unsigned> ElfAArch64SectionFlags[] = { 1342 ENUM_ENT(SHF_AARCH64_PURECODE, "y") 1343 }; 1344 1345 const EnumEntry<unsigned> ElfARMSectionFlags[] = { 1346 ENUM_ENT(SHF_ARM_PURECODE, "y") 1347 }; 1348 1349 const EnumEntry<unsigned> ElfHexagonSectionFlags[] = { 1350 ENUM_ENT(SHF_HEX_GPREL, "") 1351 }; 1352 1353 const EnumEntry<unsigned> ElfMipsSectionFlags[] = { 1354 ENUM_ENT(SHF_MIPS_NODUPES, ""), 1355 ENUM_ENT(SHF_MIPS_NAMES, ""), 1356 ENUM_ENT(SHF_MIPS_LOCAL, ""), 1357 ENUM_ENT(SHF_MIPS_NOSTRIP, ""), 1358 ENUM_ENT(SHF_MIPS_GPREL, ""), 1359 ENUM_ENT(SHF_MIPS_MERGE, ""), 1360 ENUM_ENT(SHF_MIPS_ADDR, ""), 1361 ENUM_ENT(SHF_MIPS_STRING, "") 1362 }; 1363 1364 const EnumEntry<unsigned> ElfX86_64SectionFlags[] = { 1365 ENUM_ENT(SHF_X86_64_LARGE, "l") 1366 }; 1367 1368 static std::vector<EnumEntry<unsigned>> 1369 getSectionFlagsForTarget(unsigned EOSAbi, unsigned EMachine) { 1370 std::vector<EnumEntry<unsigned>> Ret(std::begin(ElfSectionFlags), 1371 std::end(ElfSectionFlags)); 1372 switch (EOSAbi) { 1373 case ELFOSABI_SOLARIS: 1374 llvm::append_range(Ret, ElfSolarisSectionFlags); 1375 break; 1376 default: 1377 llvm::append_range(Ret, ElfGNUSectionFlags); 1378 break; 1379 } 1380 switch (EMachine) { 1381 case EM_AARCH64: 1382 llvm::append_range(Ret, ElfAArch64SectionFlags); 1383 break; 1384 case EM_ARM: 1385 llvm::append_range(Ret, ElfARMSectionFlags); 1386 break; 1387 case EM_HEXAGON: 1388 llvm::append_range(Ret, ElfHexagonSectionFlags); 1389 break; 1390 case EM_MIPS: 1391 llvm::append_range(Ret, ElfMipsSectionFlags); 1392 break; 1393 case EM_X86_64: 1394 llvm::append_range(Ret, ElfX86_64SectionFlags); 1395 break; 1396 case EM_XCORE: 1397 llvm::append_range(Ret, ElfXCoreSectionFlags); 1398 break; 1399 default: 1400 break; 1401 } 1402 return Ret; 1403 } 1404 1405 static std::string getGNUFlags(unsigned EOSAbi, unsigned EMachine, 1406 uint64_t Flags) { 1407 // Here we are trying to build the flags string in the same way as GNU does. 1408 // It is not that straightforward. Imagine we have sh_flags == 0x90000000. 1409 // SHF_EXCLUDE ("E") has a value of 0x80000000 and SHF_MASKPROC is 0xf0000000. 1410 // GNU readelf will not print "E" or "Ep" in this case, but will print just 1411 // "p". It only will print "E" when no other processor flag is set. 1412 std::string Str; 1413 bool HasUnknownFlag = false; 1414 bool HasOSFlag = false; 1415 bool HasProcFlag = false; 1416 std::vector<EnumEntry<unsigned>> FlagsList = 1417 getSectionFlagsForTarget(EOSAbi, EMachine); 1418 while (Flags) { 1419 // Take the least significant bit as a flag. 1420 uint64_t Flag = Flags & -Flags; 1421 Flags -= Flag; 1422 1423 // Find the flag in the known flags list. 1424 auto I = llvm::find_if(FlagsList, [=](const EnumEntry<unsigned> &E) { 1425 // Flags with empty names are not printed in GNU style output. 1426 return E.Value == Flag && !E.AltName.empty(); 1427 }); 1428 if (I != FlagsList.end()) { 1429 Str += I->AltName; 1430 continue; 1431 } 1432 1433 // If we did not find a matching regular flag, then we deal with an OS 1434 // specific flag, processor specific flag or an unknown flag. 1435 if (Flag & ELF::SHF_MASKOS) { 1436 HasOSFlag = true; 1437 Flags &= ~ELF::SHF_MASKOS; 1438 } else if (Flag & ELF::SHF_MASKPROC) { 1439 HasProcFlag = true; 1440 // Mask off all the processor-specific bits. This removes the SHF_EXCLUDE 1441 // bit if set so that it doesn't also get printed. 1442 Flags &= ~ELF::SHF_MASKPROC; 1443 } else { 1444 HasUnknownFlag = true; 1445 } 1446 } 1447 1448 // "o", "p" and "x" are printed last. 1449 if (HasOSFlag) 1450 Str += "o"; 1451 if (HasProcFlag) 1452 Str += "p"; 1453 if (HasUnknownFlag) 1454 Str += "x"; 1455 return Str; 1456 } 1457 1458 static StringRef segmentTypeToString(unsigned Arch, unsigned Type) { 1459 // Check potentially overlapped processor-specific program header type. 1460 switch (Arch) { 1461 case ELF::EM_ARM: 1462 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); } 1463 break; 1464 case ELF::EM_MIPS: 1465 case ELF::EM_MIPS_RS3_LE: 1466 switch (Type) { 1467 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO); 1468 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC); 1469 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS); 1470 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS); 1471 } 1472 break; 1473 case ELF::EM_RISCV: 1474 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_RISCV_ATTRIBUTES); } 1475 } 1476 1477 switch (Type) { 1478 LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL); 1479 LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD); 1480 LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC); 1481 LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP); 1482 LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE); 1483 LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB); 1484 LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR); 1485 LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS); 1486 1487 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME); 1488 LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND); 1489 1490 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK); 1491 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO); 1492 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_PROPERTY); 1493 1494 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_MUTABLE); 1495 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE); 1496 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED); 1497 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_NOBTCFI); 1498 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_SYSCALLS); 1499 LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA); 1500 default: 1501 return ""; 1502 } 1503 } 1504 1505 static std::string getGNUPtType(unsigned Arch, unsigned Type) { 1506 StringRef Seg = segmentTypeToString(Arch, Type); 1507 if (Seg.empty()) 1508 return std::string("<unknown>: ") + to_string(format_hex(Type, 1)); 1509 1510 // E.g. "PT_ARM_EXIDX" -> "EXIDX". 1511 if (Seg.consume_front("PT_ARM_")) 1512 return Seg.str(); 1513 1514 // E.g. "PT_MIPS_REGINFO" -> "REGINFO". 1515 if (Seg.consume_front("PT_MIPS_")) 1516 return Seg.str(); 1517 1518 // E.g. "PT_RISCV_ATTRIBUTES" 1519 if (Seg.consume_front("PT_RISCV_")) 1520 return Seg.str(); 1521 1522 // E.g. "PT_LOAD" -> "LOAD". 1523 assert(Seg.starts_with("PT_")); 1524 return Seg.drop_front(3).str(); 1525 } 1526 1527 const EnumEntry<unsigned> ElfSegmentFlags[] = { 1528 LLVM_READOBJ_ENUM_ENT(ELF, PF_X), 1529 LLVM_READOBJ_ENUM_ENT(ELF, PF_W), 1530 LLVM_READOBJ_ENUM_ENT(ELF, PF_R) 1531 }; 1532 1533 const EnumEntry<unsigned> ElfHeaderMipsFlags[] = { 1534 ENUM_ENT(EF_MIPS_NOREORDER, "noreorder"), 1535 ENUM_ENT(EF_MIPS_PIC, "pic"), 1536 ENUM_ENT(EF_MIPS_CPIC, "cpic"), 1537 ENUM_ENT(EF_MIPS_ABI2, "abi2"), 1538 ENUM_ENT(EF_MIPS_32BITMODE, "32bitmode"), 1539 ENUM_ENT(EF_MIPS_FP64, "fp64"), 1540 ENUM_ENT(EF_MIPS_NAN2008, "nan2008"), 1541 ENUM_ENT(EF_MIPS_ABI_O32, "o32"), 1542 ENUM_ENT(EF_MIPS_ABI_O64, "o64"), 1543 ENUM_ENT(EF_MIPS_ABI_EABI32, "eabi32"), 1544 ENUM_ENT(EF_MIPS_ABI_EABI64, "eabi64"), 1545 ENUM_ENT(EF_MIPS_MACH_3900, "3900"), 1546 ENUM_ENT(EF_MIPS_MACH_4010, "4010"), 1547 ENUM_ENT(EF_MIPS_MACH_4100, "4100"), 1548 ENUM_ENT(EF_MIPS_MACH_4650, "4650"), 1549 ENUM_ENT(EF_MIPS_MACH_4120, "4120"), 1550 ENUM_ENT(EF_MIPS_MACH_4111, "4111"), 1551 ENUM_ENT(EF_MIPS_MACH_SB1, "sb1"), 1552 ENUM_ENT(EF_MIPS_MACH_OCTEON, "octeon"), 1553 ENUM_ENT(EF_MIPS_MACH_XLR, "xlr"), 1554 ENUM_ENT(EF_MIPS_MACH_OCTEON2, "octeon2"), 1555 ENUM_ENT(EF_MIPS_MACH_OCTEON3, "octeon3"), 1556 ENUM_ENT(EF_MIPS_MACH_5400, "5400"), 1557 ENUM_ENT(EF_MIPS_MACH_5900, "5900"), 1558 ENUM_ENT(EF_MIPS_MACH_5500, "5500"), 1559 ENUM_ENT(EF_MIPS_MACH_9000, "9000"), 1560 ENUM_ENT(EF_MIPS_MACH_LS2E, "loongson-2e"), 1561 ENUM_ENT(EF_MIPS_MACH_LS2F, "loongson-2f"), 1562 ENUM_ENT(EF_MIPS_MACH_LS3A, "loongson-3a"), 1563 ENUM_ENT(EF_MIPS_MICROMIPS, "micromips"), 1564 ENUM_ENT(EF_MIPS_ARCH_ASE_M16, "mips16"), 1565 ENUM_ENT(EF_MIPS_ARCH_ASE_MDMX, "mdmx"), 1566 ENUM_ENT(EF_MIPS_ARCH_1, "mips1"), 1567 ENUM_ENT(EF_MIPS_ARCH_2, "mips2"), 1568 ENUM_ENT(EF_MIPS_ARCH_3, "mips3"), 1569 ENUM_ENT(EF_MIPS_ARCH_4, "mips4"), 1570 ENUM_ENT(EF_MIPS_ARCH_5, "mips5"), 1571 ENUM_ENT(EF_MIPS_ARCH_32, "mips32"), 1572 ENUM_ENT(EF_MIPS_ARCH_64, "mips64"), 1573 ENUM_ENT(EF_MIPS_ARCH_32R2, "mips32r2"), 1574 ENUM_ENT(EF_MIPS_ARCH_64R2, "mips64r2"), 1575 ENUM_ENT(EF_MIPS_ARCH_32R6, "mips32r6"), 1576 ENUM_ENT(EF_MIPS_ARCH_64R6, "mips64r6") 1577 }; 1578 1579 // clang-format off 1580 #define AMDGPU_MACH_ENUM_ENTS \ 1581 ENUM_ENT(EF_AMDGPU_MACH_NONE, "none"), \ 1582 ENUM_ENT(EF_AMDGPU_MACH_R600_R600, "r600"), \ 1583 ENUM_ENT(EF_AMDGPU_MACH_R600_R630, "r630"), \ 1584 ENUM_ENT(EF_AMDGPU_MACH_R600_RS880, "rs880"), \ 1585 ENUM_ENT(EF_AMDGPU_MACH_R600_RV670, "rv670"), \ 1586 ENUM_ENT(EF_AMDGPU_MACH_R600_RV710, "rv710"), \ 1587 ENUM_ENT(EF_AMDGPU_MACH_R600_RV730, "rv730"), \ 1588 ENUM_ENT(EF_AMDGPU_MACH_R600_RV770, "rv770"), \ 1589 ENUM_ENT(EF_AMDGPU_MACH_R600_CEDAR, "cedar"), \ 1590 ENUM_ENT(EF_AMDGPU_MACH_R600_CYPRESS, "cypress"), \ 1591 ENUM_ENT(EF_AMDGPU_MACH_R600_JUNIPER, "juniper"), \ 1592 ENUM_ENT(EF_AMDGPU_MACH_R600_REDWOOD, "redwood"), \ 1593 ENUM_ENT(EF_AMDGPU_MACH_R600_SUMO, "sumo"), \ 1594 ENUM_ENT(EF_AMDGPU_MACH_R600_BARTS, "barts"), \ 1595 ENUM_ENT(EF_AMDGPU_MACH_R600_CAICOS, "caicos"), \ 1596 ENUM_ENT(EF_AMDGPU_MACH_R600_CAYMAN, "cayman"), \ 1597 ENUM_ENT(EF_AMDGPU_MACH_R600_TURKS, "turks"), \ 1598 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600"), \ 1599 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601"), \ 1600 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602"), \ 1601 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700"), \ 1602 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701"), \ 1603 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702"), \ 1604 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703"), \ 1605 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704"), \ 1606 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705"), \ 1607 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801"), \ 1608 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802"), \ 1609 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803"), \ 1610 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805"), \ 1611 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810"), \ 1612 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900"), \ 1613 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902"), \ 1614 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904"), \ 1615 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906"), \ 1616 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908"), \ 1617 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909"), \ 1618 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a"), \ 1619 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c"), \ 1620 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX942, "gfx942"), \ 1621 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX950, "gfx950"), \ 1622 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010"), \ 1623 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011"), \ 1624 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012"), \ 1625 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013"), \ 1626 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030"), \ 1627 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031"), \ 1628 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032"), \ 1629 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033"), \ 1630 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034"), \ 1631 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035"), \ 1632 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036"), \ 1633 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100"), \ 1634 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101"), \ 1635 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102"), \ 1636 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1103, "gfx1103"), \ 1637 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1150, "gfx1150"), \ 1638 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1151, "gfx1151"), \ 1639 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1152, "gfx1152"), \ 1640 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1153, "gfx1153"), \ 1641 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1200, "gfx1200"), \ 1642 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1201, "gfx1201"), \ 1643 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX1250, "gfx1250"), \ 1644 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC, "gfx9-generic"), \ 1645 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC, "gfx9-4-generic"), \ 1646 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC, "gfx10-1-generic"), \ 1647 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC, "gfx10-3-generic"), \ 1648 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC, "gfx11-generic"), \ 1649 ENUM_ENT(EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC, "gfx12-generic") 1650 // clang-format on 1651 1652 const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion3[] = { 1653 AMDGPU_MACH_ENUM_ENTS, 1654 ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_V3, "xnack"), 1655 ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_V3, "sramecc"), 1656 }; 1657 1658 const EnumEntry<unsigned> ElfHeaderAMDGPUFlagsABIVersion4[] = { 1659 AMDGPU_MACH_ENUM_ENTS, 1660 ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_ANY_V4, "xnack"), 1661 ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_OFF_V4, "xnack-"), 1662 ENUM_ENT(EF_AMDGPU_FEATURE_XNACK_ON_V4, "xnack+"), 1663 ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_ANY_V4, "sramecc"), 1664 ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_OFF_V4, "sramecc-"), 1665 ENUM_ENT(EF_AMDGPU_FEATURE_SRAMECC_ON_V4, "sramecc+"), 1666 }; 1667 1668 const EnumEntry<unsigned> ElfHeaderNVPTXFlags[] = { 1669 ENUM_ENT(EF_CUDA_SM20, "sm_20"), 1670 ENUM_ENT(EF_CUDA_SM21, "sm_21"), 1671 ENUM_ENT(EF_CUDA_SM30, "sm_30"), 1672 ENUM_ENT(EF_CUDA_SM32, "sm_32"), 1673 ENUM_ENT(EF_CUDA_SM35, "sm_35"), 1674 ENUM_ENT(EF_CUDA_SM37, "sm_37"), 1675 ENUM_ENT(EF_CUDA_SM50, "sm_50"), 1676 ENUM_ENT(EF_CUDA_SM52, "sm_52"), 1677 ENUM_ENT(EF_CUDA_SM53, "sm_53"), 1678 ENUM_ENT(EF_CUDA_SM60, "sm_60"), 1679 ENUM_ENT(EF_CUDA_SM61, "sm_61"), 1680 ENUM_ENT(EF_CUDA_SM62, "sm_62"), 1681 ENUM_ENT(EF_CUDA_SM70, "sm_70"), 1682 ENUM_ENT(EF_CUDA_SM72, "sm_72"), 1683 ENUM_ENT(EF_CUDA_SM75, "sm_75"), 1684 ENUM_ENT(EF_CUDA_SM80, "sm_80"), 1685 ENUM_ENT(EF_CUDA_SM86, "sm_86"), 1686 ENUM_ENT(EF_CUDA_SM87, "sm_87"), 1687 ENUM_ENT(EF_CUDA_SM88, "sm_88"), 1688 ENUM_ENT(EF_CUDA_SM89, "sm_89"), 1689 ENUM_ENT(EF_CUDA_SM90, "sm_90"), 1690 ENUM_ENT(EF_CUDA_SM100, "sm_100"), 1691 ENUM_ENT(EF_CUDA_SM101, "sm_101"), 1692 ENUM_ENT(EF_CUDA_SM103, "sm_103"), 1693 ENUM_ENT(EF_CUDA_SM110, "sm_110"), 1694 ENUM_ENT(EF_CUDA_SM120, "sm_120"), 1695 ENUM_ENT(EF_CUDA_SM121, "sm_121"), 1696 ENUM_ENT(EF_CUDA_SM20 << EF_CUDA_SM_OFFSET, "sm_20"), 1697 ENUM_ENT(EF_CUDA_SM21 << EF_CUDA_SM_OFFSET, "sm_21"), 1698 ENUM_ENT(EF_CUDA_SM30 << EF_CUDA_SM_OFFSET, "sm_30"), 1699 ENUM_ENT(EF_CUDA_SM32 << EF_CUDA_SM_OFFSET, "sm_32"), 1700 ENUM_ENT(EF_CUDA_SM35 << EF_CUDA_SM_OFFSET, "sm_35"), 1701 ENUM_ENT(EF_CUDA_SM37 << EF_CUDA_SM_OFFSET, "sm_37"), 1702 ENUM_ENT(EF_CUDA_SM50 << EF_CUDA_SM_OFFSET, "sm_50"), 1703 ENUM_ENT(EF_CUDA_SM52 << EF_CUDA_SM_OFFSET, "sm_52"), 1704 ENUM_ENT(EF_CUDA_SM53 << EF_CUDA_SM_OFFSET, "sm_53"), 1705 ENUM_ENT(EF_CUDA_SM60 << EF_CUDA_SM_OFFSET, "sm_60"), 1706 ENUM_ENT(EF_CUDA_SM61 << EF_CUDA_SM_OFFSET, "sm_61"), 1707 ENUM_ENT(EF_CUDA_SM62 << EF_CUDA_SM_OFFSET, "sm_62"), 1708 ENUM_ENT(EF_CUDA_SM70 << EF_CUDA_SM_OFFSET, "sm_70"), 1709 ENUM_ENT(EF_CUDA_SM72 << EF_CUDA_SM_OFFSET, "sm_72"), 1710 ENUM_ENT(EF_CUDA_SM75 << EF_CUDA_SM_OFFSET, "sm_75"), 1711 ENUM_ENT(EF_CUDA_SM80 << EF_CUDA_SM_OFFSET, "sm_80"), 1712 ENUM_ENT(EF_CUDA_SM86 << EF_CUDA_SM_OFFSET, "sm_86"), 1713 ENUM_ENT(EF_CUDA_SM87 << EF_CUDA_SM_OFFSET, "sm_87"), 1714 ENUM_ENT(EF_CUDA_SM88 << EF_CUDA_SM_OFFSET, "sm_88"), 1715 ENUM_ENT(EF_CUDA_SM89 << EF_CUDA_SM_OFFSET, "sm_89"), 1716 ENUM_ENT(EF_CUDA_SM90 << EF_CUDA_SM_OFFSET, "sm_90"), 1717 ENUM_ENT(EF_CUDA_SM100 << EF_CUDA_SM_OFFSET, "sm_100"), 1718 ENUM_ENT(EF_CUDA_SM101 << EF_CUDA_SM_OFFSET, "sm_101"), 1719 ENUM_ENT(EF_CUDA_SM103 << EF_CUDA_SM_OFFSET, "sm_103"), 1720 ENUM_ENT(EF_CUDA_SM110 << EF_CUDA_SM_OFFSET, "sm_110"), 1721 ENUM_ENT(EF_CUDA_SM120 << EF_CUDA_SM_OFFSET, "sm_120"), 1722 ENUM_ENT(EF_CUDA_SM121 << EF_CUDA_SM_OFFSET, "sm_121"), 1723 }; 1724 1725 const EnumEntry<unsigned> ElfHeaderRISCVFlags[] = { 1726 ENUM_ENT(EF_RISCV_RVC, "RVC"), 1727 ENUM_ENT(EF_RISCV_FLOAT_ABI_SINGLE, "single-float ABI"), 1728 ENUM_ENT(EF_RISCV_FLOAT_ABI_DOUBLE, "double-float ABI"), 1729 ENUM_ENT(EF_RISCV_FLOAT_ABI_QUAD, "quad-float ABI"), 1730 ENUM_ENT(EF_RISCV_RVE, "RVE"), 1731 ENUM_ENT(EF_RISCV_TSO, "TSO"), 1732 }; 1733 1734 const EnumEntry<unsigned> ElfHeaderSPARCFlags[] = { 1735 ENUM_ENT(EF_SPARC_32PLUS, "V8+ ABI"), 1736 ENUM_ENT(EF_SPARC_SUN_US1, "Sun UltraSPARC I extensions"), 1737 ENUM_ENT(EF_SPARC_HAL_R1, "HAL/Fujitsu R1 extensions"), 1738 ENUM_ENT(EF_SPARC_SUN_US3, "Sun UltraSPARC III extensions"), 1739 ENUM_ENT(EF_SPARCV9_TSO, "Total Store Ordering"), 1740 ENUM_ENT(EF_SPARCV9_PSO, "Partial Store Ordering"), 1741 ENUM_ENT(EF_SPARCV9_RMO, "Relaxed Memory Ordering"), 1742 }; 1743 1744 const EnumEntry<unsigned> ElfHeaderAVRFlags[] = { 1745 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR1), 1746 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR2), 1747 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR25), 1748 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR3), 1749 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR31), 1750 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR35), 1751 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR4), 1752 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR5), 1753 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR51), 1754 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVR6), 1755 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_AVRTINY), 1756 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA1), 1757 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA2), 1758 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA3), 1759 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA4), 1760 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA5), 1761 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA6), 1762 LLVM_READOBJ_ENUM_ENT(ELF, EF_AVR_ARCH_XMEGA7), 1763 ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"), 1764 }; 1765 1766 const EnumEntry<unsigned> ElfHeaderLoongArchFlags[] = { 1767 ENUM_ENT(EF_LOONGARCH_ABI_SOFT_FLOAT, "SOFT-FLOAT"), 1768 ENUM_ENT(EF_LOONGARCH_ABI_SINGLE_FLOAT, "SINGLE-FLOAT"), 1769 ENUM_ENT(EF_LOONGARCH_ABI_DOUBLE_FLOAT, "DOUBLE-FLOAT"), 1770 ENUM_ENT(EF_LOONGARCH_OBJABI_V0, "OBJ-v0"), 1771 ENUM_ENT(EF_LOONGARCH_OBJABI_V1, "OBJ-v1"), 1772 }; 1773 1774 static const EnumEntry<unsigned> ElfHeaderXtensaFlags[] = { 1775 LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_MACH_NONE), 1776 LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_INSN), 1777 LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_LIT) 1778 }; 1779 1780 const EnumEntry<unsigned> ElfSymOtherFlags[] = { 1781 LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL), 1782 LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN), 1783 LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED) 1784 }; 1785 1786 const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = { 1787 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL), 1788 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT), 1789 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC), 1790 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS) 1791 }; 1792 1793 const EnumEntry<unsigned> ElfAArch64SymOtherFlags[] = { 1794 LLVM_READOBJ_ENUM_ENT(ELF, STO_AARCH64_VARIANT_PCS) 1795 }; 1796 1797 const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = { 1798 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL), 1799 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT), 1800 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16) 1801 }; 1802 1803 const EnumEntry<unsigned> ElfRISCVSymOtherFlags[] = { 1804 LLVM_READOBJ_ENUM_ENT(ELF, STO_RISCV_VARIANT_CC)}; 1805 1806 static const char *getElfMipsOptionsOdkType(unsigned Odk) { 1807 switch (Odk) { 1808 LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL); 1809 LLVM_READOBJ_ENUM_CASE(ELF, ODK_REGINFO); 1810 LLVM_READOBJ_ENUM_CASE(ELF, ODK_EXCEPTIONS); 1811 LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAD); 1812 LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWPATCH); 1813 LLVM_READOBJ_ENUM_CASE(ELF, ODK_FILL); 1814 LLVM_READOBJ_ENUM_CASE(ELF, ODK_TAGS); 1815 LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWAND); 1816 LLVM_READOBJ_ENUM_CASE(ELF, ODK_HWOR); 1817 LLVM_READOBJ_ENUM_CASE(ELF, ODK_GP_GROUP); 1818 LLVM_READOBJ_ENUM_CASE(ELF, ODK_IDENT); 1819 LLVM_READOBJ_ENUM_CASE(ELF, ODK_PAGESIZE); 1820 default: 1821 return "Unknown"; 1822 } 1823 } 1824 1825 template <typename ELFT> 1826 std::pair<const typename ELFT::Phdr *, const typename ELFT::Shdr *> 1827 ELFDumper<ELFT>::findDynamic() { 1828 // Try to locate the PT_DYNAMIC header. 1829 const Elf_Phdr *DynamicPhdr = nullptr; 1830 if (Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = Obj.program_headers()) { 1831 for (const Elf_Phdr &Phdr : *PhdrsOrErr) { 1832 if (Phdr.p_type != ELF::PT_DYNAMIC) 1833 continue; 1834 DynamicPhdr = &Phdr; 1835 break; 1836 } 1837 } else { 1838 reportUniqueWarning( 1839 "unable to read program headers to locate the PT_DYNAMIC segment: " + 1840 toString(PhdrsOrErr.takeError())); 1841 } 1842 1843 // Try to locate the .dynamic section in the sections header table. 1844 const Elf_Shdr *DynamicSec = nullptr; 1845 for (const Elf_Shdr &Sec : cantFail(Obj.sections())) { 1846 if (Sec.sh_type != ELF::SHT_DYNAMIC) 1847 continue; 1848 DynamicSec = &Sec; 1849 break; 1850 } 1851 1852 if (DynamicPhdr && ((DynamicPhdr->p_offset + DynamicPhdr->p_filesz > 1853 ObjF.getMemoryBufferRef().getBufferSize()) || 1854 (DynamicPhdr->p_offset + DynamicPhdr->p_filesz < 1855 DynamicPhdr->p_offset))) { 1856 reportUniqueWarning( 1857 "PT_DYNAMIC segment offset (0x" + 1858 Twine::utohexstr(DynamicPhdr->p_offset) + ") + file size (0x" + 1859 Twine::utohexstr(DynamicPhdr->p_filesz) + 1860 ") exceeds the size of the file (0x" + 1861 Twine::utohexstr(ObjF.getMemoryBufferRef().getBufferSize()) + ")"); 1862 // Don't use the broken dynamic header. 1863 DynamicPhdr = nullptr; 1864 } 1865 1866 if (DynamicPhdr && DynamicSec) { 1867 if (DynamicSec->sh_addr + DynamicSec->sh_size > 1868 DynamicPhdr->p_vaddr + DynamicPhdr->p_memsz || 1869 DynamicSec->sh_addr < DynamicPhdr->p_vaddr) 1870 reportUniqueWarning(describe(*DynamicSec) + 1871 " is not contained within the " 1872 "PT_DYNAMIC segment"); 1873 1874 if (DynamicSec->sh_addr != DynamicPhdr->p_vaddr) 1875 reportUniqueWarning(describe(*DynamicSec) + " is not at the start of " 1876 "PT_DYNAMIC segment"); 1877 } 1878 1879 return std::make_pair(DynamicPhdr, DynamicSec); 1880 } 1881 1882 template <typename ELFT> 1883 void ELFDumper<ELFT>::loadDynamicTable() { 1884 const Elf_Phdr *DynamicPhdr; 1885 const Elf_Shdr *DynamicSec; 1886 std::tie(DynamicPhdr, DynamicSec) = findDynamic(); 1887 if (!DynamicPhdr && !DynamicSec) 1888 return; 1889 1890 DynRegionInfo FromPhdr(ObjF, *this); 1891 bool IsPhdrTableValid = false; 1892 if (DynamicPhdr) { 1893 // Use cantFail(), because p_offset/p_filesz fields of a PT_DYNAMIC are 1894 // validated in findDynamic() and so createDRI() is not expected to fail. 1895 FromPhdr = cantFail(createDRI(DynamicPhdr->p_offset, DynamicPhdr->p_filesz, 1896 sizeof(Elf_Dyn))); 1897 FromPhdr.SizePrintName = "PT_DYNAMIC size"; 1898 FromPhdr.EntSizePrintName = ""; 1899 IsPhdrTableValid = !FromPhdr.template getAsArrayRef<Elf_Dyn>().empty(); 1900 } 1901 1902 // Locate the dynamic table described in a section header. 1903 // Ignore sh_entsize and use the expected value for entry size explicitly. 1904 // This allows us to dump dynamic sections with a broken sh_entsize 1905 // field. 1906 DynRegionInfo FromSec(ObjF, *this); 1907 bool IsSecTableValid = false; 1908 if (DynamicSec) { 1909 Expected<DynRegionInfo> RegOrErr = 1910 createDRI(DynamicSec->sh_offset, DynamicSec->sh_size, sizeof(Elf_Dyn)); 1911 if (RegOrErr) { 1912 FromSec = *RegOrErr; 1913 FromSec.Context = describe(*DynamicSec); 1914 FromSec.EntSizePrintName = ""; 1915 IsSecTableValid = !FromSec.template getAsArrayRef<Elf_Dyn>().empty(); 1916 } else { 1917 reportUniqueWarning("unable to read the dynamic table from " + 1918 describe(*DynamicSec) + ": " + 1919 toString(RegOrErr.takeError())); 1920 } 1921 } 1922 1923 // When we only have information from one of the SHT_DYNAMIC section header or 1924 // PT_DYNAMIC program header, just use that. 1925 if (!DynamicPhdr || !DynamicSec) { 1926 if ((DynamicPhdr && IsPhdrTableValid) || (DynamicSec && IsSecTableValid)) { 1927 DynamicTable = DynamicPhdr ? FromPhdr : FromSec; 1928 parseDynamicTable(); 1929 } else { 1930 reportUniqueWarning("no valid dynamic table was found"); 1931 } 1932 return; 1933 } 1934 1935 // At this point we have tables found from the section header and from the 1936 // dynamic segment. Usually they match, but we have to do sanity checks to 1937 // verify that. 1938 1939 if (FromPhdr.Addr != FromSec.Addr) 1940 reportUniqueWarning("SHT_DYNAMIC section header and PT_DYNAMIC " 1941 "program header disagree about " 1942 "the location of the dynamic table"); 1943 1944 if (!IsPhdrTableValid && !IsSecTableValid) { 1945 reportUniqueWarning("no valid dynamic table was found"); 1946 return; 1947 } 1948 1949 // Information in the PT_DYNAMIC program header has priority over the 1950 // information in a section header. 1951 if (IsPhdrTableValid) { 1952 if (!IsSecTableValid) 1953 reportUniqueWarning( 1954 "SHT_DYNAMIC dynamic table is invalid: PT_DYNAMIC will be used"); 1955 DynamicTable = FromPhdr; 1956 } else { 1957 reportUniqueWarning( 1958 "PT_DYNAMIC dynamic table is invalid: SHT_DYNAMIC will be used"); 1959 DynamicTable = FromSec; 1960 } 1961 1962 parseDynamicTable(); 1963 } 1964 1965 template <typename ELFT> 1966 ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> &O, 1967 ScopedPrinter &Writer) 1968 : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(O.getELFFile()), 1969 FileName(O.getFileName()), DynRelRegion(O, *this), 1970 DynRelaRegion(O, *this), DynCrelRegion(O, *this), DynRelrRegion(O, *this), 1971 DynPLTRelRegion(O, *this), DynSymTabShndxRegion(O, *this), 1972 DynamicTable(O, *this) { 1973 if (!O.IsContentValid()) 1974 return; 1975 1976 typename ELFT::ShdrRange Sections = cantFail(Obj.sections()); 1977 for (const Elf_Shdr &Sec : Sections) { 1978 switch (Sec.sh_type) { 1979 case ELF::SHT_SYMTAB: 1980 if (!DotSymtabSec) 1981 DotSymtabSec = &Sec; 1982 break; 1983 case ELF::SHT_DYNSYM: 1984 if (!DotDynsymSec) 1985 DotDynsymSec = &Sec; 1986 1987 if (!DynSymRegion) { 1988 Expected<DynRegionInfo> RegOrErr = 1989 createDRI(Sec.sh_offset, Sec.sh_size, Sec.sh_entsize); 1990 if (RegOrErr) { 1991 DynSymRegion = *RegOrErr; 1992 DynSymRegion->Context = describe(Sec); 1993 1994 if (Expected<StringRef> E = Obj.getStringTableForSymtab(Sec)) 1995 DynamicStringTable = *E; 1996 else 1997 reportUniqueWarning("unable to get the string table for the " + 1998 describe(Sec) + ": " + toString(E.takeError())); 1999 } else { 2000 reportUniqueWarning("unable to read dynamic symbols from " + 2001 describe(Sec) + ": " + 2002 toString(RegOrErr.takeError())); 2003 } 2004 } 2005 break; 2006 case ELF::SHT_SYMTAB_SHNDX: { 2007 uint32_t SymtabNdx = Sec.sh_link; 2008 if (SymtabNdx >= Sections.size()) { 2009 reportUniqueWarning( 2010 "unable to get the associated symbol table for " + describe(Sec) + 2011 ": sh_link (" + Twine(SymtabNdx) + 2012 ") is greater than or equal to the total number of sections (" + 2013 Twine(Sections.size()) + ")"); 2014 continue; 2015 } 2016 2017 if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr = 2018 Obj.getSHNDXTable(Sec)) { 2019 if (!ShndxTables.insert({&Sections[SymtabNdx], *ShndxTableOrErr}) 2020 .second) 2021 reportUniqueWarning( 2022 "multiple SHT_SYMTAB_SHNDX sections are linked to " + 2023 describe(Sec)); 2024 } else { 2025 reportUniqueWarning(ShndxTableOrErr.takeError()); 2026 } 2027 break; 2028 } 2029 case ELF::SHT_GNU_versym: 2030 if (!SymbolVersionSection) 2031 SymbolVersionSection = &Sec; 2032 break; 2033 case ELF::SHT_GNU_verdef: 2034 if (!SymbolVersionDefSection) 2035 SymbolVersionDefSection = &Sec; 2036 break; 2037 case ELF::SHT_GNU_verneed: 2038 if (!SymbolVersionNeedSection) 2039 SymbolVersionNeedSection = &Sec; 2040 break; 2041 case ELF::SHT_LLVM_ADDRSIG: 2042 if (!DotAddrsigSec) 2043 DotAddrsigSec = &Sec; 2044 break; 2045 } 2046 } 2047 2048 loadDynamicTable(); 2049 } 2050 2051 template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() { 2052 auto toMappedAddr = [&](uint64_t Tag, uint64_t VAddr) -> const uint8_t * { 2053 auto MappedAddrOrError = Obj.toMappedAddr(VAddr, [&](const Twine &Msg) { 2054 this->reportUniqueWarning(Msg); 2055 return Error::success(); 2056 }); 2057 if (!MappedAddrOrError) { 2058 this->reportUniqueWarning("unable to parse DT_" + 2059 Obj.getDynamicTagAsString(Tag) + ": " + 2060 llvm::toString(MappedAddrOrError.takeError())); 2061 return nullptr; 2062 } 2063 return MappedAddrOrError.get(); 2064 }; 2065 2066 const char *StringTableBegin = nullptr; 2067 uint64_t StringTableSize = 0; 2068 std::optional<DynRegionInfo> DynSymFromTable; 2069 for (const Elf_Dyn &Dyn : dynamic_table()) { 2070 if (Obj.getHeader().e_machine == EM_AARCH64) { 2071 switch (Dyn.d_tag) { 2072 case ELF::DT_AARCH64_AUTH_RELRSZ: 2073 DynRelrRegion.Size = Dyn.getVal(); 2074 DynRelrRegion.SizePrintName = "DT_AARCH64_AUTH_RELRSZ value"; 2075 continue; 2076 case ELF::DT_AARCH64_AUTH_RELRENT: 2077 DynRelrRegion.EntSize = Dyn.getVal(); 2078 DynRelrRegion.EntSizePrintName = "DT_AARCH64_AUTH_RELRENT value"; 2079 continue; 2080 } 2081 } 2082 switch (Dyn.d_tag) { 2083 case ELF::DT_HASH: 2084 HashTable = reinterpret_cast<const Elf_Hash *>( 2085 toMappedAddr(Dyn.getTag(), Dyn.getPtr())); 2086 break; 2087 case ELF::DT_GNU_HASH: 2088 GnuHashTable = reinterpret_cast<const Elf_GnuHash *>( 2089 toMappedAddr(Dyn.getTag(), Dyn.getPtr())); 2090 break; 2091 case ELF::DT_STRTAB: 2092 StringTableBegin = reinterpret_cast<const char *>( 2093 toMappedAddr(Dyn.getTag(), Dyn.getPtr())); 2094 break; 2095 case ELF::DT_STRSZ: 2096 StringTableSize = Dyn.getVal(); 2097 break; 2098 case ELF::DT_SYMTAB: { 2099 // If we can't map the DT_SYMTAB value to an address (e.g. when there are 2100 // no program headers), we ignore its value. 2101 if (const uint8_t *VA = toMappedAddr(Dyn.getTag(), Dyn.getPtr())) { 2102 DynSymFromTable.emplace(ObjF, *this); 2103 DynSymFromTable->Addr = VA; 2104 DynSymFromTable->EntSize = sizeof(Elf_Sym); 2105 DynSymFromTable->EntSizePrintName = ""; 2106 } 2107 break; 2108 } 2109 case ELF::DT_SYMENT: { 2110 uint64_t Val = Dyn.getVal(); 2111 if (Val != sizeof(Elf_Sym)) 2112 this->reportUniqueWarning("DT_SYMENT value of 0x" + 2113 Twine::utohexstr(Val) + 2114 " is not the size of a symbol (0x" + 2115 Twine::utohexstr(sizeof(Elf_Sym)) + ")"); 2116 break; 2117 } 2118 case ELF::DT_RELA: 2119 DynRelaRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); 2120 break; 2121 case ELF::DT_RELASZ: 2122 DynRelaRegion.Size = Dyn.getVal(); 2123 DynRelaRegion.SizePrintName = "DT_RELASZ value"; 2124 break; 2125 case ELF::DT_RELAENT: 2126 DynRelaRegion.EntSize = Dyn.getVal(); 2127 DynRelaRegion.EntSizePrintName = "DT_RELAENT value"; 2128 break; 2129 case ELF::DT_CREL: 2130 DynCrelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); 2131 break; 2132 case ELF::DT_SONAME: 2133 SONameOffset = Dyn.getVal(); 2134 break; 2135 case ELF::DT_REL: 2136 DynRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); 2137 break; 2138 case ELF::DT_RELSZ: 2139 DynRelRegion.Size = Dyn.getVal(); 2140 DynRelRegion.SizePrintName = "DT_RELSZ value"; 2141 break; 2142 case ELF::DT_RELENT: 2143 DynRelRegion.EntSize = Dyn.getVal(); 2144 DynRelRegion.EntSizePrintName = "DT_RELENT value"; 2145 break; 2146 case ELF::DT_RELR: 2147 case ELF::DT_ANDROID_RELR: 2148 case ELF::DT_AARCH64_AUTH_RELR: 2149 DynRelrRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); 2150 break; 2151 case ELF::DT_RELRSZ: 2152 case ELF::DT_ANDROID_RELRSZ: 2153 case ELF::DT_AARCH64_AUTH_RELRSZ: 2154 DynRelrRegion.Size = Dyn.getVal(); 2155 DynRelrRegion.SizePrintName = Dyn.d_tag == ELF::DT_RELRSZ 2156 ? "DT_RELRSZ value" 2157 : "DT_ANDROID_RELRSZ value"; 2158 break; 2159 case ELF::DT_RELRENT: 2160 case ELF::DT_ANDROID_RELRENT: 2161 case ELF::DT_AARCH64_AUTH_RELRENT: 2162 DynRelrRegion.EntSize = Dyn.getVal(); 2163 DynRelrRegion.EntSizePrintName = Dyn.d_tag == ELF::DT_RELRENT 2164 ? "DT_RELRENT value" 2165 : "DT_ANDROID_RELRENT value"; 2166 break; 2167 case ELF::DT_PLTREL: 2168 if (Dyn.getVal() == DT_REL) 2169 DynPLTRelRegion.EntSize = sizeof(Elf_Rel); 2170 else if (Dyn.getVal() == DT_RELA) 2171 DynPLTRelRegion.EntSize = sizeof(Elf_Rela); 2172 else if (Dyn.getVal() == DT_CREL) 2173 DynPLTRelRegion.EntSize = 1; 2174 else 2175 reportUniqueWarning(Twine("unknown DT_PLTREL value of ") + 2176 Twine((uint64_t)Dyn.getVal())); 2177 DynPLTRelRegion.EntSizePrintName = "PLTREL entry size"; 2178 break; 2179 case ELF::DT_JMPREL: 2180 DynPLTRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); 2181 break; 2182 case ELF::DT_PLTRELSZ: 2183 DynPLTRelRegion.Size = Dyn.getVal(); 2184 DynPLTRelRegion.SizePrintName = "DT_PLTRELSZ value"; 2185 break; 2186 case ELF::DT_SYMTAB_SHNDX: 2187 DynSymTabShndxRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); 2188 DynSymTabShndxRegion.EntSize = sizeof(Elf_Word); 2189 break; 2190 } 2191 } 2192 2193 if (StringTableBegin) { 2194 const uint64_t FileSize = Obj.getBufSize(); 2195 const uint64_t Offset = (const uint8_t *)StringTableBegin - Obj.base(); 2196 if (StringTableSize > FileSize - Offset) 2197 reportUniqueWarning( 2198 "the dynamic string table at 0x" + Twine::utohexstr(Offset) + 2199 " goes past the end of the file (0x" + Twine::utohexstr(FileSize) + 2200 ") with DT_STRSZ = 0x" + Twine::utohexstr(StringTableSize)); 2201 else 2202 DynamicStringTable = StringRef(StringTableBegin, StringTableSize); 2203 } 2204 2205 const bool IsHashTableSupported = getHashTableEntSize() == 4; 2206 if (DynSymRegion) { 2207 // Often we find the information about the dynamic symbol table 2208 // location in the SHT_DYNSYM section header. However, the value in 2209 // DT_SYMTAB has priority, because it is used by dynamic loaders to 2210 // locate .dynsym at runtime. The location we find in the section header 2211 // and the location we find here should match. 2212 if (DynSymFromTable && DynSymFromTable->Addr != DynSymRegion->Addr) 2213 reportUniqueWarning( 2214 createError("SHT_DYNSYM section header and DT_SYMTAB disagree about " 2215 "the location of the dynamic symbol table")); 2216 2217 // According to the ELF gABI: "The number of symbol table entries should 2218 // equal nchain". Check to see if the DT_HASH hash table nchain value 2219 // conflicts with the number of symbols in the dynamic symbol table 2220 // according to the section header. 2221 if (HashTable && IsHashTableSupported) { 2222 if (DynSymRegion->EntSize == 0) 2223 reportUniqueWarning("SHT_DYNSYM section has sh_entsize == 0"); 2224 else if (HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize) 2225 reportUniqueWarning( 2226 "hash table nchain (" + Twine(HashTable->nchain) + 2227 ") differs from symbol count derived from SHT_DYNSYM section " 2228 "header (" + 2229 Twine(DynSymRegion->Size / DynSymRegion->EntSize) + ")"); 2230 } 2231 } 2232 2233 // Delay the creation of the actual dynamic symbol table until now, so that 2234 // checks can always be made against the section header-based properties, 2235 // without worrying about tag order. 2236 if (DynSymFromTable) { 2237 if (!DynSymRegion) { 2238 DynSymRegion = DynSymFromTable; 2239 } else { 2240 DynSymRegion->Addr = DynSymFromTable->Addr; 2241 DynSymRegion->EntSize = DynSymFromTable->EntSize; 2242 DynSymRegion->EntSizePrintName = DynSymFromTable->EntSizePrintName; 2243 } 2244 } 2245 2246 // Derive the dynamic symbol table size from the DT_HASH hash table, if 2247 // present. 2248 if (HashTable && IsHashTableSupported && DynSymRegion) { 2249 const uint64_t FileSize = Obj.getBufSize(); 2250 const uint64_t DerivedSize = 2251 (uint64_t)HashTable->nchain * DynSymRegion->EntSize; 2252 const uint64_t Offset = (const uint8_t *)DynSymRegion->Addr - Obj.base(); 2253 if (DerivedSize > FileSize - Offset) 2254 reportUniqueWarning( 2255 "the size (0x" + Twine::utohexstr(DerivedSize) + 2256 ") of the dynamic symbol table at 0x" + Twine::utohexstr(Offset) + 2257 ", derived from the hash table, goes past the end of the file (0x" + 2258 Twine::utohexstr(FileSize) + ") and will be ignored"); 2259 else 2260 DynSymRegion->Size = HashTable->nchain * DynSymRegion->EntSize; 2261 } 2262 } 2263 2264 template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() { 2265 // Dump version symbol section. 2266 printVersionSymbolSection(SymbolVersionSection); 2267 2268 // Dump version definition section. 2269 printVersionDefinitionSection(SymbolVersionDefSection); 2270 2271 // Dump version dependency section. 2272 printVersionDependencySection(SymbolVersionNeedSection); 2273 } 2274 2275 #define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \ 2276 { #enum, prefix##_##enum } 2277 2278 const EnumEntry<unsigned> ElfDynamicDTFlags[] = { 2279 LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN), 2280 LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC), 2281 LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL), 2282 LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW), 2283 LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS) 2284 }; 2285 2286 const EnumEntry<unsigned> ElfDynamicDTFlags1[] = { 2287 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW), 2288 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL), 2289 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP), 2290 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE), 2291 LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR), 2292 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST), 2293 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN), 2294 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN), 2295 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT), 2296 LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS), 2297 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE), 2298 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB), 2299 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP), 2300 LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT), 2301 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE), 2302 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE), 2303 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELPND), 2304 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT), 2305 LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF), 2306 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS), 2307 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR), 2308 LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED), 2309 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC), 2310 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE), 2311 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT), 2312 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON), 2313 LLVM_READOBJ_DT_FLAG_ENT(DF_1, PIE), 2314 }; 2315 2316 const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = { 2317 LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE), 2318 LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART), 2319 LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT), 2320 LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT), 2321 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE), 2322 LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY), 2323 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT), 2324 LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS), 2325 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT), 2326 LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE), 2327 LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD), 2328 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART), 2329 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED), 2330 LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD), 2331 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF), 2332 LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE) 2333 }; 2334 2335 #undef LLVM_READOBJ_DT_FLAG_ENT 2336 2337 template <typename T, typename TFlag> 2338 void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) { 2339 SmallVector<EnumEntry<TFlag>, 10> SetFlags; 2340 for (const EnumEntry<TFlag> &Flag : Flags) 2341 if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value) 2342 SetFlags.push_back(Flag); 2343 2344 for (const EnumEntry<TFlag> &Flag : SetFlags) 2345 OS << Flag.Name << " "; 2346 } 2347 2348 template <class ELFT> 2349 const typename ELFT::Shdr * 2350 ELFDumper<ELFT>::findSectionByName(StringRef Name) const { 2351 for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) { 2352 if (Expected<StringRef> NameOrErr = Obj.getSectionName(Shdr)) { 2353 if (*NameOrErr == Name) 2354 return &Shdr; 2355 } else { 2356 reportUniqueWarning("unable to read the name of " + describe(Shdr) + 2357 ": " + toString(NameOrErr.takeError())); 2358 } 2359 } 2360 return nullptr; 2361 } 2362 2363 template <class ELFT> 2364 std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type, 2365 uint64_t Value) const { 2366 auto FormatHexValue = [](uint64_t V) { 2367 std::string Str; 2368 raw_string_ostream OS(Str); 2369 const char *ConvChar = 2370 (opts::Output == opts::GNU) ? "0x%" PRIx64 : "0x%" PRIX64; 2371 OS << format(ConvChar, V); 2372 return Str; 2373 }; 2374 2375 auto FormatFlags = [](uint64_t V, 2376 llvm::ArrayRef<llvm::EnumEntry<unsigned int>> Array) { 2377 std::string Str; 2378 raw_string_ostream OS(Str); 2379 printFlags(V, Array, OS); 2380 return Str; 2381 }; 2382 2383 // Handle custom printing of architecture specific tags 2384 switch (Obj.getHeader().e_machine) { 2385 case EM_AARCH64: 2386 switch (Type) { 2387 case DT_AARCH64_BTI_PLT: 2388 case DT_AARCH64_PAC_PLT: 2389 case DT_AARCH64_VARIANT_PCS: 2390 case DT_AARCH64_MEMTAG_GLOBALSSZ: 2391 return std::to_string(Value); 2392 case DT_AARCH64_MEMTAG_MODE: 2393 switch (Value) { 2394 case 0: 2395 return "Synchronous (0)"; 2396 case 1: 2397 return "Asynchronous (1)"; 2398 default: 2399 return (Twine("Unknown (") + Twine(Value) + ")").str(); 2400 } 2401 case DT_AARCH64_MEMTAG_HEAP: 2402 case DT_AARCH64_MEMTAG_STACK: 2403 switch (Value) { 2404 case 0: 2405 return "Disabled (0)"; 2406 case 1: 2407 return "Enabled (1)"; 2408 default: 2409 return (Twine("Unknown (") + Twine(Value) + ")").str(); 2410 } 2411 case DT_AARCH64_MEMTAG_GLOBALS: 2412 return (Twine("0x") + utohexstr(Value, /*LowerCase=*/true)).str(); 2413 default: 2414 break; 2415 } 2416 break; 2417 case EM_HEXAGON: 2418 switch (Type) { 2419 case DT_HEXAGON_VER: 2420 return std::to_string(Value); 2421 case DT_HEXAGON_SYMSZ: 2422 case DT_HEXAGON_PLT: 2423 return FormatHexValue(Value); 2424 default: 2425 break; 2426 } 2427 break; 2428 case EM_MIPS: 2429 switch (Type) { 2430 case DT_MIPS_RLD_VERSION: 2431 case DT_MIPS_LOCAL_GOTNO: 2432 case DT_MIPS_SYMTABNO: 2433 case DT_MIPS_UNREFEXTNO: 2434 return std::to_string(Value); 2435 case DT_MIPS_TIME_STAMP: 2436 case DT_MIPS_ICHECKSUM: 2437 case DT_MIPS_IVERSION: 2438 case DT_MIPS_BASE_ADDRESS: 2439 case DT_MIPS_MSYM: 2440 case DT_MIPS_CONFLICT: 2441 case DT_MIPS_LIBLIST: 2442 case DT_MIPS_CONFLICTNO: 2443 case DT_MIPS_LIBLISTNO: 2444 case DT_MIPS_GOTSYM: 2445 case DT_MIPS_HIPAGENO: 2446 case DT_MIPS_RLD_MAP: 2447 case DT_MIPS_DELTA_CLASS: 2448 case DT_MIPS_DELTA_CLASS_NO: 2449 case DT_MIPS_DELTA_INSTANCE: 2450 case DT_MIPS_DELTA_RELOC: 2451 case DT_MIPS_DELTA_RELOC_NO: 2452 case DT_MIPS_DELTA_SYM: 2453 case DT_MIPS_DELTA_SYM_NO: 2454 case DT_MIPS_DELTA_CLASSSYM: 2455 case DT_MIPS_DELTA_CLASSSYM_NO: 2456 case DT_MIPS_CXX_FLAGS: 2457 case DT_MIPS_PIXIE_INIT: 2458 case DT_MIPS_SYMBOL_LIB: 2459 case DT_MIPS_LOCALPAGE_GOTIDX: 2460 case DT_MIPS_LOCAL_GOTIDX: 2461 case DT_MIPS_HIDDEN_GOTIDX: 2462 case DT_MIPS_PROTECTED_GOTIDX: 2463 case DT_MIPS_OPTIONS: 2464 case DT_MIPS_INTERFACE: 2465 case DT_MIPS_DYNSTR_ALIGN: 2466 case DT_MIPS_INTERFACE_SIZE: 2467 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: 2468 case DT_MIPS_PERF_SUFFIX: 2469 case DT_MIPS_COMPACT_SIZE: 2470 case DT_MIPS_GP_VALUE: 2471 case DT_MIPS_AUX_DYNAMIC: 2472 case DT_MIPS_PLTGOT: 2473 case DT_MIPS_RWPLT: 2474 case DT_MIPS_RLD_MAP_REL: 2475 case DT_MIPS_XHASH: 2476 return FormatHexValue(Value); 2477 case DT_MIPS_FLAGS: 2478 return FormatFlags(Value, ArrayRef(ElfDynamicDTMipsFlags)); 2479 default: 2480 break; 2481 } 2482 break; 2483 default: 2484 break; 2485 } 2486 2487 switch (Type) { 2488 case DT_PLTREL: 2489 if (Value == DT_REL) 2490 return "REL"; 2491 if (Value == DT_RELA) 2492 return "RELA"; 2493 if (Value == DT_CREL) 2494 return "CREL"; 2495 [[fallthrough]]; 2496 case DT_PLTGOT: 2497 case DT_HASH: 2498 case DT_STRTAB: 2499 case DT_SYMTAB: 2500 case DT_RELA: 2501 case DT_INIT: 2502 case DT_FINI: 2503 case DT_REL: 2504 case DT_JMPREL: 2505 case DT_INIT_ARRAY: 2506 case DT_FINI_ARRAY: 2507 case DT_PREINIT_ARRAY: 2508 case DT_DEBUG: 2509 case DT_CREL: 2510 case DT_VERDEF: 2511 case DT_VERNEED: 2512 case DT_VERSYM: 2513 case DT_GNU_HASH: 2514 case DT_NULL: 2515 return FormatHexValue(Value); 2516 case DT_RELACOUNT: 2517 case DT_RELCOUNT: 2518 case DT_VERDEFNUM: 2519 case DT_VERNEEDNUM: 2520 return std::to_string(Value); 2521 case DT_PLTRELSZ: 2522 case DT_RELASZ: 2523 case DT_RELAENT: 2524 case DT_STRSZ: 2525 case DT_SYMENT: 2526 case DT_RELSZ: 2527 case DT_RELENT: 2528 case DT_INIT_ARRAYSZ: 2529 case DT_FINI_ARRAYSZ: 2530 case DT_PREINIT_ARRAYSZ: 2531 case DT_RELRSZ: 2532 case DT_RELRENT: 2533 case DT_AARCH64_AUTH_RELRSZ: 2534 case DT_AARCH64_AUTH_RELRENT: 2535 case DT_ANDROID_RELSZ: 2536 case DT_ANDROID_RELASZ: 2537 return std::to_string(Value) + " (bytes)"; 2538 case DT_NEEDED: 2539 case DT_SONAME: 2540 case DT_AUXILIARY: 2541 case DT_USED: 2542 case DT_FILTER: 2543 case DT_RPATH: 2544 case DT_RUNPATH: { 2545 const std::map<uint64_t, const char *> TagNames = { 2546 {DT_NEEDED, "Shared library"}, {DT_SONAME, "Library soname"}, 2547 {DT_AUXILIARY, "Auxiliary library"}, {DT_USED, "Not needed object"}, 2548 {DT_FILTER, "Filter library"}, {DT_RPATH, "Library rpath"}, 2549 {DT_RUNPATH, "Library runpath"}, 2550 }; 2551 2552 return (Twine(TagNames.at(Type)) + ": [" + getDynamicString(Value) + "]") 2553 .str(); 2554 } 2555 case DT_FLAGS: 2556 return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags)); 2557 case DT_FLAGS_1: 2558 return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags1)); 2559 default: 2560 return FormatHexValue(Value); 2561 } 2562 } 2563 2564 template <class ELFT> 2565 StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const { 2566 if (DynamicStringTable.empty() && !DynamicStringTable.data()) { 2567 reportUniqueWarning("string table was not found"); 2568 return "<?>"; 2569 } 2570 2571 auto WarnAndReturn = [this](const Twine &Msg, uint64_t Offset) { 2572 reportUniqueWarning("string table at offset 0x" + Twine::utohexstr(Offset) + 2573 Msg); 2574 return "<?>"; 2575 }; 2576 2577 const uint64_t FileSize = Obj.getBufSize(); 2578 const uint64_t Offset = 2579 (const uint8_t *)DynamicStringTable.data() - Obj.base(); 2580 if (DynamicStringTable.size() > FileSize - Offset) 2581 return WarnAndReturn(" with size 0x" + 2582 Twine::utohexstr(DynamicStringTable.size()) + 2583 " goes past the end of the file (0x" + 2584 Twine::utohexstr(FileSize) + ")", 2585 Offset); 2586 2587 if (Value >= DynamicStringTable.size()) 2588 return WarnAndReturn( 2589 ": unable to read the string at 0x" + Twine::utohexstr(Offset + Value) + 2590 ": it goes past the end of the table (0x" + 2591 Twine::utohexstr(Offset + DynamicStringTable.size()) + ")", 2592 Offset); 2593 2594 if (DynamicStringTable.back() != '\0') 2595 return WarnAndReturn(": unable to read the string at 0x" + 2596 Twine::utohexstr(Offset + Value) + 2597 ": the string table is not null-terminated", 2598 Offset); 2599 2600 return DynamicStringTable.data() + Value; 2601 } 2602 2603 template <class ELFT> void ELFDumper<ELFT>::printUnwindInfo() { 2604 DwarfCFIEH::PrinterContext<ELFT> Ctx(W, ObjF); 2605 Ctx.printUnwindInformation(); 2606 } 2607 2608 // The namespace is needed to fix the compilation with GCC older than 7.0+. 2609 namespace { 2610 template <> void ELFDumper<ELF32LE>::printUnwindInfo() { 2611 if (Obj.getHeader().e_machine == EM_ARM) { 2612 ARM::EHABI::PrinterContext<ELF32LE> Ctx(W, Obj, ObjF.getFileName(), 2613 DotSymtabSec); 2614 Ctx.PrintUnwindInformation(); 2615 } 2616 DwarfCFIEH::PrinterContext<ELF32LE> Ctx(W, ObjF); 2617 Ctx.printUnwindInformation(); 2618 } 2619 } // namespace 2620 2621 template <class ELFT> void ELFDumper<ELFT>::printNeededLibraries() { 2622 ListScope D(W, "NeededLibraries"); 2623 2624 std::vector<StringRef> Libs; 2625 for (const auto &Entry : dynamic_table()) 2626 if (Entry.d_tag == ELF::DT_NEEDED) 2627 Libs.push_back(getDynamicString(Entry.d_un.d_val)); 2628 2629 llvm::sort(Libs); 2630 2631 for (StringRef L : Libs) 2632 W.printString(L); 2633 } 2634 2635 template <class ELFT> 2636 static Error checkHashTable(const ELFDumper<ELFT> &Dumper, 2637 const typename ELFT::Hash *H, 2638 bool *IsHeaderValid = nullptr) { 2639 const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile(); 2640 const uint64_t SecOffset = (const uint8_t *)H - Obj.base(); 2641 if (Dumper.getHashTableEntSize() == 8) { 2642 auto It = llvm::find_if(ElfMachineType, [&](const EnumEntry<unsigned> &E) { 2643 return E.Value == Obj.getHeader().e_machine; 2644 }); 2645 if (IsHeaderValid) 2646 *IsHeaderValid = false; 2647 return createError("the hash table at 0x" + Twine::utohexstr(SecOffset) + 2648 " is not supported: it contains non-standard 8 " 2649 "byte entries on " + 2650 It->AltName + " platform"); 2651 } 2652 2653 auto MakeError = [&](const Twine &Msg = "") { 2654 return createError("the hash table at offset 0x" + 2655 Twine::utohexstr(SecOffset) + 2656 " goes past the end of the file (0x" + 2657 Twine::utohexstr(Obj.getBufSize()) + ")" + Msg); 2658 }; 2659 2660 // Each SHT_HASH section starts from two 32-bit fields: nbucket and nchain. 2661 const unsigned HeaderSize = 2 * sizeof(typename ELFT::Word); 2662 2663 if (IsHeaderValid) 2664 *IsHeaderValid = Obj.getBufSize() - SecOffset >= HeaderSize; 2665 2666 if (Obj.getBufSize() - SecOffset < HeaderSize) 2667 return MakeError(); 2668 2669 if (Obj.getBufSize() - SecOffset - HeaderSize < 2670 ((uint64_t)H->nbucket + H->nchain) * sizeof(typename ELFT::Word)) 2671 return MakeError(", nbucket = " + Twine(H->nbucket) + 2672 ", nchain = " + Twine(H->nchain)); 2673 return Error::success(); 2674 } 2675 2676 template <class ELFT> 2677 static Error checkGNUHashTable(const ELFFile<ELFT> &Obj, 2678 const typename ELFT::GnuHash *GnuHashTable, 2679 bool *IsHeaderValid = nullptr) { 2680 const uint8_t *TableData = reinterpret_cast<const uint8_t *>(GnuHashTable); 2681 assert(TableData >= Obj.base() && TableData < Obj.base() + Obj.getBufSize() && 2682 "GnuHashTable must always point to a location inside the file"); 2683 2684 uint64_t TableOffset = TableData - Obj.base(); 2685 if (IsHeaderValid) 2686 *IsHeaderValid = TableOffset + /*Header size:*/ 16 < Obj.getBufSize(); 2687 if (TableOffset + 16 + (uint64_t)GnuHashTable->nbuckets * 4 + 2688 (uint64_t)GnuHashTable->maskwords * sizeof(typename ELFT::Off) >= 2689 Obj.getBufSize()) 2690 return createError("unable to dump the SHT_GNU_HASH " 2691 "section at 0x" + 2692 Twine::utohexstr(TableOffset) + 2693 ": it goes past the end of the file"); 2694 return Error::success(); 2695 } 2696 2697 template <typename ELFT> void ELFDumper<ELFT>::printHashTable() { 2698 DictScope D(W, "HashTable"); 2699 if (!HashTable) 2700 return; 2701 2702 bool IsHeaderValid; 2703 Error Err = checkHashTable(*this, HashTable, &IsHeaderValid); 2704 if (IsHeaderValid) { 2705 W.printNumber("Num Buckets", HashTable->nbucket); 2706 W.printNumber("Num Chains", HashTable->nchain); 2707 } 2708 2709 if (Err) { 2710 reportUniqueWarning(std::move(Err)); 2711 return; 2712 } 2713 2714 W.printList("Buckets", HashTable->buckets()); 2715 W.printList("Chains", HashTable->chains()); 2716 } 2717 2718 template <class ELFT> 2719 static Expected<ArrayRef<typename ELFT::Word>> 2720 getGnuHashTableChains(std::optional<DynRegionInfo> DynSymRegion, 2721 const typename ELFT::GnuHash *GnuHashTable) { 2722 if (!DynSymRegion) 2723 return createError("no dynamic symbol table found"); 2724 2725 ArrayRef<typename ELFT::Sym> DynSymTable = 2726 DynSymRegion->template getAsArrayRef<typename ELFT::Sym>(); 2727 size_t NumSyms = DynSymTable.size(); 2728 if (!NumSyms) 2729 return createError("the dynamic symbol table is empty"); 2730 2731 if (GnuHashTable->symndx < NumSyms) 2732 return GnuHashTable->values(NumSyms); 2733 2734 // A normal empty GNU hash table section produced by linker might have 2735 // symndx set to the number of dynamic symbols + 1 (for the zero symbol) 2736 // and have dummy null values in the Bloom filter and in the buckets 2737 // vector (or no values at all). It happens because the value of symndx is not 2738 // important for dynamic loaders when the GNU hash table is empty. They just 2739 // skip the whole object during symbol lookup. In such cases, the symndx value 2740 // is irrelevant and we should not report a warning. 2741 ArrayRef<typename ELFT::Word> Buckets = GnuHashTable->buckets(); 2742 if (!llvm::all_of(Buckets, [](typename ELFT::Word V) { return V == 0; })) 2743 return createError( 2744 "the first hashed symbol index (" + Twine(GnuHashTable->symndx) + 2745 ") is greater than or equal to the number of dynamic symbols (" + 2746 Twine(NumSyms) + ")"); 2747 // There is no way to represent an array of (dynamic symbols count - symndx) 2748 // length. 2749 return ArrayRef<typename ELFT::Word>(); 2750 } 2751 2752 template <typename ELFT> 2753 void ELFDumper<ELFT>::printGnuHashTable() { 2754 DictScope D(W, "GnuHashTable"); 2755 if (!GnuHashTable) 2756 return; 2757 2758 bool IsHeaderValid; 2759 Error Err = checkGNUHashTable<ELFT>(Obj, GnuHashTable, &IsHeaderValid); 2760 if (IsHeaderValid) { 2761 W.printNumber("Num Buckets", GnuHashTable->nbuckets); 2762 W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx); 2763 W.printNumber("Num Mask Words", GnuHashTable->maskwords); 2764 W.printNumber("Shift Count", GnuHashTable->shift2); 2765 } 2766 2767 if (Err) { 2768 reportUniqueWarning(std::move(Err)); 2769 return; 2770 } 2771 2772 ArrayRef<typename ELFT::Off> BloomFilter = GnuHashTable->filter(); 2773 W.printHexList("Bloom Filter", BloomFilter); 2774 2775 ArrayRef<Elf_Word> Buckets = GnuHashTable->buckets(); 2776 W.printList("Buckets", Buckets); 2777 2778 Expected<ArrayRef<Elf_Word>> Chains = 2779 getGnuHashTableChains<ELFT>(DynSymRegion, GnuHashTable); 2780 if (!Chains) { 2781 reportUniqueWarning("unable to dump 'Values' for the SHT_GNU_HASH " 2782 "section: " + 2783 toString(Chains.takeError())); 2784 return; 2785 } 2786 2787 W.printHexList("Values", *Chains); 2788 } 2789 2790 template <typename ELFT> void ELFDumper<ELFT>::printHashHistograms() { 2791 // Print histogram for the .hash section. 2792 if (this->HashTable) { 2793 if (Error E = checkHashTable<ELFT>(*this, this->HashTable)) 2794 this->reportUniqueWarning(std::move(E)); 2795 else 2796 printHashHistogram(*this->HashTable); 2797 } 2798 2799 // Print histogram for the .gnu.hash section. 2800 if (this->GnuHashTable) { 2801 if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable)) 2802 this->reportUniqueWarning(std::move(E)); 2803 else 2804 printGnuHashHistogram(*this->GnuHashTable); 2805 } 2806 } 2807 2808 template <typename ELFT> 2809 void ELFDumper<ELFT>::printHashHistogram(const Elf_Hash &HashTable) const { 2810 size_t NBucket = HashTable.nbucket; 2811 size_t NChain = HashTable.nchain; 2812 ArrayRef<Elf_Word> Buckets = HashTable.buckets(); 2813 ArrayRef<Elf_Word> Chains = HashTable.chains(); 2814 size_t TotalSyms = 0; 2815 // If hash table is correct, we have at least chains with 0 length. 2816 size_t MaxChain = 1; 2817 2818 if (NChain == 0 || NBucket == 0) 2819 return; 2820 2821 std::vector<size_t> ChainLen(NBucket, 0); 2822 // Go over all buckets and note chain lengths of each bucket (total 2823 // unique chain lengths). 2824 for (size_t B = 0; B < NBucket; ++B) { 2825 BitVector Visited(NChain); 2826 for (size_t C = Buckets[B]; C < NChain; C = Chains[C]) { 2827 if (C == ELF::STN_UNDEF) 2828 break; 2829 if (Visited[C]) { 2830 this->reportUniqueWarning( 2831 ".hash section is invalid: bucket " + Twine(C) + 2832 ": a cycle was detected in the linked chain"); 2833 break; 2834 } 2835 Visited[C] = true; 2836 if (MaxChain <= ++ChainLen[B]) 2837 ++MaxChain; 2838 } 2839 TotalSyms += ChainLen[B]; 2840 } 2841 2842 if (!TotalSyms) 2843 return; 2844 2845 std::vector<size_t> Count(MaxChain, 0); 2846 // Count how long is the chain for each bucket. 2847 for (size_t B = 0; B < NBucket; B++) 2848 ++Count[ChainLen[B]]; 2849 // Print Number of buckets with each chain lengths and their cumulative 2850 // coverage of the symbols. 2851 printHashHistogramStats(NBucket, MaxChain, TotalSyms, Count, /*IsGnu=*/false); 2852 } 2853 2854 template <class ELFT> 2855 void ELFDumper<ELFT>::printGnuHashHistogram( 2856 const Elf_GnuHash &GnuHashTable) const { 2857 Expected<ArrayRef<Elf_Word>> ChainsOrErr = 2858 getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHashTable); 2859 if (!ChainsOrErr) { 2860 this->reportUniqueWarning("unable to print the GNU hash table histogram: " + 2861 toString(ChainsOrErr.takeError())); 2862 return; 2863 } 2864 2865 ArrayRef<Elf_Word> Chains = *ChainsOrErr; 2866 size_t Symndx = GnuHashTable.symndx; 2867 size_t TotalSyms = 0; 2868 size_t MaxChain = 1; 2869 2870 size_t NBucket = GnuHashTable.nbuckets; 2871 if (Chains.empty() || NBucket == 0) 2872 return; 2873 2874 ArrayRef<Elf_Word> Buckets = GnuHashTable.buckets(); 2875 std::vector<size_t> ChainLen(NBucket, 0); 2876 for (size_t B = 0; B < NBucket; ++B) { 2877 if (!Buckets[B]) 2878 continue; 2879 size_t Len = 1; 2880 for (size_t C = Buckets[B] - Symndx; 2881 C < Chains.size() && (Chains[C] & 1) == 0; ++C) 2882 if (MaxChain < ++Len) 2883 ++MaxChain; 2884 ChainLen[B] = Len; 2885 TotalSyms += Len; 2886 } 2887 ++MaxChain; 2888 2889 if (!TotalSyms) 2890 return; 2891 2892 std::vector<size_t> Count(MaxChain, 0); 2893 for (size_t B = 0; B < NBucket; ++B) 2894 ++Count[ChainLen[B]]; 2895 // Print Number of buckets with each chain lengths and their cumulative 2896 // coverage of the symbols. 2897 printHashHistogramStats(NBucket, MaxChain, TotalSyms, Count, /*IsGnu=*/true); 2898 } 2899 2900 template <typename ELFT> void ELFDumper<ELFT>::printLoadName() { 2901 StringRef SOName = "<Not found>"; 2902 if (SONameOffset) 2903 SOName = getDynamicString(*SONameOffset); 2904 W.printString("LoadName", SOName); 2905 } 2906 2907 template <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() { 2908 switch (Obj.getHeader().e_machine) { 2909 case EM_HEXAGON: 2910 printAttributes(ELF::SHT_HEXAGON_ATTRIBUTES, 2911 std::make_unique<HexagonAttributeParser>(&W), 2912 llvm::endianness::little); 2913 break; 2914 case EM_ARM: 2915 printAttributes( 2916 ELF::SHT_ARM_ATTRIBUTES, std::make_unique<ARMAttributeParser>(&W), 2917 Obj.isLE() ? llvm::endianness::little : llvm::endianness::big); 2918 break; 2919 case EM_AARCH64: 2920 printAttributes(ELF::SHT_AARCH64_ATTRIBUTES, 2921 std::make_unique<AArch64AttributeParser>(&W), 2922 Obj.isLE() ? llvm::endianness::little 2923 : llvm::endianness::big); 2924 break; 2925 case EM_RISCV: 2926 if (Obj.isLE()) 2927 printAttributes(ELF::SHT_RISCV_ATTRIBUTES, 2928 std::make_unique<RISCVAttributeParser>(&W), 2929 llvm::endianness::little); 2930 else 2931 reportUniqueWarning("attribute printing not implemented for big-endian " 2932 "RISC-V objects"); 2933 break; 2934 case EM_MSP430: 2935 printAttributes(ELF::SHT_MSP430_ATTRIBUTES, 2936 std::make_unique<MSP430AttributeParser>(&W), 2937 llvm::endianness::little); 2938 break; 2939 case EM_MIPS: { 2940 printMipsABIFlags(); 2941 printMipsOptions(); 2942 printMipsReginfo(); 2943 MipsGOTParser<ELFT> Parser(*this); 2944 if (Error E = Parser.findGOT(dynamic_table(), dynamic_symbols())) 2945 reportUniqueWarning(std::move(E)); 2946 else if (!Parser.isGotEmpty()) 2947 printMipsGOT(Parser); 2948 2949 if (Error E = Parser.findPLT(dynamic_table())) 2950 reportUniqueWarning(std::move(E)); 2951 else if (!Parser.isPltEmpty()) 2952 printMipsPLT(Parser); 2953 break; 2954 } 2955 default: 2956 break; 2957 } 2958 } 2959 2960 template <class ELFT> 2961 void ELFDumper<ELFT>::printAttributes( 2962 unsigned AttrShType, std::unique_ptr<ELFAttributeParser> AttrParser, 2963 llvm::endianness Endianness) { 2964 assert((AttrShType != ELF::SHT_NULL) && AttrParser && 2965 "Incomplete ELF attribute implementation"); 2966 DictScope BA(W, "BuildAttributes"); 2967 for (const Elf_Shdr &Sec : cantFail(Obj.sections())) { 2968 if (Sec.sh_type != AttrShType) 2969 continue; 2970 2971 ArrayRef<uint8_t> Contents; 2972 if (Expected<ArrayRef<uint8_t>> ContentOrErr = 2973 Obj.getSectionContents(Sec)) { 2974 Contents = *ContentOrErr; 2975 if (Contents.empty()) { 2976 reportUniqueWarning("the " + describe(Sec) + " is empty"); 2977 continue; 2978 } 2979 } else { 2980 reportUniqueWarning("unable to read the content of the " + describe(Sec) + 2981 ": " + toString(ContentOrErr.takeError())); 2982 continue; 2983 } 2984 2985 W.printHex("FormatVersion", Contents[0]); 2986 2987 if (Error E = AttrParser->parse(Contents, Endianness)) 2988 reportUniqueWarning("unable to dump attributes from the " + 2989 describe(Sec) + ": " + toString(std::move(E))); 2990 } 2991 } 2992 2993 namespace { 2994 2995 template <class ELFT> class MipsGOTParser { 2996 public: 2997 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 2998 using Entry = typename ELFT::Addr; 2999 using Entries = ArrayRef<Entry>; 3000 3001 const bool IsStatic; 3002 const ELFFile<ELFT> &Obj; 3003 const ELFDumper<ELFT> &Dumper; 3004 3005 MipsGOTParser(const ELFDumper<ELFT> &D); 3006 Error findGOT(Elf_Dyn_Range DynTable, Elf_Sym_Range DynSyms); 3007 Error findPLT(Elf_Dyn_Range DynTable); 3008 3009 bool isGotEmpty() const { return GotEntries.empty(); } 3010 bool isPltEmpty() const { return PltEntries.empty(); } 3011 3012 uint64_t getGp() const; 3013 3014 const Entry *getGotLazyResolver() const; 3015 const Entry *getGotModulePointer() const; 3016 const Entry *getPltLazyResolver() const; 3017 const Entry *getPltModulePointer() const; 3018 3019 Entries getLocalEntries() const; 3020 Entries getGlobalEntries() const; 3021 Entries getOtherEntries() const; 3022 Entries getPltEntries() const; 3023 3024 uint64_t getGotAddress(const Entry * E) const; 3025 int64_t getGotOffset(const Entry * E) const; 3026 const Elf_Sym *getGotSym(const Entry *E) const; 3027 3028 uint64_t getPltAddress(const Entry * E) const; 3029 const Elf_Sym *getPltSym(const Entry *E) const; 3030 3031 StringRef getPltStrTable() const { return PltStrTable; } 3032 const Elf_Shdr *getPltSymTable() const { return PltSymTable; } 3033 3034 private: 3035 const Elf_Shdr *GotSec; 3036 size_t LocalNum; 3037 size_t GlobalNum; 3038 3039 const Elf_Shdr *PltSec; 3040 const Elf_Shdr *PltRelSec; 3041 const Elf_Shdr *PltSymTable; 3042 StringRef FileName; 3043 3044 Elf_Sym_Range GotDynSyms; 3045 StringRef PltStrTable; 3046 3047 Entries GotEntries; 3048 Entries PltEntries; 3049 }; 3050 3051 } // end anonymous namespace 3052 3053 template <class ELFT> 3054 MipsGOTParser<ELFT>::MipsGOTParser(const ELFDumper<ELFT> &D) 3055 : IsStatic(D.dynamic_table().empty()), Obj(D.getElfObject().getELFFile()), 3056 Dumper(D), GotSec(nullptr), LocalNum(0), GlobalNum(0), PltSec(nullptr), 3057 PltRelSec(nullptr), PltSymTable(nullptr), 3058 FileName(D.getElfObject().getFileName()) {} 3059 3060 template <class ELFT> 3061 Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable, 3062 Elf_Sym_Range DynSyms) { 3063 // See "Global Offset Table" in Chapter 5 in the following document 3064 // for detailed GOT description. 3065 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf 3066 3067 // Find static GOT secton. 3068 if (IsStatic) { 3069 GotSec = Dumper.findSectionByName(".got"); 3070 if (!GotSec) 3071 return Error::success(); 3072 3073 ArrayRef<uint8_t> Content = 3074 unwrapOrError(FileName, Obj.getSectionContents(*GotSec)); 3075 GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()), 3076 Content.size() / sizeof(Entry)); 3077 LocalNum = GotEntries.size(); 3078 return Error::success(); 3079 } 3080 3081 // Lookup dynamic table tags which define the GOT layout. 3082 std::optional<uint64_t> DtPltGot; 3083 std::optional<uint64_t> DtLocalGotNum; 3084 std::optional<uint64_t> DtGotSym; 3085 for (const auto &Entry : DynTable) { 3086 switch (Entry.getTag()) { 3087 case ELF::DT_PLTGOT: 3088 DtPltGot = Entry.getVal(); 3089 break; 3090 case ELF::DT_MIPS_LOCAL_GOTNO: 3091 DtLocalGotNum = Entry.getVal(); 3092 break; 3093 case ELF::DT_MIPS_GOTSYM: 3094 DtGotSym = Entry.getVal(); 3095 break; 3096 } 3097 } 3098 3099 if (!DtPltGot && !DtLocalGotNum && !DtGotSym) 3100 return Error::success(); 3101 3102 if (!DtPltGot) 3103 return createError("cannot find PLTGOT dynamic tag"); 3104 if (!DtLocalGotNum) 3105 return createError("cannot find MIPS_LOCAL_GOTNO dynamic tag"); 3106 if (!DtGotSym) 3107 return createError("cannot find MIPS_GOTSYM dynamic tag"); 3108 3109 size_t DynSymTotal = DynSyms.size(); 3110 if (*DtGotSym > DynSymTotal) 3111 return createError("DT_MIPS_GOTSYM value (" + Twine(*DtGotSym) + 3112 ") exceeds the number of dynamic symbols (" + 3113 Twine(DynSymTotal) + ")"); 3114 3115 GotSec = findNotEmptySectionByAddress(Obj, FileName, *DtPltGot); 3116 if (!GotSec) 3117 return createError("there is no non-empty GOT section at 0x" + 3118 Twine::utohexstr(*DtPltGot)); 3119 3120 LocalNum = *DtLocalGotNum; 3121 GlobalNum = DynSymTotal - *DtGotSym; 3122 3123 ArrayRef<uint8_t> Content = 3124 unwrapOrError(FileName, Obj.getSectionContents(*GotSec)); 3125 GotEntries = Entries(reinterpret_cast<const Entry *>(Content.data()), 3126 Content.size() / sizeof(Entry)); 3127 GotDynSyms = DynSyms.drop_front(*DtGotSym); 3128 3129 return Error::success(); 3130 } 3131 3132 template <class ELFT> 3133 Error MipsGOTParser<ELFT>::findPLT(Elf_Dyn_Range DynTable) { 3134 // Lookup dynamic table tags which define the PLT layout. 3135 std::optional<uint64_t> DtMipsPltGot; 3136 std::optional<uint64_t> DtJmpRel; 3137 for (const auto &Entry : DynTable) { 3138 switch (Entry.getTag()) { 3139 case ELF::DT_MIPS_PLTGOT: 3140 DtMipsPltGot = Entry.getVal(); 3141 break; 3142 case ELF::DT_JMPREL: 3143 DtJmpRel = Entry.getVal(); 3144 break; 3145 } 3146 } 3147 3148 if (!DtMipsPltGot && !DtJmpRel) 3149 return Error::success(); 3150 3151 // Find PLT section. 3152 if (!DtMipsPltGot) 3153 return createError("cannot find MIPS_PLTGOT dynamic tag"); 3154 if (!DtJmpRel) 3155 return createError("cannot find JMPREL dynamic tag"); 3156 3157 PltSec = findNotEmptySectionByAddress(Obj, FileName, *DtMipsPltGot); 3158 if (!PltSec) 3159 return createError("there is no non-empty PLTGOT section at 0x" + 3160 Twine::utohexstr(*DtMipsPltGot)); 3161 3162 PltRelSec = findNotEmptySectionByAddress(Obj, FileName, *DtJmpRel); 3163 if (!PltRelSec) 3164 return createError("there is no non-empty RELPLT section at 0x" + 3165 Twine::utohexstr(*DtJmpRel)); 3166 3167 if (Expected<ArrayRef<uint8_t>> PltContentOrErr = 3168 Obj.getSectionContents(*PltSec)) 3169 PltEntries = 3170 Entries(reinterpret_cast<const Entry *>(PltContentOrErr->data()), 3171 PltContentOrErr->size() / sizeof(Entry)); 3172 else 3173 return createError("unable to read PLTGOT section content: " + 3174 toString(PltContentOrErr.takeError())); 3175 3176 if (Expected<const Elf_Shdr *> PltSymTableOrErr = 3177 Obj.getSection(PltRelSec->sh_link)) 3178 PltSymTable = *PltSymTableOrErr; 3179 else 3180 return createError("unable to get a symbol table linked to the " + 3181 describe(Obj, *PltRelSec) + ": " + 3182 toString(PltSymTableOrErr.takeError())); 3183 3184 if (Expected<StringRef> StrTabOrErr = 3185 Obj.getStringTableForSymtab(*PltSymTable)) 3186 PltStrTable = *StrTabOrErr; 3187 else 3188 return createError("unable to get a string table for the " + 3189 describe(Obj, *PltSymTable) + ": " + 3190 toString(StrTabOrErr.takeError())); 3191 3192 return Error::success(); 3193 } 3194 3195 template <class ELFT> uint64_t MipsGOTParser<ELFT>::getGp() const { 3196 return GotSec->sh_addr + 0x7ff0; 3197 } 3198 3199 template <class ELFT> 3200 const typename MipsGOTParser<ELFT>::Entry * 3201 MipsGOTParser<ELFT>::getGotLazyResolver() const { 3202 return LocalNum > 0 ? &GotEntries[0] : nullptr; 3203 } 3204 3205 template <class ELFT> 3206 const typename MipsGOTParser<ELFT>::Entry * 3207 MipsGOTParser<ELFT>::getGotModulePointer() const { 3208 if (LocalNum < 2) 3209 return nullptr; 3210 const Entry &E = GotEntries[1]; 3211 if ((E >> (sizeof(Entry) * 8 - 1)) == 0) 3212 return nullptr; 3213 return &E; 3214 } 3215 3216 template <class ELFT> 3217 typename MipsGOTParser<ELFT>::Entries 3218 MipsGOTParser<ELFT>::getLocalEntries() const { 3219 size_t Skip = getGotModulePointer() ? 2 : 1; 3220 if (LocalNum - Skip <= 0) 3221 return Entries(); 3222 return GotEntries.slice(Skip, LocalNum - Skip); 3223 } 3224 3225 template <class ELFT> 3226 typename MipsGOTParser<ELFT>::Entries 3227 MipsGOTParser<ELFT>::getGlobalEntries() const { 3228 if (GlobalNum == 0) 3229 return Entries(); 3230 return GotEntries.slice(LocalNum, GlobalNum); 3231 } 3232 3233 template <class ELFT> 3234 typename MipsGOTParser<ELFT>::Entries 3235 MipsGOTParser<ELFT>::getOtherEntries() const { 3236 size_t OtherNum = GotEntries.size() - LocalNum - GlobalNum; 3237 if (OtherNum == 0) 3238 return Entries(); 3239 return GotEntries.slice(LocalNum + GlobalNum, OtherNum); 3240 } 3241 3242 template <class ELFT> 3243 uint64_t MipsGOTParser<ELFT>::getGotAddress(const Entry *E) const { 3244 int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry); 3245 return GotSec->sh_addr + Offset; 3246 } 3247 3248 template <class ELFT> 3249 int64_t MipsGOTParser<ELFT>::getGotOffset(const Entry *E) const { 3250 int64_t Offset = std::distance(GotEntries.data(), E) * sizeof(Entry); 3251 return Offset - 0x7ff0; 3252 } 3253 3254 template <class ELFT> 3255 const typename MipsGOTParser<ELFT>::Elf_Sym * 3256 MipsGOTParser<ELFT>::getGotSym(const Entry *E) const { 3257 int64_t Offset = std::distance(GotEntries.data(), E); 3258 return &GotDynSyms[Offset - LocalNum]; 3259 } 3260 3261 template <class ELFT> 3262 const typename MipsGOTParser<ELFT>::Entry * 3263 MipsGOTParser<ELFT>::getPltLazyResolver() const { 3264 return PltEntries.empty() ? nullptr : &PltEntries[0]; 3265 } 3266 3267 template <class ELFT> 3268 const typename MipsGOTParser<ELFT>::Entry * 3269 MipsGOTParser<ELFT>::getPltModulePointer() const { 3270 return PltEntries.size() < 2 ? nullptr : &PltEntries[1]; 3271 } 3272 3273 template <class ELFT> 3274 typename MipsGOTParser<ELFT>::Entries 3275 MipsGOTParser<ELFT>::getPltEntries() const { 3276 if (PltEntries.size() <= 2) 3277 return Entries(); 3278 return PltEntries.slice(2, PltEntries.size() - 2); 3279 } 3280 3281 template <class ELFT> 3282 uint64_t MipsGOTParser<ELFT>::getPltAddress(const Entry *E) const { 3283 int64_t Offset = std::distance(PltEntries.data(), E) * sizeof(Entry); 3284 return PltSec->sh_addr + Offset; 3285 } 3286 3287 template <class ELFT> 3288 const typename MipsGOTParser<ELFT>::Elf_Sym * 3289 MipsGOTParser<ELFT>::getPltSym(const Entry *E) const { 3290 int64_t Offset = std::distance(getPltEntries().data(), E); 3291 if (PltRelSec->sh_type == ELF::SHT_REL) { 3292 Elf_Rel_Range Rels = unwrapOrError(FileName, Obj.rels(*PltRelSec)); 3293 return unwrapOrError(FileName, 3294 Obj.getRelocationSymbol(Rels[Offset], PltSymTable)); 3295 } else { 3296 Elf_Rela_Range Rels = unwrapOrError(FileName, Obj.relas(*PltRelSec)); 3297 return unwrapOrError(FileName, 3298 Obj.getRelocationSymbol(Rels[Offset], PltSymTable)); 3299 } 3300 } 3301 3302 const EnumEntry<unsigned> ElfMipsISAExtType[] = { 3303 {"None", Mips::AFL_EXT_NONE}, 3304 {"Broadcom SB-1", Mips::AFL_EXT_SB1}, 3305 {"Cavium Networks Octeon", Mips::AFL_EXT_OCTEON}, 3306 {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2}, 3307 {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP}, 3308 {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3}, 3309 {"LSI R4010", Mips::AFL_EXT_4010}, 3310 {"Loongson 2E", Mips::AFL_EXT_LOONGSON_2E}, 3311 {"Loongson 2F", Mips::AFL_EXT_LOONGSON_2F}, 3312 {"Loongson 3A", Mips::AFL_EXT_LOONGSON_3A}, 3313 {"MIPS R4650", Mips::AFL_EXT_4650}, 3314 {"MIPS R5900", Mips::AFL_EXT_5900}, 3315 {"MIPS R10000", Mips::AFL_EXT_10000}, 3316 {"NEC VR4100", Mips::AFL_EXT_4100}, 3317 {"NEC VR4111/VR4181", Mips::AFL_EXT_4111}, 3318 {"NEC VR4120", Mips::AFL_EXT_4120}, 3319 {"NEC VR5400", Mips::AFL_EXT_5400}, 3320 {"NEC VR5500", Mips::AFL_EXT_5500}, 3321 {"RMI Xlr", Mips::AFL_EXT_XLR}, 3322 {"Toshiba R3900", Mips::AFL_EXT_3900} 3323 }; 3324 3325 const EnumEntry<unsigned> ElfMipsASEFlags[] = { 3326 {"DSP", Mips::AFL_ASE_DSP}, 3327 {"DSPR2", Mips::AFL_ASE_DSPR2}, 3328 {"Enhanced VA Scheme", Mips::AFL_ASE_EVA}, 3329 {"MCU", Mips::AFL_ASE_MCU}, 3330 {"MDMX", Mips::AFL_ASE_MDMX}, 3331 {"MIPS-3D", Mips::AFL_ASE_MIPS3D}, 3332 {"MT", Mips::AFL_ASE_MT}, 3333 {"SmartMIPS", Mips::AFL_ASE_SMARTMIPS}, 3334 {"VZ", Mips::AFL_ASE_VIRT}, 3335 {"MSA", Mips::AFL_ASE_MSA}, 3336 {"MIPS16", Mips::AFL_ASE_MIPS16}, 3337 {"microMIPS", Mips::AFL_ASE_MICROMIPS}, 3338 {"XPA", Mips::AFL_ASE_XPA}, 3339 {"CRC", Mips::AFL_ASE_CRC}, 3340 {"GINV", Mips::AFL_ASE_GINV}, 3341 }; 3342 3343 const EnumEntry<unsigned> ElfMipsFpABIType[] = { 3344 {"Hard or soft float", Mips::Val_GNU_MIPS_ABI_FP_ANY}, 3345 {"Hard float (double precision)", Mips::Val_GNU_MIPS_ABI_FP_DOUBLE}, 3346 {"Hard float (single precision)", Mips::Val_GNU_MIPS_ABI_FP_SINGLE}, 3347 {"Soft float", Mips::Val_GNU_MIPS_ABI_FP_SOFT}, 3348 {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)", 3349 Mips::Val_GNU_MIPS_ABI_FP_OLD_64}, 3350 {"Hard float (32-bit CPU, Any FPU)", Mips::Val_GNU_MIPS_ABI_FP_XX}, 3351 {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64}, 3352 {"Hard float compat (32-bit CPU, 64-bit FPU)", 3353 Mips::Val_GNU_MIPS_ABI_FP_64A} 3354 }; 3355 3356 static const EnumEntry<unsigned> ElfMipsFlags1[] { 3357 {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG}, 3358 }; 3359 3360 static int getMipsRegisterSize(uint8_t Flag) { 3361 switch (Flag) { 3362 case Mips::AFL_REG_NONE: 3363 return 0; 3364 case Mips::AFL_REG_32: 3365 return 32; 3366 case Mips::AFL_REG_64: 3367 return 64; 3368 case Mips::AFL_REG_128: 3369 return 128; 3370 default: 3371 return -1; 3372 } 3373 } 3374 3375 template <class ELFT> 3376 static void printMipsReginfoData(ScopedPrinter &W, 3377 const Elf_Mips_RegInfo<ELFT> &Reginfo) { 3378 W.printHex("GP", Reginfo.ri_gp_value); 3379 W.printHex("General Mask", Reginfo.ri_gprmask); 3380 W.printHex("Co-Proc Mask0", Reginfo.ri_cprmask[0]); 3381 W.printHex("Co-Proc Mask1", Reginfo.ri_cprmask[1]); 3382 W.printHex("Co-Proc Mask2", Reginfo.ri_cprmask[2]); 3383 W.printHex("Co-Proc Mask3", Reginfo.ri_cprmask[3]); 3384 } 3385 3386 template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() { 3387 const Elf_Shdr *RegInfoSec = findSectionByName(".reginfo"); 3388 if (!RegInfoSec) { 3389 W.startLine() << "There is no .reginfo section in the file.\n"; 3390 return; 3391 } 3392 3393 Expected<ArrayRef<uint8_t>> ContentsOrErr = 3394 Obj.getSectionContents(*RegInfoSec); 3395 if (!ContentsOrErr) { 3396 this->reportUniqueWarning( 3397 "unable to read the content of the .reginfo section (" + 3398 describe(*RegInfoSec) + "): " + toString(ContentsOrErr.takeError())); 3399 return; 3400 } 3401 3402 if (ContentsOrErr->size() < sizeof(Elf_Mips_RegInfo<ELFT>)) { 3403 this->reportUniqueWarning("the .reginfo section has an invalid size (0x" + 3404 Twine::utohexstr(ContentsOrErr->size()) + ")"); 3405 return; 3406 } 3407 3408 DictScope GS(W, "MIPS RegInfo"); 3409 printMipsReginfoData(W, *reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>( 3410 ContentsOrErr->data())); 3411 } 3412 3413 template <class ELFT> 3414 static Expected<const Elf_Mips_Options<ELFT> *> 3415 readMipsOptions(const uint8_t *SecBegin, ArrayRef<uint8_t> &SecData, 3416 bool &IsSupported) { 3417 if (SecData.size() < sizeof(Elf_Mips_Options<ELFT>)) 3418 return createError("the .MIPS.options section has an invalid size (0x" + 3419 Twine::utohexstr(SecData.size()) + ")"); 3420 3421 const Elf_Mips_Options<ELFT> *O = 3422 reinterpret_cast<const Elf_Mips_Options<ELFT> *>(SecData.data()); 3423 const uint8_t Size = O->size; 3424 if (Size > SecData.size()) { 3425 const uint64_t Offset = SecData.data() - SecBegin; 3426 const uint64_t SecSize = Offset + SecData.size(); 3427 return createError("a descriptor of size 0x" + Twine::utohexstr(Size) + 3428 " at offset 0x" + Twine::utohexstr(Offset) + 3429 " goes past the end of the .MIPS.options " 3430 "section of size 0x" + 3431 Twine::utohexstr(SecSize)); 3432 } 3433 3434 IsSupported = O->kind == ODK_REGINFO; 3435 const size_t ExpectedSize = 3436 sizeof(Elf_Mips_Options<ELFT>) + sizeof(Elf_Mips_RegInfo<ELFT>); 3437 3438 if (IsSupported) 3439 if (Size < ExpectedSize) 3440 return createError( 3441 "a .MIPS.options entry of kind " + 3442 Twine(getElfMipsOptionsOdkType(O->kind)) + 3443 " has an invalid size (0x" + Twine::utohexstr(Size) + 3444 "), the expected size is 0x" + Twine::utohexstr(ExpectedSize)); 3445 3446 SecData = SecData.drop_front(Size); 3447 return O; 3448 } 3449 3450 template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() { 3451 const Elf_Shdr *MipsOpts = findSectionByName(".MIPS.options"); 3452 if (!MipsOpts) { 3453 W.startLine() << "There is no .MIPS.options section in the file.\n"; 3454 return; 3455 } 3456 3457 DictScope GS(W, "MIPS Options"); 3458 3459 ArrayRef<uint8_t> Data = 3460 unwrapOrError(ObjF.getFileName(), Obj.getSectionContents(*MipsOpts)); 3461 const uint8_t *const SecBegin = Data.begin(); 3462 while (!Data.empty()) { 3463 bool IsSupported; 3464 Expected<const Elf_Mips_Options<ELFT> *> OptsOrErr = 3465 readMipsOptions<ELFT>(SecBegin, Data, IsSupported); 3466 if (!OptsOrErr) { 3467 reportUniqueWarning(OptsOrErr.takeError()); 3468 break; 3469 } 3470 3471 unsigned Kind = (*OptsOrErr)->kind; 3472 const char *Type = getElfMipsOptionsOdkType(Kind); 3473 if (!IsSupported) { 3474 W.startLine() << "Unsupported MIPS options tag: " << Type << " (" << Kind 3475 << ")\n"; 3476 continue; 3477 } 3478 3479 DictScope GS(W, Type); 3480 if (Kind == ODK_REGINFO) 3481 printMipsReginfoData(W, (*OptsOrErr)->getRegInfo()); 3482 else 3483 llvm_unreachable("unexpected .MIPS.options section descriptor kind"); 3484 } 3485 } 3486 3487 template <class ELFT> void ELFDumper<ELFT>::printStackMap() const { 3488 const Elf_Shdr *StackMapSection = findSectionByName(".llvm_stackmaps"); 3489 if (!StackMapSection) 3490 return; 3491 3492 auto Warn = [&](Error &&E) { 3493 this->reportUniqueWarning("unable to read the stack map from " + 3494 describe(*StackMapSection) + ": " + 3495 toString(std::move(E))); 3496 }; 3497 3498 Expected<ArrayRef<uint8_t>> ContentOrErr = 3499 Obj.getSectionContents(*StackMapSection); 3500 if (!ContentOrErr) { 3501 Warn(ContentOrErr.takeError()); 3502 return; 3503 } 3504 3505 if (Error E = 3506 StackMapParser<ELFT::Endianness>::validateHeader(*ContentOrErr)) { 3507 Warn(std::move(E)); 3508 return; 3509 } 3510 3511 prettyPrintStackMap(W, StackMapParser<ELFT::Endianness>(*ContentOrErr)); 3512 } 3513 3514 template <class ELFT> 3515 void ELFDumper<ELFT>::printReloc(const Relocation<ELFT> &R, unsigned RelIndex, 3516 const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { 3517 Expected<RelSymbol<ELFT>> Target = getRelocationTarget(R, SymTab); 3518 if (!Target) 3519 reportUniqueWarning("unable to print relocation " + Twine(RelIndex) + 3520 " in " + describe(Sec) + ": " + 3521 toString(Target.takeError())); 3522 else 3523 printRelRelaReloc(R, *Target); 3524 } 3525 3526 template <class ELFT> 3527 std::vector<EnumEntry<unsigned>> 3528 ELFDumper<ELFT>::getOtherFlagsFromSymbol(const Elf_Ehdr &Header, 3529 const Elf_Sym &Symbol) const { 3530 std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags), 3531 std::end(ElfSymOtherFlags)); 3532 if (Header.e_machine == EM_MIPS) { 3533 // Someone in their infinite wisdom decided to make STO_MIPS_MIPS16 3534 // flag overlap with other ST_MIPS_xxx flags. So consider both 3535 // cases separately. 3536 if ((Symbol.st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16) 3537 llvm::append_range(SymOtherFlags, ElfMips16SymOtherFlags); 3538 else 3539 llvm::append_range(SymOtherFlags, ElfMipsSymOtherFlags); 3540 } else if (Header.e_machine == EM_AARCH64) { 3541 llvm::append_range(SymOtherFlags, ElfAArch64SymOtherFlags); 3542 } else if (Header.e_machine == EM_RISCV) { 3543 llvm::append_range(SymOtherFlags, ElfRISCVSymOtherFlags); 3544 } 3545 return SymOtherFlags; 3546 } 3547 3548 static inline void printFields(formatted_raw_ostream &OS, StringRef Str1, 3549 StringRef Str2) { 3550 OS.PadToColumn(2u); 3551 OS << Str1; 3552 OS.PadToColumn(37u); 3553 OS << Str2 << "\n"; 3554 OS.flush(); 3555 } 3556 3557 template <class ELFT> 3558 static std::string getSectionHeadersNumString(const ELFFile<ELFT> &Obj, 3559 StringRef FileName) { 3560 const typename ELFT::Ehdr &ElfHeader = Obj.getHeader(); 3561 if (ElfHeader.e_shnum != 0) 3562 return to_string(ElfHeader.e_shnum); 3563 3564 Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections(); 3565 if (!ArrOrErr) { 3566 // In this case we can ignore an error, because we have already reported a 3567 // warning about the broken section header table earlier. 3568 consumeError(ArrOrErr.takeError()); 3569 return "<?>"; 3570 } 3571 3572 if (ArrOrErr->empty()) 3573 return "0"; 3574 return "0 (" + to_string((*ArrOrErr)[0].sh_size) + ")"; 3575 } 3576 3577 template <class ELFT> 3578 static std::string getSectionHeaderTableIndexString(const ELFFile<ELFT> &Obj, 3579 StringRef FileName) { 3580 const typename ELFT::Ehdr &ElfHeader = Obj.getHeader(); 3581 if (ElfHeader.e_shstrndx != SHN_XINDEX) 3582 return to_string(ElfHeader.e_shstrndx); 3583 3584 Expected<ArrayRef<typename ELFT::Shdr>> ArrOrErr = Obj.sections(); 3585 if (!ArrOrErr) { 3586 // In this case we can ignore an error, because we have already reported a 3587 // warning about the broken section header table earlier. 3588 consumeError(ArrOrErr.takeError()); 3589 return "<?>"; 3590 } 3591 3592 if (ArrOrErr->empty()) 3593 return "65535 (corrupt: out of range)"; 3594 return to_string(ElfHeader.e_shstrndx) + " (" + 3595 to_string((*ArrOrErr)[0].sh_link) + ")"; 3596 } 3597 3598 static const EnumEntry<unsigned> *getObjectFileEnumEntry(unsigned Type) { 3599 auto It = llvm::find_if(ElfObjectFileType, [&](const EnumEntry<unsigned> &E) { 3600 return E.Value == Type; 3601 }); 3602 if (It != ArrayRef(ElfObjectFileType).end()) 3603 return It; 3604 return nullptr; 3605 } 3606 3607 template <class ELFT> 3608 void GNUELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj, 3609 ArrayRef<std::string> InputFilenames, 3610 const Archive *A) { 3611 if (InputFilenames.size() > 1 || A) { 3612 this->W.startLine() << "\n"; 3613 this->W.printString("File", FileStr); 3614 } 3615 } 3616 3617 template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() { 3618 const Elf_Ehdr &e = this->Obj.getHeader(); 3619 OS << "ELF Header:\n"; 3620 OS << " Magic: "; 3621 std::string Str; 3622 for (int i = 0; i < ELF::EI_NIDENT; i++) 3623 OS << format(" %02x", static_cast<int>(e.e_ident[i])); 3624 OS << "\n"; 3625 Str = enumToString(e.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass)); 3626 printFields(OS, "Class:", Str); 3627 Str = enumToString(e.e_ident[ELF::EI_DATA], ArrayRef(ElfDataEncoding)); 3628 printFields(OS, "Data:", Str); 3629 OS.PadToColumn(2u); 3630 OS << "Version:"; 3631 OS.PadToColumn(37u); 3632 OS << utohexstr(e.e_ident[ELF::EI_VERSION]); 3633 if (e.e_version == ELF::EV_CURRENT) 3634 OS << " (current)"; 3635 OS << "\n"; 3636 auto OSABI = ArrayRef(ElfOSABI); 3637 if (e.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH && 3638 e.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) { 3639 switch (e.e_machine) { 3640 case ELF::EM_ARM: 3641 OSABI = ArrayRef(ARMElfOSABI); 3642 break; 3643 case ELF::EM_AMDGPU: 3644 OSABI = ArrayRef(AMDGPUElfOSABI); 3645 break; 3646 default: 3647 break; 3648 } 3649 } 3650 Str = enumToString(e.e_ident[ELF::EI_OSABI], OSABI); 3651 printFields(OS, "OS/ABI:", Str); 3652 printFields(OS, 3653 "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION])); 3654 3655 if (const EnumEntry<unsigned> *E = getObjectFileEnumEntry(e.e_type)) { 3656 Str = E->AltName.str(); 3657 } else { 3658 if (e.e_type >= ET_LOPROC) 3659 Str = "Processor Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")"; 3660 else if (e.e_type >= ET_LOOS) 3661 Str = "OS Specific: (" + utohexstr(e.e_type, /*LowerCase=*/true) + ")"; 3662 else 3663 Str = "<unknown>: " + utohexstr(e.e_type, /*LowerCase=*/true); 3664 } 3665 printFields(OS, "Type:", Str); 3666 3667 Str = enumToString(e.e_machine, ArrayRef(ElfMachineType)); 3668 printFields(OS, "Machine:", Str); 3669 Str = "0x" + utohexstr(e.e_version); 3670 printFields(OS, "Version:", Str); 3671 Str = "0x" + utohexstr(e.e_entry); 3672 printFields(OS, "Entry point address:", Str); 3673 Str = to_string(e.e_phoff) + " (bytes into file)"; 3674 printFields(OS, "Start of program headers:", Str); 3675 Str = to_string(e.e_shoff) + " (bytes into file)"; 3676 printFields(OS, "Start of section headers:", Str); 3677 std::string ElfFlags; 3678 if (e.e_machine == EM_MIPS) 3679 ElfFlags = printFlags( 3680 e.e_flags, ArrayRef(ElfHeaderMipsFlags), unsigned(ELF::EF_MIPS_ARCH), 3681 unsigned(ELF::EF_MIPS_ABI), unsigned(ELF::EF_MIPS_MACH)); 3682 else if (e.e_machine == EM_RISCV) 3683 ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderRISCVFlags)); 3684 else if (e.e_machine == EM_SPARC32PLUS || e.e_machine == EM_SPARCV9) 3685 ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderSPARCFlags), 3686 unsigned(ELF::EF_SPARCV9_MM)); 3687 else if (e.e_machine == EM_AVR) 3688 ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderAVRFlags), 3689 unsigned(ELF::EF_AVR_ARCH_MASK)); 3690 else if (e.e_machine == EM_LOONGARCH) 3691 ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderLoongArchFlags), 3692 unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK), 3693 unsigned(ELF::EF_LOONGARCH_OBJABI_MASK)); 3694 else if (e.e_machine == EM_XTENSA) 3695 ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderXtensaFlags), 3696 unsigned(ELF::EF_XTENSA_MACH)); 3697 else if (e.e_machine == EM_CUDA) { 3698 ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderNVPTXFlags), 3699 unsigned(ELF::EF_CUDA_SM)); 3700 if (e.e_ident[ELF::EI_ABIVERSION] == ELF::ELFABIVERSION_CUDA_V1 && 3701 (e.e_flags & ELF::EF_CUDA_ACCELERATORS_V1)) 3702 ElfFlags += "a"; 3703 else if (e.e_ident[ELF::EI_ABIVERSION] == ELF::ELFABIVERSION_CUDA_V2 && 3704 (e.e_flags & ELF::EF_CUDA_ACCELERATORS)) 3705 ElfFlags += "a"; 3706 } else if (e.e_machine == EM_AMDGPU) { 3707 switch (e.e_ident[ELF::EI_ABIVERSION]) { 3708 default: 3709 break; 3710 case 0: 3711 // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags. 3712 [[fallthrough]]; 3713 case ELF::ELFABIVERSION_AMDGPU_HSA_V3: 3714 ElfFlags = 3715 printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion3), 3716 unsigned(ELF::EF_AMDGPU_MACH)); 3717 break; 3718 case ELF::ELFABIVERSION_AMDGPU_HSA_V4: 3719 case ELF::ELFABIVERSION_AMDGPU_HSA_V5: 3720 ElfFlags = 3721 printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4), 3722 unsigned(ELF::EF_AMDGPU_MACH), 3723 unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4), 3724 unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4)); 3725 break; 3726 case ELF::ELFABIVERSION_AMDGPU_HSA_V6: { 3727 ElfFlags = 3728 printFlags(e.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4), 3729 unsigned(ELF::EF_AMDGPU_MACH), 3730 unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4), 3731 unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4)); 3732 if (auto GenericV = e.e_flags & ELF::EF_AMDGPU_GENERIC_VERSION) { 3733 ElfFlags += 3734 ", generic_v" + 3735 to_string(GenericV >> ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET); 3736 } 3737 } break; 3738 } 3739 } 3740 Str = "0x" + utohexstr(e.e_flags); 3741 if (!ElfFlags.empty()) 3742 Str = Str + ", " + ElfFlags; 3743 printFields(OS, "Flags:", Str); 3744 Str = to_string(e.e_ehsize) + " (bytes)"; 3745 printFields(OS, "Size of this header:", Str); 3746 Str = to_string(e.e_phentsize) + " (bytes)"; 3747 printFields(OS, "Size of program headers:", Str); 3748 Str = to_string(e.e_phnum); 3749 printFields(OS, "Number of program headers:", Str); 3750 Str = to_string(e.e_shentsize) + " (bytes)"; 3751 printFields(OS, "Size of section headers:", Str); 3752 Str = getSectionHeadersNumString(this->Obj, this->FileName); 3753 printFields(OS, "Number of section headers:", Str); 3754 Str = getSectionHeaderTableIndexString(this->Obj, this->FileName); 3755 printFields(OS, "Section header string table index:", Str); 3756 } 3757 3758 template <class ELFT> std::vector<GroupSection> ELFDumper<ELFT>::getGroups() { 3759 auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx, 3760 const Elf_Shdr &Symtab) -> StringRef { 3761 Expected<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(Symtab); 3762 if (!StrTableOrErr) { 3763 reportUniqueWarning("unable to get the string table for " + 3764 describe(Symtab) + ": " + 3765 toString(StrTableOrErr.takeError())); 3766 return "<?>"; 3767 } 3768 3769 StringRef Strings = *StrTableOrErr; 3770 if (Sym.st_name >= Strings.size()) { 3771 reportUniqueWarning("unable to get the name of the symbol with index " + 3772 Twine(SymNdx) + ": st_name (0x" + 3773 Twine::utohexstr(Sym.st_name) + 3774 ") is past the end of the string table of size 0x" + 3775 Twine::utohexstr(Strings.size())); 3776 return "<?>"; 3777 } 3778 3779 return StrTableOrErr->data() + Sym.st_name; 3780 }; 3781 3782 std::vector<GroupSection> Ret; 3783 uint64_t I = 0; 3784 for (const Elf_Shdr &Sec : cantFail(Obj.sections())) { 3785 ++I; 3786 if (Sec.sh_type != ELF::SHT_GROUP) 3787 continue; 3788 3789 StringRef Signature = "<?>"; 3790 if (Expected<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Sec.sh_link)) { 3791 if (Expected<const Elf_Sym *> SymOrErr = 3792 Obj.template getEntry<Elf_Sym>(**SymtabOrErr, Sec.sh_info)) 3793 Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr); 3794 else 3795 reportUniqueWarning("unable to get the signature symbol for " + 3796 describe(Sec) + ": " + 3797 toString(SymOrErr.takeError())); 3798 } else { 3799 reportUniqueWarning("unable to get the symbol table for " + 3800 describe(Sec) + ": " + 3801 toString(SymtabOrErr.takeError())); 3802 } 3803 3804 ArrayRef<Elf_Word> Data; 3805 if (Expected<ArrayRef<Elf_Word>> ContentsOrErr = 3806 Obj.template getSectionContentsAsArray<Elf_Word>(Sec)) { 3807 if (ContentsOrErr->empty()) 3808 reportUniqueWarning("unable to read the section group flag from the " + 3809 describe(Sec) + ": the section is empty"); 3810 else 3811 Data = *ContentsOrErr; 3812 } else { 3813 reportUniqueWarning("unable to get the content of the " + describe(Sec) + 3814 ": " + toString(ContentsOrErr.takeError())); 3815 } 3816 3817 Ret.push_back({getPrintableSectionName(Sec), 3818 maybeDemangle(Signature), 3819 Sec.sh_name, 3820 I - 1, 3821 Sec.sh_link, 3822 Sec.sh_info, 3823 Data.empty() ? Elf_Word(0) : Data[0], 3824 {}}); 3825 3826 if (Data.empty()) 3827 continue; 3828 3829 std::vector<GroupMember> &GM = Ret.back().Members; 3830 for (uint32_t Ndx : Data.slice(1)) { 3831 if (Expected<const Elf_Shdr *> SecOrErr = Obj.getSection(Ndx)) { 3832 GM.push_back({getPrintableSectionName(**SecOrErr), Ndx}); 3833 } else { 3834 reportUniqueWarning("unable to get the section with index " + 3835 Twine(Ndx) + " when dumping the " + describe(Sec) + 3836 ": " + toString(SecOrErr.takeError())); 3837 GM.push_back({"<?>", Ndx}); 3838 } 3839 } 3840 } 3841 return Ret; 3842 } 3843 3844 static DenseMap<uint64_t, const GroupSection *> 3845 mapSectionsToGroups(ArrayRef<GroupSection> Groups) { 3846 DenseMap<uint64_t, const GroupSection *> Ret; 3847 for (const GroupSection &G : Groups) 3848 for (const GroupMember &GM : G.Members) 3849 Ret.insert({GM.Index, &G}); 3850 return Ret; 3851 } 3852 3853 template <class ELFT> void GNUELFDumper<ELFT>::printGroupSections() { 3854 std::vector<GroupSection> V = this->getGroups(); 3855 DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V); 3856 for (const GroupSection &G : V) { 3857 OS << "\n" 3858 << getGroupType(G.Type) << " group section [" 3859 << format_decimal(G.Index, 5) << "] `" << G.Name << "' [" << G.Signature 3860 << "] contains " << G.Members.size() << " sections:\n" 3861 << " [Index] Name\n"; 3862 for (const GroupMember &GM : G.Members) { 3863 const GroupSection *MainGroup = Map[GM.Index]; 3864 if (MainGroup != &G) 3865 this->reportUniqueWarning( 3866 "section with index " + Twine(GM.Index) + 3867 ", included in the group section with index " + 3868 Twine(MainGroup->Index) + 3869 ", was also found in the group section with index " + 3870 Twine(G.Index)); 3871 OS << " [" << format_decimal(GM.Index, 5) << "] " << GM.Name << "\n"; 3872 } 3873 } 3874 3875 if (V.empty()) 3876 OS << "There are no section groups in this file.\n"; 3877 } 3878 3879 template <class ELFT> 3880 void GNUELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R, 3881 const RelSymbol<ELFT> &RelSym) { 3882 // First two fields are bit width dependent. The rest of them are fixed width. 3883 unsigned Bias = ELFT::Is64Bits ? 8 : 0; 3884 Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias}; 3885 unsigned Width = ELFT::Is64Bits ? 16 : 8; 3886 3887 Fields[0].Str = to_string(format_hex_no_prefix(R.Offset, Width)); 3888 Fields[1].Str = to_string(format_hex_no_prefix(R.Info, Width)); 3889 3890 SmallString<32> RelocName; 3891 this->Obj.getRelocationTypeName(R.Type, RelocName); 3892 Fields[2].Str = RelocName.c_str(); 3893 3894 if (RelSym.Sym) 3895 Fields[3].Str = 3896 to_string(format_hex_no_prefix(RelSym.Sym->getValue(), Width)); 3897 if (RelSym.Sym && RelSym.Name.empty()) 3898 Fields[4].Str = "<null>"; 3899 else 3900 Fields[4].Str = std::string(RelSym.Name); 3901 3902 for (const Field &F : Fields) 3903 printField(F); 3904 3905 std::string Addend; 3906 if (std::optional<int64_t> A = R.Addend) { 3907 int64_t RelAddend = *A; 3908 if (!Fields[4].Str.empty()) { 3909 if (RelAddend < 0) { 3910 Addend = " - "; 3911 RelAddend = -static_cast<uint64_t>(RelAddend); 3912 } else { 3913 Addend = " + "; 3914 } 3915 } 3916 Addend += utohexstr(RelAddend, /*LowerCase=*/true); 3917 } 3918 OS << Addend << "\n"; 3919 } 3920 3921 template <class ELFT> 3922 static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType, 3923 const typename ELFT::Ehdr &EHeader, 3924 uint64_t CrelHdr = 0) { 3925 bool IsRela = SType == ELF::SHT_RELA || SType == ELF::SHT_ANDROID_RELA; 3926 if (ELFT::Is64Bits) 3927 OS << " Offset Info Type Symbol's " 3928 "Value Symbol's Name"; 3929 else 3930 OS << " Offset Info Type Sym. Value Symbol's Name"; 3931 if (IsRela || (SType == ELF::SHT_CREL && (CrelHdr & CREL_HDR_ADDEND))) 3932 OS << " + Addend"; 3933 OS << "\n"; 3934 } 3935 3936 template <class ELFT> 3937 void GNUELFDumper<ELFT>::printDynamicRelocHeader(unsigned Type, StringRef Name, 3938 const DynRegionInfo &Reg) { 3939 uint64_t Offset = Reg.Addr - this->Obj.base(); 3940 OS << "\n'" << Name.str().c_str() << "' relocation section at offset 0x" 3941 << utohexstr(Offset, /*LowerCase=*/true); 3942 if (Type != ELF::SHT_CREL) 3943 OS << " contains " << Reg.Size << " bytes"; 3944 OS << ":\n"; 3945 printRelocHeaderFields<ELFT>(OS, Type, this->Obj.getHeader()); 3946 } 3947 3948 template <class ELFT> 3949 static bool isRelocationSec(const typename ELFT::Shdr &Sec, 3950 const typename ELFT::Ehdr &EHeader) { 3951 return Sec.sh_type == ELF::SHT_REL || Sec.sh_type == ELF::SHT_RELA || 3952 Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_CREL || 3953 Sec.sh_type == ELF::SHT_ANDROID_REL || 3954 Sec.sh_type == ELF::SHT_ANDROID_RELA || 3955 Sec.sh_type == ELF::SHT_ANDROID_RELR || 3956 (EHeader.e_machine == EM_AARCH64 && 3957 Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR); 3958 } 3959 3960 template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() { 3961 auto PrintAsRelr = [&](const Elf_Shdr &Sec) { 3962 return Sec.sh_type == ELF::SHT_RELR || 3963 Sec.sh_type == ELF::SHT_ANDROID_RELR || 3964 (this->Obj.getHeader().e_machine == EM_AARCH64 && 3965 Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR); 3966 }; 3967 auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected<size_t> { 3968 // Android's packed relocation section needs to be unpacked first 3969 // to get the actual number of entries. 3970 if (Sec.sh_type == ELF::SHT_ANDROID_REL || 3971 Sec.sh_type == ELF::SHT_ANDROID_RELA) { 3972 Expected<std::vector<typename ELFT::Rela>> RelasOrErr = 3973 this->Obj.android_relas(Sec); 3974 if (!RelasOrErr) 3975 return RelasOrErr.takeError(); 3976 return RelasOrErr->size(); 3977 } 3978 3979 if (Sec.sh_type == ELF::SHT_CREL) { 3980 Expected<ArrayRef<uint8_t>> ContentsOrErr = 3981 this->Obj.getSectionContents(Sec); 3982 if (!ContentsOrErr) 3983 return ContentsOrErr.takeError(); 3984 auto NumOrErr = this->Obj.getCrelHeader(*ContentsOrErr); 3985 if (!NumOrErr) 3986 return NumOrErr.takeError(); 3987 return *NumOrErr / 8; 3988 } 3989 3990 if (PrintAsRelr(Sec)) { 3991 Expected<Elf_Relr_Range> RelrsOrErr = this->Obj.relrs(Sec); 3992 if (!RelrsOrErr) 3993 return RelrsOrErr.takeError(); 3994 return this->Obj.decode_relrs(*RelrsOrErr).size(); 3995 } 3996 3997 return Sec.getEntityCount(); 3998 }; 3999 4000 bool HasRelocSections = false; 4001 for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) { 4002 if (!isRelocationSec<ELFT>(Sec, this->Obj.getHeader())) 4003 continue; 4004 HasRelocSections = true; 4005 4006 std::string EntriesNum = "<?>"; 4007 if (Expected<size_t> NumOrErr = GetEntriesNum(Sec)) 4008 EntriesNum = std::to_string(*NumOrErr); 4009 else 4010 this->reportUniqueWarning("unable to get the number of relocations in " + 4011 this->describe(Sec) + ": " + 4012 toString(NumOrErr.takeError())); 4013 4014 uintX_t Offset = Sec.sh_offset; 4015 StringRef Name = this->getPrintableSectionName(Sec); 4016 OS << "\nRelocation section '" << Name << "' at offset 0x" 4017 << utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum 4018 << " entries:\n"; 4019 4020 if (PrintAsRelr(Sec)) { 4021 printRelr(Sec); 4022 } else { 4023 uint64_t CrelHdr = 0; 4024 // For CREL, read the header and call printRelocationsHelper only if 4025 // GetEntriesNum(Sec) succeeded. 4026 if (Sec.sh_type == ELF::SHT_CREL && EntriesNum != "<?>") { 4027 CrelHdr = cantFail(this->Obj.getCrelHeader( 4028 cantFail(this->Obj.getSectionContents(Sec)))); 4029 } 4030 printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader(), 4031 CrelHdr); 4032 if (Sec.sh_type != ELF::SHT_CREL || EntriesNum != "<?>") 4033 this->printRelocationsHelper(Sec); 4034 } 4035 } 4036 if (!HasRelocSections) 4037 OS << "\nThere are no relocations in this file.\n"; 4038 } 4039 4040 template <class ELFT> void GNUELFDumper<ELFT>::printRelr(const Elf_Shdr &Sec) { 4041 Expected<Elf_Relr_Range> RangeOrErr = this->Obj.relrs(Sec); 4042 if (!RangeOrErr) { 4043 this->reportUniqueWarning("unable to read relocations from " + 4044 this->describe(Sec) + ": " + 4045 toString(RangeOrErr.takeError())); 4046 return; 4047 } 4048 if (ELFT::Is64Bits) 4049 OS << "Index: Entry Address Symbolic Address\n"; 4050 else 4051 OS << "Index: Entry Address Symbolic Address\n"; 4052 4053 // If .symtab is available, collect its defined symbols and sort them by 4054 // st_value. 4055 SmallVector<std::pair<uint64_t, std::string>, 0> Syms; 4056 if (this->DotSymtabSec) { 4057 Elf_Sym_Range Symtab; 4058 std::optional<StringRef> Strtab; 4059 std::tie(Symtab, Strtab) = this->getSymtabAndStrtab(); 4060 if (Symtab.size() && Strtab) { 4061 for (auto [I, Sym] : enumerate(Symtab)) { 4062 if (!Sym.st_shndx) 4063 continue; 4064 Syms.emplace_back(Sym.st_value, 4065 this->getFullSymbolName(Sym, I, ArrayRef<Elf_Word>(), 4066 *Strtab, false)); 4067 } 4068 } 4069 } 4070 llvm::stable_sort(Syms); 4071 4072 typename ELFT::uint Base = 0; 4073 size_t I = 0; 4074 auto Print = [&](uint64_t Where) { 4075 OS << format_hex_no_prefix(Where, ELFT::Is64Bits ? 16 : 8); 4076 for (; I < Syms.size() && Syms[I].first <= Where; ++I) 4077 ; 4078 // Try symbolizing the address. Find the nearest symbol before or at the 4079 // address and print the symbol and the address difference. 4080 if (I) { 4081 OS << " " << Syms[I - 1].second; 4082 if (Syms[I - 1].first < Where) 4083 OS << " + 0x" << Twine::utohexstr(Where - Syms[I - 1].first); 4084 } 4085 OS << '\n'; 4086 }; 4087 for (auto [Index, R] : enumerate(*RangeOrErr)) { 4088 typename ELFT::uint Entry = R; 4089 OS << formatv("{0:4}: ", Index) 4090 << format_hex_no_prefix(Entry, ELFT::Is64Bits ? 16 : 8) << ' '; 4091 if ((Entry & 1) == 0) { 4092 Print(Entry); 4093 Base = Entry + sizeof(typename ELFT::uint); 4094 } else { 4095 bool First = true; 4096 for (auto Where = Base; Entry >>= 1; 4097 Where += sizeof(typename ELFT::uint)) { 4098 if (Entry & 1) { 4099 if (First) 4100 First = false; 4101 else 4102 OS.indent(ELFT::Is64Bits ? 24 : 16); 4103 Print(Where); 4104 } 4105 } 4106 Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(typename ELFT::uint); 4107 } 4108 } 4109 } 4110 4111 // Print the offset of a particular section from anyone of the ranges: 4112 // [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER]. 4113 // If 'Type' does not fall within any of those ranges, then a string is 4114 // returned as '<unknown>' followed by the type value. 4115 static std::string getSectionTypeOffsetString(unsigned Type) { 4116 if (Type >= SHT_LOOS && Type <= SHT_HIOS) 4117 return "LOOS+0x" + utohexstr(Type - SHT_LOOS); 4118 else if (Type >= SHT_LOPROC && Type <= SHT_HIPROC) 4119 return "LOPROC+0x" + utohexstr(Type - SHT_LOPROC); 4120 else if (Type >= SHT_LOUSER && Type <= SHT_HIUSER) 4121 return "LOUSER+0x" + utohexstr(Type - SHT_LOUSER); 4122 return "0x" + utohexstr(Type) + ": <unknown>"; 4123 } 4124 4125 static std::string getSectionTypeString(unsigned Machine, unsigned Type) { 4126 StringRef Name = getELFSectionTypeName(Machine, Type); 4127 4128 // Handle SHT_GNU_* type names. 4129 if (Name.consume_front("SHT_GNU_")) { 4130 if (Name == "HASH") 4131 return "GNU_HASH"; 4132 // E.g. SHT_GNU_verneed -> VERNEED. 4133 return Name.upper(); 4134 } 4135 4136 if (Name == "SHT_SYMTAB_SHNDX") 4137 return "SYMTAB SECTION INDICES"; 4138 4139 if (Name.consume_front("SHT_")) 4140 return Name.str(); 4141 return getSectionTypeOffsetString(Type); 4142 } 4143 4144 static void printSectionDescription(formatted_raw_ostream &OS, 4145 unsigned EMachine) { 4146 OS << "Key to Flags:\n"; 4147 OS << " W (write), A (alloc), X (execute), M (merge), S (strings), I " 4148 "(info),\n"; 4149 OS << " L (link order), O (extra OS processing required), G (group), T " 4150 "(TLS),\n"; 4151 OS << " C (compressed), x (unknown), o (OS specific), E (exclude),\n"; 4152 OS << " R (retain)"; 4153 4154 if (EMachine == EM_X86_64) 4155 OS << ", l (large)"; 4156 else if (EMachine == EM_ARM || EMachine == EM_AARCH64) 4157 OS << ", y (purecode)"; 4158 4159 OS << ", p (processor specific)\n"; 4160 } 4161 4162 template <class ELFT> void GNUELFDumper<ELFT>::printSectionHeaders() { 4163 ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections()); 4164 if (Sections.empty()) { 4165 OS << "\nThere are no sections in this file.\n"; 4166 Expected<StringRef> SecStrTableOrErr = 4167 this->Obj.getSectionStringTable(Sections, this->WarningHandler); 4168 if (!SecStrTableOrErr) 4169 this->reportUniqueWarning(SecStrTableOrErr.takeError()); 4170 return; 4171 } 4172 unsigned Bias = ELFT::Is64Bits ? 0 : 8; 4173 OS << "There are " << to_string(Sections.size()) 4174 << " section headers, starting at offset " 4175 << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n"; 4176 OS << "Section Headers:\n"; 4177 Field Fields[11] = { 4178 {"[Nr]", 2}, {"Name", 7}, {"Type", 25}, 4179 {"Address", 41}, {"Off", 58 - Bias}, {"Size", 65 - Bias}, 4180 {"ES", 72 - Bias}, {"Flg", 75 - Bias}, {"Lk", 79 - Bias}, 4181 {"Inf", 82 - Bias}, {"Al", 86 - Bias}}; 4182 for (const Field &F : Fields) 4183 printField(F); 4184 OS << "\n"; 4185 4186 StringRef SecStrTable; 4187 if (Expected<StringRef> SecStrTableOrErr = 4188 this->Obj.getSectionStringTable(Sections, this->WarningHandler)) 4189 SecStrTable = *SecStrTableOrErr; 4190 else 4191 this->reportUniqueWarning(SecStrTableOrErr.takeError()); 4192 4193 size_t SectionIndex = 0; 4194 for (const Elf_Shdr &Sec : Sections) { 4195 Fields[0].Str = to_string(SectionIndex); 4196 if (SecStrTable.empty()) 4197 Fields[1].Str = "<no-strings>"; 4198 else 4199 Fields[1].Str = std::string(unwrapOrError<StringRef>( 4200 this->FileName, this->Obj.getSectionName(Sec, SecStrTable))); 4201 Fields[2].Str = 4202 getSectionTypeString(this->Obj.getHeader().e_machine, Sec.sh_type); 4203 Fields[3].Str = 4204 to_string(format_hex_no_prefix(Sec.sh_addr, ELFT::Is64Bits ? 16 : 8)); 4205 Fields[4].Str = to_string(format_hex_no_prefix(Sec.sh_offset, 6)); 4206 Fields[5].Str = to_string(format_hex_no_prefix(Sec.sh_size, 6)); 4207 Fields[6].Str = to_string(format_hex_no_prefix(Sec.sh_entsize, 2)); 4208 Fields[7].Str = getGNUFlags(this->Obj.getHeader().e_ident[ELF::EI_OSABI], 4209 this->Obj.getHeader().e_machine, Sec.sh_flags); 4210 Fields[8].Str = to_string(Sec.sh_link); 4211 Fields[9].Str = to_string(Sec.sh_info); 4212 Fields[10].Str = to_string(Sec.sh_addralign); 4213 4214 OS.PadToColumn(Fields[0].Column); 4215 OS << "[" << right_justify(Fields[0].Str, 2) << "]"; 4216 for (int i = 1; i < 7; i++) 4217 printField(Fields[i]); 4218 OS.PadToColumn(Fields[7].Column); 4219 OS << right_justify(Fields[7].Str, 3); 4220 OS.PadToColumn(Fields[8].Column); 4221 OS << right_justify(Fields[8].Str, 2); 4222 OS.PadToColumn(Fields[9].Column); 4223 OS << right_justify(Fields[9].Str, 3); 4224 OS.PadToColumn(Fields[10].Column); 4225 OS << right_justify(Fields[10].Str, 2); 4226 OS << "\n"; 4227 ++SectionIndex; 4228 } 4229 printSectionDescription(OS, this->Obj.getHeader().e_machine); 4230 } 4231 4232 template <class ELFT> 4233 void GNUELFDumper<ELFT>::printSymtabMessage(const Elf_Shdr *Symtab, 4234 size_t Entries, 4235 bool NonVisibilityBitsUsed, 4236 bool ExtraSymInfo) const { 4237 StringRef Name; 4238 if (Symtab) 4239 Name = this->getPrintableSectionName(*Symtab); 4240 if (!Name.empty()) 4241 OS << "\nSymbol table '" << Name << "'"; 4242 else 4243 OS << "\nSymbol table for image"; 4244 OS << " contains " << Entries << " entries:\n"; 4245 4246 if (ELFT::Is64Bits) { 4247 OS << " Num: Value Size Type Bind Vis"; 4248 if (ExtraSymInfo) 4249 OS << "+Other"; 4250 } else { 4251 OS << " Num: Value Size Type Bind Vis"; 4252 if (ExtraSymInfo) 4253 OS << "+Other"; 4254 } 4255 4256 OS.PadToColumn((ELFT::Is64Bits ? 56 : 48) + (NonVisibilityBitsUsed ? 13 : 0)); 4257 if (ExtraSymInfo) 4258 OS << "Ndx(SecName) Name [+ Version Info]\n"; 4259 else 4260 OS << "Ndx Name\n"; 4261 } 4262 4263 template <class ELFT> 4264 std::string GNUELFDumper<ELFT>::getSymbolSectionNdx( 4265 const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, 4266 bool ExtraSymInfo) const { 4267 unsigned SectionIndex = Symbol.st_shndx; 4268 switch (SectionIndex) { 4269 case ELF::SHN_UNDEF: 4270 return "UND"; 4271 case ELF::SHN_ABS: 4272 return "ABS"; 4273 case ELF::SHN_COMMON: 4274 return "COM"; 4275 case ELF::SHN_XINDEX: { 4276 Expected<uint32_t> IndexOrErr = 4277 object::getExtendedSymbolTableIndex<ELFT>(Symbol, SymIndex, ShndxTable); 4278 if (!IndexOrErr) { 4279 assert(Symbol.st_shndx == SHN_XINDEX && 4280 "getExtendedSymbolTableIndex should only fail due to an invalid " 4281 "SHT_SYMTAB_SHNDX table/reference"); 4282 this->reportUniqueWarning(IndexOrErr.takeError()); 4283 return "RSV[0xffff]"; 4284 } 4285 SectionIndex = *IndexOrErr; 4286 break; 4287 } 4288 default: 4289 // Find if: 4290 // Processor specific 4291 if (SectionIndex >= ELF::SHN_LOPROC && SectionIndex <= ELF::SHN_HIPROC) 4292 return std::string("PRC[0x") + 4293 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]"; 4294 // OS specific 4295 if (SectionIndex >= ELF::SHN_LOOS && SectionIndex <= ELF::SHN_HIOS) 4296 return std::string("OS[0x") + 4297 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]"; 4298 // Architecture reserved: 4299 if (SectionIndex >= ELF::SHN_LORESERVE && 4300 SectionIndex <= ELF::SHN_HIRESERVE) 4301 return std::string("RSV[0x") + 4302 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]"; 4303 break; 4304 } 4305 4306 std::string Extra; 4307 if (ExtraSymInfo) { 4308 auto Sec = this->Obj.getSection(SectionIndex); 4309 if (!Sec) { 4310 this->reportUniqueWarning(Sec.takeError()); 4311 } else { 4312 auto SecName = this->Obj.getSectionName(**Sec); 4313 if (!SecName) 4314 this->reportUniqueWarning(SecName.takeError()); 4315 else 4316 Extra = Twine(" (" + *SecName + ")").str(); 4317 } 4318 } 4319 return to_string(format_decimal(SectionIndex, 3)) + Extra; 4320 } 4321 4322 template <class ELFT> 4323 void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, 4324 DataRegion<Elf_Word> ShndxTable, 4325 std::optional<StringRef> StrTable, 4326 bool IsDynamic, bool NonVisibilityBitsUsed, 4327 bool ExtraSymInfo) const { 4328 unsigned Bias = ELFT::Is64Bits ? 8 : 0; 4329 Field Fields[8] = {0, 8, 17 + Bias, 23 + Bias, 4330 31 + Bias, 38 + Bias, 48 + Bias, 51 + Bias}; 4331 Fields[0].Str = to_string(format_decimal(SymIndex, 6)) + ":"; 4332 Fields[1].Str = 4333 to_string(format_hex_no_prefix(Symbol.st_value, ELFT::Is64Bits ? 16 : 8)); 4334 Fields[2].Str = to_string(format_decimal(Symbol.st_size, 5)); 4335 4336 unsigned char SymbolType = Symbol.getType(); 4337 if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && 4338 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) 4339 Fields[3].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes)); 4340 else 4341 Fields[3].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes)); 4342 4343 Fields[4].Str = 4344 enumToString(Symbol.getBinding(), ArrayRef(ElfSymbolBindings)); 4345 Fields[5].Str = 4346 enumToString(Symbol.getVisibility(), ArrayRef(ElfSymbolVisibilities)); 4347 4348 if (Symbol.st_other & ~0x3) { 4349 if (this->Obj.getHeader().e_machine == ELF::EM_AARCH64) { 4350 uint8_t Other = Symbol.st_other & ~0x3; 4351 if (Other & STO_AARCH64_VARIANT_PCS) { 4352 Other &= ~STO_AARCH64_VARIANT_PCS; 4353 Fields[5].Str += " [VARIANT_PCS"; 4354 if (Other != 0) 4355 Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true)); 4356 Fields[5].Str.append("]"); 4357 } 4358 } else if (this->Obj.getHeader().e_machine == ELF::EM_RISCV) { 4359 uint8_t Other = Symbol.st_other & ~0x3; 4360 if (Other & STO_RISCV_VARIANT_CC) { 4361 Other &= ~STO_RISCV_VARIANT_CC; 4362 Fields[5].Str += " [VARIANT_CC"; 4363 if (Other != 0) 4364 Fields[5].Str.append(" | " + utohexstr(Other, /*LowerCase=*/true)); 4365 Fields[5].Str.append("]"); 4366 } 4367 } else { 4368 Fields[5].Str += 4369 " [<other: " + to_string(format_hex(Symbol.st_other, 2)) + ">]"; 4370 } 4371 } 4372 4373 Fields[6].Column += NonVisibilityBitsUsed ? 13 : 0; 4374 Fields[6].Str = 4375 getSymbolSectionNdx(Symbol, SymIndex, ShndxTable, ExtraSymInfo); 4376 4377 Fields[7].Column += ExtraSymInfo ? 10 : 0; 4378 Fields[7].Str = this->getFullSymbolName(Symbol, SymIndex, ShndxTable, 4379 StrTable, IsDynamic); 4380 for (const Field &Entry : Fields) 4381 printField(Entry); 4382 OS << "\n"; 4383 } 4384 4385 template <class ELFT> 4386 void GNUELFDumper<ELFT>::printHashedSymbol(const Elf_Sym *Symbol, 4387 unsigned SymIndex, 4388 DataRegion<Elf_Word> ShndxTable, 4389 StringRef StrTable, 4390 uint32_t Bucket) { 4391 unsigned Bias = ELFT::Is64Bits ? 8 : 0; 4392 Field Fields[9] = {0, 6, 11, 20 + Bias, 25 + Bias, 4393 34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias}; 4394 Fields[0].Str = to_string(format_decimal(SymIndex, 5)); 4395 Fields[1].Str = to_string(format_decimal(Bucket, 3)) + ":"; 4396 4397 Fields[2].Str = to_string( 4398 format_hex_no_prefix(Symbol->st_value, ELFT::Is64Bits ? 16 : 8)); 4399 Fields[3].Str = to_string(format_decimal(Symbol->st_size, 5)); 4400 4401 unsigned char SymbolType = Symbol->getType(); 4402 if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && 4403 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) 4404 Fields[4].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes)); 4405 else 4406 Fields[4].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes)); 4407 4408 Fields[5].Str = 4409 enumToString(Symbol->getBinding(), ArrayRef(ElfSymbolBindings)); 4410 Fields[6].Str = 4411 enumToString(Symbol->getVisibility(), ArrayRef(ElfSymbolVisibilities)); 4412 Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex, ShndxTable); 4413 Fields[8].Str = 4414 this->getFullSymbolName(*Symbol, SymIndex, ShndxTable, StrTable, true); 4415 4416 for (const Field &Entry : Fields) 4417 printField(Entry); 4418 OS << "\n"; 4419 } 4420 4421 template <class ELFT> 4422 void GNUELFDumper<ELFT>::printSymbols(bool PrintSymbols, 4423 bool PrintDynamicSymbols, 4424 bool ExtraSymInfo) { 4425 if (!PrintSymbols && !PrintDynamicSymbols) 4426 return; 4427 // GNU readelf prints both the .dynsym and .symtab with --symbols. 4428 this->printSymbolsHelper(true, ExtraSymInfo); 4429 if (PrintSymbols) 4430 this->printSymbolsHelper(false, ExtraSymInfo); 4431 } 4432 4433 template <class ELFT> 4434 void GNUELFDumper<ELFT>::printHashTableSymbols(const Elf_Hash &SysVHash) { 4435 if (this->DynamicStringTable.empty()) 4436 return; 4437 4438 if (ELFT::Is64Bits) 4439 OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; 4440 else 4441 OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; 4442 OS << "\n"; 4443 4444 Elf_Sym_Range DynSyms = this->dynamic_symbols(); 4445 const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0]; 4446 if (!FirstSym) { 4447 this->reportUniqueWarning( 4448 Twine("unable to print symbols for the .hash table: the " 4449 "dynamic symbol table ") + 4450 (this->DynSymRegion ? "is empty" : "was not found")); 4451 return; 4452 } 4453 4454 DataRegion<Elf_Word> ShndxTable( 4455 (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end()); 4456 auto Buckets = SysVHash.buckets(); 4457 auto Chains = SysVHash.chains(); 4458 for (uint32_t Buc = 0; Buc < SysVHash.nbucket; Buc++) { 4459 if (Buckets[Buc] == ELF::STN_UNDEF) 4460 continue; 4461 BitVector Visited(SysVHash.nchain); 4462 for (uint32_t Ch = Buckets[Buc]; Ch < SysVHash.nchain; Ch = Chains[Ch]) { 4463 if (Ch == ELF::STN_UNDEF) 4464 break; 4465 4466 if (Visited[Ch]) { 4467 this->reportUniqueWarning(".hash section is invalid: bucket " + 4468 Twine(Ch) + 4469 ": a cycle was detected in the linked chain"); 4470 break; 4471 } 4472 4473 printHashedSymbol(FirstSym + Ch, Ch, ShndxTable, this->DynamicStringTable, 4474 Buc); 4475 Visited[Ch] = true; 4476 } 4477 } 4478 } 4479 4480 template <class ELFT> 4481 void GNUELFDumper<ELFT>::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) { 4482 if (this->DynamicStringTable.empty()) 4483 return; 4484 4485 Elf_Sym_Range DynSyms = this->dynamic_symbols(); 4486 const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0]; 4487 if (!FirstSym) { 4488 this->reportUniqueWarning( 4489 Twine("unable to print symbols for the .gnu.hash table: the " 4490 "dynamic symbol table ") + 4491 (this->DynSymRegion ? "is empty" : "was not found")); 4492 return; 4493 } 4494 4495 auto GetSymbol = [&](uint64_t SymIndex, 4496 uint64_t SymsTotal) -> const Elf_Sym * { 4497 if (SymIndex >= SymsTotal) { 4498 this->reportUniqueWarning( 4499 "unable to print hashed symbol with index " + Twine(SymIndex) + 4500 ", which is greater than or equal to the number of dynamic symbols " 4501 "(" + 4502 Twine::utohexstr(SymsTotal) + ")"); 4503 return nullptr; 4504 } 4505 return FirstSym + SymIndex; 4506 }; 4507 4508 Expected<ArrayRef<Elf_Word>> ValuesOrErr = 4509 getGnuHashTableChains<ELFT>(this->DynSymRegion, &GnuHash); 4510 ArrayRef<Elf_Word> Values; 4511 if (!ValuesOrErr) 4512 this->reportUniqueWarning("unable to get hash values for the SHT_GNU_HASH " 4513 "section: " + 4514 toString(ValuesOrErr.takeError())); 4515 else 4516 Values = *ValuesOrErr; 4517 4518 DataRegion<Elf_Word> ShndxTable( 4519 (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end()); 4520 ArrayRef<Elf_Word> Buckets = GnuHash.buckets(); 4521 for (uint32_t Buc = 0; Buc < GnuHash.nbuckets; Buc++) { 4522 if (Buckets[Buc] == ELF::STN_UNDEF) 4523 continue; 4524 uint32_t Index = Buckets[Buc]; 4525 // Print whole chain. 4526 while (true) { 4527 uint32_t SymIndex = Index++; 4528 if (const Elf_Sym *Sym = GetSymbol(SymIndex, DynSyms.size())) 4529 printHashedSymbol(Sym, SymIndex, ShndxTable, this->DynamicStringTable, 4530 Buc); 4531 else 4532 break; 4533 4534 if (SymIndex < GnuHash.symndx) { 4535 this->reportUniqueWarning( 4536 "unable to read the hash value for symbol with index " + 4537 Twine(SymIndex) + 4538 ", which is less than the index of the first hashed symbol (" + 4539 Twine(GnuHash.symndx) + ")"); 4540 break; 4541 } 4542 4543 // Chain ends at symbol with stopper bit. 4544 if ((Values[SymIndex - GnuHash.symndx] & 1) == 1) 4545 break; 4546 } 4547 } 4548 } 4549 4550 template <class ELFT> void GNUELFDumper<ELFT>::printHashSymbols() { 4551 if (this->HashTable) { 4552 OS << "\n Symbol table of .hash for image:\n"; 4553 if (Error E = checkHashTable<ELFT>(*this, this->HashTable)) 4554 this->reportUniqueWarning(std::move(E)); 4555 else 4556 printHashTableSymbols(*this->HashTable); 4557 } 4558 4559 // Try printing the .gnu.hash table. 4560 if (this->GnuHashTable) { 4561 OS << "\n Symbol table of .gnu.hash for image:\n"; 4562 if (ELFT::Is64Bits) 4563 OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; 4564 else 4565 OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; 4566 OS << "\n"; 4567 4568 if (Error E = checkGNUHashTable<ELFT>(this->Obj, this->GnuHashTable)) 4569 this->reportUniqueWarning(std::move(E)); 4570 else 4571 printGnuHashTableSymbols(*this->GnuHashTable); 4572 } 4573 } 4574 4575 template <class ELFT> void GNUELFDumper<ELFT>::printSectionDetails() { 4576 ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections()); 4577 if (Sections.empty()) { 4578 OS << "\nThere are no sections in this file.\n"; 4579 Expected<StringRef> SecStrTableOrErr = 4580 this->Obj.getSectionStringTable(Sections, this->WarningHandler); 4581 if (!SecStrTableOrErr) 4582 this->reportUniqueWarning(SecStrTableOrErr.takeError()); 4583 return; 4584 } 4585 OS << "There are " << to_string(Sections.size()) 4586 << " section headers, starting at offset " 4587 << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n"; 4588 4589 OS << "Section Headers:\n"; 4590 4591 auto PrintFields = [&](ArrayRef<Field> V) { 4592 for (const Field &F : V) 4593 printField(F); 4594 OS << "\n"; 4595 }; 4596 4597 PrintFields({{"[Nr]", 2}, {"Name", 7}}); 4598 4599 constexpr bool Is64 = ELFT::Is64Bits; 4600 PrintFields({{"Type", 7}, 4601 {Is64 ? "Address" : "Addr", 23}, 4602 {"Off", Is64 ? 40 : 32}, 4603 {"Size", Is64 ? 47 : 39}, 4604 {"ES", Is64 ? 54 : 46}, 4605 {"Lk", Is64 ? 59 : 51}, 4606 {"Inf", Is64 ? 62 : 54}, 4607 {"Al", Is64 ? 66 : 57}}); 4608 PrintFields({{"Flags", 7}}); 4609 4610 StringRef SecStrTable; 4611 if (Expected<StringRef> SecStrTableOrErr = 4612 this->Obj.getSectionStringTable(Sections, this->WarningHandler)) 4613 SecStrTable = *SecStrTableOrErr; 4614 else 4615 this->reportUniqueWarning(SecStrTableOrErr.takeError()); 4616 4617 size_t SectionIndex = 0; 4618 const unsigned AddrSize = Is64 ? 16 : 8; 4619 for (const Elf_Shdr &S : Sections) { 4620 StringRef Name = "<?>"; 4621 if (Expected<StringRef> NameOrErr = 4622 this->Obj.getSectionName(S, SecStrTable)) 4623 Name = *NameOrErr; 4624 else 4625 this->reportUniqueWarning(NameOrErr.takeError()); 4626 4627 OS.PadToColumn(2); 4628 OS << "[" << right_justify(to_string(SectionIndex), 2) << "]"; 4629 PrintFields({{Name, 7}}); 4630 PrintFields( 4631 {{getSectionTypeString(this->Obj.getHeader().e_machine, S.sh_type), 7}, 4632 {to_string(format_hex_no_prefix(S.sh_addr, AddrSize)), 23}, 4633 {to_string(format_hex_no_prefix(S.sh_offset, 6)), Is64 ? 39 : 32}, 4634 {to_string(format_hex_no_prefix(S.sh_size, 6)), Is64 ? 47 : 39}, 4635 {to_string(format_hex_no_prefix(S.sh_entsize, 2)), Is64 ? 54 : 46}, 4636 {to_string(S.sh_link), Is64 ? 59 : 51}, 4637 {to_string(S.sh_info), Is64 ? 63 : 55}, 4638 {to_string(S.sh_addralign), Is64 ? 66 : 58}}); 4639 4640 OS.PadToColumn(7); 4641 OS << "[" << to_string(format_hex_no_prefix(S.sh_flags, AddrSize)) << "]: "; 4642 4643 DenseMap<unsigned, StringRef> FlagToName = { 4644 {SHF_WRITE, "WRITE"}, {SHF_ALLOC, "ALLOC"}, 4645 {SHF_EXECINSTR, "EXEC"}, {SHF_MERGE, "MERGE"}, 4646 {SHF_STRINGS, "STRINGS"}, {SHF_INFO_LINK, "INFO LINK"}, 4647 {SHF_LINK_ORDER, "LINK ORDER"}, {SHF_OS_NONCONFORMING, "OS NONCONF"}, 4648 {SHF_GROUP, "GROUP"}, {SHF_TLS, "TLS"}, 4649 {SHF_COMPRESSED, "COMPRESSED"}, {SHF_EXCLUDE, "EXCLUDE"}}; 4650 4651 uint64_t Flags = S.sh_flags; 4652 uint64_t UnknownFlags = 0; 4653 ListSeparator LS; 4654 while (Flags) { 4655 // Take the least significant bit as a flag. 4656 uint64_t Flag = Flags & -Flags; 4657 Flags -= Flag; 4658 4659 auto It = FlagToName.find(Flag); 4660 if (It != FlagToName.end()) 4661 OS << LS << It->second; 4662 else 4663 UnknownFlags |= Flag; 4664 } 4665 4666 auto PrintUnknownFlags = [&](uint64_t Mask, StringRef Name) { 4667 uint64_t FlagsToPrint = UnknownFlags & Mask; 4668 if (!FlagsToPrint) 4669 return; 4670 4671 OS << LS << Name << " (" 4672 << to_string(format_hex_no_prefix(FlagsToPrint, AddrSize)) << ")"; 4673 UnknownFlags &= ~Mask; 4674 }; 4675 4676 PrintUnknownFlags(SHF_MASKOS, "OS"); 4677 PrintUnknownFlags(SHF_MASKPROC, "PROC"); 4678 PrintUnknownFlags(uint64_t(-1), "UNKNOWN"); 4679 4680 OS << "\n"; 4681 ++SectionIndex; 4682 4683 if (!(S.sh_flags & SHF_COMPRESSED)) 4684 continue; 4685 Expected<ArrayRef<uint8_t>> Data = this->Obj.getSectionContents(S); 4686 if (!Data || Data->size() < sizeof(Elf_Chdr)) { 4687 consumeError(Data.takeError()); 4688 reportWarning(createError("SHF_COMPRESSED section '" + Name + 4689 "' does not have an Elf_Chdr header"), 4690 this->FileName); 4691 OS.indent(7); 4692 OS << "[<corrupt>]"; 4693 } else { 4694 OS.indent(7); 4695 auto *Chdr = reinterpret_cast<const Elf_Chdr *>(Data->data()); 4696 if (Chdr->ch_type == ELFCOMPRESS_ZLIB) 4697 OS << "ZLIB"; 4698 else if (Chdr->ch_type == ELFCOMPRESS_ZSTD) 4699 OS << "ZSTD"; 4700 else 4701 OS << format("[<unknown>: 0x%x]", unsigned(Chdr->ch_type)); 4702 OS << ", " << format_hex_no_prefix(Chdr->ch_size, ELFT::Is64Bits ? 16 : 8) 4703 << ", " << Chdr->ch_addralign; 4704 } 4705 OS << '\n'; 4706 } 4707 } 4708 4709 static inline std::string printPhdrFlags(unsigned Flag) { 4710 std::string Str; 4711 Str = (Flag & PF_R) ? "R" : " "; 4712 Str += (Flag & PF_W) ? "W" : " "; 4713 Str += (Flag & PF_X) ? "E" : " "; 4714 return Str; 4715 } 4716 4717 template <class ELFT> 4718 static bool checkTLSSections(const typename ELFT::Phdr &Phdr, 4719 const typename ELFT::Shdr &Sec) { 4720 if (Sec.sh_flags & ELF::SHF_TLS) { 4721 // .tbss must only be shown in the PT_TLS segment. 4722 if (Sec.sh_type == ELF::SHT_NOBITS) 4723 return Phdr.p_type == ELF::PT_TLS; 4724 4725 // SHF_TLS sections are only shown in PT_TLS, PT_LOAD or PT_GNU_RELRO 4726 // segments. 4727 return (Phdr.p_type == ELF::PT_TLS) || (Phdr.p_type == ELF::PT_LOAD) || 4728 (Phdr.p_type == ELF::PT_GNU_RELRO); 4729 } 4730 4731 // PT_TLS must only have SHF_TLS sections. 4732 return Phdr.p_type != ELF::PT_TLS; 4733 } 4734 4735 template <class ELFT> 4736 static bool checkPTDynamic(const typename ELFT::Phdr &Phdr, 4737 const typename ELFT::Shdr &Sec) { 4738 if (Phdr.p_type != ELF::PT_DYNAMIC || Phdr.p_memsz == 0 || Sec.sh_size != 0) 4739 return true; 4740 4741 // We get here when we have an empty section. Only non-empty sections can be 4742 // at the start or at the end of PT_DYNAMIC. 4743 // Is section within the phdr both based on offset and VMA? 4744 bool CheckOffset = (Sec.sh_type == ELF::SHT_NOBITS) || 4745 (Sec.sh_offset > Phdr.p_offset && 4746 Sec.sh_offset < Phdr.p_offset + Phdr.p_filesz); 4747 bool CheckVA = !(Sec.sh_flags & ELF::SHF_ALLOC) || 4748 (Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz); 4749 return CheckOffset && CheckVA; 4750 } 4751 4752 template <class ELFT> 4753 void GNUELFDumper<ELFT>::printProgramHeaders( 4754 bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) { 4755 const bool ShouldPrintSectionMapping = (PrintSectionMapping != cl::BOU_FALSE); 4756 // Exit early if no program header or section mapping details were requested. 4757 if (!PrintProgramHeaders && !ShouldPrintSectionMapping) 4758 return; 4759 4760 if (PrintProgramHeaders) { 4761 const Elf_Ehdr &Header = this->Obj.getHeader(); 4762 if (Header.e_phnum == 0) { 4763 OS << "\nThere are no program headers in this file.\n"; 4764 } else { 4765 printProgramHeaders(); 4766 } 4767 } 4768 4769 if (ShouldPrintSectionMapping) 4770 printSectionMapping(); 4771 } 4772 4773 template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders() { 4774 unsigned Bias = ELFT::Is64Bits ? 8 : 0; 4775 const Elf_Ehdr &Header = this->Obj.getHeader(); 4776 Field Fields[8] = {2, 17, 26, 37 + Bias, 4777 48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias}; 4778 OS << "\nElf file type is " 4779 << enumToString(Header.e_type, ArrayRef(ElfObjectFileType)) << "\n" 4780 << "Entry point " << format_hex(Header.e_entry, 3) << "\n" 4781 << "There are " << Header.e_phnum << " program headers," 4782 << " starting at offset " << Header.e_phoff << "\n\n" 4783 << "Program Headers:\n"; 4784 if (ELFT::Is64Bits) 4785 OS << " Type Offset VirtAddr PhysAddr " 4786 << " FileSiz MemSiz Flg Align\n"; 4787 else 4788 OS << " Type Offset VirtAddr PhysAddr FileSiz " 4789 << "MemSiz Flg Align\n"; 4790 4791 unsigned Width = ELFT::Is64Bits ? 18 : 10; 4792 unsigned SizeWidth = ELFT::Is64Bits ? 8 : 7; 4793 4794 Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers(); 4795 if (!PhdrsOrErr) { 4796 this->reportUniqueWarning("unable to dump program headers: " + 4797 toString(PhdrsOrErr.takeError())); 4798 return; 4799 } 4800 4801 for (const Elf_Phdr &Phdr : *PhdrsOrErr) { 4802 Fields[0].Str = getGNUPtType(Header.e_machine, Phdr.p_type); 4803 Fields[1].Str = to_string(format_hex(Phdr.p_offset, 8)); 4804 Fields[2].Str = to_string(format_hex(Phdr.p_vaddr, Width)); 4805 Fields[3].Str = to_string(format_hex(Phdr.p_paddr, Width)); 4806 Fields[4].Str = to_string(format_hex(Phdr.p_filesz, SizeWidth)); 4807 Fields[5].Str = to_string(format_hex(Phdr.p_memsz, SizeWidth)); 4808 Fields[6].Str = printPhdrFlags(Phdr.p_flags); 4809 Fields[7].Str = to_string(format_hex(Phdr.p_align, 1)); 4810 for (const Field &F : Fields) 4811 printField(F); 4812 if (Phdr.p_type == ELF::PT_INTERP) { 4813 OS << "\n"; 4814 auto ReportBadInterp = [&](const Twine &Msg) { 4815 this->reportUniqueWarning( 4816 "unable to read program interpreter name at offset 0x" + 4817 Twine::utohexstr(Phdr.p_offset) + ": " + Msg); 4818 }; 4819 4820 if (Phdr.p_offset >= this->Obj.getBufSize()) { 4821 ReportBadInterp("it goes past the end of the file (0x" + 4822 Twine::utohexstr(this->Obj.getBufSize()) + ")"); 4823 continue; 4824 } 4825 4826 const char *Data = 4827 reinterpret_cast<const char *>(this->Obj.base()) + Phdr.p_offset; 4828 size_t MaxSize = this->Obj.getBufSize() - Phdr.p_offset; 4829 size_t Len = strnlen(Data, MaxSize); 4830 if (Len == MaxSize) { 4831 ReportBadInterp("it is not null-terminated"); 4832 continue; 4833 } 4834 4835 OS << " [Requesting program interpreter: "; 4836 OS << StringRef(Data, Len) << "]"; 4837 } 4838 OS << "\n"; 4839 } 4840 } 4841 4842 template <class ELFT> void GNUELFDumper<ELFT>::printSectionMapping() { 4843 OS << "\n Section to Segment mapping:\n Segment Sections...\n"; 4844 DenseSet<const Elf_Shdr *> BelongsToSegment; 4845 int Phnum = 0; 4846 4847 Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers(); 4848 if (!PhdrsOrErr) { 4849 this->reportUniqueWarning( 4850 "can't read program headers to build section to segment mapping: " + 4851 toString(PhdrsOrErr.takeError())); 4852 return; 4853 } 4854 4855 for (const Elf_Phdr &Phdr : *PhdrsOrErr) { 4856 std::string Sections; 4857 OS << format(" %2.2d ", Phnum++); 4858 // Check if each section is in a segment and then print mapping. 4859 for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) { 4860 if (Sec.sh_type == ELF::SHT_NULL) 4861 continue; 4862 4863 // readelf additionally makes sure it does not print zero sized sections 4864 // at end of segments and for PT_DYNAMIC both start and end of section 4865 // .tbss must only be shown in PT_TLS section. 4866 if (isSectionInSegment<ELFT>(Phdr, Sec) && 4867 checkTLSSections<ELFT>(Phdr, Sec) && 4868 checkPTDynamic<ELFT>(Phdr, Sec)) { 4869 Sections += 4870 unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() + 4871 " "; 4872 BelongsToSegment.insert(&Sec); 4873 } 4874 } 4875 OS << Sections << "\n"; 4876 OS.flush(); 4877 } 4878 4879 // Display sections that do not belong to a segment. 4880 std::string Sections; 4881 for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) { 4882 if (BelongsToSegment.find(&Sec) == BelongsToSegment.end()) 4883 Sections += 4884 unwrapOrError(this->FileName, this->Obj.getSectionName(Sec)).str() + 4885 ' '; 4886 } 4887 if (!Sections.empty()) { 4888 OS << " None " << Sections << '\n'; 4889 OS.flush(); 4890 } 4891 } 4892 4893 namespace { 4894 4895 template <class ELFT> 4896 RelSymbol<ELFT> getSymbolForReloc(const ELFDumper<ELFT> &Dumper, 4897 const Relocation<ELFT> &Reloc) { 4898 using Elf_Sym = typename ELFT::Sym; 4899 auto WarnAndReturn = [&](const Elf_Sym *Sym, 4900 const Twine &Reason) -> RelSymbol<ELFT> { 4901 Dumper.reportUniqueWarning( 4902 "unable to get name of the dynamic symbol with index " + 4903 Twine(Reloc.Symbol) + ": " + Reason); 4904 return {Sym, "<corrupt>"}; 4905 }; 4906 4907 ArrayRef<Elf_Sym> Symbols = Dumper.dynamic_symbols(); 4908 const Elf_Sym *FirstSym = Symbols.begin(); 4909 if (!FirstSym) 4910 return WarnAndReturn(nullptr, "no dynamic symbol table found"); 4911 4912 // We might have an object without a section header. In this case the size of 4913 // Symbols is zero, because there is no way to know the size of the dynamic 4914 // table. We should allow this case and not print a warning. 4915 if (!Symbols.empty() && Reloc.Symbol >= Symbols.size()) 4916 return WarnAndReturn( 4917 nullptr, 4918 "index is greater than or equal to the number of dynamic symbols (" + 4919 Twine(Symbols.size()) + ")"); 4920 4921 const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile(); 4922 const uint64_t FileSize = Obj.getBufSize(); 4923 const uint64_t SymOffset = ((const uint8_t *)FirstSym - Obj.base()) + 4924 (uint64_t)Reloc.Symbol * sizeof(Elf_Sym); 4925 if (SymOffset + sizeof(Elf_Sym) > FileSize) 4926 return WarnAndReturn(nullptr, "symbol at 0x" + Twine::utohexstr(SymOffset) + 4927 " goes past the end of the file (0x" + 4928 Twine::utohexstr(FileSize) + ")"); 4929 4930 const Elf_Sym *Sym = FirstSym + Reloc.Symbol; 4931 Expected<StringRef> ErrOrName = Sym->getName(Dumper.getDynamicStringTable()); 4932 if (!ErrOrName) 4933 return WarnAndReturn(Sym, toString(ErrOrName.takeError())); 4934 4935 return {Sym == FirstSym ? nullptr : Sym, maybeDemangle(*ErrOrName)}; 4936 } 4937 } // namespace 4938 4939 template <class ELFT> 4940 static size_t getMaxDynamicTagSize(const ELFFile<ELFT> &Obj, 4941 typename ELFT::DynRange Tags) { 4942 size_t Max = 0; 4943 for (const typename ELFT::Dyn &Dyn : Tags) 4944 Max = std::max(Max, Obj.getDynamicTagAsString(Dyn.d_tag).size()); 4945 return Max; 4946 } 4947 4948 template <class ELFT> void GNUELFDumper<ELFT>::printDynamicTable() { 4949 Elf_Dyn_Range Table = this->dynamic_table(); 4950 if (Table.empty()) 4951 return; 4952 4953 OS << "Dynamic section at offset " 4954 << format_hex(reinterpret_cast<const uint8_t *>(this->DynamicTable.Addr) - 4955 this->Obj.base(), 4956 1) 4957 << " contains " << Table.size() << " entries:\n"; 4958 4959 // The type name is surrounded with round brackets, hence add 2. 4960 size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table) + 2; 4961 // The "Name/Value" column should be indented from the "Type" column by N 4962 // spaces, where N = MaxTagSize - length of "Type" (4) + trailing 4963 // space (1) = 3. 4964 OS << " Tag" + std::string(ELFT::Is64Bits ? 16 : 8, ' ') + "Type" 4965 << std::string(MaxTagSize - 3, ' ') << "Name/Value\n"; 4966 4967 std::string ValueFmt = " %-" + std::to_string(MaxTagSize) + "s "; 4968 for (auto Entry : Table) { 4969 uintX_t Tag = Entry.getTag(); 4970 std::string Type = 4971 std::string("(") + this->Obj.getDynamicTagAsString(Tag) + ")"; 4972 std::string Value = this->getDynamicEntry(Tag, Entry.getVal()); 4973 OS << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10) 4974 << format(ValueFmt.c_str(), Type.c_str()) << Value << "\n"; 4975 } 4976 } 4977 4978 template <class ELFT> void GNUELFDumper<ELFT>::printDynamicRelocations() { 4979 this->printDynamicRelocationsHelper(); 4980 } 4981 4982 template <class ELFT> 4983 void ELFDumper<ELFT>::printDynamicReloc(const Relocation<ELFT> &R) { 4984 printRelRelaReloc(R, getSymbolForReloc(*this, R)); 4985 } 4986 4987 template <class ELFT> 4988 void ELFDumper<ELFT>::printRelocationsHelper(const Elf_Shdr &Sec) { 4989 this->forEachRelocationDo( 4990 Sec, [&](const Relocation<ELFT> &R, unsigned Ndx, const Elf_Shdr &Sec, 4991 const Elf_Shdr *SymTab) { printReloc(R, Ndx, Sec, SymTab); }); 4992 } 4993 4994 template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocationsHelper() { 4995 const bool IsMips64EL = this->Obj.isMips64EL(); 4996 auto DumpCrelRegion = [&](DynRegionInfo &Region) { 4997 // While the size is unknown, a valid CREL has at least one byte. We can 4998 // check whether Addr is in bounds, and then decode CREL until the file 4999 // end. 5000 Region.Size = Region.EntSize = 1; 5001 if (!Region.template getAsArrayRef<uint8_t>().empty()) { 5002 const uint64_t Offset = 5003 Region.Addr - reinterpret_cast<const uint8_t *>( 5004 ObjF.getMemoryBufferRef().getBufferStart()); 5005 const uint64_t ObjSize = ObjF.getMemoryBufferRef().getBufferSize(); 5006 auto RelsOrRelas = 5007 Obj.decodeCrel(ArrayRef<uint8_t>(Region.Addr, ObjSize - Offset)); 5008 if (!RelsOrRelas) { 5009 reportUniqueWarning(toString(RelsOrRelas.takeError())); 5010 } else { 5011 for (const Elf_Rel &R : RelsOrRelas->first) 5012 printDynamicReloc(Relocation<ELFT>(R, false)); 5013 for (const Elf_Rela &R : RelsOrRelas->second) 5014 printDynamicReloc(Relocation<ELFT>(R, false)); 5015 } 5016 } 5017 }; 5018 5019 if (this->DynCrelRegion.Addr) { 5020 printDynamicRelocHeader(ELF::SHT_CREL, "CREL", this->DynCrelRegion); 5021 DumpCrelRegion(this->DynCrelRegion); 5022 } 5023 5024 if (this->DynRelaRegion.Size > 0) { 5025 printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion); 5026 for (const Elf_Rela &Rela : 5027 this->DynRelaRegion.template getAsArrayRef<Elf_Rela>()) 5028 printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL)); 5029 } 5030 5031 if (this->DynRelRegion.Size > 0) { 5032 printDynamicRelocHeader(ELF::SHT_REL, "REL", this->DynRelRegion); 5033 for (const Elf_Rel &Rel : 5034 this->DynRelRegion.template getAsArrayRef<Elf_Rel>()) 5035 printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL)); 5036 } 5037 5038 if (this->DynRelrRegion.Size > 0) { 5039 printDynamicRelocHeader(ELF::SHT_REL, "RELR", this->DynRelrRegion); 5040 Elf_Relr_Range Relrs = 5041 this->DynRelrRegion.template getAsArrayRef<Elf_Relr>(); 5042 for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs)) 5043 printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL)); 5044 } 5045 5046 if (this->DynPLTRelRegion.Size) { 5047 if (this->DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { 5048 printDynamicRelocHeader(ELF::SHT_RELA, "PLT", this->DynPLTRelRegion); 5049 for (const Elf_Rela &Rela : 5050 this->DynPLTRelRegion.template getAsArrayRef<Elf_Rela>()) 5051 printDynamicReloc(Relocation<ELFT>(Rela, IsMips64EL)); 5052 } else if (this->DynPLTRelRegion.EntSize == 1) { 5053 DumpCrelRegion(this->DynPLTRelRegion); 5054 } else { 5055 printDynamicRelocHeader(ELF::SHT_REL, "PLT", this->DynPLTRelRegion); 5056 for (const Elf_Rel &Rel : 5057 this->DynPLTRelRegion.template getAsArrayRef<Elf_Rel>()) 5058 printDynamicReloc(Relocation<ELFT>(Rel, IsMips64EL)); 5059 } 5060 } 5061 } 5062 5063 template <class ELFT> 5064 void GNUELFDumper<ELFT>::printGNUVersionSectionProlog( 5065 const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) { 5066 // Don't inline the SecName, because it might report a warning to stderr and 5067 // corrupt the output. 5068 StringRef SecName = this->getPrintableSectionName(Sec); 5069 OS << Label << " section '" << SecName << "' " 5070 << "contains " << EntriesNum << " entries:\n"; 5071 5072 StringRef LinkedSecName = "<corrupt>"; 5073 if (Expected<const typename ELFT::Shdr *> LinkedSecOrErr = 5074 this->Obj.getSection(Sec.sh_link)) 5075 LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr); 5076 else 5077 this->reportUniqueWarning("invalid section linked to " + 5078 this->describe(Sec) + ": " + 5079 toString(LinkedSecOrErr.takeError())); 5080 5081 OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16) 5082 << " Offset: " << format_hex(Sec.sh_offset, 8) 5083 << " Link: " << Sec.sh_link << " (" << LinkedSecName << ")\n"; 5084 } 5085 5086 template <class ELFT> 5087 void GNUELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) { 5088 if (!Sec) 5089 return; 5090 5091 printGNUVersionSectionProlog(*Sec, "Version symbols", 5092 Sec->sh_size / sizeof(Elf_Versym)); 5093 Expected<ArrayRef<Elf_Versym>> VerTableOrErr = 5094 this->getVersionTable(*Sec, /*SymTab=*/nullptr, 5095 /*StrTab=*/nullptr, /*SymTabSec=*/nullptr); 5096 if (!VerTableOrErr) { 5097 this->reportUniqueWarning(VerTableOrErr.takeError()); 5098 return; 5099 } 5100 5101 SmallVector<std::optional<VersionEntry>, 0> *VersionMap = nullptr; 5102 if (Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr = 5103 this->getVersionMap()) 5104 VersionMap = *MapOrErr; 5105 else 5106 this->reportUniqueWarning(MapOrErr.takeError()); 5107 5108 ArrayRef<Elf_Versym> VerTable = *VerTableOrErr; 5109 std::vector<StringRef> Versions; 5110 for (size_t I = 0, E = VerTable.size(); I < E; ++I) { 5111 unsigned Ndx = VerTable[I].vs_index; 5112 if (Ndx == VER_NDX_LOCAL || Ndx == VER_NDX_GLOBAL) { 5113 Versions.emplace_back(Ndx == VER_NDX_LOCAL ? "*local*" : "*global*"); 5114 continue; 5115 } 5116 5117 if (!VersionMap) { 5118 Versions.emplace_back("<corrupt>"); 5119 continue; 5120 } 5121 5122 bool IsDefault; 5123 Expected<StringRef> NameOrErr = this->Obj.getSymbolVersionByIndex( 5124 Ndx, IsDefault, *VersionMap, /*IsSymHidden=*/std::nullopt); 5125 if (!NameOrErr) { 5126 this->reportUniqueWarning("unable to get a version for entry " + 5127 Twine(I) + " of " + this->describe(*Sec) + 5128 ": " + toString(NameOrErr.takeError())); 5129 Versions.emplace_back("<corrupt>"); 5130 continue; 5131 } 5132 Versions.emplace_back(*NameOrErr); 5133 } 5134 5135 // readelf prints 4 entries per line. 5136 uint64_t Entries = VerTable.size(); 5137 for (uint64_t VersymRow = 0; VersymRow < Entries; VersymRow += 4) { 5138 OS << " " << format_hex_no_prefix(VersymRow, 3) << ":"; 5139 for (uint64_t I = 0; (I < 4) && (I + VersymRow) < Entries; ++I) { 5140 unsigned Ndx = VerTable[VersymRow + I].vs_index; 5141 OS << format("%4x%c", Ndx & VERSYM_VERSION, 5142 Ndx & VERSYM_HIDDEN ? 'h' : ' '); 5143 OS << left_justify("(" + std::string(Versions[VersymRow + I]) + ")", 13); 5144 } 5145 OS << '\n'; 5146 } 5147 OS << '\n'; 5148 } 5149 5150 static std::string versionFlagToString(unsigned Flags) { 5151 if (Flags == 0) 5152 return "none"; 5153 5154 std::string Ret; 5155 auto AddFlag = [&Ret, &Flags](unsigned Flag, StringRef Name) { 5156 if (!(Flags & Flag)) 5157 return; 5158 if (!Ret.empty()) 5159 Ret += " | "; 5160 Ret += Name; 5161 Flags &= ~Flag; 5162 }; 5163 5164 AddFlag(VER_FLG_BASE, "BASE"); 5165 AddFlag(VER_FLG_WEAK, "WEAK"); 5166 AddFlag(VER_FLG_INFO, "INFO"); 5167 AddFlag(~0, "<unknown>"); 5168 return Ret; 5169 } 5170 5171 template <class ELFT> 5172 void GNUELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) { 5173 if (!Sec) 5174 return; 5175 5176 printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info); 5177 5178 Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec); 5179 if (!V) { 5180 this->reportUniqueWarning(V.takeError()); 5181 return; 5182 } 5183 5184 for (const VerDef &Def : *V) { 5185 OS << format(" 0x%04x: Rev: %u Flags: %s Index: %u Cnt: %u Name: %s\n", 5186 Def.Offset, Def.Version, 5187 versionFlagToString(Def.Flags).c_str(), Def.Ndx, Def.Cnt, 5188 Def.Name.data()); 5189 unsigned I = 0; 5190 for (const VerdAux &Aux : Def.AuxV) 5191 OS << format(" 0x%04x: Parent %u: %s\n", Aux.Offset, ++I, 5192 Aux.Name.data()); 5193 } 5194 5195 OS << '\n'; 5196 } 5197 5198 template <class ELFT> 5199 void GNUELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) { 5200 if (!Sec) 5201 return; 5202 5203 unsigned VerneedNum = Sec->sh_info; 5204 printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum); 5205 5206 Expected<std::vector<VerNeed>> V = 5207 this->Obj.getVersionDependencies(*Sec, this->WarningHandler); 5208 if (!V) { 5209 this->reportUniqueWarning(V.takeError()); 5210 return; 5211 } 5212 5213 for (const VerNeed &VN : *V) { 5214 OS << format(" 0x%04x: Version: %u File: %s Cnt: %u\n", VN.Offset, 5215 VN.Version, VN.File.data(), VN.Cnt); 5216 for (const VernAux &Aux : VN.AuxV) 5217 OS << format(" 0x%04x: Name: %s Flags: %s Version: %u\n", Aux.Offset, 5218 Aux.Name.data(), versionFlagToString(Aux.Flags).c_str(), 5219 Aux.Other); 5220 } 5221 OS << '\n'; 5222 } 5223 5224 template <class ELFT> 5225 void GNUELFDumper<ELFT>::printHashHistogramStats(size_t NBucket, 5226 size_t MaxChain, 5227 size_t TotalSyms, 5228 ArrayRef<size_t> Count, 5229 bool IsGnu) const { 5230 size_t CumulativeNonZero = 0; 5231 OS << "Histogram for" << (IsGnu ? " `.gnu.hash'" : "") 5232 << " bucket list length (total of " << NBucket << " buckets)\n" 5233 << " Length Number % of total Coverage\n"; 5234 for (size_t I = 0; I < MaxChain; ++I) { 5235 CumulativeNonZero += Count[I] * I; 5236 OS << format("%7lu %-10lu (%5.1f%%) %5.1f%%\n", I, Count[I], 5237 (Count[I] * 100.0) / NBucket, 5238 (CumulativeNonZero * 100.0) / TotalSyms); 5239 } 5240 } 5241 5242 template <class ELFT> void GNUELFDumper<ELFT>::printCGProfile() { 5243 OS << "GNUStyle::printCGProfile not implemented\n"; 5244 } 5245 5246 template <class ELFT> 5247 void GNUELFDumper<ELFT>::printBBAddrMaps(bool /*PrettyPGOAnalysis*/) { 5248 OS << "GNUStyle::printBBAddrMaps not implemented\n"; 5249 } 5250 5251 static Expected<std::vector<uint64_t>> toULEB128Array(ArrayRef<uint8_t> Data) { 5252 std::vector<uint64_t> Ret; 5253 const uint8_t *Cur = Data.begin(); 5254 const uint8_t *End = Data.end(); 5255 while (Cur != End) { 5256 unsigned Size; 5257 const char *Err = nullptr; 5258 Ret.push_back(decodeULEB128(Cur, &Size, End, &Err)); 5259 if (Err) 5260 return createError(Err); 5261 Cur += Size; 5262 } 5263 return Ret; 5264 } 5265 5266 template <class ELFT> 5267 static Expected<std::vector<uint64_t>> 5268 decodeAddrsigSection(const ELFFile<ELFT> &Obj, const typename ELFT::Shdr &Sec) { 5269 Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Sec); 5270 if (!ContentsOrErr) 5271 return ContentsOrErr.takeError(); 5272 5273 if (Expected<std::vector<uint64_t>> SymsOrErr = 5274 toULEB128Array(*ContentsOrErr)) 5275 return *SymsOrErr; 5276 else 5277 return createError("unable to decode " + describe(Obj, Sec) + ": " + 5278 toString(SymsOrErr.takeError())); 5279 } 5280 5281 template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() { 5282 if (!this->DotAddrsigSec) 5283 return; 5284 5285 Expected<std::vector<uint64_t>> SymsOrErr = 5286 decodeAddrsigSection(this->Obj, *this->DotAddrsigSec); 5287 if (!SymsOrErr) { 5288 this->reportUniqueWarning(SymsOrErr.takeError()); 5289 return; 5290 } 5291 5292 StringRef Name = this->getPrintableSectionName(*this->DotAddrsigSec); 5293 OS << "\nAddress-significant symbols section '" << Name << "'" 5294 << " contains " << SymsOrErr->size() << " entries:\n"; 5295 OS << " Num: Name\n"; 5296 5297 Field Fields[2] = {0, 8}; 5298 size_t SymIndex = 0; 5299 for (uint64_t Sym : *SymsOrErr) { 5300 Fields[0].Str = to_string(format_decimal(++SymIndex, 6)) + ":"; 5301 Fields[1].Str = this->getStaticSymbolName(Sym); 5302 for (const Field &Entry : Fields) 5303 printField(Entry); 5304 OS << "\n"; 5305 } 5306 } 5307 5308 template <class ELFT> 5309 static bool printAArch64PAuthABICoreInfo(raw_ostream &OS, uint32_t DataSize, 5310 ArrayRef<uint8_t> Desc) { 5311 OS << " AArch64 PAuth ABI core info: "; 5312 // DataSize - size without padding, Desc.size() - size with padding 5313 if (DataSize != 16) { 5314 OS << format("<corrupted size: expected 16, got %d>", DataSize); 5315 return false; 5316 } 5317 5318 uint64_t Platform = 5319 support::endian::read64<ELFT::Endianness>(Desc.data() + 0); 5320 uint64_t Version = support::endian::read64<ELFT::Endianness>(Desc.data() + 8); 5321 5322 const char *PlatformDesc = [Platform]() { 5323 switch (Platform) { 5324 case AARCH64_PAUTH_PLATFORM_INVALID: 5325 return "invalid"; 5326 case AARCH64_PAUTH_PLATFORM_BAREMETAL: 5327 return "baremetal"; 5328 case AARCH64_PAUTH_PLATFORM_LLVM_LINUX: 5329 return "llvm_linux"; 5330 default: 5331 return "unknown"; 5332 } 5333 }(); 5334 5335 std::string VersionDesc = [Platform, Version]() -> std::string { 5336 if (Platform != AARCH64_PAUTH_PLATFORM_LLVM_LINUX) 5337 return ""; 5338 if (Version >= (1 << (AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1))) 5339 return "unknown"; 5340 5341 std::array<StringRef, AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST + 1> 5342 Flags; 5343 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INTRINSICS] = "Intrinsics"; 5344 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_CALLS] = "Calls"; 5345 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_RETURNS] = "Returns"; 5346 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_AUTHTRAPS] = "AuthTraps"; 5347 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRADDRDISCR] = 5348 "VTPtrAddressDiscrimination"; 5349 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_VPTRTYPEDISCR] = 5350 "VTPtrTypeDiscrimination"; 5351 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINI] = "InitFini"; 5352 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_INITFINIADDRDISC] = 5353 "InitFiniAddressDiscrimination"; 5354 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT] = "ELFGOT"; 5355 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOTOS] = "IndirectGotos"; 5356 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_TYPEINFOVPTRDISCR] = 5357 "TypeInfoVTPtrDiscrimination"; 5358 Flags[AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_FPTRTYPEDISCR] = 5359 "FPtrTypeDiscrimination"; 5360 5361 static_assert(AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_FPTRTYPEDISCR == 5362 AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_LAST, 5363 "Update when new enum items are defined"); 5364 5365 std::string Desc; 5366 for (uint32_t I = 0, End = Flags.size(); I < End; ++I) { 5367 if (!(Version & (1ULL << I))) 5368 Desc += '!'; 5369 Desc += 5370 Twine("PointerAuth" + Flags[I] + (I == End - 1 ? "" : ", ")).str(); 5371 } 5372 return Desc; 5373 }(); 5374 5375 OS << format("platform 0x%" PRIx64 " (%s), version 0x%" PRIx64, Platform, 5376 PlatformDesc, Version); 5377 if (!VersionDesc.empty()) 5378 OS << format(" (%s)", VersionDesc.c_str()); 5379 5380 return true; 5381 } 5382 5383 template <typename ELFT> 5384 static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, 5385 ArrayRef<uint8_t> Data, 5386 typename ELFT::Half EMachine) { 5387 std::string str; 5388 raw_string_ostream OS(str); 5389 uint32_t PrData; 5390 auto DumpBit = [&](uint32_t Flag, StringRef Name) { 5391 if (PrData & Flag) { 5392 PrData &= ~Flag; 5393 OS << Name; 5394 if (PrData) 5395 OS << ", "; 5396 } 5397 }; 5398 5399 switch (Type) { 5400 default: 5401 OS << format("<application-specific type 0x%x>", Type); 5402 return str; 5403 case GNU_PROPERTY_STACK_SIZE: { 5404 OS << "stack size: "; 5405 if (DataSize == sizeof(typename ELFT::uint)) 5406 OS << formatv("{0:x}", 5407 (uint64_t)(*(const typename ELFT::Addr *)Data.data())); 5408 else 5409 OS << format("<corrupt length: 0x%x>", DataSize); 5410 return str; 5411 } 5412 case GNU_PROPERTY_NO_COPY_ON_PROTECTED: 5413 OS << "no copy on protected"; 5414 if (DataSize) 5415 OS << format(" <corrupt length: 0x%x>", DataSize); 5416 return str; 5417 case GNU_PROPERTY_AARCH64_FEATURE_1_AND: 5418 case GNU_PROPERTY_X86_FEATURE_1_AND: 5419 static_assert(GNU_PROPERTY_AARCH64_FEATURE_1_AND == 5420 GNU_PROPERTY_RISCV_FEATURE_1_AND, 5421 "GNU_PROPERTY_RISCV_FEATURE_1_AND should equal " 5422 "GNU_PROPERTY_AARCH64_FEATURE_1_AND, otherwise " 5423 "GNU_PROPERTY_RISCV_FEATURE_1_AND would be skipped!"); 5424 5425 if (EMachine == EM_AARCH64 && Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { 5426 OS << "aarch64 feature: "; 5427 } else if (EMachine == EM_RISCV && 5428 Type == GNU_PROPERTY_RISCV_FEATURE_1_AND) { 5429 OS << "RISC-V feature: "; 5430 } else if ((EMachine == EM_386 || EMachine == EM_X86_64) && 5431 Type == GNU_PROPERTY_X86_FEATURE_1_AND) { 5432 OS << "x86 feature: "; 5433 } else { 5434 OS << format("<application-specific type 0x%x>", Type); 5435 return str; 5436 } 5437 5438 if (DataSize != 4) { 5439 OS << format("<corrupt length: 0x%x>", DataSize); 5440 return str; 5441 } 5442 PrData = endian::read32<ELFT::Endianness>(Data.data()); 5443 if (PrData == 0) { 5444 OS << "<None>"; 5445 return str; 5446 } 5447 5448 if (EMachine == EM_AARCH64) { 5449 DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI"); 5450 DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC"); 5451 DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS"); 5452 } else if (EMachine == EM_RISCV) { 5453 DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED, 5454 "ZICFILP-unlabeled"); 5455 DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS, "ZICFISS"); 5456 DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG, "ZICFILP-func-sig"); 5457 } else { 5458 DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT"); 5459 DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK"); 5460 } 5461 if (PrData) 5462 OS << format("<unknown flags: 0x%x>", PrData); 5463 return str; 5464 case GNU_PROPERTY_AARCH64_FEATURE_PAUTH: 5465 printAArch64PAuthABICoreInfo<ELFT>(OS, DataSize, Data); 5466 return str; 5467 case GNU_PROPERTY_X86_FEATURE_2_NEEDED: 5468 case GNU_PROPERTY_X86_FEATURE_2_USED: 5469 OS << "x86 feature " 5470 << (Type == GNU_PROPERTY_X86_FEATURE_2_NEEDED ? "needed: " : "used: "); 5471 if (DataSize != 4) { 5472 OS << format("<corrupt length: 0x%x>", DataSize); 5473 return str; 5474 } 5475 PrData = endian::read32<ELFT::Endianness>(Data.data()); 5476 if (PrData == 0) { 5477 OS << "<None>"; 5478 return str; 5479 } 5480 DumpBit(GNU_PROPERTY_X86_FEATURE_2_X86, "x86"); 5481 DumpBit(GNU_PROPERTY_X86_FEATURE_2_X87, "x87"); 5482 DumpBit(GNU_PROPERTY_X86_FEATURE_2_MMX, "MMX"); 5483 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XMM, "XMM"); 5484 DumpBit(GNU_PROPERTY_X86_FEATURE_2_YMM, "YMM"); 5485 DumpBit(GNU_PROPERTY_X86_FEATURE_2_ZMM, "ZMM"); 5486 DumpBit(GNU_PROPERTY_X86_FEATURE_2_FXSR, "FXSR"); 5487 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVE, "XSAVE"); 5488 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT, "XSAVEOPT"); 5489 DumpBit(GNU_PROPERTY_X86_FEATURE_2_XSAVEC, "XSAVEC"); 5490 if (PrData) 5491 OS << format("<unknown flags: 0x%x>", PrData); 5492 return str; 5493 case GNU_PROPERTY_X86_ISA_1_NEEDED: 5494 case GNU_PROPERTY_X86_ISA_1_USED: 5495 OS << "x86 ISA " 5496 << (Type == GNU_PROPERTY_X86_ISA_1_NEEDED ? "needed: " : "used: "); 5497 if (DataSize != 4) { 5498 OS << format("<corrupt length: 0x%x>", DataSize); 5499 return str; 5500 } 5501 PrData = endian::read32<ELFT::Endianness>(Data.data()); 5502 if (PrData == 0) { 5503 OS << "<None>"; 5504 return str; 5505 } 5506 DumpBit(GNU_PROPERTY_X86_ISA_1_BASELINE, "x86-64-baseline"); 5507 DumpBit(GNU_PROPERTY_X86_ISA_1_V2, "x86-64-v2"); 5508 DumpBit(GNU_PROPERTY_X86_ISA_1_V3, "x86-64-v3"); 5509 DumpBit(GNU_PROPERTY_X86_ISA_1_V4, "x86-64-v4"); 5510 if (PrData) 5511 OS << format("<unknown flags: 0x%x>", PrData); 5512 return str; 5513 } 5514 } 5515 5516 template <typename ELFT> 5517 static SmallVector<std::string, 4> 5518 getGNUPropertyList(ArrayRef<uint8_t> Arr, typename ELFT::Half EMachine) { 5519 using Elf_Word = typename ELFT::Word; 5520 5521 SmallVector<std::string, 4> Properties; 5522 while (Arr.size() >= 8) { 5523 uint32_t Type = *reinterpret_cast<const Elf_Word *>(Arr.data()); 5524 uint32_t DataSize = *reinterpret_cast<const Elf_Word *>(Arr.data() + 4); 5525 Arr = Arr.drop_front(8); 5526 5527 // Take padding size into account if present. 5528 uint64_t PaddedSize = alignTo(DataSize, sizeof(typename ELFT::uint)); 5529 std::string str; 5530 raw_string_ostream OS(str); 5531 if (Arr.size() < PaddedSize) { 5532 OS << format("<corrupt type (0x%x) datasz: 0x%x>", Type, DataSize); 5533 Properties.push_back(str); 5534 break; 5535 } 5536 Properties.push_back(getGNUProperty<ELFT>( 5537 Type, DataSize, Arr.take_front(PaddedSize), EMachine)); 5538 Arr = Arr.drop_front(PaddedSize); 5539 } 5540 5541 if (!Arr.empty()) 5542 Properties.push_back("<corrupted GNU_PROPERTY_TYPE_0>"); 5543 5544 return Properties; 5545 } 5546 5547 struct GNUAbiTag { 5548 std::string OSName; 5549 std::string ABI; 5550 bool IsValid; 5551 }; 5552 5553 template <typename ELFT> static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) { 5554 typedef typename ELFT::Word Elf_Word; 5555 5556 ArrayRef<Elf_Word> Words(reinterpret_cast<const Elf_Word *>(Desc.begin()), 5557 reinterpret_cast<const Elf_Word *>(Desc.end())); 5558 5559 if (Words.size() < 4) 5560 return {"", "", /*IsValid=*/false}; 5561 5562 static const char *OSNames[] = { 5563 "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl", 5564 }; 5565 StringRef OSName = "Unknown"; 5566 if (Words[0] < std::size(OSNames)) 5567 OSName = OSNames[Words[0]]; 5568 uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3]; 5569 std::string str; 5570 raw_string_ostream ABI(str); 5571 ABI << Major << "." << Minor << "." << Patch; 5572 return {std::string(OSName), str, /*IsValid=*/true}; 5573 } 5574 5575 static std::string getGNUBuildId(ArrayRef<uint8_t> Desc) { 5576 std::string str; 5577 raw_string_ostream OS(str); 5578 for (uint8_t B : Desc) 5579 OS << format_hex_no_prefix(B, 2); 5580 return str; 5581 } 5582 5583 static StringRef getDescAsStringRef(ArrayRef<uint8_t> Desc) { 5584 return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size()); 5585 } 5586 5587 template <typename ELFT> 5588 static bool printGNUNote(raw_ostream &OS, uint32_t NoteType, 5589 ArrayRef<uint8_t> Desc, typename ELFT::Half EMachine) { 5590 // Return true if we were able to pretty-print the note, false otherwise. 5591 switch (NoteType) { 5592 default: 5593 return false; 5594 case ELF::NT_GNU_ABI_TAG: { 5595 const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc); 5596 if (!AbiTag.IsValid) 5597 OS << " <corrupt GNU_ABI_TAG>"; 5598 else 5599 OS << " OS: " << AbiTag.OSName << ", ABI: " << AbiTag.ABI; 5600 break; 5601 } 5602 case ELF::NT_GNU_BUILD_ID: { 5603 OS << " Build ID: " << getGNUBuildId(Desc); 5604 break; 5605 } 5606 case ELF::NT_GNU_GOLD_VERSION: 5607 OS << " Version: " << getDescAsStringRef(Desc); 5608 break; 5609 case ELF::NT_GNU_PROPERTY_TYPE_0: 5610 OS << " Properties:"; 5611 for (const std::string &Property : getGNUPropertyList<ELFT>(Desc, EMachine)) 5612 OS << " " << Property << "\n"; 5613 break; 5614 } 5615 OS << '\n'; 5616 return true; 5617 } 5618 5619 using AndroidNoteProperties = std::vector<std::pair<StringRef, std::string>>; 5620 static AndroidNoteProperties getAndroidNoteProperties(uint32_t NoteType, 5621 ArrayRef<uint8_t> Desc) { 5622 AndroidNoteProperties Props; 5623 switch (NoteType) { 5624 case ELF::NT_ANDROID_TYPE_MEMTAG: 5625 if (Desc.empty()) { 5626 Props.emplace_back("Invalid .note.android.memtag", ""); 5627 return Props; 5628 } 5629 5630 switch (Desc[0] & NT_MEMTAG_LEVEL_MASK) { 5631 case NT_MEMTAG_LEVEL_NONE: 5632 Props.emplace_back("Tagging Mode", "NONE"); 5633 break; 5634 case NT_MEMTAG_LEVEL_ASYNC: 5635 Props.emplace_back("Tagging Mode", "ASYNC"); 5636 break; 5637 case NT_MEMTAG_LEVEL_SYNC: 5638 Props.emplace_back("Tagging Mode", "SYNC"); 5639 break; 5640 default: 5641 Props.emplace_back( 5642 "Tagging Mode", 5643 ("Unknown (" + Twine::utohexstr(Desc[0] & NT_MEMTAG_LEVEL_MASK) + ")") 5644 .str()); 5645 break; 5646 } 5647 Props.emplace_back("Heap", 5648 (Desc[0] & NT_MEMTAG_HEAP) ? "Enabled" : "Disabled"); 5649 Props.emplace_back("Stack", 5650 (Desc[0] & NT_MEMTAG_STACK) ? "Enabled" : "Disabled"); 5651 break; 5652 default: 5653 return Props; 5654 } 5655 return Props; 5656 } 5657 5658 static bool printAndroidNote(raw_ostream &OS, uint32_t NoteType, 5659 ArrayRef<uint8_t> Desc) { 5660 // Return true if we were able to pretty-print the note, false otherwise. 5661 AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc); 5662 if (Props.empty()) 5663 return false; 5664 for (const auto &KV : Props) 5665 OS << " " << KV.first << ": " << KV.second << '\n'; 5666 return true; 5667 } 5668 5669 template <class ELFT> 5670 void GNUELFDumper<ELFT>::printMemtag( 5671 const ArrayRef<std::pair<std::string, std::string>> DynamicEntries, 5672 const ArrayRef<uint8_t> AndroidNoteDesc, 5673 const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) { 5674 OS << "Memtag Dynamic Entries:\n"; 5675 if (DynamicEntries.empty()) 5676 OS << " < none found >\n"; 5677 for (const auto &DynamicEntryKV : DynamicEntries) 5678 OS << " " << DynamicEntryKV.first << ": " << DynamicEntryKV.second 5679 << "\n"; 5680 5681 if (!AndroidNoteDesc.empty()) { 5682 OS << "Memtag Android Note:\n"; 5683 printAndroidNote(OS, ELF::NT_ANDROID_TYPE_MEMTAG, AndroidNoteDesc); 5684 } 5685 5686 if (Descriptors.empty()) 5687 return; 5688 5689 OS << "Memtag Global Descriptors:\n"; 5690 for (const auto &[Addr, BytesToTag] : Descriptors) { 5691 OS << " 0x" << utohexstr(Addr, /*LowerCase=*/true) << ": 0x" 5692 << utohexstr(BytesToTag, /*LowerCase=*/true) << "\n"; 5693 } 5694 } 5695 5696 template <typename ELFT> 5697 static bool printLLVMOMPOFFLOADNote(raw_ostream &OS, uint32_t NoteType, 5698 ArrayRef<uint8_t> Desc) { 5699 switch (NoteType) { 5700 default: 5701 return false; 5702 case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION: 5703 OS << " Version: " << getDescAsStringRef(Desc); 5704 break; 5705 case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER: 5706 OS << " Producer: " << getDescAsStringRef(Desc); 5707 break; 5708 case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION: 5709 OS << " Producer version: " << getDescAsStringRef(Desc); 5710 break; 5711 } 5712 OS << '\n'; 5713 return true; 5714 } 5715 5716 const EnumEntry<unsigned> FreeBSDFeatureCtlFlags[] = { 5717 {"ASLR_DISABLE", NT_FREEBSD_FCTL_ASLR_DISABLE}, 5718 {"PROTMAX_DISABLE", NT_FREEBSD_FCTL_PROTMAX_DISABLE}, 5719 {"STKGAP_DISABLE", NT_FREEBSD_FCTL_STKGAP_DISABLE}, 5720 {"WXNEEDED", NT_FREEBSD_FCTL_WXNEEDED}, 5721 {"LA48", NT_FREEBSD_FCTL_LA48}, 5722 {"ASG_DISABLE", NT_FREEBSD_FCTL_ASG_DISABLE}, 5723 }; 5724 5725 struct FreeBSDNote { 5726 std::string Type; 5727 std::string Value; 5728 }; 5729 5730 template <typename ELFT> 5731 static std::optional<FreeBSDNote> 5732 getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) { 5733 if (IsCore) 5734 return std::nullopt; // No pretty-printing yet. 5735 switch (NoteType) { 5736 case ELF::NT_FREEBSD_ABI_TAG: 5737 if (Desc.size() != 4) 5738 return std::nullopt; 5739 return FreeBSDNote{"ABI tag", 5740 utostr(endian::read32<ELFT::Endianness>(Desc.data()))}; 5741 case ELF::NT_FREEBSD_ARCH_TAG: 5742 return FreeBSDNote{"Arch tag", toStringRef(Desc).str()}; 5743 case ELF::NT_FREEBSD_FEATURE_CTL: { 5744 if (Desc.size() != 4) 5745 return std::nullopt; 5746 unsigned Value = endian::read32<ELFT::Endianness>(Desc.data()); 5747 std::string FlagsStr; 5748 raw_string_ostream OS(FlagsStr); 5749 printFlags(Value, ArrayRef(FreeBSDFeatureCtlFlags), OS); 5750 if (FlagsStr.empty()) 5751 OS << "0x" << utohexstr(Value); 5752 else 5753 OS << "(0x" << utohexstr(Value) << ")"; 5754 return FreeBSDNote{"Feature flags", FlagsStr}; 5755 } 5756 default: 5757 return std::nullopt; 5758 } 5759 } 5760 5761 struct AMDNote { 5762 std::string Type; 5763 std::string Value; 5764 }; 5765 5766 template <typename ELFT> 5767 static AMDNote getAMDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) { 5768 switch (NoteType) { 5769 default: 5770 return {"", ""}; 5771 case ELF::NT_AMD_HSA_CODE_OBJECT_VERSION: { 5772 struct CodeObjectVersion { 5773 support::aligned_ulittle32_t MajorVersion; 5774 support::aligned_ulittle32_t MinorVersion; 5775 }; 5776 if (Desc.size() != sizeof(CodeObjectVersion)) 5777 return {"AMD HSA Code Object Version", 5778 "Invalid AMD HSA Code Object Version"}; 5779 std::string VersionString; 5780 raw_string_ostream StrOS(VersionString); 5781 auto Version = reinterpret_cast<const CodeObjectVersion *>(Desc.data()); 5782 StrOS << "[Major: " << Version->MajorVersion 5783 << ", Minor: " << Version->MinorVersion << "]"; 5784 return {"AMD HSA Code Object Version", VersionString}; 5785 } 5786 case ELF::NT_AMD_HSA_HSAIL: { 5787 struct HSAILProperties { 5788 support::aligned_ulittle32_t HSAILMajorVersion; 5789 support::aligned_ulittle32_t HSAILMinorVersion; 5790 uint8_t Profile; 5791 uint8_t MachineModel; 5792 uint8_t DefaultFloatRound; 5793 }; 5794 if (Desc.size() != sizeof(HSAILProperties)) 5795 return {"AMD HSA HSAIL Properties", "Invalid AMD HSA HSAIL Properties"}; 5796 auto Properties = reinterpret_cast<const HSAILProperties *>(Desc.data()); 5797 std::string HSAILPropetiesString; 5798 raw_string_ostream StrOS(HSAILPropetiesString); 5799 StrOS << "[HSAIL Major: " << Properties->HSAILMajorVersion 5800 << ", HSAIL Minor: " << Properties->HSAILMinorVersion 5801 << ", Profile: " << uint32_t(Properties->Profile) 5802 << ", Machine Model: " << uint32_t(Properties->MachineModel) 5803 << ", Default Float Round: " 5804 << uint32_t(Properties->DefaultFloatRound) << "]"; 5805 return {"AMD HSA HSAIL Properties", HSAILPropetiesString}; 5806 } 5807 case ELF::NT_AMD_HSA_ISA_VERSION: { 5808 struct IsaVersion { 5809 support::aligned_ulittle16_t VendorNameSize; 5810 support::aligned_ulittle16_t ArchitectureNameSize; 5811 support::aligned_ulittle32_t Major; 5812 support::aligned_ulittle32_t Minor; 5813 support::aligned_ulittle32_t Stepping; 5814 }; 5815 if (Desc.size() < sizeof(IsaVersion)) 5816 return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"}; 5817 auto Isa = reinterpret_cast<const IsaVersion *>(Desc.data()); 5818 if (Desc.size() < sizeof(IsaVersion) + 5819 Isa->VendorNameSize + Isa->ArchitectureNameSize || 5820 Isa->VendorNameSize == 0 || Isa->ArchitectureNameSize == 0) 5821 return {"AMD HSA ISA Version", "Invalid AMD HSA ISA Version"}; 5822 std::string IsaString; 5823 raw_string_ostream StrOS(IsaString); 5824 StrOS << "[Vendor: " 5825 << StringRef((const char*)Desc.data() + sizeof(IsaVersion), Isa->VendorNameSize - 1) 5826 << ", Architecture: " 5827 << StringRef((const char*)Desc.data() + sizeof(IsaVersion) + Isa->VendorNameSize, 5828 Isa->ArchitectureNameSize - 1) 5829 << ", Major: " << Isa->Major << ", Minor: " << Isa->Minor 5830 << ", Stepping: " << Isa->Stepping << "]"; 5831 return {"AMD HSA ISA Version", IsaString}; 5832 } 5833 case ELF::NT_AMD_HSA_METADATA: { 5834 if (Desc.size() == 0) 5835 return {"AMD HSA Metadata", ""}; 5836 return { 5837 "AMD HSA Metadata", 5838 std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size() - 1)}; 5839 } 5840 case ELF::NT_AMD_HSA_ISA_NAME: { 5841 if (Desc.size() == 0) 5842 return {"AMD HSA ISA Name", ""}; 5843 return { 5844 "AMD HSA ISA Name", 5845 std::string(reinterpret_cast<const char *>(Desc.data()), Desc.size())}; 5846 } 5847 case ELF::NT_AMD_PAL_METADATA: { 5848 struct PALMetadata { 5849 support::aligned_ulittle32_t Key; 5850 support::aligned_ulittle32_t Value; 5851 }; 5852 if (Desc.size() % sizeof(PALMetadata) != 0) 5853 return {"AMD PAL Metadata", "Invalid AMD PAL Metadata"}; 5854 auto Isa = reinterpret_cast<const PALMetadata *>(Desc.data()); 5855 std::string MetadataString; 5856 raw_string_ostream StrOS(MetadataString); 5857 for (size_t I = 0, E = Desc.size() / sizeof(PALMetadata); I < E; ++I) { 5858 StrOS << "[" << Isa[I].Key << ": " << Isa[I].Value << "]"; 5859 } 5860 return {"AMD PAL Metadata", MetadataString}; 5861 } 5862 } 5863 } 5864 5865 struct AMDGPUNote { 5866 std::string Type; 5867 std::string Value; 5868 }; 5869 5870 template <typename ELFT> 5871 static AMDGPUNote getAMDGPUNote(uint32_t NoteType, ArrayRef<uint8_t> Desc) { 5872 switch (NoteType) { 5873 default: 5874 return {"", ""}; 5875 case ELF::NT_AMDGPU_METADATA: { 5876 StringRef MsgPackString = 5877 StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size()); 5878 msgpack::Document MsgPackDoc; 5879 if (!MsgPackDoc.readFromBlob(MsgPackString, /*Multi=*/false)) 5880 return {"", ""}; 5881 5882 std::string MetadataString; 5883 5884 // FIXME: Metadata Verifier only works with AMDHSA. 5885 // This is an ugly workaround to avoid the verifier for other MD 5886 // formats (e.g. amdpal) 5887 if (MsgPackString.contains("amdhsa.")) { 5888 AMDGPU::HSAMD::V3::MetadataVerifier Verifier(true); 5889 if (!Verifier.verify(MsgPackDoc.getRoot())) 5890 MetadataString = "Invalid AMDGPU Metadata\n"; 5891 } 5892 5893 raw_string_ostream StrOS(MetadataString); 5894 if (MsgPackDoc.getRoot().isScalar()) { 5895 // TODO: passing a scalar root to toYAML() asserts: 5896 // (PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && 5897 // "plain scalar documents are not supported") 5898 // To avoid this crash we print the raw data instead. 5899 return {"", ""}; 5900 } 5901 MsgPackDoc.toYAML(StrOS); 5902 return {"AMDGPU Metadata", MetadataString}; 5903 } 5904 } 5905 } 5906 5907 struct CoreFileMapping { 5908 uint64_t Start, End, Offset; 5909 StringRef Filename; 5910 }; 5911 5912 struct CoreNote { 5913 uint64_t PageSize; 5914 std::vector<CoreFileMapping> Mappings; 5915 }; 5916 5917 static Expected<CoreNote> readCoreNote(DataExtractor Desc) { 5918 // Expected format of the NT_FILE note description: 5919 // 1. # of file mappings (call it N) 5920 // 2. Page size 5921 // 3. N (start, end, offset) triples 5922 // 4. N packed filenames (null delimited) 5923 // Each field is an Elf_Addr, except for filenames which are char* strings. 5924 5925 CoreNote Ret; 5926 const int Bytes = Desc.getAddressSize(); 5927 5928 if (!Desc.isValidOffsetForAddress(2)) 5929 return createError("the note of size 0x" + Twine::utohexstr(Desc.size()) + 5930 " is too short, expected at least 0x" + 5931 Twine::utohexstr(Bytes * 2)); 5932 if (Desc.getData().back() != 0) 5933 return createError("the note is not NUL terminated"); 5934 5935 uint64_t DescOffset = 0; 5936 uint64_t FileCount = Desc.getAddress(&DescOffset); 5937 Ret.PageSize = Desc.getAddress(&DescOffset); 5938 5939 if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes)) 5940 return createError("unable to read file mappings (found " + 5941 Twine(FileCount) + "): the note of size 0x" + 5942 Twine::utohexstr(Desc.size()) + " is too short"); 5943 5944 uint64_t FilenamesOffset = 0; 5945 DataExtractor Filenames( 5946 Desc.getData().drop_front(DescOffset + 3 * FileCount * Bytes), 5947 Desc.isLittleEndian(), Desc.getAddressSize()); 5948 5949 Ret.Mappings.resize(FileCount); 5950 size_t I = 0; 5951 for (CoreFileMapping &Mapping : Ret.Mappings) { 5952 ++I; 5953 if (!Filenames.isValidOffsetForDataOfSize(FilenamesOffset, 1)) 5954 return createError( 5955 "unable to read the file name for the mapping with index " + 5956 Twine(I) + ": the note of size 0x" + Twine::utohexstr(Desc.size()) + 5957 " is truncated"); 5958 Mapping.Start = Desc.getAddress(&DescOffset); 5959 Mapping.End = Desc.getAddress(&DescOffset); 5960 Mapping.Offset = Desc.getAddress(&DescOffset); 5961 Mapping.Filename = Filenames.getCStrRef(&FilenamesOffset); 5962 } 5963 5964 return Ret; 5965 } 5966 5967 template <typename ELFT> 5968 static void printCoreNote(raw_ostream &OS, const CoreNote &Note) { 5969 // Length of "0x<address>" string. 5970 const int FieldWidth = ELFT::Is64Bits ? 18 : 10; 5971 5972 OS << " Page size: " << format_decimal(Note.PageSize, 0) << '\n'; 5973 OS << " " << right_justify("Start", FieldWidth) << " " 5974 << right_justify("End", FieldWidth) << " " 5975 << right_justify("Page Offset", FieldWidth) << '\n'; 5976 for (const CoreFileMapping &Mapping : Note.Mappings) { 5977 OS << " " << format_hex(Mapping.Start, FieldWidth) << " " 5978 << format_hex(Mapping.End, FieldWidth) << " " 5979 << format_hex(Mapping.Offset, FieldWidth) << "\n " 5980 << Mapping.Filename << '\n'; 5981 } 5982 } 5983 5984 const NoteType GenericNoteTypes[] = { 5985 {ELF::NT_VERSION, "NT_VERSION (version)"}, 5986 {ELF::NT_ARCH, "NT_ARCH (architecture)"}, 5987 {ELF::NT_GNU_BUILD_ATTRIBUTE_OPEN, "OPEN"}, 5988 {ELF::NT_GNU_BUILD_ATTRIBUTE_FUNC, "func"}, 5989 }; 5990 5991 const NoteType GNUNoteTypes[] = { 5992 {ELF::NT_GNU_ABI_TAG, "NT_GNU_ABI_TAG (ABI version tag)"}, 5993 {ELF::NT_GNU_HWCAP, "NT_GNU_HWCAP (DSO-supplied software HWCAP info)"}, 5994 {ELF::NT_GNU_BUILD_ID, "NT_GNU_BUILD_ID (unique build ID bitstring)"}, 5995 {ELF::NT_GNU_GOLD_VERSION, "NT_GNU_GOLD_VERSION (gold version)"}, 5996 {ELF::NT_GNU_PROPERTY_TYPE_0, "NT_GNU_PROPERTY_TYPE_0 (property note)"}, 5997 }; 5998 5999 const NoteType FreeBSDCoreNoteTypes[] = { 6000 {ELF::NT_FREEBSD_THRMISC, "NT_THRMISC (thrmisc structure)"}, 6001 {ELF::NT_FREEBSD_PROCSTAT_PROC, "NT_PROCSTAT_PROC (proc data)"}, 6002 {ELF::NT_FREEBSD_PROCSTAT_FILES, "NT_PROCSTAT_FILES (files data)"}, 6003 {ELF::NT_FREEBSD_PROCSTAT_VMMAP, "NT_PROCSTAT_VMMAP (vmmap data)"}, 6004 {ELF::NT_FREEBSD_PROCSTAT_GROUPS, "NT_PROCSTAT_GROUPS (groups data)"}, 6005 {ELF::NT_FREEBSD_PROCSTAT_UMASK, "NT_PROCSTAT_UMASK (umask data)"}, 6006 {ELF::NT_FREEBSD_PROCSTAT_RLIMIT, "NT_PROCSTAT_RLIMIT (rlimit data)"}, 6007 {ELF::NT_FREEBSD_PROCSTAT_OSREL, "NT_PROCSTAT_OSREL (osreldate data)"}, 6008 {ELF::NT_FREEBSD_PROCSTAT_PSSTRINGS, 6009 "NT_PROCSTAT_PSSTRINGS (ps_strings data)"}, 6010 {ELF::NT_FREEBSD_PROCSTAT_AUXV, "NT_PROCSTAT_AUXV (auxv data)"}, 6011 }; 6012 6013 const NoteType FreeBSDNoteTypes[] = { 6014 {ELF::NT_FREEBSD_ABI_TAG, "NT_FREEBSD_ABI_TAG (ABI version tag)"}, 6015 {ELF::NT_FREEBSD_NOINIT_TAG, "NT_FREEBSD_NOINIT_TAG (no .init tag)"}, 6016 {ELF::NT_FREEBSD_ARCH_TAG, "NT_FREEBSD_ARCH_TAG (architecture tag)"}, 6017 {ELF::NT_FREEBSD_FEATURE_CTL, 6018 "NT_FREEBSD_FEATURE_CTL (FreeBSD feature control)"}, 6019 }; 6020 6021 const NoteType NetBSDCoreNoteTypes[] = { 6022 {ELF::NT_NETBSDCORE_PROCINFO, 6023 "NT_NETBSDCORE_PROCINFO (procinfo structure)"}, 6024 {ELF::NT_NETBSDCORE_AUXV, "NT_NETBSDCORE_AUXV (ELF auxiliary vector data)"}, 6025 {ELF::NT_NETBSDCORE_LWPSTATUS, "PT_LWPSTATUS (ptrace_lwpstatus structure)"}, 6026 }; 6027 6028 const NoteType OpenBSDCoreNoteTypes[] = { 6029 {ELF::NT_OPENBSD_PROCINFO, "NT_OPENBSD_PROCINFO (procinfo structure)"}, 6030 {ELF::NT_OPENBSD_AUXV, "NT_OPENBSD_AUXV (ELF auxiliary vector data)"}, 6031 {ELF::NT_OPENBSD_REGS, "NT_OPENBSD_REGS (regular registers)"}, 6032 {ELF::NT_OPENBSD_FPREGS, "NT_OPENBSD_FPREGS (floating point registers)"}, 6033 {ELF::NT_OPENBSD_WCOOKIE, "NT_OPENBSD_WCOOKIE (window cookie)"}, 6034 }; 6035 6036 const NoteType AMDNoteTypes[] = { 6037 {ELF::NT_AMD_HSA_CODE_OBJECT_VERSION, 6038 "NT_AMD_HSA_CODE_OBJECT_VERSION (AMD HSA Code Object Version)"}, 6039 {ELF::NT_AMD_HSA_HSAIL, "NT_AMD_HSA_HSAIL (AMD HSA HSAIL Properties)"}, 6040 {ELF::NT_AMD_HSA_ISA_VERSION, "NT_AMD_HSA_ISA_VERSION (AMD HSA ISA Version)"}, 6041 {ELF::NT_AMD_HSA_METADATA, "NT_AMD_HSA_METADATA (AMD HSA Metadata)"}, 6042 {ELF::NT_AMD_HSA_ISA_NAME, "NT_AMD_HSA_ISA_NAME (AMD HSA ISA Name)"}, 6043 {ELF::NT_AMD_PAL_METADATA, "NT_AMD_PAL_METADATA (AMD PAL Metadata)"}, 6044 }; 6045 6046 const NoteType AMDGPUNoteTypes[] = { 6047 {ELF::NT_AMDGPU_METADATA, "NT_AMDGPU_METADATA (AMDGPU Metadata)"}, 6048 }; 6049 6050 const NoteType LLVMOMPOFFLOADNoteTypes[] = { 6051 {ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION, 6052 "NT_LLVM_OPENMP_OFFLOAD_VERSION (image format version)"}, 6053 {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER, 6054 "NT_LLVM_OPENMP_OFFLOAD_PRODUCER (producing toolchain)"}, 6055 {ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION, 6056 "NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION (producing toolchain version)"}, 6057 }; 6058 6059 const NoteType AndroidNoteTypes[] = { 6060 {ELF::NT_ANDROID_TYPE_IDENT, "NT_ANDROID_TYPE_IDENT"}, 6061 {ELF::NT_ANDROID_TYPE_KUSER, "NT_ANDROID_TYPE_KUSER"}, 6062 {ELF::NT_ANDROID_TYPE_MEMTAG, 6063 "NT_ANDROID_TYPE_MEMTAG (Android memory tagging information)"}, 6064 }; 6065 6066 const NoteType CoreNoteTypes[] = { 6067 {ELF::NT_PRSTATUS, "NT_PRSTATUS (prstatus structure)"}, 6068 {ELF::NT_FPREGSET, "NT_FPREGSET (floating point registers)"}, 6069 {ELF::NT_PRPSINFO, "NT_PRPSINFO (prpsinfo structure)"}, 6070 {ELF::NT_TASKSTRUCT, "NT_TASKSTRUCT (task structure)"}, 6071 {ELF::NT_AUXV, "NT_AUXV (auxiliary vector)"}, 6072 {ELF::NT_PSTATUS, "NT_PSTATUS (pstatus structure)"}, 6073 {ELF::NT_FPREGS, "NT_FPREGS (floating point registers)"}, 6074 {ELF::NT_PSINFO, "NT_PSINFO (psinfo structure)"}, 6075 {ELF::NT_LWPSTATUS, "NT_LWPSTATUS (lwpstatus_t structure)"}, 6076 {ELF::NT_LWPSINFO, "NT_LWPSINFO (lwpsinfo_t structure)"}, 6077 {ELF::NT_WIN32PSTATUS, "NT_WIN32PSTATUS (win32_pstatus structure)"}, 6078 6079 {ELF::NT_PPC_VMX, "NT_PPC_VMX (ppc Altivec registers)"}, 6080 {ELF::NT_PPC_VSX, "NT_PPC_VSX (ppc VSX registers)"}, 6081 {ELF::NT_PPC_TAR, "NT_PPC_TAR (ppc TAR register)"}, 6082 {ELF::NT_PPC_PPR, "NT_PPC_PPR (ppc PPR register)"}, 6083 {ELF::NT_PPC_DSCR, "NT_PPC_DSCR (ppc DSCR register)"}, 6084 {ELF::NT_PPC_EBB, "NT_PPC_EBB (ppc EBB registers)"}, 6085 {ELF::NT_PPC_PMU, "NT_PPC_PMU (ppc PMU registers)"}, 6086 {ELF::NT_PPC_TM_CGPR, "NT_PPC_TM_CGPR (ppc checkpointed GPR registers)"}, 6087 {ELF::NT_PPC_TM_CFPR, 6088 "NT_PPC_TM_CFPR (ppc checkpointed floating point registers)"}, 6089 {ELF::NT_PPC_TM_CVMX, 6090 "NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)"}, 6091 {ELF::NT_PPC_TM_CVSX, "NT_PPC_TM_CVSX (ppc checkpointed VSX registers)"}, 6092 {ELF::NT_PPC_TM_SPR, "NT_PPC_TM_SPR (ppc TM special purpose registers)"}, 6093 {ELF::NT_PPC_TM_CTAR, "NT_PPC_TM_CTAR (ppc checkpointed TAR register)"}, 6094 {ELF::NT_PPC_TM_CPPR, "NT_PPC_TM_CPPR (ppc checkpointed PPR register)"}, 6095 {ELF::NT_PPC_TM_CDSCR, "NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)"}, 6096 6097 {ELF::NT_386_TLS, "NT_386_TLS (x86 TLS information)"}, 6098 {ELF::NT_386_IOPERM, "NT_386_IOPERM (x86 I/O permissions)"}, 6099 {ELF::NT_X86_XSTATE, "NT_X86_XSTATE (x86 XSAVE extended state)"}, 6100 6101 {ELF::NT_S390_HIGH_GPRS, "NT_S390_HIGH_GPRS (s390 upper register halves)"}, 6102 {ELF::NT_S390_TIMER, "NT_S390_TIMER (s390 timer register)"}, 6103 {ELF::NT_S390_TODCMP, "NT_S390_TODCMP (s390 TOD comparator register)"}, 6104 {ELF::NT_S390_TODPREG, "NT_S390_TODPREG (s390 TOD programmable register)"}, 6105 {ELF::NT_S390_CTRS, "NT_S390_CTRS (s390 control registers)"}, 6106 {ELF::NT_S390_PREFIX, "NT_S390_PREFIX (s390 prefix register)"}, 6107 {ELF::NT_S390_LAST_BREAK, 6108 "NT_S390_LAST_BREAK (s390 last breaking event address)"}, 6109 {ELF::NT_S390_SYSTEM_CALL, 6110 "NT_S390_SYSTEM_CALL (s390 system call restart data)"}, 6111 {ELF::NT_S390_TDB, "NT_S390_TDB (s390 transaction diagnostic block)"}, 6112 {ELF::NT_S390_VXRS_LOW, 6113 "NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)"}, 6114 {ELF::NT_S390_VXRS_HIGH, "NT_S390_VXRS_HIGH (s390 vector registers 16-31)"}, 6115 {ELF::NT_S390_GS_CB, "NT_S390_GS_CB (s390 guarded-storage registers)"}, 6116 {ELF::NT_S390_GS_BC, 6117 "NT_S390_GS_BC (s390 guarded-storage broadcast control)"}, 6118 6119 {ELF::NT_ARM_VFP, "NT_ARM_VFP (arm VFP registers)"}, 6120 {ELF::NT_ARM_TLS, "NT_ARM_TLS (AArch TLS registers)"}, 6121 {ELF::NT_ARM_HW_BREAK, 6122 "NT_ARM_HW_BREAK (AArch hardware breakpoint registers)"}, 6123 {ELF::NT_ARM_HW_WATCH, 6124 "NT_ARM_HW_WATCH (AArch hardware watchpoint registers)"}, 6125 {ELF::NT_ARM_SVE, "NT_ARM_SVE (AArch64 SVE registers)"}, 6126 {ELF::NT_ARM_PAC_MASK, 6127 "NT_ARM_PAC_MASK (AArch64 Pointer Authentication code masks)"}, 6128 {ELF::NT_ARM_TAGGED_ADDR_CTRL, 6129 "NT_ARM_TAGGED_ADDR_CTRL (AArch64 Tagged Address Control)"}, 6130 {ELF::NT_ARM_SSVE, "NT_ARM_SSVE (AArch64 Streaming SVE registers)"}, 6131 {ELF::NT_ARM_ZA, "NT_ARM_ZA (AArch64 SME ZA registers)"}, 6132 {ELF::NT_ARM_ZT, "NT_ARM_ZT (AArch64 SME ZT registers)"}, 6133 {ELF::NT_ARM_FPMR, "NT_ARM_FPMR (AArch64 Floating Point Mode Register)"}, 6134 {ELF::NT_ARM_GCS, "NT_ARM_GCS (AArch64 Guarded Control Stack state)"}, 6135 6136 {ELF::NT_FILE, "NT_FILE (mapped files)"}, 6137 {ELF::NT_PRXFPREG, "NT_PRXFPREG (user_xfpregs structure)"}, 6138 {ELF::NT_SIGINFO, "NT_SIGINFO (siginfo_t data)"}, 6139 }; 6140 6141 template <class ELFT> 6142 StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) { 6143 uint32_t Type = Note.getType(); 6144 auto FindNote = [&](ArrayRef<NoteType> V) -> StringRef { 6145 for (const NoteType &N : V) 6146 if (N.ID == Type) 6147 return N.Name; 6148 return ""; 6149 }; 6150 6151 StringRef Name = Note.getName(); 6152 if (Name == "GNU") 6153 return FindNote(GNUNoteTypes); 6154 if (Name == "FreeBSD") { 6155 if (ELFType == ELF::ET_CORE) { 6156 // FreeBSD also places the generic core notes in the FreeBSD namespace. 6157 StringRef Result = FindNote(FreeBSDCoreNoteTypes); 6158 if (!Result.empty()) 6159 return Result; 6160 return FindNote(CoreNoteTypes); 6161 } else { 6162 return FindNote(FreeBSDNoteTypes); 6163 } 6164 } 6165 if (ELFType == ELF::ET_CORE && Name.starts_with("NetBSD-CORE")) { 6166 StringRef Result = FindNote(NetBSDCoreNoteTypes); 6167 if (!Result.empty()) 6168 return Result; 6169 return FindNote(CoreNoteTypes); 6170 } 6171 if (ELFType == ELF::ET_CORE && Name.starts_with("OpenBSD")) { 6172 // OpenBSD also places the generic core notes in the OpenBSD namespace. 6173 StringRef Result = FindNote(OpenBSDCoreNoteTypes); 6174 if (!Result.empty()) 6175 return Result; 6176 return FindNote(CoreNoteTypes); 6177 } 6178 if (Name == "AMD") 6179 return FindNote(AMDNoteTypes); 6180 if (Name == "AMDGPU") 6181 return FindNote(AMDGPUNoteTypes); 6182 if (Name == "LLVMOMPOFFLOAD") 6183 return FindNote(LLVMOMPOFFLOADNoteTypes); 6184 if (Name == "Android") 6185 return FindNote(AndroidNoteTypes); 6186 6187 if (ELFType == ELF::ET_CORE) 6188 return FindNote(CoreNoteTypes); 6189 return FindNote(GenericNoteTypes); 6190 } 6191 6192 template <class ELFT> 6193 static void processNotesHelper( 6194 const ELFDumper<ELFT> &Dumper, 6195 llvm::function_ref<void(std::optional<StringRef>, typename ELFT::Off, 6196 typename ELFT::Addr, size_t)> 6197 StartNotesFn, 6198 llvm::function_ref<Error(const typename ELFT::Note &, bool)> ProcessNoteFn, 6199 llvm::function_ref<void()> FinishNotesFn) { 6200 const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile(); 6201 bool IsCoreFile = Obj.getHeader().e_type == ELF::ET_CORE; 6202 6203 ArrayRef<typename ELFT::Shdr> Sections = cantFail(Obj.sections()); 6204 if (!IsCoreFile && !Sections.empty()) { 6205 for (const typename ELFT::Shdr &S : Sections) { 6206 if (S.sh_type != SHT_NOTE) 6207 continue; 6208 StartNotesFn(expectedToStdOptional(Obj.getSectionName(S)), S.sh_offset, 6209 S.sh_size, S.sh_addralign); 6210 Error Err = Error::success(); 6211 size_t I = 0; 6212 for (const typename ELFT::Note Note : Obj.notes(S, Err)) { 6213 if (Error E = ProcessNoteFn(Note, IsCoreFile)) 6214 Dumper.reportUniqueWarning( 6215 "unable to read note with index " + Twine(I) + " from the " + 6216 describe(Obj, S) + ": " + toString(std::move(E))); 6217 ++I; 6218 } 6219 if (Err) 6220 Dumper.reportUniqueWarning("unable to read notes from the " + 6221 describe(Obj, S) + ": " + 6222 toString(std::move(Err))); 6223 FinishNotesFn(); 6224 } 6225 return; 6226 } 6227 6228 Expected<ArrayRef<typename ELFT::Phdr>> PhdrsOrErr = Obj.program_headers(); 6229 if (!PhdrsOrErr) { 6230 Dumper.reportUniqueWarning( 6231 "unable to read program headers to locate the PT_NOTE segment: " + 6232 toString(PhdrsOrErr.takeError())); 6233 return; 6234 } 6235 6236 for (size_t I = 0, E = (*PhdrsOrErr).size(); I != E; ++I) { 6237 const typename ELFT::Phdr &P = (*PhdrsOrErr)[I]; 6238 if (P.p_type != PT_NOTE) 6239 continue; 6240 StartNotesFn(/*SecName=*/std::nullopt, P.p_offset, P.p_filesz, P.p_align); 6241 Error Err = Error::success(); 6242 size_t Index = 0; 6243 for (const typename ELFT::Note Note : Obj.notes(P, Err)) { 6244 if (Error E = ProcessNoteFn(Note, IsCoreFile)) 6245 Dumper.reportUniqueWarning("unable to read note with index " + 6246 Twine(Index) + 6247 " from the PT_NOTE segment with index " + 6248 Twine(I) + ": " + toString(std::move(E))); 6249 ++Index; 6250 } 6251 if (Err) 6252 Dumper.reportUniqueWarning( 6253 "unable to read notes from the PT_NOTE segment with index " + 6254 Twine(I) + ": " + toString(std::move(Err))); 6255 FinishNotesFn(); 6256 } 6257 } 6258 6259 template <class ELFT> void GNUELFDumper<ELFT>::printNotes() { 6260 size_t Align = 0; 6261 bool IsFirstHeader = true; 6262 auto PrintHeader = [&](std::optional<StringRef> SecName, 6263 const typename ELFT::Off Offset, 6264 const typename ELFT::Addr Size, size_t Al) { 6265 Align = std::max<size_t>(Al, 4); 6266 // Print a newline between notes sections to match GNU readelf. 6267 if (!IsFirstHeader) { 6268 OS << '\n'; 6269 } else { 6270 IsFirstHeader = false; 6271 } 6272 6273 OS << "Displaying notes found "; 6274 6275 if (SecName) 6276 OS << "in: " << *SecName << "\n"; 6277 else 6278 OS << "at file offset " << format_hex(Offset, 10) << " with length " 6279 << format_hex(Size, 10) << ":\n"; 6280 6281 OS << " Owner Data size \tDescription\n"; 6282 }; 6283 6284 auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error { 6285 StringRef Name = Note.getName(); 6286 ArrayRef<uint8_t> Descriptor = Note.getDesc(Align); 6287 Elf_Word Type = Note.getType(); 6288 6289 // Print the note owner/type. 6290 OS << " " << left_justify(Name, 20) << ' ' 6291 << format_hex(Descriptor.size(), 10) << '\t'; 6292 6293 StringRef NoteType = 6294 getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type); 6295 if (!NoteType.empty()) 6296 OS << NoteType << '\n'; 6297 else 6298 OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n"; 6299 6300 const typename ELFT::Half EMachine = this->Obj.getHeader().e_machine; 6301 6302 // Print the description, or fallback to printing raw bytes for unknown 6303 // owners/if we fail to pretty-print the contents. 6304 if (Name == "GNU") { 6305 if (printGNUNote<ELFT>(OS, Type, Descriptor, EMachine)) 6306 return Error::success(); 6307 } else if (Name == "FreeBSD") { 6308 if (std::optional<FreeBSDNote> N = 6309 getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) { 6310 OS << " " << N->Type << ": " << N->Value << '\n'; 6311 return Error::success(); 6312 } 6313 } else if (Name == "AMD") { 6314 const AMDNote N = getAMDNote<ELFT>(Type, Descriptor); 6315 if (!N.Type.empty()) { 6316 OS << " " << N.Type << ":\n " << N.Value << '\n'; 6317 return Error::success(); 6318 } 6319 } else if (Name == "AMDGPU") { 6320 const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor); 6321 if (!N.Type.empty()) { 6322 OS << " " << N.Type << ":\n " << N.Value << '\n'; 6323 return Error::success(); 6324 } 6325 } else if (Name == "LLVMOMPOFFLOAD") { 6326 if (printLLVMOMPOFFLOADNote<ELFT>(OS, Type, Descriptor)) 6327 return Error::success(); 6328 } else if (Name == "CORE") { 6329 if (Type == ELF::NT_FILE) { 6330 DataExtractor DescExtractor( 6331 Descriptor, ELFT::Endianness == llvm::endianness::little, 6332 sizeof(Elf_Addr)); 6333 if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor)) { 6334 printCoreNote<ELFT>(OS, *NoteOrErr); 6335 return Error::success(); 6336 } else { 6337 return NoteOrErr.takeError(); 6338 } 6339 } 6340 } else if (Name == "Android") { 6341 if (printAndroidNote(OS, Type, Descriptor)) 6342 return Error::success(); 6343 } 6344 if (!Descriptor.empty()) { 6345 OS << " description data:"; 6346 for (uint8_t B : Descriptor) 6347 OS << " " << format("%02x", B); 6348 OS << '\n'; 6349 } 6350 return Error::success(); 6351 }; 6352 6353 processNotesHelper(*this, /*StartNotesFn=*/PrintHeader, 6354 /*ProcessNoteFn=*/ProcessNote, /*FinishNotesFn=*/[]() {}); 6355 } 6356 6357 template <class ELFT> 6358 ArrayRef<uint8_t> 6359 ELFDumper<ELFT>::getMemtagGlobalsSectionContents(uint64_t ExpectedAddr) { 6360 for (const typename ELFT::Shdr &Sec : cantFail(Obj.sections())) { 6361 if (Sec.sh_type != SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC) 6362 continue; 6363 if (Sec.sh_addr != ExpectedAddr) { 6364 reportUniqueWarning( 6365 "SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section was unexpectedly at 0x" + 6366 Twine::utohexstr(Sec.sh_addr) + 6367 ", when DT_AARCH64_MEMTAG_GLOBALS says it should be at 0x" + 6368 Twine::utohexstr(ExpectedAddr)); 6369 return ArrayRef<uint8_t>(); 6370 } 6371 Expected<ArrayRef<uint8_t>> Contents = Obj.getSectionContents(Sec); 6372 if (auto E = Contents.takeError()) { 6373 reportUniqueWarning( 6374 "couldn't get SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section contents: " + 6375 toString(std::move(E))); 6376 return ArrayRef<uint8_t>(); 6377 } 6378 return Contents.get(); 6379 } 6380 return ArrayRef<uint8_t>(); 6381 } 6382 6383 // Reserve the lower three bits of the first byte of the step distance when 6384 // encoding the memtag descriptors. Found to be the best overall size tradeoff 6385 // when compiling Android T with full MTE globals enabled. 6386 constexpr uint64_t MemtagStepVarintReservedBits = 3; 6387 constexpr uint64_t MemtagGranuleSize = 16; 6388 6389 template <typename ELFT> void ELFDumper<ELFT>::printMemtag() { 6390 if (Obj.getHeader().e_machine != EM_AARCH64) return; 6391 std::vector<std::pair<std::string, std::string>> DynamicEntries; 6392 uint64_t MemtagGlobalsSz = 0; 6393 uint64_t MemtagGlobals = 0; 6394 for (const typename ELFT::Dyn &Entry : dynamic_table()) { 6395 uintX_t Tag = Entry.getTag(); 6396 switch (Tag) { 6397 case DT_AARCH64_MEMTAG_GLOBALSSZ: 6398 MemtagGlobalsSz = Entry.getVal(); 6399 DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag), 6400 getDynamicEntry(Tag, Entry.getVal())); 6401 break; 6402 case DT_AARCH64_MEMTAG_GLOBALS: 6403 MemtagGlobals = Entry.getVal(); 6404 DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag), 6405 getDynamicEntry(Tag, Entry.getVal())); 6406 break; 6407 case DT_AARCH64_MEMTAG_MODE: 6408 case DT_AARCH64_MEMTAG_HEAP: 6409 case DT_AARCH64_MEMTAG_STACK: 6410 DynamicEntries.emplace_back(Obj.getDynamicTagAsString(Tag), 6411 getDynamicEntry(Tag, Entry.getVal())); 6412 break; 6413 } 6414 } 6415 6416 ArrayRef<uint8_t> AndroidNoteDesc; 6417 auto FindAndroidNote = [&](const Elf_Note &Note, bool IsCore) -> Error { 6418 if (Note.getName() == "Android" && 6419 Note.getType() == ELF::NT_ANDROID_TYPE_MEMTAG) 6420 AndroidNoteDesc = Note.getDesc(4); 6421 return Error::success(); 6422 }; 6423 6424 processNotesHelper( 6425 *this, 6426 /*StartNotesFn=*/ 6427 [](std::optional<StringRef>, const typename ELFT::Off, 6428 const typename ELFT::Addr, size_t) {}, 6429 /*ProcessNoteFn=*/FindAndroidNote, /*FinishNotesFn=*/[]() {}); 6430 6431 ArrayRef<uint8_t> Contents = getMemtagGlobalsSectionContents(MemtagGlobals); 6432 if (Contents.size() != MemtagGlobalsSz) { 6433 reportUniqueWarning( 6434 "mismatch between DT_AARCH64_MEMTAG_GLOBALSSZ (0x" + 6435 Twine::utohexstr(MemtagGlobalsSz) + 6436 ") and SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC section size (0x" + 6437 Twine::utohexstr(Contents.size()) + ")"); 6438 Contents = ArrayRef<uint8_t>(); 6439 } 6440 6441 std::vector<std::pair<uint64_t, uint64_t>> GlobalDescriptors; 6442 uint64_t Address = 0; 6443 // See the AArch64 MemtagABI document for a description of encoding scheme: 6444 // https://github.com/ARM-software/abi-aa/blob/main/memtagabielf64/memtagabielf64.rst#83encoding-of-sht_aarch64_memtag_globals_dynamic 6445 for (size_t I = 0; I < Contents.size();) { 6446 const char *Error = nullptr; 6447 unsigned DecodedBytes = 0; 6448 uint64_t Value = decodeULEB128(Contents.data() + I, &DecodedBytes, 6449 Contents.end(), &Error); 6450 I += DecodedBytes; 6451 if (Error) { 6452 reportUniqueWarning( 6453 "error decoding distance uleb, " + Twine(DecodedBytes) + 6454 " byte(s) into SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC: " + Twine(Error)); 6455 GlobalDescriptors.clear(); 6456 break; 6457 } 6458 uint64_t Distance = Value >> MemtagStepVarintReservedBits; 6459 uint64_t GranulesToTag = Value & ((1 << MemtagStepVarintReservedBits) - 1); 6460 if (GranulesToTag == 0) { 6461 GranulesToTag = decodeULEB128(Contents.data() + I, &DecodedBytes, 6462 Contents.end(), &Error) + 6463 1; 6464 I += DecodedBytes; 6465 if (Error) { 6466 reportUniqueWarning( 6467 "error decoding size-only uleb, " + Twine(DecodedBytes) + 6468 " byte(s) into SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC: " + Twine(Error)); 6469 GlobalDescriptors.clear(); 6470 break; 6471 } 6472 } 6473 Address += Distance * MemtagGranuleSize; 6474 GlobalDescriptors.emplace_back(Address, GranulesToTag * MemtagGranuleSize); 6475 Address += GranulesToTag * MemtagGranuleSize; 6476 } 6477 6478 printMemtag(DynamicEntries, AndroidNoteDesc, GlobalDescriptors); 6479 } 6480 6481 template <class ELFT> void GNUELFDumper<ELFT>::printELFLinkerOptions() { 6482 OS << "printELFLinkerOptions not implemented!\n"; 6483 } 6484 6485 template <class ELFT> 6486 void ELFDumper<ELFT>::printDependentLibsHelper( 6487 function_ref<void(const Elf_Shdr &)> OnSectionStart, 6488 function_ref<void(StringRef, uint64_t)> OnLibEntry) { 6489 auto Warn = [this](unsigned SecNdx, StringRef Msg) { 6490 this->reportUniqueWarning("SHT_LLVM_DEPENDENT_LIBRARIES section at index " + 6491 Twine(SecNdx) + " is broken: " + Msg); 6492 }; 6493 6494 unsigned I = -1; 6495 for (const Elf_Shdr &Shdr : cantFail(Obj.sections())) { 6496 ++I; 6497 if (Shdr.sh_type != ELF::SHT_LLVM_DEPENDENT_LIBRARIES) 6498 continue; 6499 6500 OnSectionStart(Shdr); 6501 6502 Expected<ArrayRef<uint8_t>> ContentsOrErr = Obj.getSectionContents(Shdr); 6503 if (!ContentsOrErr) { 6504 Warn(I, toString(ContentsOrErr.takeError())); 6505 continue; 6506 } 6507 6508 ArrayRef<uint8_t> Contents = *ContentsOrErr; 6509 if (!Contents.empty() && Contents.back() != 0) { 6510 Warn(I, "the content is not null-terminated"); 6511 continue; 6512 } 6513 6514 for (const uint8_t *I = Contents.begin(), *E = Contents.end(); I < E;) { 6515 StringRef Lib((const char *)I); 6516 OnLibEntry(Lib, I - Contents.begin()); 6517 I += Lib.size() + 1; 6518 } 6519 } 6520 } 6521 6522 template <class ELFT> 6523 void ELFDumper<ELFT>::forEachRelocationDo( 6524 const Elf_Shdr &Sec, 6525 llvm::function_ref<void(const Relocation<ELFT> &, unsigned, 6526 const Elf_Shdr &, const Elf_Shdr *)> 6527 RelRelaFn) { 6528 auto Warn = [&](Error &&E, 6529 const Twine &Prefix = "unable to read relocations from") { 6530 this->reportUniqueWarning(Prefix + " " + describe(Sec) + ": " + 6531 toString(std::move(E))); 6532 }; 6533 6534 // SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR sections do not have an 6535 // associated symbol table. For them we should not treat the value of the 6536 // sh_link field as an index of a symbol table. 6537 const Elf_Shdr *SymTab; 6538 if (Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_RELR && 6539 !(Obj.getHeader().e_machine == EM_AARCH64 && 6540 Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR)) { 6541 Expected<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Sec.sh_link); 6542 if (!SymTabOrErr) { 6543 Warn(SymTabOrErr.takeError(), "unable to locate a symbol table for"); 6544 return; 6545 } 6546 SymTab = *SymTabOrErr; 6547 } 6548 6549 unsigned RelNdx = 0; 6550 const bool IsMips64EL = this->Obj.isMips64EL(); 6551 switch (Sec.sh_type) { 6552 case ELF::SHT_REL: 6553 if (Expected<Elf_Rel_Range> RangeOrErr = Obj.rels(Sec)) { 6554 for (const Elf_Rel &R : *RangeOrErr) 6555 RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab); 6556 } else { 6557 Warn(RangeOrErr.takeError()); 6558 } 6559 break; 6560 case ELF::SHT_RELA: 6561 if (Expected<Elf_Rela_Range> RangeOrErr = Obj.relas(Sec)) { 6562 for (const Elf_Rela &R : *RangeOrErr) 6563 RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab); 6564 } else { 6565 Warn(RangeOrErr.takeError()); 6566 } 6567 break; 6568 case ELF::SHT_AARCH64_AUTH_RELR: 6569 if (Obj.getHeader().e_machine != EM_AARCH64) 6570 break; 6571 [[fallthrough]]; 6572 case ELF::SHT_RELR: 6573 case ELF::SHT_ANDROID_RELR: { 6574 Expected<Elf_Relr_Range> RangeOrErr = Obj.relrs(Sec); 6575 if (!RangeOrErr) { 6576 Warn(RangeOrErr.takeError()); 6577 break; 6578 } 6579 6580 for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr)) 6581 RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, 6582 /*SymTab=*/nullptr); 6583 break; 6584 } 6585 case ELF::SHT_CREL: { 6586 if (auto RelsOrRelas = Obj.crels(Sec)) { 6587 for (const Elf_Rel &R : RelsOrRelas->first) 6588 RelRelaFn(Relocation<ELFT>(R, false), RelNdx++, Sec, SymTab); 6589 for (const Elf_Rela &R : RelsOrRelas->second) 6590 RelRelaFn(Relocation<ELFT>(R, false), RelNdx++, Sec, SymTab); 6591 } else { 6592 Warn(RelsOrRelas.takeError()); 6593 } 6594 break; 6595 } 6596 case ELF::SHT_ANDROID_REL: 6597 case ELF::SHT_ANDROID_RELA: 6598 if (Expected<std::vector<Elf_Rela>> RelasOrErr = Obj.android_relas(Sec)) { 6599 for (const Elf_Rela &R : *RelasOrErr) 6600 RelRelaFn(Relocation<ELFT>(R, IsMips64EL), RelNdx++, Sec, SymTab); 6601 } else { 6602 Warn(RelasOrErr.takeError()); 6603 } 6604 break; 6605 } 6606 } 6607 6608 template <class ELFT> 6609 StringRef ELFDumper<ELFT>::getPrintableSectionName(const Elf_Shdr &Sec) const { 6610 StringRef Name = "<?>"; 6611 if (Expected<StringRef> SecNameOrErr = 6612 Obj.getSectionName(Sec, this->WarningHandler)) 6613 Name = *SecNameOrErr; 6614 else 6615 this->reportUniqueWarning("unable to get the name of " + describe(Sec) + 6616 ": " + toString(SecNameOrErr.takeError())); 6617 return Name; 6618 } 6619 6620 template <class ELFT> void GNUELFDumper<ELFT>::printDependentLibs() { 6621 bool SectionStarted = false; 6622 struct NameOffset { 6623 StringRef Name; 6624 uint64_t Offset; 6625 }; 6626 std::vector<NameOffset> SecEntries; 6627 NameOffset Current; 6628 auto PrintSection = [&]() { 6629 OS << "Dependent libraries section " << Current.Name << " at offset " 6630 << format_hex(Current.Offset, 1) << " contains " << SecEntries.size() 6631 << " entries:\n"; 6632 for (NameOffset Entry : SecEntries) 6633 OS << " [" << format("%6" PRIx64, Entry.Offset) << "] " << Entry.Name 6634 << "\n"; 6635 OS << "\n"; 6636 SecEntries.clear(); 6637 }; 6638 6639 auto OnSectionStart = [&](const Elf_Shdr &Shdr) { 6640 if (SectionStarted) 6641 PrintSection(); 6642 SectionStarted = true; 6643 Current.Offset = Shdr.sh_offset; 6644 Current.Name = this->getPrintableSectionName(Shdr); 6645 }; 6646 auto OnLibEntry = [&](StringRef Lib, uint64_t Offset) { 6647 SecEntries.push_back(NameOffset{Lib, Offset}); 6648 }; 6649 6650 this->printDependentLibsHelper(OnSectionStart, OnLibEntry); 6651 if (SectionStarted) 6652 PrintSection(); 6653 } 6654 6655 template <class ELFT> 6656 SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress( 6657 uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec) { 6658 SmallVector<uint32_t> SymbolIndexes; 6659 if (!this->AddressToIndexMap) { 6660 // Populate the address to index map upon the first invocation of this 6661 // function. 6662 this->AddressToIndexMap.emplace(); 6663 if (this->DotSymtabSec) { 6664 if (Expected<Elf_Sym_Range> SymsOrError = 6665 Obj.symbols(this->DotSymtabSec)) { 6666 uint32_t Index = (uint32_t)-1; 6667 for (const Elf_Sym &Sym : *SymsOrError) { 6668 ++Index; 6669 6670 if (Sym.st_shndx == ELF::SHN_UNDEF || Sym.getType() != ELF::STT_FUNC) 6671 continue; 6672 6673 Expected<uint64_t> SymAddrOrErr = 6674 ObjF.toSymbolRef(this->DotSymtabSec, Index).getAddress(); 6675 if (!SymAddrOrErr) { 6676 std::string Name = this->getStaticSymbolName(Index); 6677 reportUniqueWarning("unable to get address of symbol '" + Name + 6678 "': " + toString(SymAddrOrErr.takeError())); 6679 return SymbolIndexes; 6680 } 6681 6682 (*this->AddressToIndexMap)[*SymAddrOrErr].push_back(Index); 6683 } 6684 } else { 6685 reportUniqueWarning("unable to read the symbol table: " + 6686 toString(SymsOrError.takeError())); 6687 } 6688 } 6689 } 6690 6691 auto Symbols = this->AddressToIndexMap->find(SymValue); 6692 if (Symbols == this->AddressToIndexMap->end()) 6693 return SymbolIndexes; 6694 6695 for (uint32_t Index : Symbols->second) { 6696 // Check if the symbol is in the right section. FunctionSec == None 6697 // means "any section". 6698 if (FunctionSec) { 6699 const Elf_Sym &Sym = *cantFail(Obj.getSymbol(this->DotSymtabSec, Index)); 6700 if (Expected<const Elf_Shdr *> SecOrErr = 6701 Obj.getSection(Sym, this->DotSymtabSec, 6702 this->getShndxTable(this->DotSymtabSec))) { 6703 if (*FunctionSec != *SecOrErr) 6704 continue; 6705 } else { 6706 std::string Name = this->getStaticSymbolName(Index); 6707 // Note: it is impossible to trigger this error currently, it is 6708 // untested. 6709 reportUniqueWarning("unable to get section of symbol '" + Name + 6710 "': " + toString(SecOrErr.takeError())); 6711 return SymbolIndexes; 6712 } 6713 } 6714 6715 SymbolIndexes.push_back(Index); 6716 } 6717 6718 return SymbolIndexes; 6719 } 6720 6721 template <class ELFT> 6722 bool ELFDumper<ELFT>::printFunctionStackSize( 6723 uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec, 6724 const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) { 6725 SmallVector<uint32_t> FuncSymIndexes = 6726 this->getSymbolIndexesForFunctionAddress(SymValue, FunctionSec); 6727 if (FuncSymIndexes.empty()) 6728 reportUniqueWarning( 6729 "could not identify function symbol for stack size entry in " + 6730 describe(StackSizeSec)); 6731 6732 // Extract the size. The expectation is that Offset is pointing to the right 6733 // place, i.e. past the function address. 6734 Error Err = Error::success(); 6735 uint64_t StackSize = Data.getULEB128(Offset, &Err); 6736 if (Err) { 6737 reportUniqueWarning("could not extract a valid stack size from " + 6738 describe(StackSizeSec) + ": " + 6739 toString(std::move(Err))); 6740 return false; 6741 } 6742 6743 if (FuncSymIndexes.empty()) { 6744 printStackSizeEntry(StackSize, {"?"}); 6745 } else { 6746 SmallVector<std::string> FuncSymNames; 6747 for (uint32_t Index : FuncSymIndexes) 6748 FuncSymNames.push_back(this->getStaticSymbolName(Index)); 6749 printStackSizeEntry(StackSize, FuncSymNames); 6750 } 6751 6752 return true; 6753 } 6754 6755 template <class ELFT> 6756 void GNUELFDumper<ELFT>::printStackSizeEntry(uint64_t Size, 6757 ArrayRef<std::string> FuncNames) { 6758 OS.PadToColumn(2); 6759 OS << format_decimal(Size, 11); 6760 OS.PadToColumn(18); 6761 6762 OS << join(FuncNames.begin(), FuncNames.end(), ", ") << "\n"; 6763 } 6764 6765 template <class ELFT> 6766 void ELFDumper<ELFT>::printStackSize(const Relocation<ELFT> &R, 6767 const Elf_Shdr &RelocSec, unsigned Ndx, 6768 const Elf_Shdr *SymTab, 6769 const Elf_Shdr *FunctionSec, 6770 const Elf_Shdr &StackSizeSec, 6771 const RelocationResolver &Resolver, 6772 DataExtractor Data) { 6773 // This function ignores potentially erroneous input, unless it is directly 6774 // related to stack size reporting. 6775 const Elf_Sym *Sym = nullptr; 6776 Expected<RelSymbol<ELFT>> TargetOrErr = this->getRelocationTarget(R, SymTab); 6777 if (!TargetOrErr) 6778 reportUniqueWarning("unable to get the target of relocation with index " + 6779 Twine(Ndx) + " in " + describe(RelocSec) + ": " + 6780 toString(TargetOrErr.takeError())); 6781 else 6782 Sym = TargetOrErr->Sym; 6783 6784 uint64_t RelocSymValue = 0; 6785 if (Sym) { 6786 Expected<const Elf_Shdr *> SectionOrErr = 6787 this->Obj.getSection(*Sym, SymTab, this->getShndxTable(SymTab)); 6788 if (!SectionOrErr) { 6789 reportUniqueWarning( 6790 "cannot identify the section for relocation symbol '" + 6791 (*TargetOrErr).Name + "': " + toString(SectionOrErr.takeError())); 6792 } else if (*SectionOrErr != FunctionSec) { 6793 reportUniqueWarning("relocation symbol '" + (*TargetOrErr).Name + 6794 "' is not in the expected section"); 6795 // Pretend that the symbol is in the correct section and report its 6796 // stack size anyway. 6797 FunctionSec = *SectionOrErr; 6798 } 6799 6800 RelocSymValue = Sym->st_value; 6801 } 6802 6803 uint64_t Offset = R.Offset; 6804 if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) { 6805 reportUniqueWarning("found invalid relocation offset (0x" + 6806 Twine::utohexstr(Offset) + ") into " + 6807 describe(StackSizeSec) + 6808 " while trying to extract a stack size entry"); 6809 return; 6810 } 6811 6812 uint64_t SymValue = Resolver(R.Type, Offset, RelocSymValue, 6813 Data.getAddress(&Offset), R.Addend.value_or(0)); 6814 this->printFunctionStackSize(SymValue, FunctionSec, StackSizeSec, Data, 6815 &Offset); 6816 } 6817 6818 template <class ELFT> 6819 void ELFDumper<ELFT>::printNonRelocatableStackSizes( 6820 std::function<void()> PrintHeader) { 6821 // This function ignores potentially erroneous input, unless it is directly 6822 // related to stack size reporting. 6823 for (const Elf_Shdr &Sec : cantFail(Obj.sections())) { 6824 if (this->getPrintableSectionName(Sec) != ".stack_sizes") 6825 continue; 6826 PrintHeader(); 6827 ArrayRef<uint8_t> Contents = 6828 unwrapOrError(this->FileName, Obj.getSectionContents(Sec)); 6829 DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr)); 6830 uint64_t Offset = 0; 6831 while (Offset < Contents.size()) { 6832 // The function address is followed by a ULEB representing the stack 6833 // size. Check for an extra byte before we try to process the entry. 6834 if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) { 6835 reportUniqueWarning( 6836 describe(Sec) + 6837 " ended while trying to extract a stack size entry"); 6838 break; 6839 } 6840 uint64_t SymValue = Data.getAddress(&Offset); 6841 if (!printFunctionStackSize(SymValue, /*FunctionSec=*/std::nullopt, Sec, 6842 Data, &Offset)) 6843 break; 6844 } 6845 } 6846 } 6847 6848 template <class ELFT> 6849 void ELFDumper<ELFT>::printRelocatableStackSizes( 6850 std::function<void()> PrintHeader) { 6851 // Build a map between stack size sections and their corresponding relocation 6852 // sections. 6853 auto IsMatch = [&](const Elf_Shdr &Sec) -> bool { 6854 StringRef SectionName; 6855 if (Expected<StringRef> NameOrErr = Obj.getSectionName(Sec)) 6856 SectionName = *NameOrErr; 6857 else 6858 consumeError(NameOrErr.takeError()); 6859 6860 return SectionName == ".stack_sizes"; 6861 }; 6862 6863 Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> 6864 StackSizeRelocMapOrErr = Obj.getSectionAndRelocations(IsMatch); 6865 if (!StackSizeRelocMapOrErr) { 6866 reportUniqueWarning("unable to get stack size map section(s): " + 6867 toString(StackSizeRelocMapOrErr.takeError())); 6868 return; 6869 } 6870 6871 for (const auto &StackSizeMapEntry : *StackSizeRelocMapOrErr) { 6872 PrintHeader(); 6873 const Elf_Shdr *StackSizesELFSec = StackSizeMapEntry.first; 6874 const Elf_Shdr *RelocSec = StackSizeMapEntry.second; 6875 6876 // Warn about stack size sections without a relocation section. 6877 if (!RelocSec) { 6878 reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) + 6879 ") does not have a corresponding " 6880 "relocation section"), 6881 FileName); 6882 continue; 6883 } 6884 6885 // We might end up with relocations in CREL here. If we do, report a 6886 // warning since we do not currently support them. 6887 if (RelocSec->sh_type == ELF::SHT_CREL) { 6888 reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) + 6889 ") has a corresponding CREL relocation " 6890 "section, which is not currently supported"), 6891 FileName); 6892 continue; 6893 } 6894 6895 // A .stack_sizes section header's sh_link field is supposed to point 6896 // to the section that contains the functions whose stack sizes are 6897 // described in it. 6898 const Elf_Shdr *FunctionSec = unwrapOrError( 6899 this->FileName, Obj.getSection(StackSizesELFSec->sh_link)); 6900 6901 SupportsRelocation IsSupportedFn; 6902 RelocationResolver Resolver; 6903 std::tie(IsSupportedFn, Resolver) = getRelocationResolver(this->ObjF); 6904 ArrayRef<uint8_t> Contents = 6905 unwrapOrError(this->FileName, Obj.getSectionContents(*StackSizesELFSec)); 6906 DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr)); 6907 6908 forEachRelocationDo( 6909 *RelocSec, [&](const Relocation<ELFT> &R, unsigned Ndx, 6910 const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { 6911 if (!IsSupportedFn || !IsSupportedFn(R.Type)) { 6912 reportUniqueWarning( 6913 describe(*RelocSec) + 6914 " contains an unsupported relocation with index " + Twine(Ndx) + 6915 ": " + Obj.getRelocationTypeName(R.Type)); 6916 return; 6917 } 6918 6919 this->printStackSize(R, *RelocSec, Ndx, SymTab, FunctionSec, 6920 *StackSizesELFSec, Resolver, Data); 6921 }); 6922 } 6923 } 6924 6925 template <class ELFT> 6926 void GNUELFDumper<ELFT>::printStackSizes() { 6927 bool HeaderHasBeenPrinted = false; 6928 auto PrintHeader = [&]() { 6929 if (HeaderHasBeenPrinted) 6930 return; 6931 OS << "\nStack Sizes:\n"; 6932 OS.PadToColumn(9); 6933 OS << "Size"; 6934 OS.PadToColumn(18); 6935 OS << "Functions\n"; 6936 HeaderHasBeenPrinted = true; 6937 }; 6938 6939 // For non-relocatable objects, look directly for sections whose name starts 6940 // with .stack_sizes and process the contents. 6941 if (this->Obj.getHeader().e_type == ELF::ET_REL) 6942 this->printRelocatableStackSizes(PrintHeader); 6943 else 6944 this->printNonRelocatableStackSizes(PrintHeader); 6945 } 6946 6947 template <class ELFT> 6948 void GNUELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) { 6949 size_t Bias = ELFT::Is64Bits ? 8 : 0; 6950 auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) { 6951 OS.PadToColumn(2); 6952 OS << format_hex_no_prefix(Parser.getGotAddress(E), 8 + Bias); 6953 OS.PadToColumn(11 + Bias); 6954 OS << format_decimal(Parser.getGotOffset(E), 6) << "(gp)"; 6955 OS.PadToColumn(22 + Bias); 6956 OS << format_hex_no_prefix(*E, 8 + Bias); 6957 OS.PadToColumn(31 + 2 * Bias); 6958 OS << Purpose << "\n"; 6959 }; 6960 6961 OS << (Parser.IsStatic ? "Static GOT:\n" : "Primary GOT:\n"); 6962 OS << " Canonical gp value: " 6963 << format_hex_no_prefix(Parser.getGp(), 8 + Bias) << "\n\n"; 6964 6965 OS << " Reserved entries:\n"; 6966 if (ELFT::Is64Bits) 6967 OS << " Address Access Initial Purpose\n"; 6968 else 6969 OS << " Address Access Initial Purpose\n"; 6970 PrintEntry(Parser.getGotLazyResolver(), "Lazy resolver"); 6971 if (Parser.getGotModulePointer()) 6972 PrintEntry(Parser.getGotModulePointer(), "Module pointer (GNU extension)"); 6973 6974 if (!Parser.getLocalEntries().empty()) { 6975 OS << "\n"; 6976 OS << " Local entries:\n"; 6977 if (ELFT::Is64Bits) 6978 OS << " Address Access Initial\n"; 6979 else 6980 OS << " Address Access Initial\n"; 6981 for (auto &E : Parser.getLocalEntries()) 6982 PrintEntry(&E, ""); 6983 } 6984 6985 if (Parser.IsStatic) 6986 return; 6987 6988 if (!Parser.getGlobalEntries().empty()) { 6989 OS << "\n"; 6990 OS << " Global entries:\n"; 6991 if (ELFT::Is64Bits) 6992 OS << " Address Access Initial Sym.Val." 6993 << " Type Ndx Name\n"; 6994 else 6995 OS << " Address Access Initial Sym.Val. Type Ndx Name\n"; 6996 6997 DataRegion<Elf_Word> ShndxTable( 6998 (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end()); 6999 for (auto &E : Parser.getGlobalEntries()) { 7000 const Elf_Sym &Sym = *Parser.getGotSym(&E); 7001 const Elf_Sym &FirstSym = this->dynamic_symbols()[0]; 7002 std::string SymName = this->getFullSymbolName( 7003 Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false); 7004 7005 OS.PadToColumn(2); 7006 OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias)); 7007 OS.PadToColumn(11 + Bias); 7008 OS << to_string(format_decimal(Parser.getGotOffset(&E), 6)) + "(gp)"; 7009 OS.PadToColumn(22 + Bias); 7010 OS << to_string(format_hex_no_prefix(E, 8 + Bias)); 7011 OS.PadToColumn(31 + 2 * Bias); 7012 OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias)); 7013 OS.PadToColumn(40 + 3 * Bias); 7014 OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes)); 7015 OS.PadToColumn(48 + 3 * Bias); 7016 OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(), 7017 ShndxTable); 7018 OS.PadToColumn(52 + 3 * Bias); 7019 OS << SymName << "\n"; 7020 } 7021 } 7022 7023 if (!Parser.getOtherEntries().empty()) 7024 OS << "\n Number of TLS and multi-GOT entries " 7025 << Parser.getOtherEntries().size() << "\n"; 7026 } 7027 7028 template <class ELFT> 7029 void GNUELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) { 7030 size_t Bias = ELFT::Is64Bits ? 8 : 0; 7031 auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) { 7032 OS.PadToColumn(2); 7033 OS << format_hex_no_prefix(Parser.getPltAddress(E), 8 + Bias); 7034 OS.PadToColumn(11 + Bias); 7035 OS << format_hex_no_prefix(*E, 8 + Bias); 7036 OS.PadToColumn(20 + 2 * Bias); 7037 OS << Purpose << "\n"; 7038 }; 7039 7040 OS << "PLT GOT:\n\n"; 7041 7042 OS << " Reserved entries:\n"; 7043 OS << " Address Initial Purpose\n"; 7044 PrintEntry(Parser.getPltLazyResolver(), "PLT lazy resolver"); 7045 if (Parser.getPltModulePointer()) 7046 PrintEntry(Parser.getPltModulePointer(), "Module pointer"); 7047 7048 if (!Parser.getPltEntries().empty()) { 7049 OS << "\n"; 7050 OS << " Entries:\n"; 7051 OS << " Address Initial Sym.Val. Type Ndx Name\n"; 7052 DataRegion<Elf_Word> ShndxTable( 7053 (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end()); 7054 for (auto &E : Parser.getPltEntries()) { 7055 const Elf_Sym &Sym = *Parser.getPltSym(&E); 7056 const Elf_Sym &FirstSym = *cantFail( 7057 this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0)); 7058 std::string SymName = this->getFullSymbolName( 7059 Sym, &Sym - &FirstSym, ShndxTable, this->DynamicStringTable, false); 7060 7061 OS.PadToColumn(2); 7062 OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias)); 7063 OS.PadToColumn(11 + Bias); 7064 OS << to_string(format_hex_no_prefix(E, 8 + Bias)); 7065 OS.PadToColumn(20 + 2 * Bias); 7066 OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias)); 7067 OS.PadToColumn(29 + 3 * Bias); 7068 OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes)); 7069 OS.PadToColumn(37 + 3 * Bias); 7070 OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(), 7071 ShndxTable); 7072 OS.PadToColumn(41 + 3 * Bias); 7073 OS << SymName << "\n"; 7074 } 7075 } 7076 } 7077 7078 template <class ELFT> 7079 Expected<const Elf_Mips_ABIFlags<ELFT> *> 7080 getMipsAbiFlagsSection(const ELFDumper<ELFT> &Dumper) { 7081 const typename ELFT::Shdr *Sec = Dumper.findSectionByName(".MIPS.abiflags"); 7082 if (Sec == nullptr) 7083 return nullptr; 7084 7085 constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: "; 7086 Expected<ArrayRef<uint8_t>> DataOrErr = 7087 Dumper.getElfObject().getELFFile().getSectionContents(*Sec); 7088 if (!DataOrErr) 7089 return createError(ErrPrefix + toString(DataOrErr.takeError())); 7090 7091 if (DataOrErr->size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) 7092 return createError(ErrPrefix + "it has a wrong size (" + 7093 Twine(DataOrErr->size()) + ")"); 7094 return reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(DataOrErr->data()); 7095 } 7096 7097 template <class ELFT> void GNUELFDumper<ELFT>::printMipsABIFlags() { 7098 const Elf_Mips_ABIFlags<ELFT> *Flags = nullptr; 7099 if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr = 7100 getMipsAbiFlagsSection(*this)) 7101 Flags = *SecOrErr; 7102 else 7103 this->reportUniqueWarning(SecOrErr.takeError()); 7104 if (!Flags) 7105 return; 7106 7107 OS << "MIPS ABI Flags Version: " << Flags->version << "\n\n"; 7108 OS << "ISA: MIPS" << int(Flags->isa_level); 7109 if (Flags->isa_rev > 1) 7110 OS << "r" << int(Flags->isa_rev); 7111 OS << "\n"; 7112 OS << "GPR size: " << getMipsRegisterSize(Flags->gpr_size) << "\n"; 7113 OS << "CPR1 size: " << getMipsRegisterSize(Flags->cpr1_size) << "\n"; 7114 OS << "CPR2 size: " << getMipsRegisterSize(Flags->cpr2_size) << "\n"; 7115 OS << "FP ABI: " << enumToString(Flags->fp_abi, ArrayRef(ElfMipsFpABIType)) 7116 << "\n"; 7117 OS << "ISA Extension: " 7118 << enumToString(Flags->isa_ext, ArrayRef(ElfMipsISAExtType)) << "\n"; 7119 if (Flags->ases == 0) 7120 OS << "ASEs: None\n"; 7121 else 7122 // FIXME: Print each flag on a separate line. 7123 OS << "ASEs: " << printFlags(Flags->ases, ArrayRef(ElfMipsASEFlags)) 7124 << "\n"; 7125 OS << "FLAGS 1: " << format_hex_no_prefix(Flags->flags1, 8, false) << "\n"; 7126 OS << "FLAGS 2: " << format_hex_no_prefix(Flags->flags2, 8, false) << "\n"; 7127 OS << "\n"; 7128 } 7129 7130 template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() { 7131 const Elf_Ehdr &E = this->Obj.getHeader(); 7132 { 7133 DictScope D(W, "ElfHeader"); 7134 { 7135 DictScope D(W, "Ident"); 7136 W.printBinary("Magic", 7137 ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_MAG0, 4)); 7138 W.printEnum("Class", E.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass)); 7139 W.printEnum("DataEncoding", E.e_ident[ELF::EI_DATA], 7140 ArrayRef(ElfDataEncoding)); 7141 W.printNumber("FileVersion", E.e_ident[ELF::EI_VERSION]); 7142 7143 auto OSABI = ArrayRef(ElfOSABI); 7144 if (E.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH && 7145 E.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) { 7146 switch (E.e_machine) { 7147 case ELF::EM_AMDGPU: 7148 OSABI = ArrayRef(AMDGPUElfOSABI); 7149 break; 7150 case ELF::EM_ARM: 7151 OSABI = ArrayRef(ARMElfOSABI); 7152 break; 7153 case ELF::EM_TI_C6000: 7154 OSABI = ArrayRef(C6000ElfOSABI); 7155 break; 7156 } 7157 } 7158 W.printEnum("OS/ABI", E.e_ident[ELF::EI_OSABI], OSABI); 7159 W.printNumber("ABIVersion", E.e_ident[ELF::EI_ABIVERSION]); 7160 W.printBinary("Unused", 7161 ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_PAD)); 7162 } 7163 7164 std::string TypeStr; 7165 if (const EnumEntry<unsigned> *Ent = getObjectFileEnumEntry(E.e_type)) { 7166 TypeStr = Ent->Name.str(); 7167 } else { 7168 if (E.e_type >= ET_LOPROC) 7169 TypeStr = "Processor Specific"; 7170 else if (E.e_type >= ET_LOOS) 7171 TypeStr = "OS Specific"; 7172 else 7173 TypeStr = "Unknown"; 7174 } 7175 W.printString("Type", TypeStr + " (0x" + utohexstr(E.e_type) + ")"); 7176 7177 W.printEnum("Machine", E.e_machine, ArrayRef(ElfMachineType)); 7178 W.printNumber("Version", E.e_version); 7179 W.printHex("Entry", E.e_entry); 7180 W.printHex("ProgramHeaderOffset", E.e_phoff); 7181 W.printHex("SectionHeaderOffset", E.e_shoff); 7182 if (E.e_machine == EM_MIPS) 7183 W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderMipsFlags), 7184 unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI), 7185 unsigned(ELF::EF_MIPS_MACH)); 7186 else if (E.e_machine == EM_AMDGPU) { 7187 switch (E.e_ident[ELF::EI_ABIVERSION]) { 7188 default: 7189 W.printHex("Flags", E.e_flags); 7190 break; 7191 case 0: 7192 // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags. 7193 [[fallthrough]]; 7194 case ELF::ELFABIVERSION_AMDGPU_HSA_V3: 7195 W.printFlags("Flags", E.e_flags, 7196 ArrayRef(ElfHeaderAMDGPUFlagsABIVersion3), 7197 unsigned(ELF::EF_AMDGPU_MACH)); 7198 break; 7199 case ELF::ELFABIVERSION_AMDGPU_HSA_V4: 7200 case ELF::ELFABIVERSION_AMDGPU_HSA_V5: 7201 W.printFlags("Flags", E.e_flags, 7202 ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4), 7203 unsigned(ELF::EF_AMDGPU_MACH), 7204 unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4), 7205 unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4)); 7206 break; 7207 case ELF::ELFABIVERSION_AMDGPU_HSA_V6: { 7208 std::optional<FlagEntry> VerFlagEntry; 7209 // The string needs to remain alive from the moment we create a 7210 // FlagEntry until printFlags is done. 7211 std::string FlagStr; 7212 if (auto VersionFlag = E.e_flags & ELF::EF_AMDGPU_GENERIC_VERSION) { 7213 unsigned Version = 7214 VersionFlag >> ELF::EF_AMDGPU_GENERIC_VERSION_OFFSET; 7215 FlagStr = "EF_AMDGPU_GENERIC_VERSION_V" + std::to_string(Version); 7216 VerFlagEntry = FlagEntry(FlagStr, VersionFlag); 7217 } 7218 W.printFlags( 7219 "Flags", E.e_flags, ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4), 7220 unsigned(ELF::EF_AMDGPU_MACH), 7221 unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4), 7222 unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4), 7223 VerFlagEntry ? ArrayRef(*VerFlagEntry) : ArrayRef<FlagEntry>()); 7224 break; 7225 } 7226 } 7227 } else if (E.e_machine == EM_RISCV) 7228 W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderRISCVFlags)); 7229 else if (E.e_machine == EM_SPARC32PLUS || E.e_machine == EM_SPARCV9) 7230 W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderSPARCFlags), 7231 unsigned(ELF::EF_SPARCV9_MM)); 7232 else if (E.e_machine == EM_AVR) 7233 W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderAVRFlags), 7234 unsigned(ELF::EF_AVR_ARCH_MASK)); 7235 else if (E.e_machine == EM_LOONGARCH) 7236 W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderLoongArchFlags), 7237 unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK), 7238 unsigned(ELF::EF_LOONGARCH_OBJABI_MASK)); 7239 else if (E.e_machine == EM_XTENSA) 7240 W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderXtensaFlags), 7241 unsigned(ELF::EF_XTENSA_MACH)); 7242 else if (E.e_machine == EM_CUDA) 7243 W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderNVPTXFlags), 7244 unsigned(ELF::EF_CUDA_SM)); 7245 else 7246 W.printFlags("Flags", E.e_flags); 7247 W.printNumber("HeaderSize", E.e_ehsize); 7248 W.printNumber("ProgramHeaderEntrySize", E.e_phentsize); 7249 W.printNumber("ProgramHeaderCount", E.e_phnum); 7250 W.printNumber("SectionHeaderEntrySize", E.e_shentsize); 7251 W.printString("SectionHeaderCount", 7252 getSectionHeadersNumString(this->Obj, this->FileName)); 7253 W.printString("StringTableSectionIndex", 7254 getSectionHeaderTableIndexString(this->Obj, this->FileName)); 7255 } 7256 } 7257 7258 template <class ELFT> void LLVMELFDumper<ELFT>::printGroupSections() { 7259 DictScope Lists(W, "Groups"); 7260 std::vector<GroupSection> V = this->getGroups(); 7261 DenseMap<uint64_t, const GroupSection *> Map = mapSectionsToGroups(V); 7262 for (const GroupSection &G : V) { 7263 DictScope D(W, "Group"); 7264 W.printNumber("Name", G.Name, G.ShName); 7265 W.printNumber("Index", G.Index); 7266 W.printNumber("Link", G.Link); 7267 W.printNumber("Info", G.Info); 7268 W.printHex("Type", getGroupType(G.Type), G.Type); 7269 W.printString("Signature", G.Signature); 7270 7271 ListScope L(W, getGroupSectionHeaderName()); 7272 for (const GroupMember &GM : G.Members) { 7273 const GroupSection *MainGroup = Map[GM.Index]; 7274 if (MainGroup != &G) 7275 this->reportUniqueWarning( 7276 "section with index " + Twine(GM.Index) + 7277 ", included in the group section with index " + 7278 Twine(MainGroup->Index) + 7279 ", was also found in the group section with index " + 7280 Twine(G.Index)); 7281 printSectionGroupMembers(GM.Name, GM.Index); 7282 } 7283 } 7284 7285 if (V.empty()) 7286 printEmptyGroupMessage(); 7287 } 7288 7289 template <class ELFT> 7290 std::string LLVMELFDumper<ELFT>::getGroupSectionHeaderName() const { 7291 return "Section(s) in group"; 7292 } 7293 7294 template <class ELFT> 7295 void LLVMELFDumper<ELFT>::printSectionGroupMembers(StringRef Name, 7296 uint64_t Idx) const { 7297 W.startLine() << Name << " (" << Idx << ")\n"; 7298 } 7299 7300 template <class ELFT> void LLVMELFDumper<ELFT>::printRelocations() { 7301 ListScope D(W, "Relocations"); 7302 7303 for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) { 7304 if (!isRelocationSec<ELFT>(Sec, this->Obj.getHeader())) 7305 continue; 7306 7307 StringRef Name = this->getPrintableSectionName(Sec); 7308 unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front(); 7309 printRelocationSectionInfo(Sec, Name, SecNdx); 7310 } 7311 } 7312 7313 template <class ELFT> 7314 void LLVMELFDumper<ELFT>::printExpandedRelRelaReloc(const Relocation<ELFT> &R, 7315 StringRef SymbolName, 7316 StringRef RelocName) { 7317 DictScope Group(W, "Relocation"); 7318 W.printHex("Offset", R.Offset); 7319 W.printNumber("Type", RelocName, R.Type); 7320 W.printNumber("Symbol", !SymbolName.empty() ? SymbolName : "-", R.Symbol); 7321 if (R.Addend) 7322 W.printHex("Addend", (uintX_t)*R.Addend); 7323 } 7324 7325 template <class ELFT> 7326 void LLVMELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R, 7327 StringRef SymbolName, 7328 StringRef RelocName) { 7329 raw_ostream &OS = W.startLine(); 7330 OS << W.hex(R.Offset) << " " << RelocName << " " 7331 << (!SymbolName.empty() ? SymbolName : "-"); 7332 if (R.Addend) 7333 OS << " " << W.hex((uintX_t)*R.Addend); 7334 OS << "\n"; 7335 } 7336 7337 template <class ELFT> 7338 void LLVMELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec, 7339 StringRef Name, 7340 const unsigned SecNdx) { 7341 DictScope D(W, (Twine("Section (") + Twine(SecNdx) + ") " + Name).str()); 7342 this->printRelocationsHelper(Sec); 7343 } 7344 7345 template <class ELFT> void LLVMELFDumper<ELFT>::printEmptyGroupMessage() const { 7346 W.startLine() << "There are no group sections in the file.\n"; 7347 } 7348 7349 template <class ELFT> 7350 void LLVMELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R, 7351 const RelSymbol<ELFT> &RelSym) { 7352 StringRef SymbolName = RelSym.Name; 7353 if (RelSym.Sym && RelSym.Name.empty()) 7354 SymbolName = "<null>"; 7355 SmallString<32> RelocName; 7356 this->Obj.getRelocationTypeName(R.Type, RelocName); 7357 7358 if (opts::ExpandRelocs) { 7359 printExpandedRelRelaReloc(R, SymbolName, RelocName); 7360 } else { 7361 printDefaultRelRelaReloc(R, SymbolName, RelocName); 7362 } 7363 } 7364 7365 template <class ELFT> void LLVMELFDumper<ELFT>::printSectionHeaders() { 7366 ListScope SectionsD(W, "Sections"); 7367 7368 int SectionIndex = -1; 7369 std::vector<EnumEntry<unsigned>> FlagsList = 7370 getSectionFlagsForTarget(this->Obj.getHeader().e_ident[ELF::EI_OSABI], 7371 this->Obj.getHeader().e_machine); 7372 for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) { 7373 DictScope SectionD(W, "Section"); 7374 W.printNumber("Index", ++SectionIndex); 7375 W.printNumber("Name", this->getPrintableSectionName(Sec), Sec.sh_name); 7376 W.printHex("Type", 7377 object::getELFSectionTypeName(this->Obj.getHeader().e_machine, 7378 Sec.sh_type), 7379 Sec.sh_type); 7380 W.printFlags("Flags", Sec.sh_flags, ArrayRef(FlagsList)); 7381 W.printHex("Address", Sec.sh_addr); 7382 W.printHex("Offset", Sec.sh_offset); 7383 W.printNumber("Size", Sec.sh_size); 7384 W.printNumber("Link", Sec.sh_link); 7385 W.printNumber("Info", Sec.sh_info); 7386 W.printNumber("AddressAlignment", Sec.sh_addralign); 7387 W.printNumber("EntrySize", Sec.sh_entsize); 7388 7389 if (opts::SectionRelocations) { 7390 ListScope D(W, "Relocations"); 7391 this->printRelocationsHelper(Sec); 7392 } 7393 7394 if (opts::SectionSymbols) { 7395 ListScope D(W, "Symbols"); 7396 if (this->DotSymtabSec) { 7397 StringRef StrTable = unwrapOrError( 7398 this->FileName, 7399 this->Obj.getStringTableForSymtab(*this->DotSymtabSec)); 7400 ArrayRef<Elf_Word> ShndxTable = this->getShndxTable(this->DotSymtabSec); 7401 7402 typename ELFT::SymRange Symbols = unwrapOrError( 7403 this->FileName, this->Obj.symbols(this->DotSymtabSec)); 7404 for (const Elf_Sym &Sym : Symbols) { 7405 const Elf_Shdr *SymSec = unwrapOrError( 7406 this->FileName, 7407 this->Obj.getSection(Sym, this->DotSymtabSec, ShndxTable)); 7408 if (SymSec == &Sec) 7409 printSymbol(Sym, &Sym - &Symbols[0], ShndxTable, StrTable, false, 7410 /*NonVisibilityBitsUsed=*/false, 7411 /*ExtraSymInfo=*/false); 7412 } 7413 } 7414 } 7415 7416 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) { 7417 ArrayRef<uint8_t> Data = 7418 unwrapOrError(this->FileName, this->Obj.getSectionContents(Sec)); 7419 W.printBinaryBlock( 7420 "SectionData", 7421 StringRef(reinterpret_cast<const char *>(Data.data()), Data.size())); 7422 } 7423 } 7424 } 7425 7426 template <class ELFT> 7427 void LLVMELFDumper<ELFT>::printSymbolSection( 7428 const Elf_Sym &Symbol, unsigned SymIndex, 7429 DataRegion<Elf_Word> ShndxTable) const { 7430 auto GetSectionSpecialType = [&]() -> std::optional<StringRef> { 7431 if (Symbol.isUndefined()) 7432 return StringRef("Undefined"); 7433 if (Symbol.isProcessorSpecific()) 7434 return StringRef("Processor Specific"); 7435 if (Symbol.isOSSpecific()) 7436 return StringRef("Operating System Specific"); 7437 if (Symbol.isAbsolute()) 7438 return StringRef("Absolute"); 7439 if (Symbol.isCommon()) 7440 return StringRef("Common"); 7441 if (Symbol.isReserved() && Symbol.st_shndx != SHN_XINDEX) 7442 return StringRef("Reserved"); 7443 return std::nullopt; 7444 }; 7445 7446 if (std::optional<StringRef> Type = GetSectionSpecialType()) { 7447 W.printHex("Section", *Type, Symbol.st_shndx); 7448 return; 7449 } 7450 7451 Expected<unsigned> SectionIndex = 7452 this->getSymbolSectionIndex(Symbol, SymIndex, ShndxTable); 7453 if (!SectionIndex) { 7454 assert(Symbol.st_shndx == SHN_XINDEX && 7455 "getSymbolSectionIndex should only fail due to an invalid " 7456 "SHT_SYMTAB_SHNDX table/reference"); 7457 this->reportUniqueWarning(SectionIndex.takeError()); 7458 W.printHex("Section", "Reserved", SHN_XINDEX); 7459 return; 7460 } 7461 7462 Expected<StringRef> SectionName = 7463 this->getSymbolSectionName(Symbol, *SectionIndex); 7464 if (!SectionName) { 7465 // Don't report an invalid section name if the section headers are missing. 7466 // In such situations, all sections will be "invalid". 7467 if (!this->ObjF.sections().empty()) 7468 this->reportUniqueWarning(SectionName.takeError()); 7469 else 7470 consumeError(SectionName.takeError()); 7471 W.printHex("Section", "<?>", *SectionIndex); 7472 } else { 7473 W.printHex("Section", *SectionName, *SectionIndex); 7474 } 7475 } 7476 7477 template <class ELFT> 7478 void LLVMELFDumper<ELFT>::printSymbolOtherField(const Elf_Sym &Symbol) const { 7479 std::vector<EnumEntry<unsigned>> SymOtherFlags = 7480 this->getOtherFlagsFromSymbol(this->Obj.getHeader(), Symbol); 7481 W.printFlags("Other", Symbol.st_other, ArrayRef(SymOtherFlags), 0x3u); 7482 } 7483 7484 template <class ELFT> 7485 void LLVMELFDumper<ELFT>::printZeroSymbolOtherField( 7486 const Elf_Sym &Symbol) const { 7487 assert(Symbol.st_other == 0 && "non-zero Other Field"); 7488 // Usually st_other flag is zero. Do not pollute the output 7489 // by flags enumeration in that case. 7490 W.printNumber("Other", 0); 7491 } 7492 7493 template <class ELFT> 7494 void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, 7495 DataRegion<Elf_Word> ShndxTable, 7496 std::optional<StringRef> StrTable, 7497 bool IsDynamic, 7498 bool /*NonVisibilityBitsUsed*/, 7499 bool /*ExtraSymInfo*/) const { 7500 std::string FullSymbolName = this->getFullSymbolName( 7501 Symbol, SymIndex, ShndxTable, StrTable, IsDynamic); 7502 unsigned char SymbolType = Symbol.getType(); 7503 7504 DictScope D(W, "Symbol"); 7505 W.printNumber("Name", FullSymbolName, Symbol.st_name); 7506 W.printHex("Value", Symbol.st_value); 7507 W.printNumber("Size", Symbol.st_size); 7508 W.printEnum("Binding", Symbol.getBinding(), ArrayRef(ElfSymbolBindings)); 7509 if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && 7510 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) 7511 W.printEnum("Type", SymbolType, ArrayRef(AMDGPUSymbolTypes)); 7512 else 7513 W.printEnum("Type", SymbolType, ArrayRef(ElfSymbolTypes)); 7514 if (Symbol.st_other == 0) 7515 printZeroSymbolOtherField(Symbol); 7516 else 7517 printSymbolOtherField(Symbol); 7518 printSymbolSection(Symbol, SymIndex, ShndxTable); 7519 } 7520 7521 template <class ELFT> 7522 void LLVMELFDumper<ELFT>::printSymbols(bool PrintSymbols, 7523 bool PrintDynamicSymbols, 7524 bool ExtraSymInfo) { 7525 if (PrintSymbols) { 7526 ListScope Group(W, "Symbols"); 7527 this->printSymbolsHelper(false, ExtraSymInfo); 7528 } 7529 if (PrintDynamicSymbols) { 7530 ListScope Group(W, "DynamicSymbols"); 7531 this->printSymbolsHelper(true, ExtraSymInfo); 7532 } 7533 } 7534 7535 template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicTable() { 7536 Elf_Dyn_Range Table = this->dynamic_table(); 7537 if (Table.empty()) 7538 return; 7539 7540 W.startLine() << "DynamicSection [ (" << Table.size() << " entries)\n"; 7541 7542 size_t MaxTagSize = getMaxDynamicTagSize(this->Obj, Table); 7543 // The "Name/Value" column should be indented from the "Type" column by N 7544 // spaces, where N = MaxTagSize - length of "Type" (4) + trailing 7545 // space (1) = -3. 7546 W.startLine() << " Tag" << std::string(ELFT::Is64Bits ? 16 : 8, ' ') 7547 << "Type" << std::string(MaxTagSize - 3, ' ') << "Name/Value\n"; 7548 7549 std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s "; 7550 for (auto Entry : Table) { 7551 uintX_t Tag = Entry.getTag(); 7552 std::string Value = this->getDynamicEntry(Tag, Entry.getVal()); 7553 W.startLine() << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true) 7554 << " " 7555 << format(ValueFmt.c_str(), 7556 this->Obj.getDynamicTagAsString(Tag).c_str()) 7557 << Value << "\n"; 7558 } 7559 W.startLine() << "]\n"; 7560 } 7561 7562 template <class ELFT> 7563 void JSONELFDumper<ELFT>::printAuxillaryDynamicTableEntryInfo( 7564 const Elf_Dyn &Entry) { 7565 auto FormatFlags = [this, Value = Entry.getVal()](auto Flags) { 7566 ListScope L(this->W, "Flags"); 7567 for (const auto &Flag : Flags) { 7568 if (Flag.Value != 0 && (Value & Flag.Value) == Flag.Value) 7569 this->W.printString(Flag.Name); 7570 } 7571 }; 7572 switch (Entry.getTag()) { 7573 case DT_SONAME: 7574 this->W.printString("Name", this->getDynamicString(Entry.getVal())); 7575 break; 7576 case DT_AUXILIARY: 7577 case DT_FILTER: 7578 case DT_NEEDED: 7579 this->W.printString("Library", this->getDynamicString(Entry.getVal())); 7580 break; 7581 case DT_USED: 7582 this->W.printString("Object", this->getDynamicString(Entry.getVal())); 7583 break; 7584 case DT_RPATH: 7585 case DT_RUNPATH: { 7586 StringRef Value = this->getDynamicString(Entry.getVal()); 7587 ListScope L(this->W, "Path"); 7588 while (!Value.empty()) { 7589 auto [Front, Back] = Value.split(':'); 7590 this->W.printString(Front); 7591 Value = Back; 7592 } 7593 break; 7594 } 7595 case DT_FLAGS: 7596 FormatFlags(ArrayRef(ElfDynamicDTFlags)); 7597 break; 7598 case DT_FLAGS_1: 7599 FormatFlags(ArrayRef(ElfDynamicDTFlags1)); 7600 break; 7601 default: 7602 return; 7603 } 7604 } 7605 7606 template <class ELFT> void JSONELFDumper<ELFT>::printDynamicTable() { 7607 Elf_Dyn_Range Table = this->dynamic_table(); 7608 ListScope L(this->W, "DynamicSection"); 7609 for (const auto &Entry : Table) { 7610 DictScope D(this->W); 7611 uintX_t Tag = Entry.getTag(); 7612 this->W.printHex("Tag", Tag); 7613 this->W.printString("Type", this->Obj.getDynamicTagAsString(Tag)); 7614 this->W.printHex("Value", Entry.getVal()); 7615 this->printAuxillaryDynamicTableEntryInfo(Entry); 7616 } 7617 } 7618 7619 template <class ELFT> void LLVMELFDumper<ELFT>::printDynamicRelocations() { 7620 W.startLine() << "Dynamic Relocations {\n"; 7621 W.indent(); 7622 this->printDynamicRelocationsHelper(); 7623 W.unindent(); 7624 W.startLine() << "}\n"; 7625 } 7626 7627 template <class ELFT> 7628 void LLVMELFDumper<ELFT>::printProgramHeaders( 7629 bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) { 7630 if (PrintProgramHeaders) 7631 printProgramHeaders(); 7632 if (PrintSectionMapping == cl::BOU_TRUE) 7633 printSectionMapping(); 7634 } 7635 7636 template <class ELFT> void LLVMELFDumper<ELFT>::printProgramHeaders() { 7637 ListScope L(W, "ProgramHeaders"); 7638 7639 Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers(); 7640 if (!PhdrsOrErr) { 7641 this->reportUniqueWarning("unable to dump program headers: " + 7642 toString(PhdrsOrErr.takeError())); 7643 return; 7644 } 7645 7646 for (const Elf_Phdr &Phdr : *PhdrsOrErr) { 7647 DictScope P(W, "ProgramHeader"); 7648 StringRef Type = 7649 segmentTypeToString(this->Obj.getHeader().e_machine, Phdr.p_type); 7650 7651 W.printHex("Type", Type.empty() ? "Unknown" : Type, Phdr.p_type); 7652 W.printHex("Offset", Phdr.p_offset); 7653 W.printHex("VirtualAddress", Phdr.p_vaddr); 7654 W.printHex("PhysicalAddress", Phdr.p_paddr); 7655 W.printNumber("FileSize", Phdr.p_filesz); 7656 W.printNumber("MemSize", Phdr.p_memsz); 7657 W.printFlags("Flags", Phdr.p_flags, ArrayRef(ElfSegmentFlags)); 7658 W.printNumber("Alignment", Phdr.p_align); 7659 } 7660 } 7661 7662 template <class ELFT> 7663 void LLVMELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) { 7664 ListScope SS(W, "VersionSymbols"); 7665 if (!Sec) 7666 return; 7667 7668 StringRef StrTable; 7669 ArrayRef<Elf_Sym> Syms; 7670 const Elf_Shdr *SymTabSec; 7671 Expected<ArrayRef<Elf_Versym>> VerTableOrErr = 7672 this->getVersionTable(*Sec, &Syms, &StrTable, &SymTabSec); 7673 if (!VerTableOrErr) { 7674 this->reportUniqueWarning(VerTableOrErr.takeError()); 7675 return; 7676 } 7677 7678 if (StrTable.empty() || Syms.empty() || Syms.size() != VerTableOrErr->size()) 7679 return; 7680 7681 ArrayRef<Elf_Word> ShNdxTable = this->getShndxTable(SymTabSec); 7682 for (size_t I = 0, E = Syms.size(); I < E; ++I) { 7683 DictScope S(W, "Symbol"); 7684 W.printNumber("Version", (*VerTableOrErr)[I].vs_index & VERSYM_VERSION); 7685 W.printString("Name", 7686 this->getFullSymbolName(Syms[I], I, ShNdxTable, StrTable, 7687 /*IsDynamic=*/true)); 7688 } 7689 } 7690 7691 const EnumEntry<unsigned> SymVersionFlags[] = { 7692 {"Base", "BASE", VER_FLG_BASE}, 7693 {"Weak", "WEAK", VER_FLG_WEAK}, 7694 {"Info", "INFO", VER_FLG_INFO}}; 7695 7696 template <class ELFT> 7697 void LLVMELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) { 7698 ListScope SD(W, "VersionDefinitions"); 7699 if (!Sec) 7700 return; 7701 7702 Expected<std::vector<VerDef>> V = this->Obj.getVersionDefinitions(*Sec); 7703 if (!V) { 7704 this->reportUniqueWarning(V.takeError()); 7705 return; 7706 } 7707 7708 for (const VerDef &D : *V) { 7709 DictScope Def(W, "Definition"); 7710 W.printNumber("Version", D.Version); 7711 W.printFlags("Flags", D.Flags, ArrayRef(SymVersionFlags)); 7712 W.printNumber("Index", D.Ndx); 7713 W.printNumber("Hash", D.Hash); 7714 W.printString("Name", D.Name); 7715 W.printList( 7716 "Predecessors", D.AuxV, 7717 [](raw_ostream &OS, const VerdAux &Aux) { OS << Aux.Name.c_str(); }); 7718 } 7719 } 7720 7721 template <class ELFT> 7722 void LLVMELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) { 7723 ListScope SD(W, "VersionRequirements"); 7724 if (!Sec) 7725 return; 7726 7727 Expected<std::vector<VerNeed>> V = 7728 this->Obj.getVersionDependencies(*Sec, this->WarningHandler); 7729 if (!V) { 7730 this->reportUniqueWarning(V.takeError()); 7731 return; 7732 } 7733 7734 for (const VerNeed &VN : *V) { 7735 DictScope Entry(W, "Dependency"); 7736 W.printNumber("Version", VN.Version); 7737 W.printNumber("Count", VN.Cnt); 7738 W.printString("FileName", VN.File.c_str()); 7739 7740 ListScope L(W, "Entries"); 7741 for (const VernAux &Aux : VN.AuxV) { 7742 DictScope Entry(W, "Entry"); 7743 W.printNumber("Hash", Aux.Hash); 7744 W.printFlags("Flags", Aux.Flags, ArrayRef(SymVersionFlags)); 7745 W.printNumber("Index", Aux.Other); 7746 W.printString("Name", Aux.Name.c_str()); 7747 } 7748 } 7749 } 7750 7751 template <class ELFT> 7752 void LLVMELFDumper<ELFT>::printHashHistogramStats(size_t NBucket, 7753 size_t MaxChain, 7754 size_t TotalSyms, 7755 ArrayRef<size_t> Count, 7756 bool IsGnu) const { 7757 StringRef HistName = IsGnu ? "GnuHashHistogram" : "HashHistogram"; 7758 StringRef BucketName = IsGnu ? "Bucket" : "Chain"; 7759 StringRef ListName = IsGnu ? "Buckets" : "Chains"; 7760 DictScope Outer(W, HistName); 7761 W.printNumber("TotalBuckets", NBucket); 7762 ListScope Buckets(W, ListName); 7763 size_t CumulativeNonZero = 0; 7764 for (size_t I = 0; I < MaxChain; ++I) { 7765 CumulativeNonZero += Count[I] * I; 7766 DictScope Bucket(W, BucketName); 7767 W.printNumber("Length", I); 7768 W.printNumber("Count", Count[I]); 7769 W.printNumber("Percentage", (float)(Count[I] * 100.0) / NBucket); 7770 W.printNumber("Coverage", (float)(CumulativeNonZero * 100.0) / TotalSyms); 7771 } 7772 } 7773 7774 // Returns true if rel/rela section exists, and populates SymbolIndices. 7775 // Otherwise returns false. 7776 template <class ELFT> 7777 static bool getSymbolIndices(const typename ELFT::Shdr *CGRelSection, 7778 const ELFFile<ELFT> &Obj, 7779 const LLVMELFDumper<ELFT> *Dumper, 7780 SmallVector<uint32_t, 128> &SymbolIndices) { 7781 if (!CGRelSection) { 7782 Dumper->reportUniqueWarning( 7783 "relocation section for a call graph section doesn't exist"); 7784 return false; 7785 } 7786 7787 if (CGRelSection->sh_type == SHT_REL) { 7788 typename ELFT::RelRange CGProfileRel; 7789 Expected<typename ELFT::RelRange> CGProfileRelOrError = 7790 Obj.rels(*CGRelSection); 7791 if (!CGProfileRelOrError) { 7792 Dumper->reportUniqueWarning("unable to load relocations for " 7793 "SHT_LLVM_CALL_GRAPH_PROFILE section: " + 7794 toString(CGProfileRelOrError.takeError())); 7795 return false; 7796 } 7797 7798 CGProfileRel = *CGProfileRelOrError; 7799 for (const typename ELFT::Rel &Rel : CGProfileRel) 7800 SymbolIndices.push_back(Rel.getSymbol(Obj.isMips64EL())); 7801 } else { 7802 // MC unconditionally produces SHT_REL, but GNU strip/objcopy may convert 7803 // the format to SHT_RELA 7804 // (https://sourceware.org/bugzilla/show_bug.cgi?id=28035) 7805 typename ELFT::RelaRange CGProfileRela; 7806 Expected<typename ELFT::RelaRange> CGProfileRelaOrError = 7807 Obj.relas(*CGRelSection); 7808 if (!CGProfileRelaOrError) { 7809 Dumper->reportUniqueWarning("unable to load relocations for " 7810 "SHT_LLVM_CALL_GRAPH_PROFILE section: " + 7811 toString(CGProfileRelaOrError.takeError())); 7812 return false; 7813 } 7814 7815 CGProfileRela = *CGProfileRelaOrError; 7816 for (const typename ELFT::Rela &Rela : CGProfileRela) 7817 SymbolIndices.push_back(Rela.getSymbol(Obj.isMips64EL())); 7818 } 7819 7820 return true; 7821 } 7822 7823 template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() { 7824 auto IsMatch = [](const Elf_Shdr &Sec) -> bool { 7825 return Sec.sh_type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE; 7826 }; 7827 7828 Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr = 7829 this->Obj.getSectionAndRelocations(IsMatch); 7830 if (!SecToRelocMapOrErr) { 7831 this->reportUniqueWarning("unable to get CG Profile section(s): " + 7832 toString(SecToRelocMapOrErr.takeError())); 7833 return; 7834 } 7835 7836 for (const auto &CGMapEntry : *SecToRelocMapOrErr) { 7837 const Elf_Shdr *CGSection = CGMapEntry.first; 7838 const Elf_Shdr *CGRelSection = CGMapEntry.second; 7839 7840 Expected<ArrayRef<Elf_CGProfile>> CGProfileOrErr = 7841 this->Obj.template getSectionContentsAsArray<Elf_CGProfile>(*CGSection); 7842 if (!CGProfileOrErr) { 7843 this->reportUniqueWarning( 7844 "unable to load the SHT_LLVM_CALL_GRAPH_PROFILE section: " + 7845 toString(CGProfileOrErr.takeError())); 7846 return; 7847 } 7848 7849 SmallVector<uint32_t, 128> SymbolIndices; 7850 bool UseReloc = 7851 getSymbolIndices<ELFT>(CGRelSection, this->Obj, this, SymbolIndices); 7852 if (UseReloc && SymbolIndices.size() != CGProfileOrErr->size() * 2) { 7853 this->reportUniqueWarning( 7854 "number of from/to pairs does not match number of frequencies"); 7855 UseReloc = false; 7856 } 7857 7858 ListScope L(W, "CGProfile"); 7859 for (uint32_t I = 0, Size = CGProfileOrErr->size(); I != Size; ++I) { 7860 const Elf_CGProfile &CGPE = (*CGProfileOrErr)[I]; 7861 DictScope D(W, "CGProfileEntry"); 7862 if (UseReloc) { 7863 uint32_t From = SymbolIndices[I * 2]; 7864 uint32_t To = SymbolIndices[I * 2 + 1]; 7865 W.printNumber("From", this->getStaticSymbolName(From), From); 7866 W.printNumber("To", this->getStaticSymbolName(To), To); 7867 } 7868 W.printNumber("Weight", CGPE.cgp_weight); 7869 } 7870 } 7871 } 7872 7873 template <class ELFT> 7874 void LLVMELFDumper<ELFT>::printBBAddrMaps(bool PrettyPGOAnalysis) { 7875 bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL; 7876 using Elf_Shdr = typename ELFT::Shdr; 7877 auto IsMatch = [](const Elf_Shdr &Sec) -> bool { 7878 return Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP; 7879 }; 7880 Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecRelocMapOrErr = 7881 this->Obj.getSectionAndRelocations(IsMatch); 7882 if (!SecRelocMapOrErr) { 7883 this->reportUniqueWarning( 7884 "failed to get SHT_LLVM_BB_ADDR_MAP section(s): " + 7885 toString(SecRelocMapOrErr.takeError())); 7886 return; 7887 } 7888 for (auto const &[Sec, RelocSec] : *SecRelocMapOrErr) { 7889 std::optional<const Elf_Shdr *> FunctionSec; 7890 if (IsRelocatable) 7891 FunctionSec = 7892 unwrapOrError(this->FileName, this->Obj.getSection(Sec->sh_link)); 7893 ListScope L(W, "BBAddrMap"); 7894 if (IsRelocatable && !RelocSec) { 7895 this->reportUniqueWarning("unable to get relocation section for " + 7896 this->describe(*Sec)); 7897 continue; 7898 } 7899 std::vector<PGOAnalysisMap> PGOAnalyses; 7900 Expected<std::vector<BBAddrMap>> BBAddrMapOrErr = 7901 this->Obj.decodeBBAddrMap(*Sec, RelocSec, &PGOAnalyses); 7902 if (!BBAddrMapOrErr) { 7903 this->reportUniqueWarning("unable to dump " + this->describe(*Sec) + 7904 ": " + toString(BBAddrMapOrErr.takeError())); 7905 continue; 7906 } 7907 for (const auto &[AM, PAM] : zip_equal(*BBAddrMapOrErr, PGOAnalyses)) { 7908 DictScope D(W, "Function"); 7909 W.printHex("At", AM.getFunctionAddress()); 7910 SmallVector<uint32_t> FuncSymIndex = 7911 this->getSymbolIndexesForFunctionAddress(AM.getFunctionAddress(), 7912 FunctionSec); 7913 std::string FuncName = "<?>"; 7914 if (FuncSymIndex.empty()) 7915 this->reportUniqueWarning( 7916 "could not identify function symbol for address (0x" + 7917 Twine::utohexstr(AM.getFunctionAddress()) + ") in " + 7918 this->describe(*Sec)); 7919 else 7920 FuncName = this->getStaticSymbolName(FuncSymIndex.front()); 7921 W.printString("Name", FuncName); 7922 { 7923 ListScope BBRL(W, "BB Ranges"); 7924 for (const BBAddrMap::BBRangeEntry &BBR : AM.BBRanges) { 7925 DictScope BBRD(W); 7926 W.printHex("Base Address", BBR.BaseAddress); 7927 ListScope BBEL(W, "BB Entries"); 7928 for (const BBAddrMap::BBEntry &BBE : BBR.BBEntries) { 7929 DictScope BBED(W); 7930 W.printNumber("ID", BBE.ID); 7931 W.printHex("Offset", BBE.Offset); 7932 if (!BBE.CallsiteOffsets.empty()) 7933 W.printList("Callsite Offsets", BBE.CallsiteOffsets); 7934 W.printHex("Size", BBE.Size); 7935 W.printBoolean("HasReturn", BBE.hasReturn()); 7936 W.printBoolean("HasTailCall", BBE.hasTailCall()); 7937 W.printBoolean("IsEHPad", BBE.isEHPad()); 7938 W.printBoolean("CanFallThrough", BBE.canFallThrough()); 7939 W.printBoolean("HasIndirectBranch", BBE.hasIndirectBranch()); 7940 } 7941 } 7942 } 7943 7944 if (PAM.FeatEnable.hasPGOAnalysis()) { 7945 DictScope PD(W, "PGO analyses"); 7946 7947 if (PAM.FeatEnable.FuncEntryCount) 7948 W.printNumber("FuncEntryCount", PAM.FuncEntryCount); 7949 7950 if (PAM.FeatEnable.hasPGOAnalysisBBData()) { 7951 ListScope L(W, "PGO BB entries"); 7952 for (const PGOAnalysisMap::PGOBBEntry &PBBE : PAM.BBEntries) { 7953 DictScope L(W); 7954 7955 if (PAM.FeatEnable.BBFreq) { 7956 if (PrettyPGOAnalysis) { 7957 std::string BlockFreqStr; 7958 raw_string_ostream SS(BlockFreqStr); 7959 printRelativeBlockFreq(SS, PAM.BBEntries.front().BlockFreq, 7960 PBBE.BlockFreq); 7961 W.printString("Frequency", BlockFreqStr); 7962 } else { 7963 W.printNumber("Frequency", PBBE.BlockFreq.getFrequency()); 7964 } 7965 } 7966 7967 if (PAM.FeatEnable.BrProb) { 7968 ListScope L(W, "Successors"); 7969 for (const auto &Succ : PBBE.Successors) { 7970 DictScope L(W); 7971 W.printNumber("ID", Succ.ID); 7972 if (PrettyPGOAnalysis) { 7973 W.printObject("Probability", Succ.Prob); 7974 } else { 7975 W.printHex("Probability", Succ.Prob.getNumerator()); 7976 } 7977 } 7978 } 7979 } 7980 } 7981 } 7982 } 7983 } 7984 } 7985 7986 template <class ELFT> void LLVMELFDumper<ELFT>::printAddrsig() { 7987 ListScope L(W, "Addrsig"); 7988 if (!this->DotAddrsigSec) 7989 return; 7990 7991 Expected<std::vector<uint64_t>> SymsOrErr = 7992 decodeAddrsigSection(this->Obj, *this->DotAddrsigSec); 7993 if (!SymsOrErr) { 7994 this->reportUniqueWarning(SymsOrErr.takeError()); 7995 return; 7996 } 7997 7998 for (uint64_t Sym : *SymsOrErr) 7999 W.printNumber("Sym", this->getStaticSymbolName(Sym), Sym); 8000 } 8001 8002 template <typename ELFT> 8003 static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc, 8004 ScopedPrinter &W, 8005 typename ELFT::Half EMachine) { 8006 // Return true if we were able to pretty-print the note, false otherwise. 8007 switch (NoteType) { 8008 default: 8009 return false; 8010 case ELF::NT_GNU_ABI_TAG: { 8011 const GNUAbiTag &AbiTag = getGNUAbiTag<ELFT>(Desc); 8012 if (!AbiTag.IsValid) { 8013 W.printString("ABI", "<corrupt GNU_ABI_TAG>"); 8014 return false; 8015 } else { 8016 W.printString("OS", AbiTag.OSName); 8017 W.printString("ABI", AbiTag.ABI); 8018 } 8019 break; 8020 } 8021 case ELF::NT_GNU_BUILD_ID: { 8022 W.printString("Build ID", getGNUBuildId(Desc)); 8023 break; 8024 } 8025 case ELF::NT_GNU_GOLD_VERSION: 8026 W.printString("Version", getDescAsStringRef(Desc)); 8027 break; 8028 case ELF::NT_GNU_PROPERTY_TYPE_0: 8029 ListScope D(W, "Property"); 8030 for (const std::string &Property : getGNUPropertyList<ELFT>(Desc, EMachine)) 8031 W.printString(Property); 8032 break; 8033 } 8034 return true; 8035 } 8036 8037 static bool printAndroidNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc, 8038 ScopedPrinter &W) { 8039 // Return true if we were able to pretty-print the note, false otherwise. 8040 AndroidNoteProperties Props = getAndroidNoteProperties(NoteType, Desc); 8041 if (Props.empty()) 8042 return false; 8043 for (const auto &KV : Props) 8044 W.printString(KV.first, KV.second); 8045 return true; 8046 } 8047 8048 template <class ELFT> 8049 void LLVMELFDumper<ELFT>::printMemtag( 8050 const ArrayRef<std::pair<std::string, std::string>> DynamicEntries, 8051 const ArrayRef<uint8_t> AndroidNoteDesc, 8052 const ArrayRef<std::pair<uint64_t, uint64_t>> Descriptors) { 8053 { 8054 ListScope L(W, "Memtag Dynamic Entries:"); 8055 if (DynamicEntries.empty()) 8056 W.printString("< none found >"); 8057 for (const auto &DynamicEntryKV : DynamicEntries) 8058 W.printString(DynamicEntryKV.first, DynamicEntryKV.second); 8059 } 8060 8061 if (!AndroidNoteDesc.empty()) { 8062 ListScope L(W, "Memtag Android Note:"); 8063 printAndroidNoteLLVMStyle(ELF::NT_ANDROID_TYPE_MEMTAG, AndroidNoteDesc, W); 8064 } 8065 8066 if (Descriptors.empty()) 8067 return; 8068 8069 { 8070 ListScope L(W, "Memtag Global Descriptors:"); 8071 for (const auto &[Addr, BytesToTag] : Descriptors) { 8072 W.printHex("0x" + utohexstr(Addr), BytesToTag); 8073 } 8074 } 8075 } 8076 8077 template <typename ELFT> 8078 static bool printLLVMOMPOFFLOADNoteLLVMStyle(uint32_t NoteType, 8079 ArrayRef<uint8_t> Desc, 8080 ScopedPrinter &W) { 8081 switch (NoteType) { 8082 default: 8083 return false; 8084 case ELF::NT_LLVM_OPENMP_OFFLOAD_VERSION: 8085 W.printString("Version", getDescAsStringRef(Desc)); 8086 break; 8087 case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER: 8088 W.printString("Producer", getDescAsStringRef(Desc)); 8089 break; 8090 case ELF::NT_LLVM_OPENMP_OFFLOAD_PRODUCER_VERSION: 8091 W.printString("Producer version", getDescAsStringRef(Desc)); 8092 break; 8093 } 8094 return true; 8095 } 8096 8097 static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) { 8098 W.printNumber("Page Size", Note.PageSize); 8099 ListScope D(W, "Mappings"); 8100 for (const CoreFileMapping &Mapping : Note.Mappings) { 8101 DictScope D(W); 8102 W.printHex("Start", Mapping.Start); 8103 W.printHex("End", Mapping.End); 8104 W.printHex("Offset", Mapping.Offset); 8105 W.printString("Filename", Mapping.Filename); 8106 } 8107 } 8108 8109 template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() { 8110 ListScope L(W, "NoteSections"); 8111 8112 std::unique_ptr<DictScope> NoteSectionScope; 8113 std::unique_ptr<ListScope> NotesScope; 8114 size_t Align = 0; 8115 auto StartNotes = [&](std::optional<StringRef> SecName, 8116 const typename ELFT::Off Offset, 8117 const typename ELFT::Addr Size, size_t Al) { 8118 Align = std::max<size_t>(Al, 4); 8119 NoteSectionScope = std::make_unique<DictScope>(W, "NoteSection"); 8120 W.printString("Name", SecName ? *SecName : "<?>"); 8121 W.printHex("Offset", Offset); 8122 W.printHex("Size", Size); 8123 NotesScope = std::make_unique<ListScope>(W, "Notes"); 8124 }; 8125 8126 auto EndNotes = [&] { 8127 NotesScope.reset(); 8128 NoteSectionScope.reset(); 8129 }; 8130 8131 auto ProcessNote = [&](const Elf_Note &Note, bool IsCore) -> Error { 8132 DictScope D2(W); 8133 StringRef Name = Note.getName(); 8134 ArrayRef<uint8_t> Descriptor = Note.getDesc(Align); 8135 Elf_Word Type = Note.getType(); 8136 8137 // Print the note owner/type. 8138 W.printString("Owner", Name); 8139 W.printHex("Data size", Descriptor.size()); 8140 8141 StringRef NoteType = 8142 getNoteTypeName<ELFT>(Note, this->Obj.getHeader().e_type); 8143 if (!NoteType.empty()) 8144 W.printString("Type", NoteType); 8145 else 8146 W.printString("Type", 8147 "Unknown (" + to_string(format_hex(Type, 10)) + ")"); 8148 8149 const typename ELFT::Half EMachine = this->Obj.getHeader().e_machine; 8150 // Print the description, or fallback to printing raw bytes for unknown 8151 // owners/if we fail to pretty-print the contents. 8152 if (Name == "GNU") { 8153 if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W, EMachine)) 8154 return Error::success(); 8155 } else if (Name == "FreeBSD") { 8156 if (std::optional<FreeBSDNote> N = 8157 getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) { 8158 W.printString(N->Type, N->Value); 8159 return Error::success(); 8160 } 8161 } else if (Name == "AMD") { 8162 const AMDNote N = getAMDNote<ELFT>(Type, Descriptor); 8163 if (!N.Type.empty()) { 8164 W.printString(N.Type, N.Value); 8165 return Error::success(); 8166 } 8167 } else if (Name == "AMDGPU") { 8168 const AMDGPUNote N = getAMDGPUNote<ELFT>(Type, Descriptor); 8169 if (!N.Type.empty()) { 8170 W.printString(N.Type, N.Value); 8171 return Error::success(); 8172 } 8173 } else if (Name == "LLVMOMPOFFLOAD") { 8174 if (printLLVMOMPOFFLOADNoteLLVMStyle<ELFT>(Type, Descriptor, W)) 8175 return Error::success(); 8176 } else if (Name == "CORE") { 8177 if (Type == ELF::NT_FILE) { 8178 DataExtractor DescExtractor( 8179 Descriptor, ELFT::Endianness == llvm::endianness::little, 8180 sizeof(Elf_Addr)); 8181 if (Expected<CoreNote> N = readCoreNote(DescExtractor)) { 8182 printCoreNoteLLVMStyle(*N, W); 8183 return Error::success(); 8184 } else { 8185 return N.takeError(); 8186 } 8187 } 8188 } else if (Name == "Android") { 8189 if (printAndroidNoteLLVMStyle(Type, Descriptor, W)) 8190 return Error::success(); 8191 } 8192 if (!Descriptor.empty()) { 8193 W.printBinaryBlock("Description data", Descriptor); 8194 } 8195 return Error::success(); 8196 }; 8197 8198 processNotesHelper(*this, /*StartNotesFn=*/StartNotes, 8199 /*ProcessNoteFn=*/ProcessNote, /*FinishNotesFn=*/EndNotes); 8200 } 8201 8202 template <class ELFT> void LLVMELFDumper<ELFT>::printELFLinkerOptions() { 8203 ListScope L(W, "LinkerOptions"); 8204 8205 unsigned I = -1; 8206 for (const Elf_Shdr &Shdr : cantFail(this->Obj.sections())) { 8207 ++I; 8208 if (Shdr.sh_type != ELF::SHT_LLVM_LINKER_OPTIONS) 8209 continue; 8210 8211 Expected<ArrayRef<uint8_t>> ContentsOrErr = 8212 this->Obj.getSectionContents(Shdr); 8213 if (!ContentsOrErr) { 8214 this->reportUniqueWarning("unable to read the content of the " 8215 "SHT_LLVM_LINKER_OPTIONS section: " + 8216 toString(ContentsOrErr.takeError())); 8217 continue; 8218 } 8219 if (ContentsOrErr->empty()) 8220 continue; 8221 8222 if (ContentsOrErr->back() != 0) { 8223 this->reportUniqueWarning("SHT_LLVM_LINKER_OPTIONS section at index " + 8224 Twine(I) + 8225 " is broken: the " 8226 "content is not null-terminated"); 8227 continue; 8228 } 8229 8230 SmallVector<StringRef, 16> Strings; 8231 toStringRef(ContentsOrErr->drop_back()).split(Strings, '\0'); 8232 if (Strings.size() % 2 != 0) { 8233 this->reportUniqueWarning( 8234 "SHT_LLVM_LINKER_OPTIONS section at index " + Twine(I) + 8235 " is broken: an incomplete " 8236 "key-value pair was found. The last possible key was: \"" + 8237 Strings.back() + "\""); 8238 continue; 8239 } 8240 8241 for (size_t I = 0; I < Strings.size(); I += 2) 8242 W.printString(Strings[I], Strings[I + 1]); 8243 } 8244 } 8245 8246 template <class ELFT> void LLVMELFDumper<ELFT>::printDependentLibs() { 8247 ListScope L(W, "DependentLibs"); 8248 this->printDependentLibsHelper( 8249 [](const Elf_Shdr &) {}, 8250 [this](StringRef Lib, uint64_t) { W.printString(Lib); }); 8251 } 8252 8253 template <class ELFT> void LLVMELFDumper<ELFT>::printStackSizes() { 8254 ListScope L(W, "StackSizes"); 8255 if (this->Obj.getHeader().e_type == ELF::ET_REL) 8256 this->printRelocatableStackSizes([]() {}); 8257 else 8258 this->printNonRelocatableStackSizes([]() {}); 8259 } 8260 8261 template <class ELFT> 8262 void LLVMELFDumper<ELFT>::printStackSizeEntry(uint64_t Size, 8263 ArrayRef<std::string> FuncNames) { 8264 DictScope D(W, "Entry"); 8265 W.printList("Functions", FuncNames); 8266 W.printHex("Size", Size); 8267 } 8268 8269 template <class ELFT> 8270 void LLVMELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) { 8271 auto PrintEntry = [&](const Elf_Addr *E) { 8272 W.printHex("Address", Parser.getGotAddress(E)); 8273 W.printNumber("Access", Parser.getGotOffset(E)); 8274 W.printHex("Initial", *E); 8275 }; 8276 8277 DictScope GS(W, Parser.IsStatic ? "Static GOT" : "Primary GOT"); 8278 8279 W.printHex("Canonical gp value", Parser.getGp()); 8280 { 8281 ListScope RS(W, "Reserved entries"); 8282 { 8283 DictScope D(W, "Entry"); 8284 PrintEntry(Parser.getGotLazyResolver()); 8285 W.printString("Purpose", StringRef("Lazy resolver")); 8286 } 8287 8288 if (Parser.getGotModulePointer()) { 8289 DictScope D(W, "Entry"); 8290 PrintEntry(Parser.getGotModulePointer()); 8291 W.printString("Purpose", StringRef("Module pointer (GNU extension)")); 8292 } 8293 } 8294 { 8295 ListScope LS(W, "Local entries"); 8296 for (auto &E : Parser.getLocalEntries()) { 8297 DictScope D(W, "Entry"); 8298 PrintEntry(&E); 8299 } 8300 } 8301 8302 if (Parser.IsStatic) 8303 return; 8304 8305 { 8306 ListScope GS(W, "Global entries"); 8307 for (auto &E : Parser.getGlobalEntries()) { 8308 DictScope D(W, "Entry"); 8309 8310 PrintEntry(&E); 8311 8312 const Elf_Sym &Sym = *Parser.getGotSym(&E); 8313 W.printHex("Value", Sym.st_value); 8314 W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes)); 8315 8316 const unsigned SymIndex = &Sym - this->dynamic_symbols().begin(); 8317 DataRegion<Elf_Word> ShndxTable( 8318 (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end()); 8319 printSymbolSection(Sym, SymIndex, ShndxTable); 8320 8321 std::string SymName = this->getFullSymbolName( 8322 Sym, SymIndex, ShndxTable, this->DynamicStringTable, true); 8323 W.printNumber("Name", SymName, Sym.st_name); 8324 } 8325 } 8326 8327 W.printNumber("Number of TLS and multi-GOT entries", 8328 uint64_t(Parser.getOtherEntries().size())); 8329 } 8330 8331 template <class ELFT> 8332 void LLVMELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) { 8333 auto PrintEntry = [&](const Elf_Addr *E) { 8334 W.printHex("Address", Parser.getPltAddress(E)); 8335 W.printHex("Initial", *E); 8336 }; 8337 8338 DictScope GS(W, "PLT GOT"); 8339 8340 { 8341 ListScope RS(W, "Reserved entries"); 8342 { 8343 DictScope D(W, "Entry"); 8344 PrintEntry(Parser.getPltLazyResolver()); 8345 W.printString("Purpose", StringRef("PLT lazy resolver")); 8346 } 8347 8348 if (auto E = Parser.getPltModulePointer()) { 8349 DictScope D(W, "Entry"); 8350 PrintEntry(E); 8351 W.printString("Purpose", StringRef("Module pointer")); 8352 } 8353 } 8354 { 8355 ListScope LS(W, "Entries"); 8356 DataRegion<Elf_Word> ShndxTable( 8357 (const Elf_Word *)this->DynSymTabShndxRegion.Addr, this->Obj.end()); 8358 for (auto &E : Parser.getPltEntries()) { 8359 DictScope D(W, "Entry"); 8360 PrintEntry(&E); 8361 8362 const Elf_Sym &Sym = *Parser.getPltSym(&E); 8363 W.printHex("Value", Sym.st_value); 8364 W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes)); 8365 printSymbolSection(Sym, &Sym - this->dynamic_symbols().begin(), 8366 ShndxTable); 8367 8368 const Elf_Sym *FirstSym = cantFail( 8369 this->Obj.template getEntry<Elf_Sym>(*Parser.getPltSymTable(), 0)); 8370 std::string SymName = this->getFullSymbolName( 8371 Sym, &Sym - FirstSym, ShndxTable, Parser.getPltStrTable(), true); 8372 W.printNumber("Name", SymName, Sym.st_name); 8373 } 8374 } 8375 } 8376 8377 template <class ELFT> void LLVMELFDumper<ELFT>::printMipsABIFlags() { 8378 const Elf_Mips_ABIFlags<ELFT> *Flags; 8379 if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr = 8380 getMipsAbiFlagsSection(*this)) { 8381 Flags = *SecOrErr; 8382 if (!Flags) { 8383 W.startLine() << "There is no .MIPS.abiflags section in the file.\n"; 8384 return; 8385 } 8386 } else { 8387 this->reportUniqueWarning(SecOrErr.takeError()); 8388 return; 8389 } 8390 8391 raw_ostream &OS = W.getOStream(); 8392 DictScope GS(W, "MIPS ABI Flags"); 8393 8394 W.printNumber("Version", Flags->version); 8395 W.startLine() << "ISA: "; 8396 if (Flags->isa_rev <= 1) 8397 OS << format("MIPS%u", Flags->isa_level); 8398 else 8399 OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev); 8400 OS << "\n"; 8401 W.printEnum("ISA Extension", Flags->isa_ext, ArrayRef(ElfMipsISAExtType)); 8402 W.printFlags("ASEs", Flags->ases, ArrayRef(ElfMipsASEFlags)); 8403 W.printEnum("FP ABI", Flags->fp_abi, ArrayRef(ElfMipsFpABIType)); 8404 W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size)); 8405 W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size)); 8406 W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size)); 8407 W.printFlags("Flags 1", Flags->flags1, ArrayRef(ElfMipsFlags1)); 8408 W.printHex("Flags 2", Flags->flags2); 8409 } 8410 8411 template <class ELFT> 8412 void JSONELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj, 8413 ArrayRef<std::string> InputFilenames, 8414 const Archive *A) { 8415 FileScope = std::make_unique<DictScope>(this->W); 8416 DictScope D(this->W, "FileSummary"); 8417 this->W.printString("File", FileStr); 8418 this->W.printString("Format", Obj.getFileFormatName()); 8419 this->W.printString("Arch", Triple::getArchTypeName(Obj.getArch())); 8420 this->W.printString( 8421 "AddressSize", 8422 std::string(formatv("{0}bit", 8 * Obj.getBytesInAddress()))); 8423 this->printLoadName(); 8424 } 8425 8426 template <class ELFT> 8427 void JSONELFDumper<ELFT>::printZeroSymbolOtherField( 8428 const Elf_Sym &Symbol) const { 8429 // We want the JSON format to be uniform, since it is machine readable, so 8430 // always print the `Other` field the same way. 8431 this->printSymbolOtherField(Symbol); 8432 } 8433 8434 template <class ELFT> 8435 void JSONELFDumper<ELFT>::printDefaultRelRelaReloc(const Relocation<ELFT> &R, 8436 StringRef SymbolName, 8437 StringRef RelocName) { 8438 this->printExpandedRelRelaReloc(R, SymbolName, RelocName); 8439 } 8440 8441 template <class ELFT> 8442 void JSONELFDumper<ELFT>::printRelocationSectionInfo(const Elf_Shdr &Sec, 8443 StringRef Name, 8444 const unsigned SecNdx) { 8445 DictScope Group(this->W); 8446 this->W.printNumber("SectionIndex", SecNdx); 8447 ListScope D(this->W, "Relocs"); 8448 this->printRelocationsHelper(Sec); 8449 } 8450 8451 template <class ELFT> 8452 std::string JSONELFDumper<ELFT>::getGroupSectionHeaderName() const { 8453 return "GroupSections"; 8454 } 8455 8456 template <class ELFT> 8457 void JSONELFDumper<ELFT>::printSectionGroupMembers(StringRef Name, 8458 uint64_t Idx) const { 8459 DictScope Grp(this->W); 8460 this->W.printString("Name", Name); 8461 this->W.printNumber("Index", Idx); 8462 } 8463 8464 template <class ELFT> void JSONELFDumper<ELFT>::printEmptyGroupMessage() const { 8465 // JSON output does not need to print anything for empty groups 8466 } 8467