1 //===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief This file implements the ELF-specific dumper for llvm-readobj. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm-readobj.h" 16 #include "ARMAttributeParser.h" 17 #include "ARMEHABIPrinter.h" 18 #include "Error.h" 19 #include "ObjDumper.h" 20 #include "StackMapPrinter.h" 21 #include "StreamWriter.h" 22 #include "llvm/ADT/Optional.h" 23 #include "llvm/ADT/SmallString.h" 24 #include "llvm/ADT/StringExtras.h" 25 #include "llvm/Object/ELFObjectFile.h" 26 #include "llvm/Support/ARMBuildAttributes.h" 27 #include "llvm/Support/Compiler.h" 28 #include "llvm/Support/Format.h" 29 #include "llvm/Support/MathExtras.h" 30 #include "llvm/Support/MipsABIFlags.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include "llvm/Support/FormattedStream.h" 33 34 using namespace llvm; 35 using namespace llvm::object; 36 using namespace ELF; 37 38 #define LLVM_READOBJ_ENUM_CASE(ns, enum) \ 39 case ns::enum: return #enum; 40 41 #define ENUM_ENT(enum, altName) \ 42 { #enum, altName, ELF::enum } 43 44 #define ENUM_ENT_1(enum) \ 45 { #enum, #enum, ELF::enum } 46 47 #define TYPEDEF_ELF_TYPES(ELFT) \ 48 typedef ELFFile<ELFT> ELFO; \ 49 typedef typename ELFO::Elf_Shdr Elf_Shdr; \ 50 typedef typename ELFO::Elf_Sym Elf_Sym; \ 51 typedef typename ELFO::Elf_Dyn Elf_Dyn; \ 52 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range; \ 53 typedef typename ELFO::Elf_Rel Elf_Rel; \ 54 typedef typename ELFO::Elf_Rela Elf_Rela; \ 55 typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range; \ 56 typedef typename ELFO::Elf_Phdr Elf_Phdr; \ 57 typedef typename ELFO::Elf_Half Elf_Half; \ 58 typedef typename ELFO::Elf_Ehdr Elf_Ehdr; \ 59 typedef typename ELFO::Elf_Word Elf_Word; \ 60 typedef typename ELFO::uintX_t uintX_t; 61 62 namespace { 63 64 template <class ELFT> class DumpStyle; 65 66 /// Represents a contiguous uniform range in the file. We cannot just create a 67 /// range directly because when creating one of these from the .dynamic table 68 /// the size, entity size and virtual address are different entries in arbitrary 69 /// order (DT_REL, DT_RELSZ, DT_RELENT for example). 70 struct DynRegionInfo { 71 DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {} 72 DynRegionInfo(const void *A, uint64_t S, uint64_t ES) 73 : Addr(A), Size(S), EntSize(ES) {} 74 /// \brief Address in current address space. 75 const void *Addr; 76 /// \brief Size in bytes of the region. 77 uint64_t Size; 78 /// \brief Size of each entity in the region. 79 uint64_t EntSize; 80 81 template <typename Type> iterator_range<const Type *> getAsRange() const { 82 const Type *Start = reinterpret_cast<const Type *>(Addr); 83 if (!Start) 84 return {Start, Start}; 85 if (EntSize != sizeof(Type) || Size % EntSize) 86 reportError("Invalid entity size"); 87 return {Start, Start + (Size / EntSize)}; 88 } 89 }; 90 91 template<typename ELFT> 92 class ELFDumper : public ObjDumper { 93 public: 94 ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer); 95 96 void printFileHeaders() override; 97 void printSections() override; 98 void printRelocations() override; 99 void printDynamicRelocations() override; 100 void printSymbols() override; 101 void printDynamicSymbols() override; 102 void printUnwindInfo() override; 103 104 void printDynamicTable() override; 105 void printNeededLibraries() override; 106 void printProgramHeaders() override; 107 void printHashTable() override; 108 void printGnuHashTable() override; 109 void printLoadName() override; 110 void printVersionInfo() override; 111 void printGroupSections() override; 112 113 void printAttributes() override; 114 void printMipsPLTGOT() override; 115 void printMipsABIFlags() override; 116 void printMipsReginfo() override; 117 118 void printStackMap() const override; 119 120 private: 121 std::unique_ptr<DumpStyle<ELFT>> ELFDumperStyle; 122 typedef ELFFile<ELFT> ELFO; 123 typedef typename ELFO::Elf_Shdr Elf_Shdr; 124 typedef typename ELFO::Elf_Sym Elf_Sym; 125 typedef typename ELFO::Elf_Sym_Range Elf_Sym_Range; 126 typedef typename ELFO::Elf_Dyn Elf_Dyn; 127 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range; 128 typedef typename ELFO::Elf_Rel Elf_Rel; 129 typedef typename ELFO::Elf_Rela Elf_Rela; 130 typedef typename ELFO::Elf_Rel_Range Elf_Rel_Range; 131 typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range; 132 typedef typename ELFO::Elf_Phdr Elf_Phdr; 133 typedef typename ELFO::Elf_Half Elf_Half; 134 typedef typename ELFO::Elf_Hash Elf_Hash; 135 typedef typename ELFO::Elf_GnuHash Elf_GnuHash; 136 typedef typename ELFO::Elf_Ehdr Elf_Ehdr; 137 typedef typename ELFO::Elf_Word Elf_Word; 138 typedef typename ELFO::uintX_t uintX_t; 139 typedef typename ELFO::Elf_Versym Elf_Versym; 140 typedef typename ELFO::Elf_Verneed Elf_Verneed; 141 typedef typename ELFO::Elf_Vernaux Elf_Vernaux; 142 typedef typename ELFO::Elf_Verdef Elf_Verdef; 143 typedef typename ELFO::Elf_Verdaux Elf_Verdaux; 144 145 DynRegionInfo checkDRI(DynRegionInfo DRI) { 146 if (DRI.Addr < Obj->base() || 147 (const uint8_t *)DRI.Addr + DRI.Size > Obj->base() + Obj->getBufSize()) 148 error(llvm::object::object_error::parse_failed); 149 return DRI; 150 } 151 152 DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) { 153 return checkDRI({Obj->base() + P->p_offset, P->p_filesz, EntSize}); 154 } 155 156 DynRegionInfo createDRIFrom(const Elf_Shdr *S) { 157 return checkDRI({Obj->base() + S->sh_offset, S->sh_size, S->sh_entsize}); 158 } 159 160 void parseDynamicTable(ArrayRef<const Elf_Phdr *> LoadSegments); 161 162 void printValue(uint64_t Type, uint64_t Value); 163 164 StringRef getDynamicString(uint64_t Offset) const; 165 StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb, 166 bool &IsDefault) const; 167 void LoadVersionMap() const; 168 void LoadVersionNeeds(const Elf_Shdr *ec) const; 169 void LoadVersionDefs(const Elf_Shdr *sec) const; 170 171 const ELFO *Obj; 172 DynRegionInfo DynRelRegion; 173 DynRegionInfo DynRelaRegion; 174 DynRegionInfo DynPLTRelRegion; 175 DynRegionInfo DynSymRegion; 176 DynRegionInfo DynamicTable; 177 StringRef DynamicStringTable; 178 StringRef SOName; 179 const Elf_Hash *HashTable = nullptr; 180 const Elf_GnuHash *GnuHashTable = nullptr; 181 const Elf_Shdr *DotSymtabSec = nullptr; 182 StringRef DynSymtabName; 183 ArrayRef<Elf_Word> ShndxTable; 184 185 const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version 186 const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r 187 const Elf_Shdr *dot_gnu_version_d_sec = nullptr; // .gnu.version_d 188 189 // Records for each version index the corresponding Verdef or Vernaux entry. 190 // This is filled the first time LoadVersionMap() is called. 191 class VersionMapEntry : public PointerIntPair<const void *, 1> { 192 public: 193 // If the integer is 0, this is an Elf_Verdef*. 194 // If the integer is 1, this is an Elf_Vernaux*. 195 VersionMapEntry() : PointerIntPair<const void *, 1>(nullptr, 0) {} 196 VersionMapEntry(const Elf_Verdef *verdef) 197 : PointerIntPair<const void *, 1>(verdef, 0) {} 198 VersionMapEntry(const Elf_Vernaux *vernaux) 199 : PointerIntPair<const void *, 1>(vernaux, 1) {} 200 bool isNull() const { return getPointer() == nullptr; } 201 bool isVerdef() const { return !isNull() && getInt() == 0; } 202 bool isVernaux() const { return !isNull() && getInt() == 1; } 203 const Elf_Verdef *getVerdef() const { 204 return isVerdef() ? (const Elf_Verdef *)getPointer() : nullptr; 205 } 206 const Elf_Vernaux *getVernaux() const { 207 return isVernaux() ? (const Elf_Vernaux *)getPointer() : nullptr; 208 } 209 }; 210 mutable SmallVector<VersionMapEntry, 16> VersionMap; 211 212 public: 213 Elf_Dyn_Range dynamic_table() const { 214 return DynamicTable.getAsRange<Elf_Dyn>(); 215 } 216 217 Elf_Sym_Range dynamic_symbols() const { 218 return DynSymRegion.getAsRange<Elf_Sym>(); 219 } 220 221 Elf_Rel_Range dyn_rels() const; 222 Elf_Rela_Range dyn_relas() const; 223 std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable, 224 bool IsDynamic) const; 225 226 void printSymbolsHelper(bool IsDynamic) const; 227 const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; } 228 ArrayRef<Elf_Word> getShndxTable() const { return ShndxTable; } 229 StringRef getDynamicStringTable() const { return DynamicStringTable; } 230 const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; } 231 const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; } 232 const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; } 233 }; 234 235 template <class ELFT> 236 void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const { 237 StringRef StrTable, SymtabName; 238 size_t Entries = 0; 239 Elf_Sym_Range Syms(nullptr, nullptr); 240 if (IsDynamic) { 241 StrTable = DynamicStringTable; 242 Syms = dynamic_symbols(); 243 SymtabName = DynSymtabName; 244 if (DynSymRegion.Addr) 245 Entries = DynSymRegion.Size / DynSymRegion.EntSize; 246 } else { 247 if (!DotSymtabSec) 248 return; 249 StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec)); 250 Syms = Obj->symbols(DotSymtabSec); 251 SymtabName = unwrapOrError(Obj->getSectionName(DotSymtabSec)); 252 Entries = DotSymtabSec->getEntityCount(); 253 } 254 if (Syms.begin() == Syms.end()) 255 return; 256 ELFDumperStyle->printSymtabMessage(Obj, SymtabName, Entries); 257 for (const auto &Sym : Syms) 258 ELFDumperStyle->printSymbol(Obj, &Sym, Syms.begin(), StrTable, IsDynamic); 259 } 260 261 template <typename ELFT> class DumpStyle { 262 public: 263 using Elf_Shdr = typename ELFFile<ELFT>::Elf_Shdr; 264 using Elf_Sym = typename ELFFile<ELFT>::Elf_Sym; 265 266 DumpStyle(ELFDumper<ELFT> *Dumper) : Dumper(Dumper) {} 267 virtual ~DumpStyle() {} 268 virtual void printFileHeaders(const ELFFile<ELFT> *Obj) = 0; 269 virtual void printGroupSections(const ELFFile<ELFT> *Obj) = 0; 270 virtual void printRelocations(const ELFFile<ELFT> *Obj) = 0; 271 virtual void printSections(const ELFFile<ELFT> *Obj) = 0; 272 virtual void printSymbols(const ELFFile<ELFT> *Obj) = 0; 273 virtual void printDynamicSymbols(const ELFFile<ELFT> *Obj) = 0; 274 virtual void printDynamicRelocations(const ELFFile<ELFT> *Obj) = 0; 275 virtual void printSymtabMessage(const ELFFile<ELFT> *obj, StringRef Name, 276 size_t Offset) { 277 return; 278 } 279 virtual void printSymbol(const ELFFile<ELFT> *Obj, const Elf_Sym *Symbol, 280 const Elf_Sym *FirstSym, StringRef StrTable, 281 bool IsDynamic) = 0; 282 virtual void printProgramHeaders(const ELFFile<ELFT> *Obj) = 0; 283 const ELFDumper<ELFT> *dumper() const { return Dumper; } 284 private: 285 const ELFDumper<ELFT> *Dumper; 286 }; 287 288 template <typename ELFT> class GNUStyle : public DumpStyle<ELFT> { 289 formatted_raw_ostream OS; 290 public: 291 TYPEDEF_ELF_TYPES(ELFT) 292 GNUStyle(StreamWriter &W, ELFDumper<ELFT> *Dumper) 293 : DumpStyle<ELFT>(Dumper), OS(W.getOStream()) {} 294 void printFileHeaders(const ELFO *Obj) override; 295 void printGroupSections(const ELFFile<ELFT> *Obj) override; 296 void printRelocations(const ELFO *Obj) override; 297 void printSections(const ELFO *Obj) override; 298 void printSymbols(const ELFO *Obj) override; 299 void printDynamicSymbols(const ELFO *Obj) override; 300 void printDynamicRelocations(const ELFO *Obj) override; 301 virtual void printSymtabMessage(const ELFO *Obj, StringRef Name, 302 size_t Offset) override; 303 void printProgramHeaders(const ELFO *Obj) override; 304 305 private: 306 struct Field { 307 StringRef Str; 308 unsigned Column; 309 Field(StringRef S, unsigned Col) : Str(S), Column(Col) {} 310 Field(unsigned Col) : Str(""), Column(Col) {} 311 }; 312 313 template <typename T, typename TEnum> 314 std::string printEnum(T Value, ArrayRef<EnumEntry<TEnum>> EnumValues) { 315 for (const auto &EnumItem : EnumValues) 316 if (EnumItem.Value == Value) 317 return EnumItem.AltName; 318 return to_hexString(Value, false); 319 } 320 321 formatted_raw_ostream &printField(struct Field F) { 322 if (F.Column != 0) 323 OS.PadToColumn(F.Column); 324 OS << F.Str; 325 OS.flush(); 326 return OS; 327 } 328 void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab, 329 const Elf_Rela &R, bool IsRela); 330 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First, 331 StringRef StrTable, bool IsDynamic) override; 332 std::string getSymbolSectionNdx(const ELFO *Obj, const Elf_Sym *Symbol, 333 const Elf_Sym *FirstSym); 334 bool checkTLSSections(const Elf_Phdr &Phdr, const Elf_Shdr &Sec); 335 bool checkoffsets(const Elf_Phdr &Phdr, const Elf_Shdr &Sec); 336 bool checkVMA(const Elf_Phdr &Phdr, const Elf_Shdr &Sec); 337 bool checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec); 338 }; 339 340 template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> { 341 public: 342 TYPEDEF_ELF_TYPES(ELFT) 343 LLVMStyle(StreamWriter &W, ELFDumper<ELFT> *Dumper) 344 : DumpStyle<ELFT>(Dumper), W(W) {} 345 346 void printFileHeaders(const ELFO *Obj) override; 347 void printGroupSections(const ELFFile<ELFT> *Obj) override; 348 void printRelocations(const ELFO *Obj) override; 349 void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj); 350 void printSections(const ELFO *Obj) override; 351 void printSymbols(const ELFO *Obj) override; 352 void printDynamicSymbols(const ELFO *Obj) override; 353 void printDynamicRelocations(const ELFO *Obj) override; 354 void printProgramHeaders(const ELFO *Obj) override; 355 356 private: 357 void printRelocation(const ELFO *Obj, Elf_Rela Rel, const Elf_Shdr *SymTab); 358 void printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel); 359 void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First, 360 StringRef StrTable, bool IsDynamic) override; 361 StreamWriter &W; 362 }; 363 364 } // namespace 365 366 namespace llvm { 367 368 template <class ELFT> 369 static std::error_code createELFDumper(const ELFFile<ELFT> *Obj, 370 StreamWriter &Writer, 371 std::unique_ptr<ObjDumper> &Result) { 372 Result.reset(new ELFDumper<ELFT>(Obj, Writer)); 373 return readobj_error::success; 374 } 375 376 std::error_code createELFDumper(const object::ObjectFile *Obj, 377 StreamWriter &Writer, 378 std::unique_ptr<ObjDumper> &Result) { 379 // Little-endian 32-bit 380 if (const ELF32LEObjectFile *ELFObj = dyn_cast<ELF32LEObjectFile>(Obj)) 381 return createELFDumper(ELFObj->getELFFile(), Writer, Result); 382 383 // Big-endian 32-bit 384 if (const ELF32BEObjectFile *ELFObj = dyn_cast<ELF32BEObjectFile>(Obj)) 385 return createELFDumper(ELFObj->getELFFile(), Writer, Result); 386 387 // Little-endian 64-bit 388 if (const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj)) 389 return createELFDumper(ELFObj->getELFFile(), Writer, Result); 390 391 // Big-endian 64-bit 392 if (const ELF64BEObjectFile *ELFObj = dyn_cast<ELF64BEObjectFile>(Obj)) 393 return createELFDumper(ELFObj->getELFFile(), Writer, Result); 394 395 return readobj_error::unsupported_obj_file_format; 396 } 397 398 } // namespace llvm 399 400 // Iterate through the versions needed section, and place each Elf_Vernaux 401 // in the VersionMap according to its index. 402 template <class ELFT> 403 void ELFDumper<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const { 404 unsigned vn_size = sec->sh_size; // Size of section in bytes 405 unsigned vn_count = sec->sh_info; // Number of Verneed entries 406 const char *sec_start = (const char *)Obj->base() + sec->sh_offset; 407 const char *sec_end = sec_start + vn_size; 408 // The first Verneed entry is at the start of the section. 409 const char *p = sec_start; 410 for (unsigned i = 0; i < vn_count; i++) { 411 if (p + sizeof(Elf_Verneed) > sec_end) 412 report_fatal_error("Section ended unexpectedly while scanning " 413 "version needed records."); 414 const Elf_Verneed *vn = reinterpret_cast<const Elf_Verneed *>(p); 415 if (vn->vn_version != ELF::VER_NEED_CURRENT) 416 report_fatal_error("Unexpected verneed version"); 417 // Iterate through the Vernaux entries 418 const char *paux = p + vn->vn_aux; 419 for (unsigned j = 0; j < vn->vn_cnt; j++) { 420 if (paux + sizeof(Elf_Vernaux) > sec_end) 421 report_fatal_error("Section ended unexpected while scanning auxiliary " 422 "version needed records."); 423 const Elf_Vernaux *vna = reinterpret_cast<const Elf_Vernaux *>(paux); 424 size_t index = vna->vna_other & ELF::VERSYM_VERSION; 425 if (index >= VersionMap.size()) 426 VersionMap.resize(index + 1); 427 VersionMap[index] = VersionMapEntry(vna); 428 paux += vna->vna_next; 429 } 430 p += vn->vn_next; 431 } 432 } 433 434 // Iterate through the version definitions, and place each Elf_Verdef 435 // in the VersionMap according to its index. 436 template <class ELFT> 437 void ELFDumper<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const { 438 unsigned vd_size = sec->sh_size; // Size of section in bytes 439 unsigned vd_count = sec->sh_info; // Number of Verdef entries 440 const char *sec_start = (const char *)Obj->base() + sec->sh_offset; 441 const char *sec_end = sec_start + vd_size; 442 // The first Verdef entry is at the start of the section. 443 const char *p = sec_start; 444 for (unsigned i = 0; i < vd_count; i++) { 445 if (p + sizeof(Elf_Verdef) > sec_end) 446 report_fatal_error("Section ended unexpectedly while scanning " 447 "version definitions."); 448 const Elf_Verdef *vd = reinterpret_cast<const Elf_Verdef *>(p); 449 if (vd->vd_version != ELF::VER_DEF_CURRENT) 450 report_fatal_error("Unexpected verdef version"); 451 size_t index = vd->vd_ndx & ELF::VERSYM_VERSION; 452 if (index >= VersionMap.size()) 453 VersionMap.resize(index + 1); 454 VersionMap[index] = VersionMapEntry(vd); 455 p += vd->vd_next; 456 } 457 } 458 459 template <class ELFT> void ELFDumper<ELFT>::LoadVersionMap() const { 460 // If there is no dynamic symtab or version table, there is nothing to do. 461 if (!DynSymRegion.Addr || !dot_gnu_version_sec) 462 return; 463 464 // Has the VersionMap already been loaded? 465 if (VersionMap.size() > 0) 466 return; 467 468 // The first two version indexes are reserved. 469 // Index 0 is LOCAL, index 1 is GLOBAL. 470 VersionMap.push_back(VersionMapEntry()); 471 VersionMap.push_back(VersionMapEntry()); 472 473 if (dot_gnu_version_d_sec) 474 LoadVersionDefs(dot_gnu_version_d_sec); 475 476 if (dot_gnu_version_r_sec) 477 LoadVersionNeeds(dot_gnu_version_r_sec); 478 } 479 480 481 template <typename ELFO, class ELFT> 482 static void printVersionSymbolSection(ELFDumper<ELFT> *Dumper, 483 const ELFO *Obj, 484 const typename ELFO::Elf_Shdr *Sec, 485 StreamWriter &W) { 486 DictScope SS(W, "Version symbols"); 487 if (!Sec) 488 return; 489 StringRef Name = unwrapOrError(Obj->getSectionName(Sec)); 490 W.printNumber("Section Name", Name, Sec->sh_name); 491 W.printHex("Address", Sec->sh_addr); 492 W.printHex("Offset", Sec->sh_offset); 493 W.printNumber("Link", Sec->sh_link); 494 495 const uint8_t *P = (const uint8_t *)Obj->base() + Sec->sh_offset; 496 StringRef StrTable = Dumper->getDynamicStringTable(); 497 498 // Same number of entries in the dynamic symbol table (DT_SYMTAB). 499 ListScope Syms(W, "Symbols"); 500 for (const typename ELFO::Elf_Sym &Sym : Dumper->dynamic_symbols()) { 501 DictScope S(W, "Symbol"); 502 std::string FullSymbolName = 503 Dumper->getFullSymbolName(&Sym, StrTable, true /* IsDynamic */); 504 W.printNumber("Version", *P); 505 W.printString("Name", FullSymbolName); 506 P += sizeof(typename ELFO::Elf_Half); 507 } 508 } 509 510 template <typename ELFO, class ELFT> 511 static void printVersionDefinitionSection(ELFDumper<ELFT> *Dumper, 512 const ELFO *Obj, 513 const typename ELFO::Elf_Shdr *Sec, 514 StreamWriter &W) { 515 DictScope SD(W, "Version definition"); 516 if (!Sec) 517 return; 518 StringRef Name = unwrapOrError(Obj->getSectionName(Sec)); 519 W.printNumber("Section Name", Name, Sec->sh_name); 520 W.printHex("Address", Sec->sh_addr); 521 W.printHex("Offset", Sec->sh_offset); 522 W.printNumber("Link", Sec->sh_link); 523 524 unsigned verdef_entries = 0; 525 // The number of entries in the section SHT_GNU_verdef 526 // is determined by DT_VERDEFNUM tag. 527 for (const typename ELFO::Elf_Dyn &Dyn : Dumper->dynamic_table()) { 528 if (Dyn.d_tag == DT_VERDEFNUM) 529 verdef_entries = Dyn.d_un.d_val; 530 } 531 const uint8_t *SecStartAddress = 532 (const uint8_t *)Obj->base() + Sec->sh_offset; 533 const uint8_t *SecEndAddress = SecStartAddress + Sec->sh_size; 534 const uint8_t *P = SecStartAddress; 535 const typename ELFO::Elf_Shdr *StrTab = 536 unwrapOrError(Obj->getSection(Sec->sh_link)); 537 538 ListScope Entries(W, "Entries"); 539 for (unsigned i = 0; i < verdef_entries; ++i) { 540 if (P + sizeof(typename ELFO::Elf_Verdef) > SecEndAddress) 541 report_fatal_error("invalid offset in the section"); 542 auto *VD = reinterpret_cast<const typename ELFO::Elf_Verdef *>(P); 543 DictScope Entry(W, "Entry"); 544 W.printHex("Offset", (uintptr_t)P - (uintptr_t)SecStartAddress); 545 W.printNumber("Rev", VD->vd_version); 546 // FIXME: print something more readable. 547 W.printNumber("Flags", VD->vd_flags); 548 W.printNumber("Index", VD->vd_ndx); 549 W.printNumber("Cnt", VD->vd_cnt); 550 W.printString("Name", 551 StringRef((const char *)(Obj->base() + StrTab->sh_offset + 552 VD->getAux()->vda_name))); 553 P += VD->vd_next; 554 } 555 } 556 557 template <typename ELFT> void ELFDumper<ELFT>::printVersionInfo() { 558 // Dump version symbol section. 559 printVersionSymbolSection(this, Obj, dot_gnu_version_sec, W); 560 561 // Dump version definition section. 562 printVersionDefinitionSection(this, Obj, dot_gnu_version_d_sec, W); 563 } 564 565 template <typename ELFT> 566 StringRef ELFDumper<ELFT>::getSymbolVersion(StringRef StrTab, 567 const Elf_Sym *symb, 568 bool &IsDefault) const { 569 // This is a dynamic symbol. Look in the GNU symbol version table. 570 if (!dot_gnu_version_sec) { 571 // No version table. 572 IsDefault = false; 573 return StringRef(""); 574 } 575 576 // Determine the position in the symbol table of this entry. 577 size_t entry_index = (reinterpret_cast<uintptr_t>(symb) - 578 reinterpret_cast<uintptr_t>(DynSymRegion.Addr)) / 579 sizeof(Elf_Sym); 580 581 // Get the corresponding version index entry 582 const Elf_Versym *vs = 583 Obj->template getEntry<Elf_Versym>(dot_gnu_version_sec, entry_index); 584 size_t version_index = vs->vs_index & ELF::VERSYM_VERSION; 585 586 // Special markers for unversioned symbols. 587 if (version_index == ELF::VER_NDX_LOCAL || 588 version_index == ELF::VER_NDX_GLOBAL) { 589 IsDefault = false; 590 return StringRef(""); 591 } 592 593 // Lookup this symbol in the version table 594 LoadVersionMap(); 595 if (version_index >= VersionMap.size() || VersionMap[version_index].isNull()) 596 reportError("Invalid version entry"); 597 const VersionMapEntry &entry = VersionMap[version_index]; 598 599 // Get the version name string 600 size_t name_offset; 601 if (entry.isVerdef()) { 602 // The first Verdaux entry holds the name. 603 name_offset = entry.getVerdef()->getAux()->vda_name; 604 IsDefault = !(vs->vs_index & ELF::VERSYM_HIDDEN); 605 } else { 606 name_offset = entry.getVernaux()->vna_name; 607 IsDefault = false; 608 } 609 if (name_offset >= StrTab.size()) 610 reportError("Invalid string offset"); 611 return StringRef(StrTab.data() + name_offset); 612 } 613 614 template <typename ELFT> 615 std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol, 616 StringRef StrTable, 617 bool IsDynamic) const { 618 StringRef SymbolName = unwrapOrError(Symbol->getName(StrTable)); 619 if (!IsDynamic) 620 return SymbolName; 621 622 std::string FullSymbolName(SymbolName); 623 624 bool IsDefault; 625 StringRef Version = getSymbolVersion(StrTable, &*Symbol, IsDefault); 626 FullSymbolName += (IsDefault ? "@@" : "@"); 627 FullSymbolName += Version; 628 return FullSymbolName; 629 } 630 631 template <typename ELFO> 632 static void 633 getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, 634 const typename ELFO::Elf_Sym *FirstSym, 635 ArrayRef<typename ELFO::Elf_Word> ShndxTable, 636 StringRef &SectionName, unsigned &SectionIndex) { 637 SectionIndex = Symbol->st_shndx; 638 if (Symbol->isUndefined()) 639 SectionName = "Undefined"; 640 else if (Symbol->isProcessorSpecific()) 641 SectionName = "Processor Specific"; 642 else if (Symbol->isOSSpecific()) 643 SectionName = "Operating System Specific"; 644 else if (Symbol->isAbsolute()) 645 SectionName = "Absolute"; 646 else if (Symbol->isCommon()) 647 SectionName = "Common"; 648 else if (Symbol->isReserved() && SectionIndex != SHN_XINDEX) 649 SectionName = "Reserved"; 650 else { 651 if (SectionIndex == SHN_XINDEX) 652 SectionIndex = 653 Obj.getExtendedSymbolTableIndex(Symbol, FirstSym, ShndxTable); 654 const typename ELFO::Elf_Shdr *Sec = 655 unwrapOrError(Obj.getSection(SectionIndex)); 656 SectionName = unwrapOrError(Obj.getSectionName(Sec)); 657 } 658 } 659 660 template <class ELFO> 661 static const typename ELFO::Elf_Shdr * 662 findNotEmptySectionByAddress(const ELFO *Obj, uint64_t Addr) { 663 for (const auto &Shdr : Obj->sections()) 664 if (Shdr.sh_addr == Addr && Shdr.sh_size > 0) 665 return &Shdr; 666 return nullptr; 667 } 668 669 template <class ELFO> 670 static const typename ELFO::Elf_Shdr *findSectionByName(const ELFO &Obj, 671 StringRef Name) { 672 for (const auto &Shdr : Obj.sections()) { 673 if (Name == unwrapOrError(Obj.getSectionName(&Shdr))) 674 return &Shdr; 675 } 676 return nullptr; 677 } 678 679 static const EnumEntry<unsigned> ElfClass[] = { 680 {"None", "none", ELF::ELFCLASSNONE}, 681 {"32-bit", "ELF32", ELF::ELFCLASS32}, 682 {"64-bit", "ELF64", ELF::ELFCLASS64}, 683 }; 684 685 static const EnumEntry<unsigned> ElfDataEncoding[] = { 686 {"None", "none", ELF::ELFDATANONE}, 687 {"LittleEndian", "2's complement, little endian", ELF::ELFDATA2LSB}, 688 {"BigEndian", "2's complement, big endian", ELF::ELFDATA2MSB}, 689 }; 690 691 static const EnumEntry<unsigned> ElfObjectFileType[] = { 692 {"None", "NONE (none)", ELF::ET_NONE}, 693 {"Relocatable", "REL (Relocatable file)", ELF::ET_REL}, 694 {"Executable", "EXEC (Executable file)", ELF::ET_EXEC}, 695 {"SharedObject", "DYN (Shared object file)", ELF::ET_DYN}, 696 {"Core", "CORE (Core file)", ELF::ET_CORE}, 697 }; 698 699 static const EnumEntry<unsigned> ElfOSABI[] = { 700 {"SystemV", "UNIX - System V", ELF::ELFOSABI_NONE}, 701 {"HPUX", "UNIX - HP-UX", ELF::ELFOSABI_HPUX}, 702 {"NetBSD", "UNIX - NetBSD", ELF::ELFOSABI_NETBSD}, 703 {"GNU/Linux", "UNIX - GNU", ELF::ELFOSABI_LINUX}, 704 {"GNU/Hurd", "GNU/Hurd", ELF::ELFOSABI_HURD}, 705 {"Solaris", "UNIX - Solaris", ELF::ELFOSABI_SOLARIS}, 706 {"AIX", "UNIX - AIX", ELF::ELFOSABI_AIX}, 707 {"IRIX", "UNIX - IRIX", ELF::ELFOSABI_IRIX}, 708 {"FreeBSD", "UNIX - FreeBSD", ELF::ELFOSABI_FREEBSD}, 709 {"TRU64", "UNIX - TRU64", ELF::ELFOSABI_TRU64}, 710 {"Modesto", "Novell - Modesto", ELF::ELFOSABI_MODESTO}, 711 {"OpenBSD", "UNIX - OpenBSD", ELF::ELFOSABI_OPENBSD}, 712 {"OpenVMS", "VMS - OpenVMS", ELF::ELFOSABI_OPENVMS}, 713 {"NSK", "HP - Non-Stop Kernel", ELF::ELFOSABI_NSK}, 714 {"AROS", "AROS", ELF::ELFOSABI_AROS}, 715 {"FenixOS", "FenixOS", ELF::ELFOSABI_FENIXOS}, 716 {"CloudABI", "CloudABI", ELF::ELFOSABI_CLOUDABI}, 717 {"C6000_ELFABI", "Bare-metal C6000", ELF::ELFOSABI_C6000_ELFABI}, 718 {"C6000_LINUX", "Linux C6000", ELF::ELFOSABI_C6000_LINUX}, 719 {"ARM", "ARM", ELF::ELFOSABI_ARM}, 720 {"Standalone", "Standalone App", ELF::ELFOSABI_STANDALONE} 721 }; 722 723 static const EnumEntry<unsigned> ElfMachineType[] = { 724 ENUM_ENT(EM_NONE, "None"), 725 ENUM_ENT(EM_M32, "WE32100"), 726 ENUM_ENT(EM_SPARC, "Sparc"), 727 ENUM_ENT(EM_386, "Intel 80386"), 728 ENUM_ENT(EM_68K, "MC68000"), 729 ENUM_ENT(EM_88K, "MC88000"), 730 ENUM_ENT(EM_IAMCU, "EM_IAMCU"), 731 ENUM_ENT(EM_860, "Intel 80860"), 732 ENUM_ENT(EM_MIPS, "MIPS R3000"), 733 ENUM_ENT(EM_S370, "IBM System/370"), 734 ENUM_ENT(EM_MIPS_RS3_LE, "MIPS R3000 little-endian"), 735 ENUM_ENT(EM_PARISC, "HPPA"), 736 ENUM_ENT(EM_VPP500, "Fujitsu VPP500"), 737 ENUM_ENT(EM_SPARC32PLUS, "Sparc v8+"), 738 ENUM_ENT(EM_960, "Intel 80960"), 739 ENUM_ENT(EM_PPC, "PowerPC"), 740 ENUM_ENT(EM_PPC64, "PowerPC64"), 741 ENUM_ENT(EM_S390, "IBM S/390"), 742 ENUM_ENT(EM_SPU, "SPU"), 743 ENUM_ENT(EM_V800, "NEC V800 series"), 744 ENUM_ENT(EM_FR20, "Fujistsu FR20"), 745 ENUM_ENT(EM_RH32, "TRW RH-32"), 746 ENUM_ENT(EM_RCE, "Motorola RCE"), 747 ENUM_ENT(EM_ARM, "ARM"), 748 ENUM_ENT(EM_ALPHA, "EM_ALPHA"), 749 ENUM_ENT(EM_SH, "Hitachi SH"), 750 ENUM_ENT(EM_SPARCV9, "Sparc v9"), 751 ENUM_ENT(EM_TRICORE, "Siemens Tricore"), 752 ENUM_ENT(EM_ARC, "ARC"), 753 ENUM_ENT(EM_H8_300, "Hitachi H8/300"), 754 ENUM_ENT(EM_H8_300H, "Hitachi H8/300H"), 755 ENUM_ENT(EM_H8S, "Hitachi H8S"), 756 ENUM_ENT(EM_H8_500, "Hitachi H8/500"), 757 ENUM_ENT(EM_IA_64, "Intel IA-64"), 758 ENUM_ENT(EM_MIPS_X, "Stanford MIPS-X"), 759 ENUM_ENT(EM_COLDFIRE, "Motorola Coldfire"), 760 ENUM_ENT(EM_68HC12, "Motorola MC68HC12 Microcontroller"), 761 ENUM_ENT(EM_MMA, "Fujitsu Multimedia Accelerator"), 762 ENUM_ENT(EM_PCP, "Siemens PCP"), 763 ENUM_ENT(EM_NCPU, "Sony nCPU embedded RISC processor"), 764 ENUM_ENT(EM_NDR1, "Denso NDR1 microprocesspr"), 765 ENUM_ENT(EM_STARCORE, "Motorola Star*Core processor"), 766 ENUM_ENT(EM_ME16, "Toyota ME16 processor"), 767 ENUM_ENT(EM_ST100, "STMicroelectronics ST100 processor"), 768 ENUM_ENT(EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor"), 769 ENUM_ENT(EM_X86_64, "Advanced Micro Devices X86-64"), 770 ENUM_ENT(EM_PDSP, "Sony DSP processor"), 771 ENUM_ENT(EM_PDP10, "Digital Equipment Corp. PDP-10"), 772 ENUM_ENT(EM_PDP11, "Digital Equipment Corp. PDP-11"), 773 ENUM_ENT(EM_FX66, "Siemens FX66 microcontroller"), 774 ENUM_ENT(EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller"), 775 ENUM_ENT(EM_ST7, "STMicroelectronics ST7 8-bit microcontroller"), 776 ENUM_ENT(EM_68HC16, "Motorola MC68HC16 Microcontroller"), 777 ENUM_ENT(EM_68HC11, "Motorola MC68HC11 Microcontroller"), 778 ENUM_ENT(EM_68HC08, "Motorola MC68HC08 Microcontroller"), 779 ENUM_ENT(EM_68HC05, "Motorola MC68HC05 Microcontroller"), 780 ENUM_ENT(EM_SVX, "Silicon Graphics SVx"), 781 ENUM_ENT(EM_ST19, "STMicroelectronics ST19 8-bit microcontroller"), 782 ENUM_ENT(EM_VAX, "Digital VAX"), 783 ENUM_ENT(EM_CRIS, "Axis Communications 32-bit embedded processor"), 784 ENUM_ENT(EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu"), 785 ENUM_ENT(EM_FIREPATH, "Element 14 64-bit DSP processor"), 786 ENUM_ENT(EM_ZSP, "LSI Logic's 16-bit DSP processor"), 787 ENUM_ENT(EM_MMIX, "Donald Knuth's educational 64-bit processor"), 788 ENUM_ENT(EM_HUANY, "Harvard Universitys's machine-independent object format"), 789 ENUM_ENT(EM_PRISM, "Vitesse Prism"), 790 ENUM_ENT(EM_AVR, "Atmel AVR 8-bit microcontroller"), 791 ENUM_ENT(EM_FR30, "Fujitsu FR30"), 792 ENUM_ENT(EM_D10V, "Mitsubishi D10V"), 793 ENUM_ENT(EM_D30V, "Mitsubishi D30V"), 794 ENUM_ENT(EM_V850, "NEC v850"), 795 ENUM_ENT(EM_M32R, "Renesas M32R (formerly Mitsubishi M32r)"), 796 ENUM_ENT(EM_MN10300, "Matsushita MN10300"), 797 ENUM_ENT(EM_MN10200, "Matsushita MN10200"), 798 ENUM_ENT(EM_PJ, "picoJava"), 799 ENUM_ENT(EM_OPENRISC, "OpenRISC 32-bit embedded processor"), 800 ENUM_ENT(EM_ARC_COMPACT, "EM_ARC_COMPACT"), 801 ENUM_ENT(EM_XTENSA, "Tensilica Xtensa Processor"), 802 ENUM_ENT(EM_VIDEOCORE, "Alphamosaic VideoCore processor"), 803 ENUM_ENT(EM_TMM_GPP, "Thompson Multimedia General Purpose Processor"), 804 ENUM_ENT(EM_NS32K, "National Semiconductor 32000 series"), 805 ENUM_ENT(EM_TPC, "Tenor Network TPC processor"), 806 ENUM_ENT(EM_SNP1K, "EM_SNP1K"), 807 ENUM_ENT(EM_ST200, "STMicroelectronics ST200 microcontroller"), 808 ENUM_ENT(EM_IP2K, "Ubicom IP2xxx 8-bit microcontrollers"), 809 ENUM_ENT(EM_MAX, "MAX Processor"), 810 ENUM_ENT(EM_CR, "National Semiconductor CompactRISC"), 811 ENUM_ENT(EM_F2MC16, "Fujitsu F2MC16"), 812 ENUM_ENT(EM_MSP430, "Texas Instruments msp430 microcontroller"), 813 ENUM_ENT(EM_BLACKFIN, "Analog Devices Blackfin"), 814 ENUM_ENT(EM_SE_C33, "S1C33 Family of Seiko Epson processors"), 815 ENUM_ENT(EM_SEP, "Sharp embedded microprocessor"), 816 ENUM_ENT(EM_ARCA, "Arca RISC microprocessor"), 817 ENUM_ENT(EM_UNICORE, "Unicore"), 818 ENUM_ENT(EM_EXCESS, "eXcess 16/32/64-bit configurable embedded CPU"), 819 ENUM_ENT(EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor"), 820 ENUM_ENT(EM_ALTERA_NIOS2, "Altera Nios"), 821 ENUM_ENT(EM_CRX, "National Semiconductor CRX microprocessor"), 822 ENUM_ENT(EM_XGATE, "Motorola XGATE embedded processor"), 823 ENUM_ENT(EM_C166, "Infineon Technologies xc16x"), 824 ENUM_ENT(EM_M16C, "Renesas M16C"), 825 ENUM_ENT(EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller"), 826 ENUM_ENT(EM_CE, "Freescale Communication Engine RISC core"), 827 ENUM_ENT(EM_M32C, "Renesas M32C"), 828 ENUM_ENT(EM_TSK3000, "Altium TSK3000 core"), 829 ENUM_ENT(EM_RS08, "Freescale RS08 embedded processor"), 830 ENUM_ENT(EM_SHARC, "EM_SHARC"), 831 ENUM_ENT(EM_ECOG2, "Cyan Technology eCOG2 microprocessor"), 832 ENUM_ENT(EM_SCORE7, "SUNPLUS S+Core"), 833 ENUM_ENT(EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor"), 834 ENUM_ENT(EM_VIDEOCORE3, "Broadcom VideoCore III processor"), 835 ENUM_ENT(EM_LATTICEMICO32, "Lattice Mico32"), 836 ENUM_ENT(EM_SE_C17, "Seiko Epson C17 family"), 837 ENUM_ENT(EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family"), 838 ENUM_ENT(EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family"), 839 ENUM_ENT(EM_TI_C5500, "Texas Instruments TMS320C55x DSP family"), 840 ENUM_ENT(EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor"), 841 ENUM_ENT(EM_CYPRESS_M8C, "Cypress M8C microprocessor"), 842 ENUM_ENT(EM_R32C, "Renesas R32C series microprocessors"), 843 ENUM_ENT(EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family"), 844 ENUM_ENT(EM_HEXAGON, "Qualcomm Hexagon"), 845 ENUM_ENT(EM_8051, "Intel 8051 and variants"), 846 ENUM_ENT(EM_STXP7X, "STMicroelectronics STxP7x family"), 847 ENUM_ENT(EM_NDS32, "Andes Technology compact code size embedded RISC processor family"), 848 ENUM_ENT(EM_ECOG1, "Cyan Technology eCOG1 microprocessor"), 849 ENUM_ENT(EM_ECOG1X, "Cyan Technology eCOG1X family"), 850 ENUM_ENT(EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core microcontrollers"), 851 ENUM_ENT(EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor"), 852 ENUM_ENT(EM_MANIK, "M2000 Reconfigurable RISC Microprocessor"), 853 ENUM_ENT(EM_CRAYNV2, "Cray Inc. NV2 vector architecture"), 854 ENUM_ENT(EM_RX, "Renesas RX"), 855 ENUM_ENT(EM_METAG, "Imagination Technologies Meta processor architecture"), 856 ENUM_ENT(EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture"), 857 ENUM_ENT(EM_ECOG16, "Cyan Technology eCOG16 family"), 858 ENUM_ENT(EM_CR16, "Xilinx MicroBlaze"), 859 ENUM_ENT(EM_ETPU, "Freescale Extended Time Processing Unit"), 860 ENUM_ENT(EM_SLE9X, "Infineon Technologies SLE9X core"), 861 ENUM_ENT(EM_L10M, "EM_L10M"), 862 ENUM_ENT(EM_K10M, "EM_K10M"), 863 ENUM_ENT(EM_AARCH64, "AArch64"), 864 ENUM_ENT(EM_AVR32, "Atmel AVR 8-bit microcontroller"), 865 ENUM_ENT(EM_STM8, "STMicroeletronics STM8 8-bit microcontroller"), 866 ENUM_ENT(EM_TILE64, "Tilera TILE64 multicore architecture family"), 867 ENUM_ENT(EM_TILEPRO, "Tilera TILEPro multicore architecture family"), 868 ENUM_ENT(EM_CUDA, "NVIDIA CUDA architecture"), 869 ENUM_ENT(EM_TILEGX, "Tilera TILE-Gx multicore architecture family"), 870 ENUM_ENT(EM_CLOUDSHIELD, "EM_CLOUDSHIELD"), 871 ENUM_ENT(EM_COREA_1ST, "EM_COREA_1ST"), 872 ENUM_ENT(EM_COREA_2ND, "EM_COREA_2ND"), 873 ENUM_ENT(EM_ARC_COMPACT2, "EM_ARC_COMPACT2"), 874 ENUM_ENT(EM_OPEN8, "EM_OPEN8"), 875 ENUM_ENT(EM_RL78, "Renesas RL78"), 876 ENUM_ENT(EM_VIDEOCORE5, "Broadcom VideoCore V processor"), 877 ENUM_ENT(EM_78KOR, "EM_78KOR"), 878 ENUM_ENT(EM_56800EX, "EM_56800EX"), 879 ENUM_ENT(EM_AMDGPU, "EM_AMDGPU"), 880 ENUM_ENT(EM_WEBASSEMBLY, "EM_WEBASSEMBLY"), 881 ENUM_ENT(EM_LANAI, "EM_LANAI"), 882 }; 883 884 static const EnumEntry<unsigned> ElfSymbolBindings[] = { 885 {"Local", "LOCAL", ELF::STB_LOCAL}, 886 {"Global", "GLOBAL", ELF::STB_GLOBAL}, 887 {"Weak", "WEAK", ELF::STB_WEAK}, 888 {"Unique", "UNIQUE", ELF::STB_GNU_UNIQUE}}; 889 890 static const EnumEntry<unsigned> ElfSymbolVisibilities[] = { 891 {"DEFAULT", "DEFAULT", ELF::STV_DEFAULT}, 892 {"INTERNAL", "INTERNAL", ELF::STV_INTERNAL}, 893 {"HIDDEN", "HIDDEN", ELF::STV_HIDDEN}, 894 {"PROTECTED", "PROTECTED", ELF::STV_PROTECTED}}; 895 896 static const EnumEntry<unsigned> ElfSymbolTypes[] = { 897 {"None", "NOTYPE", ELF::STT_NOTYPE}, 898 {"Object", "OBJECT", ELF::STT_OBJECT}, 899 {"Function", "FUNC", ELF::STT_FUNC}, 900 {"Section", "SECTION", ELF::STT_SECTION}, 901 {"File", "FILE", ELF::STT_FILE}, 902 {"Common", "COMMON", ELF::STT_COMMON}, 903 {"TLS", "TLS", ELF::STT_TLS}, 904 {"GNU_IFunc", "IFUNC", ELF::STT_GNU_IFUNC}}; 905 906 static const EnumEntry<unsigned> AMDGPUSymbolTypes[] = { 907 { "AMDGPU_HSA_KERNEL", ELF::STT_AMDGPU_HSA_KERNEL }, 908 { "AMDGPU_HSA_INDIRECT_FUNCTION", ELF::STT_AMDGPU_HSA_INDIRECT_FUNCTION }, 909 { "AMDGPU_HSA_METADATA", ELF::STT_AMDGPU_HSA_METADATA } 910 }; 911 912 static const char *getElfSectionType(unsigned Arch, unsigned Type) { 913 switch (Arch) { 914 case ELF::EM_ARM: 915 switch (Type) { 916 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX); 917 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); 918 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES); 919 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); 920 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); 921 } 922 case ELF::EM_HEXAGON: 923 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); } 924 case ELF::EM_X86_64: 925 switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } 926 case ELF::EM_MIPS: 927 case ELF::EM_MIPS_RS3_LE: 928 switch (Type) { 929 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO); 930 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); 931 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS); 932 } 933 } 934 935 switch (Type) { 936 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL ); 937 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS ); 938 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB ); 939 LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB ); 940 LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA ); 941 LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH ); 942 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC ); 943 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE ); 944 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS ); 945 LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL ); 946 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB ); 947 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM ); 948 LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY ); 949 LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY ); 950 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY ); 951 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP ); 952 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX ); 953 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES ); 954 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH ); 955 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef ); 956 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed ); 957 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym ); 958 default: return ""; 959 } 960 } 961 962 static const char *getGroupType(uint32_t Flag) { 963 if (Flag & ELF::GRP_COMDAT) 964 return "COMDAT"; 965 else 966 return "(unknown)"; 967 } 968 969 static const EnumEntry<unsigned> ElfSectionFlags[] = { 970 ENUM_ENT(SHF_WRITE, "W"), 971 ENUM_ENT(SHF_ALLOC, "A"), 972 ENUM_ENT(SHF_EXCLUDE, "E"), 973 ENUM_ENT(SHF_EXECINSTR, "X"), 974 ENUM_ENT(SHF_MERGE, "M"), 975 ENUM_ENT(SHF_STRINGS, "S"), 976 ENUM_ENT(SHF_INFO_LINK, "I"), 977 ENUM_ENT(SHF_LINK_ORDER, "L"), 978 ENUM_ENT(SHF_OS_NONCONFORMING, "o"), 979 ENUM_ENT(SHF_GROUP, "G"), 980 ENUM_ENT(SHF_TLS, "T"), 981 ENUM_ENT_1(XCORE_SHF_CP_SECTION), 982 ENUM_ENT_1(XCORE_SHF_DP_SECTION), 983 }; 984 985 static const EnumEntry<unsigned> ElfAMDGPUSectionFlags[] = { 986 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_GLOBAL), 987 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_READONLY), 988 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_CODE), 989 LLVM_READOBJ_ENUM_ENT(ELF, SHF_AMDGPU_HSA_AGENT) 990 }; 991 992 static const EnumEntry<unsigned> ElfHexagonSectionFlags[] = { 993 LLVM_READOBJ_ENUM_ENT(ELF, SHF_HEX_GPREL) 994 }; 995 996 static const EnumEntry<unsigned> ElfMipsSectionFlags[] = { 997 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NODUPES), 998 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NAMES ), 999 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_LOCAL ), 1000 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP), 1001 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_GPREL ), 1002 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_MERGE ), 1003 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_ADDR ), 1004 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_STRING ) 1005 }; 1006 1007 static const EnumEntry<unsigned> ElfX86_64SectionFlags[] = { 1008 LLVM_READOBJ_ENUM_ENT(ELF, SHF_X86_64_LARGE) 1009 }; 1010 1011 static std::string getGNUFlags(uint64_t Flags) { 1012 std::string Str; 1013 for (auto Entry : ElfSectionFlags) { 1014 uint64_t Flag = Entry.Value & Flags; 1015 Flags &= ~Entry.Value; 1016 switch (Flag) { 1017 case ELF::SHF_WRITE: 1018 case ELF::SHF_ALLOC: 1019 case ELF::SHF_EXECINSTR: 1020 case ELF::SHF_MERGE: 1021 case ELF::SHF_STRINGS: 1022 case ELF::SHF_INFO_LINK: 1023 case ELF::SHF_LINK_ORDER: 1024 case ELF::SHF_OS_NONCONFORMING: 1025 case ELF::SHF_GROUP: 1026 case ELF::SHF_TLS: 1027 case ELF::SHF_EXCLUDE: 1028 Str += Entry.AltName; 1029 break; 1030 default: 1031 if (Flags & ELF::SHF_MASKOS) 1032 Str += "o"; 1033 else if (Flags & ELF::SHF_MASKPROC) 1034 Str += "p"; 1035 else if (Flag) 1036 Str += "x"; 1037 } 1038 } 1039 return Str; 1040 } 1041 1042 static const char *getElfSegmentType(unsigned Arch, unsigned Type) { 1043 // Check potentially overlapped processor-specific 1044 // program header type. 1045 switch (Arch) { 1046 case ELF::EM_AMDGPU: 1047 switch (Type) { 1048 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM); 1049 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT); 1050 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_READONLY_AGENT); 1051 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_CODE_AGENT); 1052 } 1053 case ELF::EM_ARM: 1054 switch (Type) { 1055 LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); 1056 } 1057 case ELF::EM_MIPS: 1058 case ELF::EM_MIPS_RS3_LE: 1059 switch (Type) { 1060 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO); 1061 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC); 1062 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS); 1063 LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_ABIFLAGS); 1064 } 1065 } 1066 1067 switch (Type) { 1068 LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL ); 1069 LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD ); 1070 LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC); 1071 LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP ); 1072 LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE ); 1073 LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB ); 1074 LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR ); 1075 LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS ); 1076 1077 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME); 1078 LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND); 1079 1080 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK); 1081 LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO); 1082 default: return ""; 1083 } 1084 } 1085 1086 static std::string getElfPtType(unsigned Arch, unsigned Type) { 1087 switch (Type) { 1088 case ELF::PT_NULL: 1089 return "NULL"; 1090 case ELF::PT_LOAD: 1091 return "LOAD"; 1092 case ELF::PT_DYNAMIC: 1093 return "DYNAMIC"; 1094 case ELF::PT_INTERP: 1095 return "INTERP"; 1096 case ELF::PT_NOTE: 1097 return "NOTE"; 1098 case ELF::PT_SHLIB: 1099 return "SHLIB"; 1100 case ELF::PT_PHDR: 1101 return "PHDR"; 1102 case ELF::PT_TLS: 1103 return "TLS"; 1104 case ELF::PT_GNU_EH_FRAME: 1105 return "GNU_EH_FRAME"; 1106 case ELF::PT_SUNW_UNWIND: 1107 return "SUNW_UNWIND"; 1108 case ELF::PT_GNU_STACK: 1109 return "GNU_STACK"; 1110 case ELF::PT_GNU_RELRO: 1111 return "GNU_RELRO"; 1112 default: 1113 // All machine specific PT_* types 1114 switch (Arch) { 1115 case ELF::EM_AMDGPU: 1116 switch (Type) { 1117 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_PROGRAM); 1118 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_GLOBAL_AGENT); 1119 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_READONLY_AGENT); 1120 LLVM_READOBJ_ENUM_CASE(ELF, PT_AMDGPU_HSA_LOAD_CODE_AGENT); 1121 } 1122 return ""; 1123 case ELF::EM_ARM: 1124 if (Type == ELF::PT_ARM_EXIDX) 1125 return "EXIDX"; 1126 return ""; 1127 case ELF::EM_MIPS: 1128 case ELF::EM_MIPS_RS3_LE: 1129 switch (Type) { 1130 case PT_MIPS_REGINFO: 1131 return "REGINFO"; 1132 case PT_MIPS_RTPROC: 1133 return "RTPROC"; 1134 case PT_MIPS_OPTIONS: 1135 return "OPTIONS"; 1136 case PT_MIPS_ABIFLAGS: 1137 return "ABIFLAGS"; 1138 } 1139 return ""; 1140 } 1141 } 1142 return std::string("<unknown>: ") + to_string(format_hex(Type, 1)); 1143 } 1144 1145 static const EnumEntry<unsigned> ElfSegmentFlags[] = { 1146 LLVM_READOBJ_ENUM_ENT(ELF, PF_X), 1147 LLVM_READOBJ_ENUM_ENT(ELF, PF_W), 1148 LLVM_READOBJ_ENUM_ENT(ELF, PF_R) 1149 }; 1150 1151 static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = { 1152 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER), 1153 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC), 1154 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC), 1155 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2), 1156 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE), 1157 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_FP64), 1158 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008), 1159 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32), 1160 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O64), 1161 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI32), 1162 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_EABI64), 1163 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_3900), 1164 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4010), 1165 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4100), 1166 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4650), 1167 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4120), 1168 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_4111), 1169 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_SB1), 1170 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON), 1171 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_XLR), 1172 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON2), 1173 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_OCTEON3), 1174 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5400), 1175 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5900), 1176 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_5500), 1177 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_9000), 1178 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2E), 1179 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS2F), 1180 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MACH_LS3A), 1181 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS), 1182 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16), 1183 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_MDMX), 1184 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1), 1185 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2), 1186 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3), 1187 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4), 1188 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5), 1189 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32), 1190 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64), 1191 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2), 1192 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2), 1193 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6), 1194 LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6) 1195 }; 1196 1197 static const EnumEntry<unsigned> ElfSymOtherFlags[] = { 1198 LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL), 1199 LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN), 1200 LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED) 1201 }; 1202 1203 static const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = { 1204 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL), 1205 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT), 1206 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC), 1207 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS) 1208 }; 1209 1210 static const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = { 1211 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL), 1212 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT), 1213 LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16) 1214 }; 1215 1216 template <typename ELFT> 1217 ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) 1218 : ObjDumper(Writer), Obj(Obj) { 1219 1220 SmallVector<const Elf_Phdr *, 4> LoadSegments; 1221 for (const Elf_Phdr &Phdr : Obj->program_headers()) { 1222 if (Phdr.p_type == ELF::PT_DYNAMIC) { 1223 DynamicTable = createDRIFrom(&Phdr, sizeof(Elf_Dyn)); 1224 continue; 1225 } 1226 if (Phdr.p_type != ELF::PT_LOAD || Phdr.p_filesz == 0) 1227 continue; 1228 LoadSegments.push_back(&Phdr); 1229 } 1230 1231 for (const Elf_Shdr &Sec : Obj->sections()) { 1232 switch (Sec.sh_type) { 1233 case ELF::SHT_SYMTAB: 1234 if (DotSymtabSec != nullptr) 1235 reportError("Multilpe SHT_SYMTAB"); 1236 DotSymtabSec = &Sec; 1237 break; 1238 case ELF::SHT_DYNSYM: 1239 if (DynSymRegion.Size) 1240 reportError("Multilpe SHT_DYNSYM"); 1241 DynSymRegion = createDRIFrom(&Sec); 1242 // This is only used (if Elf_Shdr present)for naming section in GNU style 1243 DynSymtabName = unwrapOrError(Obj->getSectionName(&Sec)); 1244 break; 1245 case ELF::SHT_SYMTAB_SHNDX: 1246 ShndxTable = unwrapOrError(Obj->getSHNDXTable(Sec)); 1247 break; 1248 case ELF::SHT_GNU_versym: 1249 if (dot_gnu_version_sec != nullptr) 1250 reportError("Multiple SHT_GNU_versym"); 1251 dot_gnu_version_sec = &Sec; 1252 break; 1253 case ELF::SHT_GNU_verdef: 1254 if (dot_gnu_version_d_sec != nullptr) 1255 reportError("Multiple SHT_GNU_verdef"); 1256 dot_gnu_version_d_sec = &Sec; 1257 break; 1258 case ELF::SHT_GNU_verneed: 1259 if (dot_gnu_version_r_sec != nullptr) 1260 reportError("Multilpe SHT_GNU_verneed"); 1261 dot_gnu_version_r_sec = &Sec; 1262 break; 1263 } 1264 } 1265 1266 parseDynamicTable(LoadSegments); 1267 1268 if (opts::Output == opts::GNU) 1269 ELFDumperStyle.reset(new GNUStyle<ELFT>(Writer, this)); 1270 else 1271 ELFDumperStyle.reset(new LLVMStyle<ELFT>(Writer, this)); 1272 } 1273 1274 template <typename ELFT> 1275 void ELFDumper<ELFT>::parseDynamicTable( 1276 ArrayRef<const Elf_Phdr *> LoadSegments) { 1277 auto toMappedAddr = [&](uint64_t VAddr) -> const uint8_t * { 1278 const Elf_Phdr *const *I = std::upper_bound( 1279 LoadSegments.begin(), LoadSegments.end(), VAddr, compareAddr<ELFT>); 1280 if (I == LoadSegments.begin()) 1281 report_fatal_error("Virtual address is not in any segment"); 1282 --I; 1283 const Elf_Phdr &Phdr = **I; 1284 uint64_t Delta = VAddr - Phdr.p_vaddr; 1285 if (Delta >= Phdr.p_filesz) 1286 report_fatal_error("Virtual address is not in any segment"); 1287 return Obj->base() + Phdr.p_offset + Delta; 1288 }; 1289 1290 uint64_t SONameOffset = 0; 1291 const char *StringTableBegin = nullptr; 1292 uint64_t StringTableSize = 0; 1293 for (const Elf_Dyn &Dyn : dynamic_table()) { 1294 switch (Dyn.d_tag) { 1295 case ELF::DT_HASH: 1296 HashTable = 1297 reinterpret_cast<const Elf_Hash *>(toMappedAddr(Dyn.getPtr())); 1298 break; 1299 case ELF::DT_GNU_HASH: 1300 GnuHashTable = 1301 reinterpret_cast<const Elf_GnuHash *>(toMappedAddr(Dyn.getPtr())); 1302 break; 1303 case ELF::DT_STRTAB: 1304 StringTableBegin = (const char *)toMappedAddr(Dyn.getPtr()); 1305 break; 1306 case ELF::DT_STRSZ: 1307 StringTableSize = Dyn.getVal(); 1308 break; 1309 case ELF::DT_SYMTAB: 1310 DynSymRegion.Addr = toMappedAddr(Dyn.getPtr()); 1311 DynSymRegion.EntSize = sizeof(Elf_Sym); 1312 break; 1313 case ELF::DT_RELA: 1314 DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr()); 1315 break; 1316 case ELF::DT_RELASZ: 1317 DynRelaRegion.Size = Dyn.getVal(); 1318 break; 1319 case ELF::DT_RELAENT: 1320 DynRelaRegion.EntSize = Dyn.getVal(); 1321 break; 1322 case ELF::DT_SONAME: 1323 SONameOffset = Dyn.getVal(); 1324 break; 1325 case ELF::DT_REL: 1326 DynRelRegion.Addr = toMappedAddr(Dyn.getPtr()); 1327 break; 1328 case ELF::DT_RELSZ: 1329 DynRelRegion.Size = Dyn.getVal(); 1330 break; 1331 case ELF::DT_RELENT: 1332 DynRelRegion.EntSize = Dyn.getVal(); 1333 break; 1334 case ELF::DT_PLTREL: 1335 if (Dyn.getVal() == DT_REL) 1336 DynPLTRelRegion.EntSize = sizeof(Elf_Rel); 1337 else if (Dyn.getVal() == DT_RELA) 1338 DynPLTRelRegion.EntSize = sizeof(Elf_Rela); 1339 else 1340 reportError(Twine("unknown DT_PLTREL value of ") + 1341 Twine((uint64_t)Dyn.getVal())); 1342 break; 1343 case ELF::DT_JMPREL: 1344 DynPLTRelRegion.Addr = toMappedAddr(Dyn.getPtr()); 1345 break; 1346 case ELF::DT_PLTRELSZ: 1347 DynPLTRelRegion.Size = Dyn.getVal(); 1348 break; 1349 } 1350 } 1351 if (StringTableBegin) 1352 DynamicStringTable = StringRef(StringTableBegin, StringTableSize); 1353 if (SONameOffset) 1354 SOName = getDynamicString(SONameOffset); 1355 } 1356 1357 template <typename ELFT> 1358 typename ELFDumper<ELFT>::Elf_Rel_Range ELFDumper<ELFT>::dyn_rels() const { 1359 return DynRelRegion.getAsRange<Elf_Rel>(); 1360 } 1361 1362 template <typename ELFT> 1363 typename ELFDumper<ELFT>::Elf_Rela_Range ELFDumper<ELFT>::dyn_relas() const { 1364 return DynRelaRegion.getAsRange<Elf_Rela>(); 1365 } 1366 1367 template<class ELFT> 1368 void ELFDumper<ELFT>::printFileHeaders() { 1369 ELFDumperStyle->printFileHeaders(Obj); 1370 } 1371 1372 template<class ELFT> 1373 void ELFDumper<ELFT>::printSections() { 1374 ELFDumperStyle->printSections(Obj); 1375 } 1376 1377 template<class ELFT> 1378 void ELFDumper<ELFT>::printRelocations() { 1379 ELFDumperStyle->printRelocations(Obj); 1380 } 1381 1382 template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() { 1383 ELFDumperStyle->printProgramHeaders(Obj); 1384 } 1385 1386 template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() { 1387 ELFDumperStyle->printDynamicRelocations(Obj); 1388 } 1389 1390 template<class ELFT> 1391 void ELFDumper<ELFT>::printSymbols() { 1392 ELFDumperStyle->printSymbols(Obj); 1393 } 1394 1395 template<class ELFT> 1396 void ELFDumper<ELFT>::printDynamicSymbols() { 1397 ELFDumperStyle->printDynamicSymbols(Obj); 1398 } 1399 1400 #define LLVM_READOBJ_TYPE_CASE(name) \ 1401 case DT_##name: return #name 1402 1403 static const char *getTypeString(uint64_t Type) { 1404 switch (Type) { 1405 LLVM_READOBJ_TYPE_CASE(BIND_NOW); 1406 LLVM_READOBJ_TYPE_CASE(DEBUG); 1407 LLVM_READOBJ_TYPE_CASE(FINI); 1408 LLVM_READOBJ_TYPE_CASE(FINI_ARRAY); 1409 LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ); 1410 LLVM_READOBJ_TYPE_CASE(FLAGS); 1411 LLVM_READOBJ_TYPE_CASE(FLAGS_1); 1412 LLVM_READOBJ_TYPE_CASE(HASH); 1413 LLVM_READOBJ_TYPE_CASE(INIT); 1414 LLVM_READOBJ_TYPE_CASE(INIT_ARRAY); 1415 LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ); 1416 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY); 1417 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ); 1418 LLVM_READOBJ_TYPE_CASE(JMPREL); 1419 LLVM_READOBJ_TYPE_CASE(NEEDED); 1420 LLVM_READOBJ_TYPE_CASE(NULL); 1421 LLVM_READOBJ_TYPE_CASE(PLTGOT); 1422 LLVM_READOBJ_TYPE_CASE(PLTREL); 1423 LLVM_READOBJ_TYPE_CASE(PLTRELSZ); 1424 LLVM_READOBJ_TYPE_CASE(REL); 1425 LLVM_READOBJ_TYPE_CASE(RELA); 1426 LLVM_READOBJ_TYPE_CASE(RELENT); 1427 LLVM_READOBJ_TYPE_CASE(RELSZ); 1428 LLVM_READOBJ_TYPE_CASE(RELAENT); 1429 LLVM_READOBJ_TYPE_CASE(RELASZ); 1430 LLVM_READOBJ_TYPE_CASE(RPATH); 1431 LLVM_READOBJ_TYPE_CASE(RUNPATH); 1432 LLVM_READOBJ_TYPE_CASE(SONAME); 1433 LLVM_READOBJ_TYPE_CASE(STRSZ); 1434 LLVM_READOBJ_TYPE_CASE(STRTAB); 1435 LLVM_READOBJ_TYPE_CASE(SYMBOLIC); 1436 LLVM_READOBJ_TYPE_CASE(SYMENT); 1437 LLVM_READOBJ_TYPE_CASE(SYMTAB); 1438 LLVM_READOBJ_TYPE_CASE(TEXTREL); 1439 LLVM_READOBJ_TYPE_CASE(VERDEF); 1440 LLVM_READOBJ_TYPE_CASE(VERDEFNUM); 1441 LLVM_READOBJ_TYPE_CASE(VERNEED); 1442 LLVM_READOBJ_TYPE_CASE(VERNEEDNUM); 1443 LLVM_READOBJ_TYPE_CASE(VERSYM); 1444 LLVM_READOBJ_TYPE_CASE(RELACOUNT); 1445 LLVM_READOBJ_TYPE_CASE(RELCOUNT); 1446 LLVM_READOBJ_TYPE_CASE(GNU_HASH); 1447 LLVM_READOBJ_TYPE_CASE(TLSDESC_PLT); 1448 LLVM_READOBJ_TYPE_CASE(TLSDESC_GOT); 1449 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION); 1450 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP_REL); 1451 LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS); 1452 LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS); 1453 LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO); 1454 LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO); 1455 LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO); 1456 LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM); 1457 LLVM_READOBJ_TYPE_CASE(MIPS_RLD_MAP); 1458 LLVM_READOBJ_TYPE_CASE(MIPS_PLTGOT); 1459 LLVM_READOBJ_TYPE_CASE(MIPS_OPTIONS); 1460 default: return "unknown"; 1461 } 1462 } 1463 1464 #undef LLVM_READOBJ_TYPE_CASE 1465 1466 #define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \ 1467 { #enum, prefix##_##enum } 1468 1469 static const EnumEntry<unsigned> ElfDynamicDTFlags[] = { 1470 LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN), 1471 LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC), 1472 LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL), 1473 LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW), 1474 LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS) 1475 }; 1476 1477 static const EnumEntry<unsigned> ElfDynamicDTFlags1[] = { 1478 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOW), 1479 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAL), 1480 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GROUP), 1481 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODELETE), 1482 LLVM_READOBJ_DT_FLAG_ENT(DF_1, LOADFLTR), 1483 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INITFIRST), 1484 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOOPEN), 1485 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ORIGIN), 1486 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DIRECT), 1487 LLVM_READOBJ_DT_FLAG_ENT(DF_1, TRANS), 1488 LLVM_READOBJ_DT_FLAG_ENT(DF_1, INTERPOSE), 1489 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODEFLIB), 1490 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODUMP), 1491 LLVM_READOBJ_DT_FLAG_ENT(DF_1, CONFALT), 1492 LLVM_READOBJ_DT_FLAG_ENT(DF_1, ENDFILTEE), 1493 LLVM_READOBJ_DT_FLAG_ENT(DF_1, DISPRELDNE), 1494 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NODIRECT), 1495 LLVM_READOBJ_DT_FLAG_ENT(DF_1, IGNMULDEF), 1496 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOKSYMS), 1497 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NOHDR), 1498 LLVM_READOBJ_DT_FLAG_ENT(DF_1, EDITED), 1499 LLVM_READOBJ_DT_FLAG_ENT(DF_1, NORELOC), 1500 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SYMINTPOSE), 1501 LLVM_READOBJ_DT_FLAG_ENT(DF_1, GLOBAUDIT), 1502 LLVM_READOBJ_DT_FLAG_ENT(DF_1, SINGLETON) 1503 }; 1504 1505 static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = { 1506 LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE), 1507 LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART), 1508 LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT), 1509 LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT), 1510 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE), 1511 LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY), 1512 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT), 1513 LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS), 1514 LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT), 1515 LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE), 1516 LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD), 1517 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART), 1518 LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED), 1519 LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD), 1520 LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF), 1521 LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE) 1522 }; 1523 1524 #undef LLVM_READOBJ_DT_FLAG_ENT 1525 1526 template <typename T, typename TFlag> 1527 void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) { 1528 typedef EnumEntry<TFlag> FlagEntry; 1529 typedef SmallVector<FlagEntry, 10> FlagVector; 1530 FlagVector SetFlags; 1531 1532 for (const auto &Flag : Flags) { 1533 if (Flag.Value == 0) 1534 continue; 1535 1536 if ((Value & Flag.Value) == Flag.Value) 1537 SetFlags.push_back(Flag); 1538 } 1539 1540 for (const auto &Flag : SetFlags) { 1541 OS << Flag.Name << " "; 1542 } 1543 } 1544 1545 template <class ELFT> 1546 StringRef ELFDumper<ELFT>::getDynamicString(uint64_t Value) const { 1547 if (Value >= DynamicStringTable.size()) 1548 reportError("Invalid dynamic string table reference"); 1549 return StringRef(DynamicStringTable.data() + Value); 1550 } 1551 1552 template <class ELFT> 1553 void ELFDumper<ELFT>::printValue(uint64_t Type, uint64_t Value) { 1554 raw_ostream &OS = W.getOStream(); 1555 switch (Type) { 1556 case DT_PLTREL: 1557 if (Value == DT_REL) { 1558 OS << "REL"; 1559 break; 1560 } else if (Value == DT_RELA) { 1561 OS << "RELA"; 1562 break; 1563 } 1564 // Fallthrough. 1565 case DT_PLTGOT: 1566 case DT_HASH: 1567 case DT_STRTAB: 1568 case DT_SYMTAB: 1569 case DT_RELA: 1570 case DT_INIT: 1571 case DT_FINI: 1572 case DT_REL: 1573 case DT_JMPREL: 1574 case DT_INIT_ARRAY: 1575 case DT_FINI_ARRAY: 1576 case DT_PREINIT_ARRAY: 1577 case DT_DEBUG: 1578 case DT_VERDEF: 1579 case DT_VERNEED: 1580 case DT_VERSYM: 1581 case DT_GNU_HASH: 1582 case DT_NULL: 1583 case DT_MIPS_BASE_ADDRESS: 1584 case DT_MIPS_GOTSYM: 1585 case DT_MIPS_RLD_MAP: 1586 case DT_MIPS_RLD_MAP_REL: 1587 case DT_MIPS_PLTGOT: 1588 case DT_MIPS_OPTIONS: 1589 OS << format("0x%" PRIX64, Value); 1590 break; 1591 case DT_RELACOUNT: 1592 case DT_RELCOUNT: 1593 case DT_VERDEFNUM: 1594 case DT_VERNEEDNUM: 1595 case DT_MIPS_RLD_VERSION: 1596 case DT_MIPS_LOCAL_GOTNO: 1597 case DT_MIPS_SYMTABNO: 1598 case DT_MIPS_UNREFEXTNO: 1599 OS << Value; 1600 break; 1601 case DT_PLTRELSZ: 1602 case DT_RELASZ: 1603 case DT_RELAENT: 1604 case DT_STRSZ: 1605 case DT_SYMENT: 1606 case DT_RELSZ: 1607 case DT_RELENT: 1608 case DT_INIT_ARRAYSZ: 1609 case DT_FINI_ARRAYSZ: 1610 case DT_PREINIT_ARRAYSZ: 1611 OS << Value << " (bytes)"; 1612 break; 1613 case DT_NEEDED: 1614 OS << "SharedLibrary (" << getDynamicString(Value) << ")"; 1615 break; 1616 case DT_SONAME: 1617 OS << "LibrarySoname (" << getDynamicString(Value) << ")"; 1618 break; 1619 case DT_RPATH: 1620 case DT_RUNPATH: 1621 OS << getDynamicString(Value); 1622 break; 1623 case DT_MIPS_FLAGS: 1624 printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS); 1625 break; 1626 case DT_FLAGS: 1627 printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS); 1628 break; 1629 case DT_FLAGS_1: 1630 printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS); 1631 break; 1632 default: 1633 OS << format("0x%" PRIX64, Value); 1634 break; 1635 } 1636 } 1637 1638 template<class ELFT> 1639 void ELFDumper<ELFT>::printUnwindInfo() { 1640 W.startLine() << "UnwindInfo not implemented.\n"; 1641 } 1642 1643 namespace { 1644 template <> void ELFDumper<ELFType<support::little, false>>::printUnwindInfo() { 1645 const unsigned Machine = Obj->getHeader()->e_machine; 1646 if (Machine == EM_ARM) { 1647 ARM::EHABI::PrinterContext<ELFType<support::little, false>> Ctx( 1648 W, Obj, DotSymtabSec); 1649 return Ctx.PrintUnwindInformation(); 1650 } 1651 W.startLine() << "UnwindInfo not implemented.\n"; 1652 } 1653 } 1654 1655 template<class ELFT> 1656 void ELFDumper<ELFT>::printDynamicTable() { 1657 auto I = dynamic_table().begin(); 1658 auto E = dynamic_table().end(); 1659 1660 if (I == E) 1661 return; 1662 1663 --E; 1664 while (I != E && E->getTag() == ELF::DT_NULL) 1665 --E; 1666 if (E->getTag() != ELF::DT_NULL) 1667 ++E; 1668 ++E; 1669 1670 ptrdiff_t Total = std::distance(I, E); 1671 if (Total == 0) 1672 return; 1673 1674 raw_ostream &OS = W.getOStream(); 1675 W.startLine() << "DynamicSection [ (" << Total << " entries)\n"; 1676 1677 bool Is64 = ELFT::Is64Bits; 1678 1679 W.startLine() 1680 << " Tag" << (Is64 ? " " : " ") << "Type" 1681 << " " << "Name/Value\n"; 1682 while (I != E) { 1683 const Elf_Dyn &Entry = *I; 1684 uintX_t Tag = Entry.getTag(); 1685 ++I; 1686 W.startLine() << " " << format_hex(Tag, Is64 ? 18 : 10, true) << " " 1687 << format("%-21s", getTypeString(Tag)); 1688 printValue(Tag, Entry.getVal()); 1689 OS << "\n"; 1690 } 1691 1692 W.startLine() << "]\n"; 1693 } 1694 1695 template<class ELFT> 1696 void ELFDumper<ELFT>::printNeededLibraries() { 1697 ListScope D(W, "NeededLibraries"); 1698 1699 typedef std::vector<StringRef> LibsTy; 1700 LibsTy Libs; 1701 1702 for (const auto &Entry : dynamic_table()) 1703 if (Entry.d_tag == ELF::DT_NEEDED) 1704 Libs.push_back(getDynamicString(Entry.d_un.d_val)); 1705 1706 std::stable_sort(Libs.begin(), Libs.end()); 1707 1708 for (const auto &L : Libs) { 1709 outs() << " " << L << "\n"; 1710 } 1711 } 1712 1713 1714 template <typename ELFT> 1715 void ELFDumper<ELFT>::printHashTable() { 1716 DictScope D(W, "HashTable"); 1717 if (!HashTable) 1718 return; 1719 W.printNumber("Num Buckets", HashTable->nbucket); 1720 W.printNumber("Num Chains", HashTable->nchain); 1721 W.printList("Buckets", HashTable->buckets()); 1722 W.printList("Chains", HashTable->chains()); 1723 } 1724 1725 template <typename ELFT> 1726 void ELFDumper<ELFT>::printGnuHashTable() { 1727 DictScope D(W, "GnuHashTable"); 1728 if (!GnuHashTable) 1729 return; 1730 W.printNumber("Num Buckets", GnuHashTable->nbuckets); 1731 W.printNumber("First Hashed Symbol Index", GnuHashTable->symndx); 1732 W.printNumber("Num Mask Words", GnuHashTable->maskwords); 1733 W.printNumber("Shift Count", GnuHashTable->shift2); 1734 W.printHexList("Bloom Filter", GnuHashTable->filter()); 1735 W.printList("Buckets", GnuHashTable->buckets()); 1736 Elf_Sym_Range Syms = dynamic_symbols(); 1737 unsigned NumSyms = std::distance(Syms.begin(), Syms.end()); 1738 if (!NumSyms) 1739 reportError("No dynamic symbol section"); 1740 W.printHexList("Values", GnuHashTable->values(NumSyms)); 1741 } 1742 1743 template <typename ELFT> void ELFDumper<ELFT>::printLoadName() { 1744 outs() << "LoadName: " << SOName << '\n'; 1745 } 1746 1747 template <class ELFT> 1748 void ELFDumper<ELFT>::printAttributes() { 1749 W.startLine() << "Attributes not implemented.\n"; 1750 } 1751 1752 namespace { 1753 template <> void ELFDumper<ELFType<support::little, false>>::printAttributes() { 1754 if (Obj->getHeader()->e_machine != EM_ARM) { 1755 W.startLine() << "Attributes not implemented.\n"; 1756 return; 1757 } 1758 1759 DictScope BA(W, "BuildAttributes"); 1760 for (const ELFO::Elf_Shdr &Sec : Obj->sections()) { 1761 if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES) 1762 continue; 1763 1764 ArrayRef<uint8_t> Contents = unwrapOrError(Obj->getSectionContents(&Sec)); 1765 if (Contents[0] != ARMBuildAttrs::Format_Version) { 1766 errs() << "unrecognised FormatVersion: 0x" << utohexstr(Contents[0]) 1767 << '\n'; 1768 continue; 1769 } 1770 1771 W.printHex("FormatVersion", Contents[0]); 1772 if (Contents.size() == 1) 1773 continue; 1774 1775 ARMAttributeParser(W).Parse(Contents); 1776 } 1777 } 1778 } 1779 1780 namespace { 1781 template <class ELFT> class MipsGOTParser { 1782 public: 1783 typedef object::ELFFile<ELFT> ELFO; 1784 typedef typename ELFO::Elf_Shdr Elf_Shdr; 1785 typedef typename ELFO::Elf_Sym Elf_Sym; 1786 typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range; 1787 typedef typename ELFO::Elf_Addr GOTEntry; 1788 typedef typename ELFO::Elf_Rel Elf_Rel; 1789 typedef typename ELFO::Elf_Rela Elf_Rela; 1790 1791 MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj, 1792 Elf_Dyn_Range DynTable, StreamWriter &W); 1793 1794 void parseGOT(); 1795 void parsePLT(); 1796 1797 private: 1798 ELFDumper<ELFT> *Dumper; 1799 const ELFO *Obj; 1800 StreamWriter &W; 1801 llvm::Optional<uint64_t> DtPltGot; 1802 llvm::Optional<uint64_t> DtLocalGotNum; 1803 llvm::Optional<uint64_t> DtGotSym; 1804 llvm::Optional<uint64_t> DtMipsPltGot; 1805 llvm::Optional<uint64_t> DtJmpRel; 1806 1807 std::size_t getGOTTotal(ArrayRef<uint8_t> GOT) const; 1808 const GOTEntry *makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum); 1809 1810 void printGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt, 1811 const GOTEntry *It); 1812 void printGlobalGotEntry(uint64_t GotAddr, const GOTEntry *BeginIt, 1813 const GOTEntry *It, const Elf_Sym *Sym, 1814 StringRef StrTable, bool IsDynamic); 1815 void printPLTEntry(uint64_t PLTAddr, const GOTEntry *BeginIt, 1816 const GOTEntry *It, StringRef Purpose); 1817 void printPLTEntry(uint64_t PLTAddr, const GOTEntry *BeginIt, 1818 const GOTEntry *It, StringRef StrTable, 1819 const Elf_Sym *Sym); 1820 }; 1821 } 1822 1823 template <class ELFT> 1824 MipsGOTParser<ELFT>::MipsGOTParser(ELFDumper<ELFT> *Dumper, const ELFO *Obj, 1825 Elf_Dyn_Range DynTable, StreamWriter &W) 1826 : Dumper(Dumper), Obj(Obj), W(W) { 1827 for (const auto &Entry : DynTable) { 1828 switch (Entry.getTag()) { 1829 case ELF::DT_PLTGOT: 1830 DtPltGot = Entry.getVal(); 1831 break; 1832 case ELF::DT_MIPS_LOCAL_GOTNO: 1833 DtLocalGotNum = Entry.getVal(); 1834 break; 1835 case ELF::DT_MIPS_GOTSYM: 1836 DtGotSym = Entry.getVal(); 1837 break; 1838 case ELF::DT_MIPS_PLTGOT: 1839 DtMipsPltGot = Entry.getVal(); 1840 break; 1841 case ELF::DT_JMPREL: 1842 DtJmpRel = Entry.getVal(); 1843 break; 1844 } 1845 } 1846 } 1847 1848 template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() { 1849 // See "Global Offset Table" in Chapter 5 in the following document 1850 // for detailed GOT description. 1851 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf 1852 if (!DtPltGot) { 1853 W.startLine() << "Cannot find PLTGOT dynamic table tag.\n"; 1854 return; 1855 } 1856 if (!DtLocalGotNum) { 1857 W.startLine() << "Cannot find MIPS_LOCAL_GOTNO dynamic table tag.\n"; 1858 return; 1859 } 1860 if (!DtGotSym) { 1861 W.startLine() << "Cannot find MIPS_GOTSYM dynamic table tag.\n"; 1862 return; 1863 } 1864 1865 StringRef StrTable = Dumper->getDynamicStringTable(); 1866 const Elf_Sym *DynSymBegin = Dumper->dynamic_symbols().begin(); 1867 const Elf_Sym *DynSymEnd = Dumper->dynamic_symbols().end(); 1868 std::size_t DynSymTotal = std::size_t(std::distance(DynSymBegin, DynSymEnd)); 1869 1870 if (*DtGotSym > DynSymTotal) 1871 report_fatal_error("MIPS_GOTSYM exceeds a number of dynamic symbols"); 1872 1873 std::size_t GlobalGotNum = DynSymTotal - *DtGotSym; 1874 1875 if (*DtLocalGotNum + GlobalGotNum == 0) { 1876 W.startLine() << "GOT is empty.\n"; 1877 return; 1878 } 1879 1880 const Elf_Shdr *GOTShdr = findNotEmptySectionByAddress(Obj, *DtPltGot); 1881 if (!GOTShdr) 1882 report_fatal_error("There is no not empty GOT section at 0x" + 1883 Twine::utohexstr(*DtPltGot)); 1884 1885 ArrayRef<uint8_t> GOT = unwrapOrError(Obj->getSectionContents(GOTShdr)); 1886 1887 if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(GOT)) 1888 report_fatal_error("Number of GOT entries exceeds the size of GOT section"); 1889 1890 const GOTEntry *GotBegin = makeGOTIter(GOT, 0); 1891 const GOTEntry *GotLocalEnd = makeGOTIter(GOT, *DtLocalGotNum); 1892 const GOTEntry *It = GotBegin; 1893 1894 DictScope GS(W, "Primary GOT"); 1895 1896 W.printHex("Canonical gp value", GOTShdr->sh_addr + 0x7ff0); 1897 { 1898 ListScope RS(W, "Reserved entries"); 1899 1900 { 1901 DictScope D(W, "Entry"); 1902 printGotEntry(GOTShdr->sh_addr, GotBegin, It++); 1903 W.printString("Purpose", StringRef("Lazy resolver")); 1904 } 1905 1906 if (It != GotLocalEnd && (*It >> (sizeof(GOTEntry) * 8 - 1)) != 0) { 1907 DictScope D(W, "Entry"); 1908 printGotEntry(GOTShdr->sh_addr, GotBegin, It++); 1909 W.printString("Purpose", StringRef("Module pointer (GNU extension)")); 1910 } 1911 } 1912 { 1913 ListScope LS(W, "Local entries"); 1914 for (; It != GotLocalEnd; ++It) { 1915 DictScope D(W, "Entry"); 1916 printGotEntry(GOTShdr->sh_addr, GotBegin, It); 1917 } 1918 } 1919 { 1920 ListScope GS(W, "Global entries"); 1921 1922 const GOTEntry *GotGlobalEnd = 1923 makeGOTIter(GOT, *DtLocalGotNum + GlobalGotNum); 1924 const Elf_Sym *GotDynSym = DynSymBegin + *DtGotSym; 1925 for (; It != GotGlobalEnd; ++It) { 1926 DictScope D(W, "Entry"); 1927 printGlobalGotEntry(GOTShdr->sh_addr, GotBegin, It, GotDynSym++, StrTable, 1928 true); 1929 } 1930 } 1931 1932 std::size_t SpecGotNum = getGOTTotal(GOT) - *DtLocalGotNum - GlobalGotNum; 1933 W.printNumber("Number of TLS and multi-GOT entries", uint64_t(SpecGotNum)); 1934 } 1935 1936 template <class ELFT> void MipsGOTParser<ELFT>::parsePLT() { 1937 if (!DtMipsPltGot) { 1938 W.startLine() << "Cannot find MIPS_PLTGOT dynamic table tag.\n"; 1939 return; 1940 } 1941 if (!DtJmpRel) { 1942 W.startLine() << "Cannot find JMPREL dynamic table tag.\n"; 1943 return; 1944 } 1945 1946 const Elf_Shdr *PLTShdr = findNotEmptySectionByAddress(Obj, *DtMipsPltGot); 1947 if (!PLTShdr) 1948 report_fatal_error("There is no not empty PLTGOT section at 0x " + 1949 Twine::utohexstr(*DtMipsPltGot)); 1950 ArrayRef<uint8_t> PLT = unwrapOrError(Obj->getSectionContents(PLTShdr)); 1951 1952 const Elf_Shdr *PLTRelShdr = findNotEmptySectionByAddress(Obj, *DtJmpRel); 1953 if (!PLTRelShdr) 1954 report_fatal_error("There is no not empty RELPLT section at 0x" + 1955 Twine::utohexstr(*DtJmpRel)); 1956 const Elf_Shdr *SymTable = 1957 unwrapOrError(Obj->getSection(PLTRelShdr->sh_link)); 1958 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTable)); 1959 1960 const GOTEntry *PLTBegin = makeGOTIter(PLT, 0); 1961 const GOTEntry *PLTEnd = makeGOTIter(PLT, getGOTTotal(PLT)); 1962 const GOTEntry *It = PLTBegin; 1963 1964 DictScope GS(W, "PLT GOT"); 1965 { 1966 ListScope RS(W, "Reserved entries"); 1967 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It++, "PLT lazy resolver"); 1968 if (It != PLTEnd) 1969 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It++, "Module pointer"); 1970 } 1971 { 1972 ListScope GS(W, "Entries"); 1973 1974 switch (PLTRelShdr->sh_type) { 1975 case ELF::SHT_REL: 1976 for (const Elf_Rel *RI = Obj->rel_begin(PLTRelShdr), 1977 *RE = Obj->rel_end(PLTRelShdr); 1978 RI != RE && It != PLTEnd; ++RI, ++It) { 1979 const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable); 1980 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym); 1981 } 1982 break; 1983 case ELF::SHT_RELA: 1984 for (const Elf_Rela *RI = Obj->rela_begin(PLTRelShdr), 1985 *RE = Obj->rela_end(PLTRelShdr); 1986 RI != RE && It != PLTEnd; ++RI, ++It) { 1987 const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable); 1988 printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym); 1989 } 1990 break; 1991 } 1992 } 1993 } 1994 1995 template <class ELFT> 1996 std::size_t MipsGOTParser<ELFT>::getGOTTotal(ArrayRef<uint8_t> GOT) const { 1997 return GOT.size() / sizeof(GOTEntry); 1998 } 1999 2000 template <class ELFT> 2001 const typename MipsGOTParser<ELFT>::GOTEntry * 2002 MipsGOTParser<ELFT>::makeGOTIter(ArrayRef<uint8_t> GOT, std::size_t EntryNum) { 2003 const char *Data = reinterpret_cast<const char *>(GOT.data()); 2004 return reinterpret_cast<const GOTEntry *>(Data + EntryNum * sizeof(GOTEntry)); 2005 } 2006 2007 template <class ELFT> 2008 void MipsGOTParser<ELFT>::printGotEntry(uint64_t GotAddr, 2009 const GOTEntry *BeginIt, 2010 const GOTEntry *It) { 2011 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry); 2012 W.printHex("Address", GotAddr + Offset); 2013 W.printNumber("Access", Offset - 0x7ff0); 2014 W.printHex("Initial", *It); 2015 } 2016 2017 template <class ELFT> 2018 void MipsGOTParser<ELFT>::printGlobalGotEntry( 2019 uint64_t GotAddr, const GOTEntry *BeginIt, const GOTEntry *It, 2020 const Elf_Sym *Sym, StringRef StrTable, bool IsDynamic) { 2021 printGotEntry(GotAddr, BeginIt, It); 2022 2023 W.printHex("Value", Sym->st_value); 2024 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes)); 2025 2026 unsigned SectionIndex = 0; 2027 StringRef SectionName; 2028 getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(), 2029 Dumper->getShndxTable(), SectionName, SectionIndex); 2030 W.printHex("Section", SectionName, SectionIndex); 2031 2032 std::string FullSymbolName = 2033 Dumper->getFullSymbolName(Sym, StrTable, IsDynamic); 2034 W.printNumber("Name", FullSymbolName, Sym->st_name); 2035 } 2036 2037 template <class ELFT> 2038 void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr, 2039 const GOTEntry *BeginIt, 2040 const GOTEntry *It, StringRef Purpose) { 2041 DictScope D(W, "Entry"); 2042 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry); 2043 W.printHex("Address", PLTAddr + Offset); 2044 W.printHex("Initial", *It); 2045 W.printString("Purpose", Purpose); 2046 } 2047 2048 template <class ELFT> 2049 void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr, 2050 const GOTEntry *BeginIt, 2051 const GOTEntry *It, StringRef StrTable, 2052 const Elf_Sym *Sym) { 2053 DictScope D(W, "Entry"); 2054 int64_t Offset = std::distance(BeginIt, It) * sizeof(GOTEntry); 2055 W.printHex("Address", PLTAddr + Offset); 2056 W.printHex("Initial", *It); 2057 W.printHex("Value", Sym->st_value); 2058 W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes)); 2059 2060 unsigned SectionIndex = 0; 2061 StringRef SectionName; 2062 getSectionNameIndex(*Obj, Sym, Dumper->dynamic_symbols().begin(), 2063 Dumper->getShndxTable(), SectionName, SectionIndex); 2064 W.printHex("Section", SectionName, SectionIndex); 2065 2066 std::string FullSymbolName = Dumper->getFullSymbolName(Sym, StrTable, true); 2067 W.printNumber("Name", FullSymbolName, Sym->st_name); 2068 } 2069 2070 template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() { 2071 if (Obj->getHeader()->e_machine != EM_MIPS) { 2072 W.startLine() << "MIPS PLT GOT is available for MIPS targets only.\n"; 2073 return; 2074 } 2075 2076 MipsGOTParser<ELFT> GOTParser(this, Obj, dynamic_table(), W); 2077 GOTParser.parseGOT(); 2078 GOTParser.parsePLT(); 2079 } 2080 2081 static const EnumEntry<unsigned> ElfMipsISAExtType[] = { 2082 {"None", Mips::AFL_EXT_NONE}, 2083 {"Broadcom SB-1", Mips::AFL_EXT_SB1}, 2084 {"Cavium Networks Octeon", Mips::AFL_EXT_OCTEON}, 2085 {"Cavium Networks Octeon2", Mips::AFL_EXT_OCTEON2}, 2086 {"Cavium Networks OcteonP", Mips::AFL_EXT_OCTEONP}, 2087 {"Cavium Networks Octeon3", Mips::AFL_EXT_OCTEON3}, 2088 {"LSI R4010", Mips::AFL_EXT_4010}, 2089 {"Loongson 2E", Mips::AFL_EXT_LOONGSON_2E}, 2090 {"Loongson 2F", Mips::AFL_EXT_LOONGSON_2F}, 2091 {"Loongson 3A", Mips::AFL_EXT_LOONGSON_3A}, 2092 {"MIPS R4650", Mips::AFL_EXT_4650}, 2093 {"MIPS R5900", Mips::AFL_EXT_5900}, 2094 {"MIPS R10000", Mips::AFL_EXT_10000}, 2095 {"NEC VR4100", Mips::AFL_EXT_4100}, 2096 {"NEC VR4111/VR4181", Mips::AFL_EXT_4111}, 2097 {"NEC VR4120", Mips::AFL_EXT_4120}, 2098 {"NEC VR5400", Mips::AFL_EXT_5400}, 2099 {"NEC VR5500", Mips::AFL_EXT_5500}, 2100 {"RMI Xlr", Mips::AFL_EXT_XLR}, 2101 {"Toshiba R3900", Mips::AFL_EXT_3900} 2102 }; 2103 2104 static const EnumEntry<unsigned> ElfMipsASEFlags[] = { 2105 {"DSP", Mips::AFL_ASE_DSP}, 2106 {"DSPR2", Mips::AFL_ASE_DSPR2}, 2107 {"Enhanced VA Scheme", Mips::AFL_ASE_EVA}, 2108 {"MCU", Mips::AFL_ASE_MCU}, 2109 {"MDMX", Mips::AFL_ASE_MDMX}, 2110 {"MIPS-3D", Mips::AFL_ASE_MIPS3D}, 2111 {"MT", Mips::AFL_ASE_MT}, 2112 {"SmartMIPS", Mips::AFL_ASE_SMARTMIPS}, 2113 {"VZ", Mips::AFL_ASE_VIRT}, 2114 {"MSA", Mips::AFL_ASE_MSA}, 2115 {"MIPS16", Mips::AFL_ASE_MIPS16}, 2116 {"microMIPS", Mips::AFL_ASE_MICROMIPS}, 2117 {"XPA", Mips::AFL_ASE_XPA} 2118 }; 2119 2120 static const EnumEntry<unsigned> ElfMipsFpABIType[] = { 2121 {"Hard or soft float", Mips::Val_GNU_MIPS_ABI_FP_ANY}, 2122 {"Hard float (double precision)", Mips::Val_GNU_MIPS_ABI_FP_DOUBLE}, 2123 {"Hard float (single precision)", Mips::Val_GNU_MIPS_ABI_FP_SINGLE}, 2124 {"Soft float", Mips::Val_GNU_MIPS_ABI_FP_SOFT}, 2125 {"Hard float (MIPS32r2 64-bit FPU 12 callee-saved)", 2126 Mips::Val_GNU_MIPS_ABI_FP_OLD_64}, 2127 {"Hard float (32-bit CPU, Any FPU)", Mips::Val_GNU_MIPS_ABI_FP_XX}, 2128 {"Hard float (32-bit CPU, 64-bit FPU)", Mips::Val_GNU_MIPS_ABI_FP_64}, 2129 {"Hard float compat (32-bit CPU, 64-bit FPU)", 2130 Mips::Val_GNU_MIPS_ABI_FP_64A} 2131 }; 2132 2133 static const EnumEntry<unsigned> ElfMipsFlags1[] { 2134 {"ODDSPREG", Mips::AFL_FLAGS1_ODDSPREG}, 2135 }; 2136 2137 static int getMipsRegisterSize(uint8_t Flag) { 2138 switch (Flag) { 2139 case Mips::AFL_REG_NONE: 2140 return 0; 2141 case Mips::AFL_REG_32: 2142 return 32; 2143 case Mips::AFL_REG_64: 2144 return 64; 2145 case Mips::AFL_REG_128: 2146 return 128; 2147 default: 2148 return -1; 2149 } 2150 } 2151 2152 template <class ELFT> void ELFDumper<ELFT>::printMipsABIFlags() { 2153 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".MIPS.abiflags"); 2154 if (!Shdr) { 2155 W.startLine() << "There is no .MIPS.abiflags section in the file.\n"; 2156 return; 2157 } 2158 ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr)); 2159 if (Sec.size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) { 2160 W.startLine() << "The .MIPS.abiflags section has a wrong size.\n"; 2161 return; 2162 } 2163 2164 auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec.data()); 2165 2166 raw_ostream &OS = W.getOStream(); 2167 DictScope GS(W, "MIPS ABI Flags"); 2168 2169 W.printNumber("Version", Flags->version); 2170 W.startLine() << "ISA: "; 2171 if (Flags->isa_rev <= 1) 2172 OS << format("MIPS%u", Flags->isa_level); 2173 else 2174 OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev); 2175 OS << "\n"; 2176 W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType)); 2177 W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags)); 2178 W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType)); 2179 W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size)); 2180 W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size)); 2181 W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size)); 2182 W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1)); 2183 W.printHex("Flags 2", Flags->flags2); 2184 } 2185 2186 template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() { 2187 const Elf_Shdr *Shdr = findSectionByName(*Obj, ".reginfo"); 2188 if (!Shdr) { 2189 W.startLine() << "There is no .reginfo section in the file.\n"; 2190 return; 2191 } 2192 ArrayRef<uint8_t> Sec = unwrapOrError(Obj->getSectionContents(Shdr)); 2193 if (Sec.size() != sizeof(Elf_Mips_RegInfo<ELFT>)) { 2194 W.startLine() << "The .reginfo section has a wrong size.\n"; 2195 return; 2196 } 2197 2198 auto *Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(Sec.data()); 2199 2200 DictScope GS(W, "MIPS RegInfo"); 2201 W.printHex("GP", Reginfo->ri_gp_value); 2202 W.printHex("General Mask", Reginfo->ri_gprmask); 2203 W.printHex("Co-Proc Mask0", Reginfo->ri_cprmask[0]); 2204 W.printHex("Co-Proc Mask1", Reginfo->ri_cprmask[1]); 2205 W.printHex("Co-Proc Mask2", Reginfo->ri_cprmask[2]); 2206 W.printHex("Co-Proc Mask3", Reginfo->ri_cprmask[3]); 2207 } 2208 2209 template <class ELFT> void ELFDumper<ELFT>::printStackMap() const { 2210 const Elf_Shdr *StackMapSection = nullptr; 2211 for (const auto &Sec : Obj->sections()) { 2212 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); 2213 if (Name == ".llvm_stackmaps") { 2214 StackMapSection = &Sec; 2215 break; 2216 } 2217 } 2218 2219 if (!StackMapSection) 2220 return; 2221 2222 StringRef StackMapContents; 2223 ArrayRef<uint8_t> StackMapContentsArray = 2224 unwrapOrError(Obj->getSectionContents(StackMapSection)); 2225 2226 prettyPrintStackMap(llvm::outs(), StackMapV1Parser<ELFT::TargetEndianness>( 2227 StackMapContentsArray)); 2228 } 2229 2230 template <class ELFT> void ELFDumper<ELFT>::printGroupSections() { 2231 ELFDumperStyle->printGroupSections(Obj); 2232 } 2233 2234 static inline void printFields(formatted_raw_ostream &OS, StringRef Str1, 2235 StringRef Str2) { 2236 OS.PadToColumn(2u); 2237 OS << Str1; 2238 OS.PadToColumn(37u); 2239 OS << Str2 << "\n"; 2240 OS.flush(); 2241 } 2242 2243 template <class ELFT> void GNUStyle<ELFT>::printFileHeaders(const ELFO *Obj) { 2244 const Elf_Ehdr *e = Obj->getHeader(); 2245 OS << "ELF Header:\n"; 2246 OS << " Magic: "; 2247 std::string Str; 2248 for (int i = 0; i < ELF::EI_NIDENT; i++) 2249 OS << format(" %02x", static_cast<int>(e->e_ident[i])); 2250 OS << "\n"; 2251 Str = printEnum(e->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass)); 2252 printFields(OS, "Class:", Str); 2253 Str = printEnum(e->e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding)); 2254 printFields(OS, "Data:", Str); 2255 OS.PadToColumn(2u); 2256 OS << "Version:"; 2257 OS.PadToColumn(37u); 2258 OS << to_hexString(e->e_ident[ELF::EI_VERSION]); 2259 if (e->e_version == ELF::EV_CURRENT) 2260 OS << " (current)"; 2261 OS << "\n"; 2262 Str = printEnum(e->e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI)); 2263 printFields(OS, "OS/ABI:", Str); 2264 Str = "0x" + to_hexString(e->e_version); 2265 Str = to_hexString(e->e_ident[ELF::EI_ABIVERSION]); 2266 printFields(OS, "ABI Version:", Str); 2267 Str = printEnum(e->e_type, makeArrayRef(ElfObjectFileType)); 2268 printFields(OS, "Type:", Str); 2269 Str = printEnum(e->e_machine, makeArrayRef(ElfMachineType)); 2270 printFields(OS, "Machine:", Str); 2271 Str = "0x" + to_hexString(e->e_version); 2272 printFields(OS, "Version:", Str); 2273 Str = "0x" + to_hexString(e->e_entry); 2274 printFields(OS, "Entry point address:", Str); 2275 Str = to_string(e->e_phoff) + " (bytes into file)"; 2276 printFields(OS, "Start of program headers:", Str); 2277 Str = to_string(e->e_shoff) + " (bytes into file)"; 2278 printFields(OS, "Start of section headers:", Str); 2279 Str = "0x" + to_hexString(e->e_flags); 2280 printFields(OS, "Flags:", Str); 2281 Str = to_string(e->e_ehsize) + " (bytes)"; 2282 printFields(OS, "Size of this header:", Str); 2283 Str = to_string(e->e_phentsize) + " (bytes)"; 2284 printFields(OS, "Size of program headers:", Str); 2285 Str = to_string(e->e_phnum); 2286 printFields(OS, "Number of program headers:", Str); 2287 Str = to_string(e->e_shentsize) + " (bytes)"; 2288 printFields(OS, "Size of section headers:", Str); 2289 Str = to_string(e->e_shnum); 2290 printFields(OS, "Number of section headers:", Str); 2291 Str = to_string(e->e_shstrndx); 2292 printFields(OS, "Section header string table index:", Str); 2293 } 2294 2295 template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) { 2296 uint32_t SectionIndex = 0; 2297 bool HasGroups = false; 2298 for (const Elf_Shdr &Sec : Obj->sections()) { 2299 if (Sec.sh_type == ELF::SHT_GROUP) { 2300 HasGroups = true; 2301 const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link)); 2302 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab)); 2303 const Elf_Sym *Signature = 2304 Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info); 2305 ArrayRef<Elf_Word> Data = unwrapOrError( 2306 Obj->template getSectionContentsAsArray<Elf_Word>(&Sec)); 2307 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); 2308 OS << "\n" << getGroupType(Data[0]) << " group section [" 2309 << format_decimal(SectionIndex, 5) << "] `" << Name << "' [" 2310 << StrTable.data() + Signature->st_name << "] contains " 2311 << (Data.size() - 1) << " sections:\n" 2312 << " [Index] Name\n"; 2313 for (auto &Ndx : Data.slice(1)) { 2314 auto Sec = unwrapOrError(Obj->getSection(Ndx)); 2315 const StringRef Name = unwrapOrError(Obj->getSectionName(Sec)); 2316 OS << " [" << format_decimal(Ndx, 5) << "] " << Name 2317 << "\n"; 2318 } 2319 } 2320 ++SectionIndex; 2321 } 2322 if (!HasGroups) 2323 OS << "There are no section groups in this file.\n"; 2324 } 2325 2326 template <class ELFT> 2327 void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab, 2328 const Elf_Rela &R, bool IsRela) { 2329 std::string Offset, Info, Addend = "", Value; 2330 SmallString<32> RelocName; 2331 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab)); 2332 StringRef TargetName; 2333 const Elf_Sym *Sym = nullptr; 2334 unsigned Bias; 2335 unsigned Width; 2336 2337 if (ELFT::Is64Bits) { 2338 Bias = 8; 2339 Width = 16; 2340 } else { 2341 Bias = 0; 2342 Width = 8; 2343 } 2344 2345 // First two fields are bit width dependent. The rest of them are after are 2346 // fixed width. 2347 Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias}; 2348 Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName); 2349 Sym = Obj->getRelocationSymbol(&R, SymTab); 2350 if (Sym && Sym->getType() == ELF::STT_SECTION) { 2351 const Elf_Shdr *Sec = unwrapOrError( 2352 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable())); 2353 TargetName = unwrapOrError(Obj->getSectionName(Sec)); 2354 } else if (Sym) { 2355 TargetName = unwrapOrError(Sym->getName(StrTable)); 2356 } 2357 2358 if (Sym && IsRela) { 2359 if (R.r_addend < 0) 2360 Addend = " - "; 2361 else 2362 Addend = " + "; 2363 } 2364 2365 Offset = to_string(format_hex_no_prefix(R.r_offset, Width)); 2366 Info = to_string(format_hex_no_prefix(R.r_info, Width)); 2367 2368 int64_t RelAddend = R.r_addend; 2369 if (IsRela) 2370 Addend += to_hexString(std::abs(RelAddend), false); 2371 2372 if (Sym) 2373 Value = to_string(format_hex_no_prefix(Sym->getValue(), Width)); 2374 2375 Fields[0].Str = Offset; 2376 Fields[1].Str = Info; 2377 Fields[2].Str = RelocName; 2378 Fields[3].Str = Value; 2379 Fields[4].Str = TargetName; 2380 for (auto &field : Fields) 2381 printField(field); 2382 if (IsRela) 2383 OS << Addend; 2384 OS << "\n"; 2385 } 2386 2387 template <class ELFT> void GNUStyle<ELFT>::printRelocations(const ELFO *Obj) { 2388 bool HasRelocSections = false; 2389 for (const Elf_Shdr &Sec : Obj->sections()) { 2390 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA) 2391 continue; 2392 HasRelocSections = true; 2393 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); 2394 unsigned Entries = Sec.getEntityCount(); 2395 uintX_t Offset = Sec.sh_offset; 2396 OS << "\nRelocation section '" << Name << "' at offset 0x" 2397 << to_hexString(Offset, false) << " contains " << Entries 2398 << " entries:\n"; 2399 if (ELFT::Is64Bits) 2400 OS << " Offset Info Type" 2401 << " Symbol's Value Symbol's Name"; 2402 else 2403 OS << " Offset Info Type Sym. Value " 2404 << "Symbol's Name"; 2405 OS << ((Sec.sh_type == ELF::SHT_RELA) ? " + Addend" : "") << "\n"; 2406 2407 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec.sh_link)); 2408 if (Sec.sh_type == ELF::SHT_REL) { 2409 for (const auto &R : Obj->rels(&Sec)) { 2410 Elf_Rela Rela; 2411 Rela.r_offset = R.r_offset; 2412 Rela.r_info = R.r_info; 2413 Rela.r_addend = 0; 2414 printRelocation(Obj, SymTab, Rela, false); 2415 } 2416 } else { 2417 for (const auto &R : Obj->relas(&Sec)) 2418 printRelocation(Obj, SymTab, R, true); 2419 } 2420 } 2421 if (!HasRelocSections) 2422 OS << "\nThere are no relocations in this file.\n"; 2423 } 2424 2425 std::string getSectionTypeString(unsigned Arch, unsigned Type) { 2426 using namespace ELF; 2427 switch (Arch) { 2428 case EM_ARM: 2429 switch (Type) { 2430 case SHT_ARM_EXIDX: 2431 return "ARM_EXIDX"; 2432 case SHT_ARM_PREEMPTMAP: 2433 return "ARM_PREEMPTMAP"; 2434 case SHT_ARM_ATTRIBUTES: 2435 return "ARM_ATTRIBUTES"; 2436 case SHT_ARM_DEBUGOVERLAY: 2437 return "ARM_DEBUGOVERLAY"; 2438 case SHT_ARM_OVERLAYSECTION: 2439 return "ARM_OVERLAYSECTION"; 2440 } 2441 case EM_X86_64: 2442 switch (Type) { 2443 case SHT_X86_64_UNWIND: 2444 return "X86_64_UNWIND"; 2445 } 2446 case EM_MIPS: 2447 case EM_MIPS_RS3_LE: 2448 switch (Type) { 2449 case SHT_MIPS_REGINFO: 2450 return "MIPS_REGINFO"; 2451 case SHT_MIPS_OPTIONS: 2452 return "MIPS_OPTIONS"; 2453 case SHT_MIPS_ABIFLAGS: 2454 return "MIPS_ABIFLAGS"; 2455 } 2456 } 2457 switch (Type) { 2458 case SHT_NULL: 2459 return "NULL"; 2460 case SHT_PROGBITS: 2461 return "PROGBITS"; 2462 case SHT_SYMTAB: 2463 return "SYMTAB"; 2464 case SHT_STRTAB: 2465 return "STRTAB"; 2466 case SHT_RELA: 2467 return "RELA"; 2468 case SHT_HASH: 2469 return "HASH"; 2470 case SHT_DYNAMIC: 2471 return "DYNAMIC"; 2472 case SHT_NOTE: 2473 return "NOTE"; 2474 case SHT_NOBITS: 2475 return "NOBITS"; 2476 case SHT_REL: 2477 return "REL"; 2478 case SHT_SHLIB: 2479 return "SHLIB"; 2480 case SHT_DYNSYM: 2481 return "DYNSYM"; 2482 case SHT_INIT_ARRAY: 2483 return "INIT_ARRAY"; 2484 case SHT_FINI_ARRAY: 2485 return "FINI_ARRAY"; 2486 case SHT_PREINIT_ARRAY: 2487 return "PREINIT_ARRAY"; 2488 case SHT_GROUP: 2489 return "GROUP"; 2490 case SHT_SYMTAB_SHNDX: 2491 return "SYMTAB SECTION INDICES"; 2492 // FIXME: Parse processor specific GNU attributes 2493 case SHT_GNU_ATTRIBUTES: 2494 return "ATTRIBUTES"; 2495 case SHT_GNU_HASH: 2496 return "GNU_HASH"; 2497 case SHT_GNU_verdef: 2498 return "VERDEF"; 2499 case SHT_GNU_verneed: 2500 return "VERNEED"; 2501 case SHT_GNU_versym: 2502 return "VERSYM"; 2503 default: 2504 return ""; 2505 } 2506 return ""; 2507 } 2508 2509 template <class ELFT> void GNUStyle<ELFT>::printSections(const ELFO *Obj) { 2510 size_t SectionIndex = 0; 2511 std::string Number, Type, Size, Address, Offset, Flags, Link, Info, EntrySize, 2512 Alignment; 2513 unsigned Bias; 2514 unsigned Width; 2515 2516 if (ELFT::Is64Bits) { 2517 Bias = 0; 2518 Width = 16; 2519 } else { 2520 Bias = 8; 2521 Width = 8; 2522 } 2523 OS << "There are " << to_string(Obj->getHeader()->e_shnum) 2524 << " section headers, starting at offset " 2525 << "0x" << to_hexString(Obj->getHeader()->e_shoff, false) << ":\n\n"; 2526 OS << "Section Headers:\n"; 2527 Field Fields[11] = {{"[Nr]", 2}, 2528 {"Name", 7}, 2529 {"Type", 25}, 2530 {"Address", 41}, 2531 {"Off", 58 - Bias}, 2532 {"Size", 65 - Bias}, 2533 {"ES", 72 - Bias}, 2534 {"Flg", 75 - Bias}, 2535 {"Lk", 79 - Bias}, 2536 {"Inf", 82 - Bias}, 2537 {"Al", 86 - Bias}}; 2538 for (auto &f : Fields) 2539 printField(f); 2540 OS << "\n"; 2541 2542 for (const Elf_Shdr &Sec : Obj->sections()) { 2543 Number = to_string(SectionIndex); 2544 Fields[0].Str = Number; 2545 Fields[1].Str = unwrapOrError(Obj->getSectionName(&Sec)); 2546 Type = getSectionTypeString(Obj->getHeader()->e_machine, Sec.sh_type); 2547 Fields[2].Str = Type; 2548 Address = to_string(format_hex_no_prefix(Sec.sh_addr, Width)); 2549 Fields[3].Str = Address; 2550 Offset = to_string(format_hex_no_prefix(Sec.sh_offset, 6)); 2551 Fields[4].Str = Offset; 2552 Size = to_string(format_hex_no_prefix(Sec.sh_size, 6)); 2553 Fields[5].Str = Size; 2554 EntrySize = to_string(format_hex_no_prefix(Sec.sh_entsize, 2)); 2555 Fields[6].Str = EntrySize; 2556 Flags = getGNUFlags(Sec.sh_flags); 2557 Fields[7].Str = Flags; 2558 Link = to_string(Sec.sh_link); 2559 Fields[8].Str = Link; 2560 Info = to_string(Sec.sh_info); 2561 Fields[9].Str = Info; 2562 Alignment = to_string(Sec.sh_addralign); 2563 Fields[10].Str = Alignment; 2564 OS.PadToColumn(Fields[0].Column); 2565 OS << "[" << right_justify(Fields[0].Str, 2) << "]"; 2566 for (int i = 1; i < 7; i++) 2567 printField(Fields[i]); 2568 OS.PadToColumn(Fields[7].Column); 2569 OS << right_justify(Fields[7].Str, 3); 2570 OS.PadToColumn(Fields[8].Column); 2571 OS << right_justify(Fields[8].Str, 2); 2572 OS.PadToColumn(Fields[9].Column); 2573 OS << right_justify(Fields[9].Str, 3); 2574 OS.PadToColumn(Fields[10].Column); 2575 OS << right_justify(Fields[10].Str, 2); 2576 OS << "\n"; 2577 ++SectionIndex; 2578 } 2579 OS << "Key to Flags:\n" 2580 << " W (write), A (alloc), X (execute), M (merge), S (strings), l " 2581 "(large)\n" 2582 << " I (info), L (link order), G (group), T (TLS), E (exclude),\ 2583 x (unknown)\n" 2584 << " O (extra OS processing required) o (OS specific),\ 2585 p (processor specific)\n"; 2586 } 2587 2588 template <class ELFT> 2589 void GNUStyle<ELFT>::printSymtabMessage(const ELFO *Obj, StringRef Name, 2590 size_t Entries) { 2591 if (Name.size()) 2592 OS << "\nSymbol table '" << Name << "' contains " << Entries 2593 << " entries:\n"; 2594 else 2595 OS << "\n Symbol table for image:\n"; 2596 2597 if (ELFT::Is64Bits) 2598 OS << " Num: Value Size Type Bind Vis Ndx Name\n"; 2599 else 2600 OS << " Num: Value Size Type Bind Vis Ndx Name\n"; 2601 } 2602 2603 template <class ELFT> 2604 std::string GNUStyle<ELFT>::getSymbolSectionNdx(const ELFO *Obj, 2605 const Elf_Sym *Symbol, 2606 const Elf_Sym *FirstSym) { 2607 unsigned SectionIndex = Symbol->st_shndx; 2608 switch (SectionIndex) { 2609 case ELF::SHN_UNDEF: 2610 return "UND"; 2611 case ELF::SHN_ABS: 2612 return "ABS"; 2613 case ELF::SHN_COMMON: 2614 return "COM"; 2615 case ELF::SHN_XINDEX: 2616 SectionIndex = Obj->getExtendedSymbolTableIndex( 2617 Symbol, FirstSym, this->dumper()->getShndxTable()); 2618 default: 2619 // Find if: 2620 // Processor specific 2621 if (SectionIndex >= ELF::SHN_LOPROC && SectionIndex <= ELF::SHN_HIPROC) 2622 return std::string("PRC[0x") + 2623 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]"; 2624 // OS specific 2625 if (SectionIndex >= ELF::SHN_LOOS && SectionIndex <= ELF::SHN_HIOS) 2626 return std::string("OS[0x") + 2627 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]"; 2628 // Architecture reserved: 2629 if (SectionIndex >= ELF::SHN_LORESERVE && 2630 SectionIndex <= ELF::SHN_HIRESERVE) 2631 return std::string("RSV[0x") + 2632 to_string(format_hex_no_prefix(SectionIndex, 4)) + "]"; 2633 // A normal section with an index 2634 return to_string(format_decimal(SectionIndex, 3)); 2635 } 2636 } 2637 2638 template <class ELFT> 2639 void GNUStyle<ELFT>::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, 2640 const Elf_Sym *FirstSym, StringRef StrTable, 2641 bool IsDynamic) { 2642 static int Idx = 0; 2643 static bool Dynamic = true; 2644 size_t Width; 2645 2646 // If this function was called with a different value from IsDynamic 2647 // from last call, happens when we move from dynamic to static symbol 2648 // table, "Num" field should be reset. 2649 if (!Dynamic != !IsDynamic) { 2650 Idx = 0; 2651 Dynamic = false; 2652 } 2653 std::string Num, Name, Value, Size, Binding, Type, Visibility, Section; 2654 unsigned Bias = 0; 2655 if (ELFT::Is64Bits) { 2656 Bias = 8; 2657 Width = 16; 2658 } else { 2659 Bias = 0; 2660 Width = 8; 2661 } 2662 Field Fields[8] = {0, 8, 17 + Bias, 23 + Bias, 2663 31 + Bias, 38 + Bias, 47 + Bias, 51 + Bias}; 2664 Num = to_string(format_decimal(Idx++, 6)) + ":"; 2665 Value = to_string(format_hex_no_prefix(Symbol->st_value, Width)); 2666 Size = to_string(format_decimal(Symbol->st_size, 5)); 2667 unsigned char SymbolType = Symbol->getType(); 2668 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU && 2669 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) 2670 Type = printEnum(SymbolType, makeArrayRef(AMDGPUSymbolTypes)); 2671 else 2672 Type = printEnum(SymbolType, makeArrayRef(ElfSymbolTypes)); 2673 unsigned Vis = Symbol->getVisibility(); 2674 Binding = printEnum(Symbol->getBinding(), makeArrayRef(ElfSymbolBindings)); 2675 Visibility = printEnum(Vis, makeArrayRef(ElfSymbolVisibilities)); 2676 Section = getSymbolSectionNdx(Obj, Symbol, FirstSym); 2677 Name = this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic); 2678 Fields[0].Str = Num; 2679 Fields[1].Str = Value; 2680 Fields[2].Str = Size; 2681 Fields[3].Str = Type; 2682 Fields[4].Str = Binding; 2683 Fields[5].Str = Visibility; 2684 Fields[6].Str = Section; 2685 Fields[7].Str = Name; 2686 for (auto &Entry : Fields) 2687 printField(Entry); 2688 OS << "\n"; 2689 } 2690 2691 template <class ELFT> void GNUStyle<ELFT>::printSymbols(const ELFO *Obj) { 2692 this->dumper()->printSymbolsHelper(true); 2693 this->dumper()->printSymbolsHelper(false); 2694 } 2695 2696 template <class ELFT> 2697 void GNUStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) { 2698 this->dumper()->printSymbolsHelper(true); 2699 } 2700 2701 static inline std::string printPhdrFlags(unsigned Flag) { 2702 std::string Str; 2703 Str = (Flag & PF_R) ? "R" : " "; 2704 Str += (Flag & PF_W) ? "W" : " "; 2705 Str += (Flag & PF_X) ? "E" : " "; 2706 return Str; 2707 } 2708 2709 // SHF_TLS sections are only in PT_TLS, PT_LOAD or PT_GNU_RELRO 2710 // PT_TLS must only have SHF_TLS sections 2711 template <class ELFT> 2712 bool GNUStyle<ELFT>::checkTLSSections(const Elf_Phdr &Phdr, 2713 const Elf_Shdr &Sec) { 2714 return (((Sec.sh_flags & ELF::SHF_TLS) && 2715 ((Phdr.p_type == ELF::PT_TLS) || (Phdr.p_type == ELF::PT_LOAD) || 2716 (Phdr.p_type == ELF::PT_GNU_RELRO))) || 2717 (!(Sec.sh_flags & ELF::SHF_TLS) && Phdr.p_type != ELF::PT_TLS)); 2718 } 2719 2720 // Non-SHT_NOBITS must have its offset inside the segment 2721 // Only non-zero section can be at end of segment 2722 template <class ELFT> 2723 bool GNUStyle<ELFT>::checkoffsets(const Elf_Phdr &Phdr, const Elf_Shdr &Sec) { 2724 if (Sec.sh_type == ELF::SHT_NOBITS) 2725 return true; 2726 bool IsSpecial = 2727 (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0); 2728 // .tbss is special, it only has memory in PT_TLS and has NOBITS properties 2729 auto SectionSize = 2730 (IsSpecial && Phdr.p_type != ELF::PT_TLS) ? 0 : Sec.sh_size; 2731 if (Sec.sh_offset >= Phdr.p_offset) 2732 return ((Sec.sh_offset + SectionSize <= Phdr.p_filesz + Phdr.p_offset) 2733 /*only non-zero sized sections at end*/ && 2734 (Sec.sh_offset + 1 <= Phdr.p_offset + Phdr.p_filesz)); 2735 return false; 2736 } 2737 2738 // SHF_ALLOC must have VMA inside segment 2739 // Only non-zero section can be at end of segment 2740 template <class ELFT> 2741 bool GNUStyle<ELFT>::checkVMA(const Elf_Phdr &Phdr, const Elf_Shdr &Sec) { 2742 if (!(Sec.sh_flags & ELF::SHF_ALLOC)) 2743 return true; 2744 bool IsSpecial = 2745 (Sec.sh_type == ELF::SHT_NOBITS) && ((Sec.sh_flags & ELF::SHF_TLS) != 0); 2746 // .tbss is special, it only has memory in PT_TLS and has NOBITS properties 2747 auto SectionSize = 2748 (IsSpecial && Phdr.p_type != ELF::PT_TLS) ? 0 : Sec.sh_size; 2749 if (Sec.sh_addr >= Phdr.p_vaddr) 2750 return ((Sec.sh_addr + SectionSize <= Phdr.p_vaddr + Phdr.p_memsz) && 2751 (Sec.sh_addr + 1 <= Phdr.p_vaddr + Phdr.p_memsz)); 2752 return false; 2753 } 2754 2755 // No section with zero size must be at start or end of PT_DYNAMIC 2756 template <class ELFT> 2757 bool GNUStyle<ELFT>::checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec) { 2758 if (Phdr.p_type != ELF::PT_DYNAMIC || Sec.sh_size != 0 || Phdr.p_memsz == 0) 2759 return true; 2760 // Is section within the phdr both based on offset and VMA ? 2761 return ((Sec.sh_type == ELF::SHT_NOBITS) || 2762 (Sec.sh_offset > Phdr.p_offset && 2763 Sec.sh_offset < Phdr.p_offset + Phdr.p_filesz)) && 2764 (!(Sec.sh_flags & ELF::SHF_ALLOC) || 2765 (Sec.sh_addr > Phdr.p_vaddr && Sec.sh_addr < Phdr.p_memsz)); 2766 } 2767 2768 template <class ELFT> 2769 void GNUStyle<ELFT>::printProgramHeaders(const ELFO *Obj) { 2770 unsigned Bias = (ELFT::Is64Bits) ? 8 : 0; 2771 unsigned Width = (ELFT::Is64Bits) ? 18 : 10; 2772 unsigned SizeWidth = (ELFT::Is64Bits) ? 8 : 7; 2773 std::string Type, Offset, VMA, LMA, FileSz, MemSz, Flag, Align; 2774 2775 const Elf_Ehdr *Header = Obj->getHeader(); 2776 Field Fields[8] = {2, 17, 26, 37 + Bias, 2777 48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias}; 2778 OS << "\nElf file type is " 2779 << printEnum(Header->e_type, makeArrayRef(ElfObjectFileType)) << "\n" 2780 << "Entry point " << format_hex(Header->e_entry, 1) << "\n" 2781 << "There are " << Header->e_phnum << " program headers," 2782 << " starting at offset " << Header->e_phoff << "\n\n" 2783 << "Program Headers:\n"; 2784 if (ELFT::Is64Bits) 2785 OS << " Type Offset VirtAddr PhysAddr " 2786 << " FileSiz MemSiz Flg Align\n"; 2787 else 2788 OS << " Type Offset VirtAddr PhysAddr FileSiz " 2789 << "MemSiz Flg Align\n"; 2790 for (const auto &Phdr : Obj->program_headers()) { 2791 Type = getElfPtType(Header->e_machine, Phdr.p_type); 2792 Offset = to_string(format_hex(Phdr.p_offset, 8)); 2793 VMA = to_string(format_hex(Phdr.p_vaddr, Width)); 2794 LMA = to_string(format_hex(Phdr.p_paddr, Width)); 2795 FileSz = to_string(format_hex(Phdr.p_filesz, SizeWidth)); 2796 MemSz = to_string(format_hex(Phdr.p_memsz, SizeWidth)); 2797 Flag = printPhdrFlags(Phdr.p_flags); 2798 Align = to_string(format_hex(Phdr.p_align, 1)); 2799 Fields[0].Str = Type; 2800 Fields[1].Str = Offset; 2801 Fields[2].Str = VMA; 2802 Fields[3].Str = LMA; 2803 Fields[4].Str = FileSz; 2804 Fields[5].Str = MemSz; 2805 Fields[6].Str = Flag; 2806 Fields[7].Str = Align; 2807 for (auto Field : Fields) 2808 printField(Field); 2809 if (Phdr.p_type == ELF::PT_INTERP) { 2810 OS << "\n [Requesting program interpreter: "; 2811 OS << reinterpret_cast<const char *>(Obj->base()) + Phdr.p_offset << "]"; 2812 } 2813 OS << "\n"; 2814 } 2815 OS << "\n Section to Segment mapping:\n Segment Sections...\n"; 2816 int Phnum = 0; 2817 for (const Elf_Phdr &Phdr : Obj->program_headers()) { 2818 std::string Sections; 2819 OS << format(" %2.2d ", Phnum++); 2820 for (const Elf_Shdr &Sec : Obj->sections()) { 2821 // Check if each section is in a segment and then print mapping. 2822 // readelf additionally makes sure it does not print zero sized sections 2823 // at end of segments and for PT_DYNAMIC both start and end of section 2824 // .tbss must only be shown in PT_TLS section. 2825 bool TbssInNonTLS = (Sec.sh_type == ELF::SHT_NOBITS) && 2826 ((Sec.sh_flags & ELF::SHF_TLS) != 0) && 2827 Phdr.p_type != ELF::PT_TLS; 2828 if (!TbssInNonTLS && checkTLSSections(Phdr, Sec) && 2829 checkoffsets(Phdr, Sec) && checkVMA(Phdr, Sec) && 2830 checkPTDynamic(Phdr, Sec) && (Sec.sh_type != ELF::SHT_NULL)) 2831 Sections += unwrapOrError(Obj->getSectionName(&Sec)).str() + " "; 2832 } 2833 OS << Sections << "\n"; 2834 OS.flush(); 2835 } 2836 } 2837 2838 template <class ELFT> 2839 void GNUStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) { 2840 OS << "GNU style dynamic relocations not implemented!\n"; 2841 } 2842 2843 template <class ELFT> void LLVMStyle<ELFT>::printFileHeaders(const ELFO *Obj) { 2844 const Elf_Ehdr *e = Obj->getHeader(); 2845 { 2846 DictScope D(W, "ElfHeader"); 2847 { 2848 DictScope D(W, "Ident"); 2849 W.printBinary("Magic", makeArrayRef(e->e_ident).slice(ELF::EI_MAG0, 4)); 2850 W.printEnum("Class", e->e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass)); 2851 W.printEnum("DataEncoding", e->e_ident[ELF::EI_DATA], 2852 makeArrayRef(ElfDataEncoding)); 2853 W.printNumber("FileVersion", e->e_ident[ELF::EI_VERSION]); 2854 2855 // Handle architecture specific OS/ABI values. 2856 if (e->e_machine == ELF::EM_AMDGPU && 2857 e->e_ident[ELF::EI_OSABI] == ELF::ELFOSABI_AMDGPU_HSA) 2858 W.printHex("OS/ABI", "AMDGPU_HSA", ELF::ELFOSABI_AMDGPU_HSA); 2859 else 2860 W.printEnum("OS/ABI", e->e_ident[ELF::EI_OSABI], 2861 makeArrayRef(ElfOSABI)); 2862 W.printNumber("ABIVersion", e->e_ident[ELF::EI_ABIVERSION]); 2863 W.printBinary("Unused", makeArrayRef(e->e_ident).slice(ELF::EI_PAD)); 2864 } 2865 2866 W.printEnum("Type", e->e_type, makeArrayRef(ElfObjectFileType)); 2867 W.printEnum("Machine", e->e_machine, makeArrayRef(ElfMachineType)); 2868 W.printNumber("Version", e->e_version); 2869 W.printHex("Entry", e->e_entry); 2870 W.printHex("ProgramHeaderOffset", e->e_phoff); 2871 W.printHex("SectionHeaderOffset", e->e_shoff); 2872 if (e->e_machine == EM_MIPS) 2873 W.printFlags("Flags", e->e_flags, makeArrayRef(ElfHeaderMipsFlags), 2874 unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI), 2875 unsigned(ELF::EF_MIPS_MACH)); 2876 else 2877 W.printFlags("Flags", e->e_flags); 2878 W.printNumber("HeaderSize", e->e_ehsize); 2879 W.printNumber("ProgramHeaderEntrySize", e->e_phentsize); 2880 W.printNumber("ProgramHeaderCount", e->e_phnum); 2881 W.printNumber("SectionHeaderEntrySize", e->e_shentsize); 2882 W.printNumber("SectionHeaderCount", e->e_shnum); 2883 W.printNumber("StringTableSectionIndex", e->e_shstrndx); 2884 } 2885 } 2886 2887 template <class ELFT> 2888 void LLVMStyle<ELFT>::printGroupSections(const ELFO *Obj) { 2889 DictScope Lists(W, "Groups"); 2890 uint32_t SectionIndex = 0; 2891 bool HasGroups = false; 2892 for (const Elf_Shdr &Sec : Obj->sections()) { 2893 if (Sec.sh_type == ELF::SHT_GROUP) { 2894 HasGroups = true; 2895 const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link)); 2896 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab)); 2897 const Elf_Sym *Sym = Obj->template getEntry<Elf_Sym>(Symtab, Sec.sh_info); 2898 auto Data = unwrapOrError( 2899 Obj->template getSectionContentsAsArray<Elf_Word>(&Sec)); 2900 DictScope D(W, "Group"); 2901 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); 2902 W.printNumber("Name", Name, Sec.sh_name); 2903 W.printNumber("Index", SectionIndex); 2904 W.printHex("Type", getGroupType(Data[0]), Data[0]); 2905 W.startLine() << "Signature: " << StrTable.data() + Sym->st_name << "\n"; 2906 { 2907 ListScope L(W, "Section(s) in group"); 2908 size_t Member = 1; 2909 while (Member < Data.size()) { 2910 auto Sec = unwrapOrError(Obj->getSection(Data[Member])); 2911 const StringRef Name = unwrapOrError(Obj->getSectionName(Sec)); 2912 W.startLine() << Name << " (" << Data[Member++] << ")\n"; 2913 } 2914 } 2915 } 2916 ++SectionIndex; 2917 } 2918 if (!HasGroups) 2919 W.startLine() << "There are no group sections in the file.\n"; 2920 } 2921 2922 template <class ELFT> void LLVMStyle<ELFT>::printRelocations(const ELFO *Obj) { 2923 ListScope D(W, "Relocations"); 2924 2925 int SectionNumber = -1; 2926 for (const Elf_Shdr &Sec : Obj->sections()) { 2927 ++SectionNumber; 2928 2929 if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA) 2930 continue; 2931 2932 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); 2933 2934 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; 2935 W.indent(); 2936 2937 printRelocations(&Sec, Obj); 2938 2939 W.unindent(); 2940 W.startLine() << "}\n"; 2941 } 2942 } 2943 2944 template <class ELFT> 2945 void LLVMStyle<ELFT>::printRelocations(const Elf_Shdr *Sec, const ELFO *Obj) { 2946 const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link)); 2947 2948 switch (Sec->sh_type) { 2949 case ELF::SHT_REL: 2950 for (const Elf_Rel &R : Obj->rels(Sec)) { 2951 Elf_Rela Rela; 2952 Rela.r_offset = R.r_offset; 2953 Rela.r_info = R.r_info; 2954 Rela.r_addend = 0; 2955 printRelocation(Obj, Rela, SymTab); 2956 } 2957 break; 2958 case ELF::SHT_RELA: 2959 for (const Elf_Rela &R : Obj->relas(Sec)) 2960 printRelocation(Obj, R, SymTab); 2961 break; 2962 } 2963 } 2964 2965 template <class ELFT> 2966 void LLVMStyle<ELFT>::printRelocation(const ELFO *Obj, Elf_Rela Rel, 2967 const Elf_Shdr *SymTab) { 2968 SmallString<32> RelocName; 2969 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); 2970 StringRef TargetName; 2971 const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab); 2972 if (Sym && Sym->getType() == ELF::STT_SECTION) { 2973 const Elf_Shdr *Sec = unwrapOrError( 2974 Obj->getSection(Sym, SymTab, this->dumper()->getShndxTable())); 2975 TargetName = unwrapOrError(Obj->getSectionName(Sec)); 2976 } else if (Sym) { 2977 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab)); 2978 TargetName = unwrapOrError(Sym->getName(StrTable)); 2979 } 2980 2981 if (opts::ExpandRelocs) { 2982 DictScope Group(W, "Relocation"); 2983 W.printHex("Offset", Rel.r_offset); 2984 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); 2985 W.printNumber("Symbol", TargetName.size() > 0 ? TargetName : "-", 2986 Rel.getSymbol(Obj->isMips64EL())); 2987 W.printHex("Addend", Rel.r_addend); 2988 } else { 2989 raw_ostream &OS = W.startLine(); 2990 OS << W.hex(Rel.r_offset) << " " << RelocName << " " 2991 << (TargetName.size() > 0 ? TargetName : "-") << " " 2992 << W.hex(Rel.r_addend) << "\n"; 2993 } 2994 } 2995 2996 template <class ELFT> void LLVMStyle<ELFT>::printSections(const ELFO *Obj) { 2997 ListScope SectionsD(W, "Sections"); 2998 2999 int SectionIndex = -1; 3000 for (const Elf_Shdr &Sec : Obj->sections()) { 3001 ++SectionIndex; 3002 3003 StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); 3004 3005 DictScope SectionD(W, "Section"); 3006 W.printNumber("Index", SectionIndex); 3007 W.printNumber("Name", Name, Sec.sh_name); 3008 W.printHex("Type", 3009 getElfSectionType(Obj->getHeader()->e_machine, Sec.sh_type), 3010 Sec.sh_type); 3011 std::vector<EnumEntry<unsigned>> SectionFlags(std::begin(ElfSectionFlags), 3012 std::end(ElfSectionFlags)); 3013 switch (Obj->getHeader()->e_machine) { 3014 case EM_AMDGPU: 3015 SectionFlags.insert(SectionFlags.end(), std::begin(ElfAMDGPUSectionFlags), 3016 std::end(ElfAMDGPUSectionFlags)); 3017 break; 3018 case EM_HEXAGON: 3019 SectionFlags.insert(SectionFlags.end(), 3020 std::begin(ElfHexagonSectionFlags), 3021 std::end(ElfHexagonSectionFlags)); 3022 break; 3023 case EM_MIPS: 3024 SectionFlags.insert(SectionFlags.end(), std::begin(ElfMipsSectionFlags), 3025 std::end(ElfMipsSectionFlags)); 3026 break; 3027 case EM_X86_64: 3028 SectionFlags.insert(SectionFlags.end(), std::begin(ElfX86_64SectionFlags), 3029 std::end(ElfX86_64SectionFlags)); 3030 break; 3031 default: 3032 // Nothing to do. 3033 break; 3034 } 3035 W.printFlags("Flags", Sec.sh_flags, makeArrayRef(SectionFlags)); 3036 W.printHex("Address", Sec.sh_addr); 3037 W.printHex("Offset", Sec.sh_offset); 3038 W.printNumber("Size", Sec.sh_size); 3039 W.printNumber("Link", Sec.sh_link); 3040 W.printNumber("Info", Sec.sh_info); 3041 W.printNumber("AddressAlignment", Sec.sh_addralign); 3042 W.printNumber("EntrySize", Sec.sh_entsize); 3043 3044 if (opts::SectionRelocations) { 3045 ListScope D(W, "Relocations"); 3046 printRelocations(&Sec, Obj); 3047 } 3048 3049 if (opts::SectionSymbols) { 3050 ListScope D(W, "Symbols"); 3051 const Elf_Shdr *Symtab = this->dumper()->getDotSymtabSec(); 3052 StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab)); 3053 3054 for (const Elf_Sym &Sym : Obj->symbols(Symtab)) { 3055 const Elf_Shdr *SymSec = unwrapOrError( 3056 Obj->getSection(&Sym, Symtab, this->dumper()->getShndxTable())); 3057 if (SymSec == &Sec) 3058 printSymbol(Obj, &Sym, Obj->symbol_begin(Symtab), StrTable, false); 3059 } 3060 } 3061 3062 if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) { 3063 ArrayRef<uint8_t> Data = unwrapOrError(Obj->getSectionContents(&Sec)); 3064 W.printBinaryBlock("SectionData", 3065 StringRef((const char *)Data.data(), Data.size())); 3066 } 3067 } 3068 } 3069 3070 template <class ELFT> 3071 void LLVMStyle<ELFT>::printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, 3072 const Elf_Sym *First, StringRef StrTable, 3073 bool IsDynamic) { 3074 unsigned SectionIndex = 0; 3075 StringRef SectionName; 3076 getSectionNameIndex(*Obj, Symbol, First, this->dumper()->getShndxTable(), 3077 SectionName, SectionIndex); 3078 std::string FullSymbolName = 3079 this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic); 3080 unsigned char SymbolType = Symbol->getType(); 3081 3082 DictScope D(W, "Symbol"); 3083 W.printNumber("Name", FullSymbolName, Symbol->st_name); 3084 W.printHex("Value", Symbol->st_value); 3085 W.printNumber("Size", Symbol->st_size); 3086 W.printEnum("Binding", Symbol->getBinding(), makeArrayRef(ElfSymbolBindings)); 3087 if (Obj->getHeader()->e_machine == ELF::EM_AMDGPU && 3088 SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) 3089 W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes)); 3090 else 3091 W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes)); 3092 if (Symbol->st_other == 0) 3093 // Usually st_other flag is zero. Do not pollute the output 3094 // by flags enumeration in that case. 3095 W.printNumber("Other", 0); 3096 else { 3097 std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags), 3098 std::end(ElfSymOtherFlags)); 3099 if (Obj->getHeader()->e_machine == EM_MIPS) { 3100 // Someones in their infinite wisdom decided to make STO_MIPS_MIPS16 3101 // flag overlapped with other ST_MIPS_xxx flags. So consider both 3102 // cases separately. 3103 if ((Symbol->st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16) 3104 SymOtherFlags.insert(SymOtherFlags.end(), 3105 std::begin(ElfMips16SymOtherFlags), 3106 std::end(ElfMips16SymOtherFlags)); 3107 else 3108 SymOtherFlags.insert(SymOtherFlags.end(), 3109 std::begin(ElfMipsSymOtherFlags), 3110 std::end(ElfMipsSymOtherFlags)); 3111 } 3112 W.printFlags("Other", Symbol->st_other, makeArrayRef(SymOtherFlags), 0x3u); 3113 } 3114 W.printHex("Section", SectionName, SectionIndex); 3115 } 3116 3117 template <class ELFT> void LLVMStyle<ELFT>::printSymbols(const ELFO *Obj) { 3118 ListScope Group(W, "Symbols"); 3119 this->dumper()->printSymbolsHelper(false); 3120 } 3121 3122 template <class ELFT> 3123 void LLVMStyle<ELFT>::printDynamicSymbols(const ELFO *Obj) { 3124 ListScope Group(W, "DynamicSymbols"); 3125 this->dumper()->printSymbolsHelper(true); 3126 } 3127 3128 template <class ELFT> 3129 void LLVMStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) { 3130 const DynRegionInfo &DynRelRegion = this->dumper()->getDynRelRegion(); 3131 const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion(); 3132 const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion(); 3133 if (DynRelRegion.Size && DynRelaRegion.Size) 3134 report_fatal_error("There are both REL and RELA dynamic relocations"); 3135 W.startLine() << "Dynamic Relocations {\n"; 3136 W.indent(); 3137 if (DynRelaRegion.Size > 0) 3138 for (const Elf_Rela &Rela : this->dumper()->dyn_relas()) 3139 printDynamicRelocation(Obj, Rela); 3140 else 3141 for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) { 3142 Elf_Rela Rela; 3143 Rela.r_offset = Rel.r_offset; 3144 Rela.r_info = Rel.r_info; 3145 Rela.r_addend = 0; 3146 printDynamicRelocation(Obj, Rela); 3147 } 3148 if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) 3149 for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange<Elf_Rela>()) 3150 printDynamicRelocation(Obj, Rela); 3151 else 3152 for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange<Elf_Rel>()) { 3153 Elf_Rela Rela; 3154 Rela.r_offset = Rel.r_offset; 3155 Rela.r_info = Rel.r_info; 3156 Rela.r_addend = 0; 3157 printDynamicRelocation(Obj, Rela); 3158 } 3159 W.unindent(); 3160 W.startLine() << "}\n"; 3161 } 3162 3163 template <class ELFT> 3164 void LLVMStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela Rel) { 3165 SmallString<32> RelocName; 3166 Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); 3167 StringRef SymbolName; 3168 uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL()); 3169 const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex; 3170 SymbolName = 3171 unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable())); 3172 if (opts::ExpandRelocs) { 3173 DictScope Group(W, "Relocation"); 3174 W.printHex("Offset", Rel.r_offset); 3175 W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); 3176 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); 3177 W.printHex("Addend", Rel.r_addend); 3178 } else { 3179 raw_ostream &OS = W.startLine(); 3180 OS << W.hex(Rel.r_offset) << " " << RelocName << " " 3181 << (SymbolName.size() > 0 ? SymbolName : "-") << " " 3182 << W.hex(Rel.r_addend) << "\n"; 3183 } 3184 } 3185 3186 template <class ELFT> 3187 void LLVMStyle<ELFT>::printProgramHeaders(const ELFO *Obj) { 3188 ListScope L(W, "ProgramHeaders"); 3189 3190 for (const Elf_Phdr &Phdr : Obj->program_headers()) { 3191 DictScope P(W, "ProgramHeader"); 3192 W.printHex("Type", 3193 getElfSegmentType(Obj->getHeader()->e_machine, Phdr.p_type), 3194 Phdr.p_type); 3195 W.printHex("Offset", Phdr.p_offset); 3196 W.printHex("VirtualAddress", Phdr.p_vaddr); 3197 W.printHex("PhysicalAddress", Phdr.p_paddr); 3198 W.printNumber("FileSize", Phdr.p_filesz); 3199 W.printNumber("MemSize", Phdr.p_memsz); 3200 W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags)); 3201 W.printNumber("Alignment", Phdr.p_align); 3202 } 3203 } 3204