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