1259698Sdim//===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim 10259698Sdim#ifndef LLVM_OBJECT_ELF_TYPES_H 11259698Sdim#define LLVM_OBJECT_ELF_TYPES_H 12259698Sdim 13259698Sdim#include "llvm/Support/AlignOf.h" 14259698Sdim#include "llvm/Support/DataTypes.h" 15259698Sdim#include "llvm/Support/ELF.h" 16259698Sdim#include "llvm/Support/Endian.h" 17259698Sdim 18259698Sdimnamespace llvm { 19259698Sdimnamespace object { 20259698Sdim 21259698Sdimusing support::endianness; 22259698Sdim 23259698Sdimtemplate <endianness target_endianness, std::size_t max_alignment, 24259698Sdim bool is64Bits> 25259698Sdimstruct ELFType { 26259698Sdim static const endianness TargetEndianness = target_endianness; 27259698Sdim static const std::size_t MaxAlignment = max_alignment; 28259698Sdim static const bool Is64Bits = is64Bits; 29259698Sdim}; 30259698Sdim 31259698Sdimtemplate <typename T, int max_align> struct MaximumAlignment { 32259698Sdim enum { value = AlignOf<T>::Alignment > max_align ? max_align 33259698Sdim : AlignOf<T>::Alignment 34259698Sdim }; 35259698Sdim}; 36259698Sdim 37259698Sdim// Templates to choose Elf_Addr and Elf_Off depending on is64Bits. 38259698Sdimtemplate <endianness target_endianness, std::size_t max_alignment> 39259698Sdimstruct ELFDataTypeTypedefHelperCommon { 40259698Sdim typedef support::detail::packed_endian_specific_integral< 41259698Sdim uint16_t, target_endianness, 42259698Sdim MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half; 43259698Sdim typedef support::detail::packed_endian_specific_integral< 44259698Sdim uint32_t, target_endianness, 45259698Sdim MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word; 46259698Sdim typedef support::detail::packed_endian_specific_integral< 47259698Sdim int32_t, target_endianness, 48259698Sdim MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword; 49259698Sdim typedef support::detail::packed_endian_specific_integral< 50259698Sdim uint64_t, target_endianness, 51259698Sdim MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword; 52259698Sdim typedef support::detail::packed_endian_specific_integral< 53259698Sdim int64_t, target_endianness, 54259698Sdim MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword; 55259698Sdim}; 56259698Sdim 57259698Sdimtemplate <class ELFT> struct ELFDataTypeTypedefHelper; 58259698Sdim 59259698Sdim/// ELF 32bit types. 60259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 61259698Sdimstruct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> > 62259698Sdim : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { 63259698Sdim typedef uint32_t value_type; 64259698Sdim typedef support::detail::packed_endian_specific_integral< 65259698Sdim value_type, TargetEndianness, 66259698Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; 67259698Sdim typedef support::detail::packed_endian_specific_integral< 68259698Sdim value_type, TargetEndianness, 69259698Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; 70259698Sdim}; 71259698Sdim 72259698Sdim/// ELF 64bit types. 73259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 74259698Sdimstruct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> > 75259698Sdim : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { 76259698Sdim typedef uint64_t value_type; 77259698Sdim typedef support::detail::packed_endian_specific_integral< 78259698Sdim value_type, TargetEndianness, 79259698Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; 80259698Sdim typedef support::detail::packed_endian_specific_integral< 81259698Sdim value_type, TargetEndianness, 82259698Sdim MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; 83259698Sdim}; 84259698Sdim 85259698Sdim// I really don't like doing this, but the alternative is copypasta. 86259698Sdim#define LLVM_ELF_IMPORT_TYPES(E, M, W) \ 87259698Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Addr \ 88259698Sdim Elf_Addr; \ 89259698Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Off \ 90259698Sdim Elf_Off; \ 91259698Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Half \ 92259698Sdim Elf_Half; \ 93259698Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Word \ 94259698Sdim Elf_Word; \ 95259698Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sword \ 96259698Sdim Elf_Sword; \ 97259698Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Xword \ 98259698Sdim Elf_Xword; \ 99259698Sdimtypedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sxword \ 100259698Sdim Elf_Sxword; 101259698Sdim 102259698Sdim#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \ 103259698Sdim LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \ 104259698Sdim ELFT::Is64Bits) 105259698Sdim 106259698Sdim// Section header. 107259698Sdimtemplate <class ELFT> struct Elf_Shdr_Base; 108259698Sdim 109259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 110259698Sdimstruct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > { 111259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 112259698Sdim Elf_Word sh_name; // Section name (index into string table) 113259698Sdim Elf_Word sh_type; // Section type (SHT_*) 114259698Sdim Elf_Word sh_flags; // Section flags (SHF_*) 115259698Sdim Elf_Addr sh_addr; // Address where section is to be loaded 116259698Sdim Elf_Off sh_offset; // File offset of section data, in bytes 117259698Sdim Elf_Word sh_size; // Size of section, in bytes 118259698Sdim Elf_Word sh_link; // Section type-specific header table index link 119259698Sdim Elf_Word sh_info; // Section type-specific extra information 120259698Sdim Elf_Word sh_addralign; // Section address alignment 121259698Sdim Elf_Word sh_entsize; // Size of records contained within the section 122259698Sdim}; 123259698Sdim 124259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 125259698Sdimstruct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > { 126259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 127259698Sdim Elf_Word sh_name; // Section name (index into string table) 128259698Sdim Elf_Word sh_type; // Section type (SHT_*) 129259698Sdim Elf_Xword sh_flags; // Section flags (SHF_*) 130259698Sdim Elf_Addr sh_addr; // Address where section is to be loaded 131259698Sdim Elf_Off sh_offset; // File offset of section data, in bytes 132259698Sdim Elf_Xword sh_size; // Size of section, in bytes 133259698Sdim Elf_Word sh_link; // Section type-specific header table index link 134259698Sdim Elf_Word sh_info; // Section type-specific extra information 135259698Sdim Elf_Xword sh_addralign; // Section address alignment 136259698Sdim Elf_Xword sh_entsize; // Size of records contained within the section 137259698Sdim}; 138259698Sdim 139259698Sdimtemplate <class ELFT> 140259698Sdimstruct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> { 141259698Sdim using Elf_Shdr_Base<ELFT>::sh_entsize; 142259698Sdim using Elf_Shdr_Base<ELFT>::sh_size; 143259698Sdim 144259698Sdim /// @brief Get the number of entities this section contains if it has any. 145259698Sdim unsigned getEntityCount() const { 146259698Sdim if (sh_entsize == 0) 147259698Sdim return 0; 148259698Sdim return sh_size / sh_entsize; 149259698Sdim } 150259698Sdim}; 151259698Sdim 152259698Sdimtemplate <class ELFT> struct Elf_Sym_Base; 153259698Sdim 154259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 155259698Sdimstruct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > { 156259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 157259698Sdim Elf_Word st_name; // Symbol name (index into string table) 158259698Sdim Elf_Addr st_value; // Value or address associated with the symbol 159259698Sdim Elf_Word st_size; // Size of the symbol 160259698Sdim unsigned char st_info; // Symbol's type and binding attributes 161259698Sdim unsigned char st_other; // Must be zero; reserved 162259698Sdim Elf_Half st_shndx; // Which section (header table index) it's defined in 163259698Sdim}; 164259698Sdim 165259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 166259698Sdimstruct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > { 167259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 168259698Sdim Elf_Word st_name; // Symbol name (index into string table) 169259698Sdim unsigned char st_info; // Symbol's type and binding attributes 170259698Sdim unsigned char st_other; // Must be zero; reserved 171259698Sdim Elf_Half st_shndx; // Which section (header table index) it's defined in 172259698Sdim Elf_Addr st_value; // Value or address associated with the symbol 173259698Sdim Elf_Xword st_size; // Size of the symbol 174259698Sdim}; 175259698Sdim 176259698Sdimtemplate <class ELFT> 177259698Sdimstruct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { 178259698Sdim using Elf_Sym_Base<ELFT>::st_info; 179259698Sdim 180259698Sdim // These accessors and mutators correspond to the ELF32_ST_BIND, 181259698Sdim // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification: 182259698Sdim unsigned char getBinding() const { return st_info >> 4; } 183259698Sdim unsigned char getType() const { return st_info & 0x0f; } 184259698Sdim void setBinding(unsigned char b) { setBindingAndType(b, getType()); } 185259698Sdim void setType(unsigned char t) { setBindingAndType(getBinding(), t); } 186259698Sdim void setBindingAndType(unsigned char b, unsigned char t) { 187259698Sdim st_info = (b << 4) + (t & 0x0f); 188259698Sdim } 189259698Sdim}; 190259698Sdim 191259698Sdim/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section 192259698Sdim/// (.gnu.version). This structure is identical for ELF32 and ELF64. 193259698Sdimtemplate <class ELFT> 194259698Sdimstruct Elf_Versym_Impl { 195259698Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 196259698Sdim Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN) 197259698Sdim}; 198259698Sdim 199259698Sdimtemplate <class ELFT> struct Elf_Verdaux_Impl; 200259698Sdim 201259698Sdim/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section 202259698Sdim/// (.gnu.version_d). This structure is identical for ELF32 and ELF64. 203259698Sdimtemplate <class ELFT> 204259698Sdimstruct Elf_Verdef_Impl { 205259698Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 206259698Sdim typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux; 207259698Sdim Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT) 208259698Sdim Elf_Half vd_flags; // Bitwise flags (VER_DEF_*) 209259698Sdim Elf_Half vd_ndx; // Version index, used in .gnu.version entries 210259698Sdim Elf_Half vd_cnt; // Number of Verdaux entries 211259698Sdim Elf_Word vd_hash; // Hash of name 212259698Sdim Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes) 213259698Sdim Elf_Word vd_next; // Offset to the next Verdef entry (in bytes) 214259698Sdim 215259698Sdim /// Get the first Verdaux entry for this Verdef. 216259698Sdim const Elf_Verdaux *getAux() const { 217259698Sdim return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux); 218259698Sdim } 219259698Sdim}; 220259698Sdim 221259698Sdim/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef 222259698Sdim/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64. 223259698Sdimtemplate <class ELFT> 224259698Sdimstruct Elf_Verdaux_Impl { 225259698Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 226259698Sdim Elf_Word vda_name; // Version name (offset in string table) 227259698Sdim Elf_Word vda_next; // Offset to next Verdaux entry (in bytes) 228259698Sdim}; 229259698Sdim 230259698Sdim/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed 231259698Sdim/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. 232259698Sdimtemplate <class ELFT> 233259698Sdimstruct Elf_Verneed_Impl { 234259698Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 235259698Sdim Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT) 236259698Sdim Elf_Half vn_cnt; // Number of associated Vernaux entries 237259698Sdim Elf_Word vn_file; // Library name (string table offset) 238259698Sdim Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes) 239259698Sdim Elf_Word vn_next; // Offset to next Verneed entry (in bytes) 240259698Sdim}; 241259698Sdim 242259698Sdim/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed 243259698Sdim/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64. 244259698Sdimtemplate <class ELFT> 245259698Sdimstruct Elf_Vernaux_Impl { 246259698Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 247259698Sdim Elf_Word vna_hash; // Hash of dependency name 248259698Sdim Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*) 249259698Sdim Elf_Half vna_other; // Version index, used in .gnu.version entries 250259698Sdim Elf_Word vna_name; // Dependency name 251259698Sdim Elf_Word vna_next; // Offset to next Vernaux entry (in bytes) 252259698Sdim}; 253259698Sdim 254259698Sdim/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic 255259698Sdim/// table section (.dynamic) look like. 256259698Sdimtemplate <class ELFT> struct Elf_Dyn_Base; 257259698Sdim 258259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 259259698Sdimstruct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > { 260259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 261259698Sdim Elf_Sword d_tag; 262259698Sdim union { 263259698Sdim Elf_Word d_val; 264259698Sdim Elf_Addr d_ptr; 265259698Sdim } d_un; 266259698Sdim}; 267259698Sdim 268259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 269259698Sdimstruct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > { 270259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 271259698Sdim Elf_Sxword d_tag; 272259698Sdim union { 273259698Sdim Elf_Xword d_val; 274259698Sdim Elf_Addr d_ptr; 275259698Sdim } d_un; 276259698Sdim}; 277259698Sdim 278259698Sdim/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters. 279259698Sdimtemplate <class ELFT> 280259698Sdimstruct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> { 281259698Sdim using Elf_Dyn_Base<ELFT>::d_tag; 282259698Sdim using Elf_Dyn_Base<ELFT>::d_un; 283259698Sdim int64_t getTag() const { return d_tag; } 284259698Sdim uint64_t getVal() const { return d_un.d_val; } 285259698Sdim uint64_t getPtr() const { return d_un.ptr; } 286259698Sdim}; 287259698Sdim 288259698Sdim// Elf_Rel: Elf Relocation 289259698Sdimtemplate <class ELFT, bool isRela> struct Elf_Rel_Base; 290259698Sdim 291259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 292259698Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> { 293259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 294259698Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 295259698Sdim Elf_Word r_info; // Symbol table index and type of relocation to apply 296259698Sdim 297259698Sdim uint32_t getRInfo(bool isMips64EL) const { 298259698Sdim assert(!isMips64EL); 299259698Sdim return r_info; 300259698Sdim } 301259698Sdim void setRInfo(uint32_t R) { r_info = R; } 302259698Sdim}; 303259698Sdim 304259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 305259698Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> { 306259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 307259698Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 308259698Sdim Elf_Xword r_info; // Symbol table index and type of relocation to apply 309259698Sdim 310259698Sdim uint64_t getRInfo(bool isMips64EL) const { 311259698Sdim uint64_t t = r_info; 312259698Sdim if (!isMips64EL) 313259698Sdim return t; 314259698Sdim // Mips64 little endian has a "special" encoding of r_info. Instead of one 315259698Sdim // 64 bit little endian number, it is a little endian 32 bit number followed 316259698Sdim // by a 32 bit big endian number. 317259698Sdim return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | 318259698Sdim ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); 319259698Sdim } 320259698Sdim void setRInfo(uint64_t R) { 321259698Sdim // FIXME: Add mips64el support. 322259698Sdim r_info = R; 323259698Sdim } 324259698Sdim}; 325259698Sdim 326259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 327259698Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> { 328259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 329259698Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 330259698Sdim Elf_Word r_info; // Symbol table index and type of relocation to apply 331259698Sdim Elf_Sword r_addend; // Compute value for relocatable field by adding this 332259698Sdim 333259698Sdim uint32_t getRInfo(bool isMips64EL) const { 334259698Sdim assert(!isMips64EL); 335259698Sdim return r_info; 336259698Sdim } 337259698Sdim void setRInfo(uint32_t R) { r_info = R; } 338259698Sdim}; 339259698Sdim 340259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 341259698Sdimstruct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> { 342259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 343259698Sdim Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) 344259698Sdim Elf_Xword r_info; // Symbol table index and type of relocation to apply 345259698Sdim Elf_Sxword r_addend; // Compute value for relocatable field by adding this. 346259698Sdim 347259698Sdim uint64_t getRInfo(bool isMips64EL) const { 348259698Sdim // Mips64 little endian has a "special" encoding of r_info. Instead of one 349259698Sdim // 64 bit little endian number, it is a little endian 32 bit number followed 350259698Sdim // by a 32 bit big endian number. 351259698Sdim uint64_t t = r_info; 352259698Sdim if (!isMips64EL) 353259698Sdim return t; 354259698Sdim return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | 355259698Sdim ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); 356259698Sdim } 357259698Sdim void setRInfo(uint64_t R) { 358259698Sdim // FIXME: Add mips64el support. 359259698Sdim r_info = R; 360259698Sdim } 361259698Sdim}; 362259698Sdim 363259698Sdimtemplate <class ELFT, bool isRela> struct Elf_Rel_Impl; 364259698Sdim 365259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign, bool isRela> 366259698Sdimstruct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, 367259698Sdim isRela> : Elf_Rel_Base< 368259698Sdim ELFType<TargetEndianness, MaxAlign, true>, isRela> { 369259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 370259698Sdim 371259698Sdim // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, 372259698Sdim // and ELF64_R_INFO macros defined in the ELF specification: 373259698Sdim uint32_t getSymbol(bool isMips64EL) const { 374259698Sdim return (uint32_t)(this->getRInfo(isMips64EL) >> 32); 375259698Sdim } 376259698Sdim uint32_t getType(bool isMips64EL) const { 377259698Sdim return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL); 378259698Sdim } 379259698Sdim void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } 380259698Sdim void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); } 381259698Sdim void setSymbolAndType(uint32_t s, uint32_t t) { 382259698Sdim this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL)); 383259698Sdim } 384259698Sdim}; 385259698Sdim 386259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign, bool isRela> 387259698Sdimstruct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, 388259698Sdim isRela> : Elf_Rel_Base< 389259698Sdim ELFType<TargetEndianness, MaxAlign, false>, isRela> { 390259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 391259698Sdim 392259698Sdim // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, 393259698Sdim // and ELF32_R_INFO macros defined in the ELF specification: 394259698Sdim uint32_t getSymbol(bool isMips64EL) const { 395259698Sdim return this->getRInfo(isMips64EL) >> 8; 396259698Sdim } 397259698Sdim unsigned char getType(bool isMips64EL) const { 398259698Sdim return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff); 399259698Sdim } 400259698Sdim void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } 401259698Sdim void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } 402259698Sdim void setSymbolAndType(uint32_t s, unsigned char t) { 403259698Sdim this->setRInfo((s << 8) + t); 404259698Sdim } 405259698Sdim}; 406259698Sdim 407259698Sdimtemplate <class ELFT> 408259698Sdimstruct Elf_Ehdr_Impl { 409259698Sdim LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) 410259698Sdim unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes 411259698Sdim Elf_Half e_type; // Type of file (see ET_*) 412259698Sdim Elf_Half e_machine; // Required architecture for this file (see EM_*) 413259698Sdim Elf_Word e_version; // Must be equal to 1 414259698Sdim Elf_Addr e_entry; // Address to jump to in order to start program 415259698Sdim Elf_Off e_phoff; // Program header table's file offset, in bytes 416259698Sdim Elf_Off e_shoff; // Section header table's file offset, in bytes 417259698Sdim Elf_Word e_flags; // Processor-specific flags 418259698Sdim Elf_Half e_ehsize; // Size of ELF header, in bytes 419259698Sdim Elf_Half e_phentsize; // Size of an entry in the program header table 420259698Sdim Elf_Half e_phnum; // Number of entries in the program header table 421259698Sdim Elf_Half e_shentsize; // Size of an entry in the section header table 422259698Sdim Elf_Half e_shnum; // Number of entries in the section header table 423259698Sdim Elf_Half e_shstrndx; // Section header table index of section name 424259698Sdim // string table 425259698Sdim bool checkMagic() const { 426259698Sdim return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0; 427259698Sdim } 428259698Sdim unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; } 429259698Sdim unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } 430259698Sdim}; 431259698Sdim 432259698Sdimtemplate <class ELFT> struct Elf_Phdr_Impl; 433259698Sdim 434259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 435259698Sdimstruct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > { 436259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) 437259698Sdim Elf_Word p_type; // Type of segment 438259698Sdim Elf_Off p_offset; // FileOffset where segment is located, in bytes 439259698Sdim Elf_Addr p_vaddr; // Virtual Address of beginning of segment 440259698Sdim Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) 441259698Sdim Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero) 442259698Sdim Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero) 443259698Sdim Elf_Word p_flags; // Segment flags 444259698Sdim Elf_Word p_align; // Segment alignment constraint 445259698Sdim}; 446259698Sdim 447259698Sdimtemplate <endianness TargetEndianness, std::size_t MaxAlign> 448259698Sdimstruct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > { 449259698Sdim LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) 450259698Sdim Elf_Word p_type; // Type of segment 451259698Sdim Elf_Word p_flags; // Segment flags 452259698Sdim Elf_Off p_offset; // FileOffset where segment is located, in bytes 453259698Sdim Elf_Addr p_vaddr; // Virtual Address of beginning of segment 454259698Sdim Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific) 455259698Sdim Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero) 456259698Sdim Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero) 457259698Sdim Elf_Xword p_align; // Segment alignment constraint 458259698Sdim}; 459259698Sdim 460259698Sdim} // end namespace object. 461259698Sdim} // end namespace llvm. 462259698Sdim 463259698Sdim#endif 464