1 //===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_OBJECT_ELFTYPES_H
10 #define LLVM_OBJECT_ELFTYPES_H
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/BinaryFormat/ELF.h"
15 #include "llvm/Object/Error.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/Error.h"
21 #include <type_traits>
26 using support::endianness
;
28 template <class ELFT
> struct Elf_Ehdr_Impl
;
29 template <class ELFT
> struct Elf_Shdr_Impl
;
30 template <class ELFT
> struct Elf_Sym_Impl
;
31 template <class ELFT
> struct Elf_Dyn_Impl
;
32 template <class ELFT
> struct Elf_Phdr_Impl
;
33 template <class ELFT
, bool isRela
> struct Elf_Rel_Impl
;
34 template <class ELFT
> struct Elf_Verdef_Impl
;
35 template <class ELFT
> struct Elf_Verdaux_Impl
;
36 template <class ELFT
> struct Elf_Verneed_Impl
;
37 template <class ELFT
> struct Elf_Vernaux_Impl
;
38 template <class ELFT
> struct Elf_Versym_Impl
;
39 template <class ELFT
> struct Elf_Hash_Impl
;
40 template <class ELFT
> struct Elf_GnuHash_Impl
;
41 template <class ELFT
> struct Elf_Chdr_Impl
;
42 template <class ELFT
> struct Elf_Nhdr_Impl
;
43 template <class ELFT
> class Elf_Note_Impl
;
44 template <class ELFT
> class Elf_Note_Iterator_Impl
;
45 template <class ELFT
> struct Elf_CGProfile_Impl
;
47 template <endianness E
, bool Is64
> struct ELFType
{
49 template <typename Ty
>
50 using packed
= support::detail::packed_endian_specific_integral
<Ty
, E
, 1>;
53 static const endianness TargetEndianness
= E
;
54 static const bool Is64Bits
= Is64
;
56 using uint
= typename
std::conditional
<Is64
, uint64_t, uint32_t>::type
;
57 using Ehdr
= Elf_Ehdr_Impl
<ELFType
<E
, Is64
>>;
58 using Shdr
= Elf_Shdr_Impl
<ELFType
<E
, Is64
>>;
59 using Sym
= Elf_Sym_Impl
<ELFType
<E
, Is64
>>;
60 using Dyn
= Elf_Dyn_Impl
<ELFType
<E
, Is64
>>;
61 using Phdr
= Elf_Phdr_Impl
<ELFType
<E
, Is64
>>;
62 using Rel
= Elf_Rel_Impl
<ELFType
<E
, Is64
>, false>;
63 using Rela
= Elf_Rel_Impl
<ELFType
<E
, Is64
>, true>;
64 using Relr
= packed
<uint
>;
65 using Verdef
= Elf_Verdef_Impl
<ELFType
<E
, Is64
>>;
66 using Verdaux
= Elf_Verdaux_Impl
<ELFType
<E
, Is64
>>;
67 using Verneed
= Elf_Verneed_Impl
<ELFType
<E
, Is64
>>;
68 using Vernaux
= Elf_Vernaux_Impl
<ELFType
<E
, Is64
>>;
69 using Versym
= Elf_Versym_Impl
<ELFType
<E
, Is64
>>;
70 using Hash
= Elf_Hash_Impl
<ELFType
<E
, Is64
>>;
71 using GnuHash
= Elf_GnuHash_Impl
<ELFType
<E
, Is64
>>;
72 using Chdr
= Elf_Chdr_Impl
<ELFType
<E
, Is64
>>;
73 using Nhdr
= Elf_Nhdr_Impl
<ELFType
<E
, Is64
>>;
74 using Note
= Elf_Note_Impl
<ELFType
<E
, Is64
>>;
75 using NoteIterator
= Elf_Note_Iterator_Impl
<ELFType
<E
, Is64
>>;
76 using CGProfile
= Elf_CGProfile_Impl
<ELFType
<E
, Is64
>>;
77 using DynRange
= ArrayRef
<Dyn
>;
78 using ShdrRange
= ArrayRef
<Shdr
>;
79 using SymRange
= ArrayRef
<Sym
>;
80 using RelRange
= ArrayRef
<Rel
>;
81 using RelaRange
= ArrayRef
<Rela
>;
82 using RelrRange
= ArrayRef
<Relr
>;
83 using PhdrRange
= ArrayRef
<Phdr
>;
85 using Half
= packed
<uint16_t>;
86 using Word
= packed
<uint32_t>;
87 using Sword
= packed
<int32_t>;
88 using Xword
= packed
<uint64_t>;
89 using Sxword
= packed
<int64_t>;
90 using Addr
= packed
<uint
>;
91 using Off
= packed
<uint
>;
94 using ELF32LE
= ELFType
<support::little
, false>;
95 using ELF32BE
= ELFType
<support::big
, false>;
96 using ELF64LE
= ELFType
<support::little
, true>;
97 using ELF64BE
= ELFType
<support::big
, true>;
99 // Use an alignment of 2 for the typedefs since that is the worst case for
100 // ELF files in archives.
102 // I really don't like doing this, but the alternative is copypasta.
103 #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
104 using Elf_Addr = typename ELFT::Addr; \
105 using Elf_Off = typename ELFT::Off; \
106 using Elf_Half = typename ELFT::Half; \
107 using Elf_Word = typename ELFT::Word; \
108 using Elf_Sword = typename ELFT::Sword; \
109 using Elf_Xword = typename ELFT::Xword; \
110 using Elf_Sxword = typename ELFT::Sxword;
112 #define LLVM_ELF_COMMA ,
113 #define LLVM_ELF_IMPORT_TYPES(E, W) \
114 LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
117 template <class ELFT
> struct Elf_Shdr_Base
;
119 template <endianness TargetEndianness
>
120 struct Elf_Shdr_Base
<ELFType
<TargetEndianness
, false>> {
121 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
122 Elf_Word sh_name
; // Section name (index into string table)
123 Elf_Word sh_type
; // Section type (SHT_*)
124 Elf_Word sh_flags
; // Section flags (SHF_*)
125 Elf_Addr sh_addr
; // Address where section is to be loaded
126 Elf_Off sh_offset
; // File offset of section data, in bytes
127 Elf_Word sh_size
; // Size of section, in bytes
128 Elf_Word sh_link
; // Section type-specific header table index link
129 Elf_Word sh_info
; // Section type-specific extra information
130 Elf_Word sh_addralign
; // Section address alignment
131 Elf_Word sh_entsize
; // Size of records contained within the section
134 template <endianness TargetEndianness
>
135 struct Elf_Shdr_Base
<ELFType
<TargetEndianness
, true>> {
136 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
137 Elf_Word sh_name
; // Section name (index into string table)
138 Elf_Word sh_type
; // Section type (SHT_*)
139 Elf_Xword sh_flags
; // Section flags (SHF_*)
140 Elf_Addr sh_addr
; // Address where section is to be loaded
141 Elf_Off sh_offset
; // File offset of section data, in bytes
142 Elf_Xword sh_size
; // Size of section, in bytes
143 Elf_Word sh_link
; // Section type-specific header table index link
144 Elf_Word sh_info
; // Section type-specific extra information
145 Elf_Xword sh_addralign
; // Section address alignment
146 Elf_Xword sh_entsize
; // Size of records contained within the section
149 template <class ELFT
>
150 struct Elf_Shdr_Impl
: Elf_Shdr_Base
<ELFT
> {
151 using Elf_Shdr_Base
<ELFT
>::sh_entsize
;
152 using Elf_Shdr_Base
<ELFT
>::sh_size
;
154 /// Get the number of entities this section contains if it has any.
155 unsigned getEntityCount() const {
158 return sh_size
/ sh_entsize
;
162 template <class ELFT
> struct Elf_Sym_Base
;
164 template <endianness TargetEndianness
>
165 struct Elf_Sym_Base
<ELFType
<TargetEndianness
, false>> {
166 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
167 Elf_Word st_name
; // Symbol name (index into string table)
168 Elf_Addr st_value
; // Value or address associated with the symbol
169 Elf_Word st_size
; // Size of the symbol
170 unsigned char st_info
; // Symbol's type and binding attributes
171 unsigned char st_other
; // Must be zero; reserved
172 Elf_Half st_shndx
; // Which section (header table index) it's defined in
175 template <endianness TargetEndianness
>
176 struct Elf_Sym_Base
<ELFType
<TargetEndianness
, true>> {
177 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
178 Elf_Word st_name
; // Symbol name (index into string table)
179 unsigned char st_info
; // Symbol's type and binding attributes
180 unsigned char st_other
; // Must be zero; reserved
181 Elf_Half st_shndx
; // Which section (header table index) it's defined in
182 Elf_Addr st_value
; // Value or address associated with the symbol
183 Elf_Xword st_size
; // Size of the symbol
186 template <class ELFT
>
187 struct Elf_Sym_Impl
: Elf_Sym_Base
<ELFT
> {
188 using Elf_Sym_Base
<ELFT
>::st_info
;
189 using Elf_Sym_Base
<ELFT
>::st_shndx
;
190 using Elf_Sym_Base
<ELFT
>::st_other
;
191 using Elf_Sym_Base
<ELFT
>::st_value
;
193 // These accessors and mutators correspond to the ELF32_ST_BIND,
194 // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
195 unsigned char getBinding() const { return st_info
>> 4; }
196 unsigned char getType() const { return st_info
& 0x0f; }
197 uint64_t getValue() const { return st_value
; }
198 void setBinding(unsigned char b
) { setBindingAndType(b
, getType()); }
199 void setType(unsigned char t
) { setBindingAndType(getBinding(), t
); }
201 void setBindingAndType(unsigned char b
, unsigned char t
) {
202 st_info
= (b
<< 4) + (t
& 0x0f);
205 /// Access to the STV_xxx flag stored in the first two bits of st_other.
210 unsigned char getVisibility() const { return st_other
& 0x3; }
211 void setVisibility(unsigned char v
) {
212 assert(v
< 4 && "Invalid value for visibility");
213 st_other
= (st_other
& ~0x3) | v
;
216 bool isAbsolute() const { return st_shndx
== ELF::SHN_ABS
; }
218 bool isCommon() const {
219 return getType() == ELF::STT_COMMON
|| st_shndx
== ELF::SHN_COMMON
;
222 bool isDefined() const { return !isUndefined(); }
224 bool isProcessorSpecific() const {
225 return st_shndx
>= ELF::SHN_LOPROC
&& st_shndx
<= ELF::SHN_HIPROC
;
228 bool isOSSpecific() const {
229 return st_shndx
>= ELF::SHN_LOOS
&& st_shndx
<= ELF::SHN_HIOS
;
232 bool isReserved() const {
233 // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
234 // true and some compilers warn about it.
235 return st_shndx
>= ELF::SHN_LORESERVE
;
238 bool isUndefined() const { return st_shndx
== ELF::SHN_UNDEF
; }
240 bool isExternal() const {
241 return getBinding() != ELF::STB_LOCAL
;
244 Expected
<StringRef
> getName(StringRef StrTab
) const;
247 template <class ELFT
>
248 Expected
<StringRef
> Elf_Sym_Impl
<ELFT
>::getName(StringRef StrTab
) const {
249 uint32_t Offset
= this->st_name
;
250 if (Offset
>= StrTab
.size())
251 return createStringError(object_error::parse_failed
,
252 "st_name (0x%" PRIx32
253 ") is past the end of the string table"
255 Offset
, StrTab
.size());
256 return StringRef(StrTab
.data() + Offset
);
259 /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
260 /// (.gnu.version). This structure is identical for ELF32 and ELF64.
261 template <class ELFT
>
262 struct Elf_Versym_Impl
{
263 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
264 Elf_Half vs_index
; // Version index with flags (e.g. VERSYM_HIDDEN)
267 /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
268 /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
269 template <class ELFT
>
270 struct Elf_Verdef_Impl
{
271 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
272 using Elf_Verdaux
= Elf_Verdaux_Impl
<ELFT
>;
273 Elf_Half vd_version
; // Version of this structure (e.g. VER_DEF_CURRENT)
274 Elf_Half vd_flags
; // Bitwise flags (VER_DEF_*)
275 Elf_Half vd_ndx
; // Version index, used in .gnu.version entries
276 Elf_Half vd_cnt
; // Number of Verdaux entries
277 Elf_Word vd_hash
; // Hash of name
278 Elf_Word vd_aux
; // Offset to the first Verdaux entry (in bytes)
279 Elf_Word vd_next
; // Offset to the next Verdef entry (in bytes)
281 /// Get the first Verdaux entry for this Verdef.
282 const Elf_Verdaux
*getAux() const {
283 return reinterpret_cast<const Elf_Verdaux
*>((const char *)this + vd_aux
);
287 /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
288 /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
289 template <class ELFT
>
290 struct Elf_Verdaux_Impl
{
291 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
292 Elf_Word vda_name
; // Version name (offset in string table)
293 Elf_Word vda_next
; // Offset to next Verdaux entry (in bytes)
296 /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
297 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
298 template <class ELFT
>
299 struct Elf_Verneed_Impl
{
300 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
301 Elf_Half vn_version
; // Version of this structure (e.g. VER_NEED_CURRENT)
302 Elf_Half vn_cnt
; // Number of associated Vernaux entries
303 Elf_Word vn_file
; // Library name (string table offset)
304 Elf_Word vn_aux
; // Offset to first Vernaux entry (in bytes)
305 Elf_Word vn_next
; // Offset to next Verneed entry (in bytes)
308 /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
309 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
310 template <class ELFT
>
311 struct Elf_Vernaux_Impl
{
312 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
313 Elf_Word vna_hash
; // Hash of dependency name
314 Elf_Half vna_flags
; // Bitwise Flags (VER_FLAG_*)
315 Elf_Half vna_other
; // Version index, used in .gnu.version entries
316 Elf_Word vna_name
; // Dependency name
317 Elf_Word vna_next
; // Offset to next Vernaux entry (in bytes)
320 /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
321 /// table section (.dynamic) look like.
322 template <class ELFT
> struct Elf_Dyn_Base
;
324 template <endianness TargetEndianness
>
325 struct Elf_Dyn_Base
<ELFType
<TargetEndianness
, false>> {
326 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
334 template <endianness TargetEndianness
>
335 struct Elf_Dyn_Base
<ELFType
<TargetEndianness
, true>> {
336 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
344 /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
345 template <class ELFT
>
346 struct Elf_Dyn_Impl
: Elf_Dyn_Base
<ELFT
> {
347 using Elf_Dyn_Base
<ELFT
>::d_tag
;
348 using Elf_Dyn_Base
<ELFT
>::d_un
;
349 using intX_t
= typename
std::conditional
<ELFT::Is64Bits
,
350 int64_t, int32_t>::type
;
351 using uintX_t
= typename
std::conditional
<ELFT::Is64Bits
,
352 uint64_t, uint32_t>::type
;
353 intX_t
getTag() const { return d_tag
; }
354 uintX_t
getVal() const { return d_un
.d_val
; }
355 uintX_t
getPtr() const { return d_un
.d_ptr
; }
358 template <endianness TargetEndianness
>
359 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, false>, false> {
360 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
361 static const bool IsRela
= false;
362 Elf_Addr r_offset
; // Location (file byte offset, or program virtual addr)
363 Elf_Word r_info
; // Symbol table index and type of relocation to apply
365 uint32_t getRInfo(bool isMips64EL
) const {
369 void setRInfo(uint32_t R
, bool IsMips64EL
) {
374 // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
375 // and ELF32_R_INFO macros defined in the ELF specification:
376 uint32_t getSymbol(bool isMips64EL
) const {
377 return this->getRInfo(isMips64EL
) >> 8;
379 unsigned char getType(bool isMips64EL
) const {
380 return (unsigned char)(this->getRInfo(isMips64EL
) & 0x0ff);
382 void setSymbol(uint32_t s
, bool IsMips64EL
) {
383 setSymbolAndType(s
, getType(IsMips64EL
), IsMips64EL
);
385 void setType(unsigned char t
, bool IsMips64EL
) {
386 setSymbolAndType(getSymbol(IsMips64EL
), t
, IsMips64EL
);
388 void setSymbolAndType(uint32_t s
, unsigned char t
, bool IsMips64EL
) {
389 this->setRInfo((s
<< 8) + t
, IsMips64EL
);
393 template <endianness TargetEndianness
>
394 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, false>, true>
395 : public Elf_Rel_Impl
<ELFType
<TargetEndianness
, false>, false> {
396 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
397 static const bool IsRela
= true;
398 Elf_Sword r_addend
; // Compute value for relocatable field by adding this
401 template <endianness TargetEndianness
>
402 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, true>, false> {
403 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
404 static const bool IsRela
= false;
405 Elf_Addr r_offset
; // Location (file byte offset, or program virtual addr)
406 Elf_Xword r_info
; // Symbol table index and type of relocation to apply
408 uint64_t getRInfo(bool isMips64EL
) const {
412 // Mips64 little endian has a "special" encoding of r_info. Instead of one
413 // 64 bit little endian number, it is a little endian 32 bit number followed
414 // by a 32 bit big endian number.
415 return (t
<< 32) | ((t
>> 8) & 0xff000000) | ((t
>> 24) & 0x00ff0000) |
416 ((t
>> 40) & 0x0000ff00) | ((t
>> 56) & 0x000000ff);
419 void setRInfo(uint64_t R
, bool IsMips64EL
) {
421 r_info
= (R
>> 32) | ((R
& 0xff000000) << 8) | ((R
& 0x00ff0000) << 24) |
422 ((R
& 0x0000ff00) << 40) | ((R
& 0x000000ff) << 56);
427 // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
428 // and ELF64_R_INFO macros defined in the ELF specification:
429 uint32_t getSymbol(bool isMips64EL
) const {
430 return (uint32_t)(this->getRInfo(isMips64EL
) >> 32);
432 uint32_t getType(bool isMips64EL
) const {
433 return (uint32_t)(this->getRInfo(isMips64EL
) & 0xffffffffL
);
435 void setSymbol(uint32_t s
, bool IsMips64EL
) {
436 setSymbolAndType(s
, getType(IsMips64EL
), IsMips64EL
);
438 void setType(uint32_t t
, bool IsMips64EL
) {
439 setSymbolAndType(getSymbol(IsMips64EL
), t
, IsMips64EL
);
441 void setSymbolAndType(uint32_t s
, uint32_t t
, bool IsMips64EL
) {
442 this->setRInfo(((uint64_t)s
<< 32) + (t
& 0xffffffffL
), IsMips64EL
);
446 template <endianness TargetEndianness
>
447 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, true>, true>
448 : public Elf_Rel_Impl
<ELFType
<TargetEndianness
, true>, false> {
449 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
450 static const bool IsRela
= true;
451 Elf_Sxword r_addend
; // Compute value for relocatable field by adding this.
454 template <class ELFT
>
455 struct Elf_Ehdr_Impl
{
456 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
457 unsigned char e_ident
[ELF::EI_NIDENT
]; // ELF Identification bytes
458 Elf_Half e_type
; // Type of file (see ET_*)
459 Elf_Half e_machine
; // Required architecture for this file (see EM_*)
460 Elf_Word e_version
; // Must be equal to 1
461 Elf_Addr e_entry
; // Address to jump to in order to start program
462 Elf_Off e_phoff
; // Program header table's file offset, in bytes
463 Elf_Off e_shoff
; // Section header table's file offset, in bytes
464 Elf_Word e_flags
; // Processor-specific flags
465 Elf_Half e_ehsize
; // Size of ELF header, in bytes
466 Elf_Half e_phentsize
; // Size of an entry in the program header table
467 Elf_Half e_phnum
; // Number of entries in the program header table
468 Elf_Half e_shentsize
; // Size of an entry in the section header table
469 Elf_Half e_shnum
; // Number of entries in the section header table
470 Elf_Half e_shstrndx
; // Section header table index of section name
473 bool checkMagic() const {
474 return (memcmp(e_ident
, ELF::ElfMagic
, strlen(ELF::ElfMagic
))) == 0;
477 unsigned char getFileClass() const { return e_ident
[ELF::EI_CLASS
]; }
478 unsigned char getDataEncoding() const { return e_ident
[ELF::EI_DATA
]; }
481 template <endianness TargetEndianness
>
482 struct Elf_Phdr_Impl
<ELFType
<TargetEndianness
, false>> {
483 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
484 Elf_Word p_type
; // Type of segment
485 Elf_Off p_offset
; // FileOffset where segment is located, in bytes
486 Elf_Addr p_vaddr
; // Virtual Address of beginning of segment
487 Elf_Addr p_paddr
; // Physical address of beginning of segment (OS-specific)
488 Elf_Word p_filesz
; // Num. of bytes in file image of segment (may be zero)
489 Elf_Word p_memsz
; // Num. of bytes in mem image of segment (may be zero)
490 Elf_Word p_flags
; // Segment flags
491 Elf_Word p_align
; // Segment alignment constraint
494 template <endianness TargetEndianness
>
495 struct Elf_Phdr_Impl
<ELFType
<TargetEndianness
, true>> {
496 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
497 Elf_Word p_type
; // Type of segment
498 Elf_Word p_flags
; // Segment flags
499 Elf_Off p_offset
; // FileOffset where segment is located, in bytes
500 Elf_Addr p_vaddr
; // Virtual Address of beginning of segment
501 Elf_Addr p_paddr
; // Physical address of beginning of segment (OS-specific)
502 Elf_Xword p_filesz
; // Num. of bytes in file image of segment (may be zero)
503 Elf_Xword p_memsz
; // Num. of bytes in mem image of segment (may be zero)
504 Elf_Xword p_align
; // Segment alignment constraint
507 // ELFT needed for endianness.
508 template <class ELFT
>
509 struct Elf_Hash_Impl
{
510 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
514 ArrayRef
<Elf_Word
> buckets() const {
515 return ArrayRef
<Elf_Word
>(&nbucket
+ 2, &nbucket
+ 2 + nbucket
);
518 ArrayRef
<Elf_Word
> chains() const {
519 return ArrayRef
<Elf_Word
>(&nbucket
+ 2 + nbucket
,
520 &nbucket
+ 2 + nbucket
+ nchain
);
525 template <class ELFT
>
526 struct Elf_GnuHash_Impl
{
527 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
533 ArrayRef
<Elf_Off
> filter() const {
534 return ArrayRef
<Elf_Off
>(reinterpret_cast<const Elf_Off
*>(&shift2
+ 1),
538 ArrayRef
<Elf_Word
> buckets() const {
539 return ArrayRef
<Elf_Word
>(
540 reinterpret_cast<const Elf_Word
*>(filter().end()), nbuckets
);
543 ArrayRef
<Elf_Word
> values(unsigned DynamicSymCount
) const {
544 return ArrayRef
<Elf_Word
>(buckets().end(), DynamicSymCount
- symndx
);
548 // Compressed section headers.
549 // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
550 template <endianness TargetEndianness
>
551 struct Elf_Chdr_Impl
<ELFType
<TargetEndianness
, false>> {
552 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
555 Elf_Word ch_addralign
;
558 template <endianness TargetEndianness
>
559 struct Elf_Chdr_Impl
<ELFType
<TargetEndianness
, true>> {
560 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
562 Elf_Word ch_reserved
;
564 Elf_Xword ch_addralign
;
568 template <class ELFT
>
569 struct Elf_Nhdr_Impl
{
570 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
575 /// The alignment of the name and descriptor.
577 /// Implementations differ from the specification here: in practice all
578 /// variants align both the name and descriptor to 4-bytes.
579 static const unsigned int Align
= 4;
581 /// Get the size of the note, including name, descriptor, and padding.
582 size_t getSize() const {
583 return sizeof(*this) + alignTo
<Align
>(n_namesz
) + alignTo
<Align
>(n_descsz
);
589 /// Wraps a note header, providing methods for accessing the name and
590 /// descriptor safely.
591 template <class ELFT
>
592 class Elf_Note_Impl
{
593 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
595 const Elf_Nhdr_Impl
<ELFT
> &Nhdr
;
597 template <class NoteIteratorELFT
> friend class Elf_Note_Iterator_Impl
;
600 Elf_Note_Impl(const Elf_Nhdr_Impl
<ELFT
> &Nhdr
) : Nhdr(Nhdr
) {}
602 /// Get the note's name, excluding the terminating null byte.
603 StringRef
getName() const {
606 return StringRef(reinterpret_cast<const char *>(&Nhdr
) + sizeof(Nhdr
),
610 /// Get the note's descriptor.
611 ArrayRef
<uint8_t> getDesc() const {
613 return ArrayRef
<uint8_t>();
614 return ArrayRef
<uint8_t>(
615 reinterpret_cast<const uint8_t *>(&Nhdr
) + sizeof(Nhdr
) +
616 alignTo
<Elf_Nhdr_Impl
<ELFT
>::Align
>(Nhdr
.n_namesz
),
620 /// Get the note's type.
621 Elf_Word
getType() const { return Nhdr
.n_type
; }
624 template <class ELFT
>
625 class Elf_Note_Iterator_Impl
626 : std::iterator
<std::forward_iterator_tag
, Elf_Note_Impl
<ELFT
>> {
627 // Nhdr being a nullptr marks the end of iteration.
628 const Elf_Nhdr_Impl
<ELFT
> *Nhdr
= nullptr;
629 size_t RemainingSize
= 0u;
630 Error
*Err
= nullptr;
632 template <class ELFFileELFT
> friend class ELFFile
;
634 // Stop iteration and indicate an overflow.
635 void stopWithOverflowError() {
637 *Err
= make_error
<StringError
>("ELF note overflows container",
638 object_error::parse_failed
);
641 // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
643 // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
644 // upon returning. Handles stopping iteration when reaching the end of the
645 // container, either cleanly or with an overflow error.
646 void advanceNhdr(const uint8_t *NhdrPos
, size_t NoteSize
) {
647 RemainingSize
-= NoteSize
;
648 if (RemainingSize
== 0u) {
649 // Ensure that if the iterator walks to the end, the error is checked
651 *Err
= Error::success();
653 } else if (sizeof(*Nhdr
) > RemainingSize
)
654 stopWithOverflowError();
656 Nhdr
= reinterpret_cast<const Elf_Nhdr_Impl
<ELFT
> *>(NhdrPos
+ NoteSize
);
657 if (Nhdr
->getSize() > RemainingSize
)
658 stopWithOverflowError();
660 *Err
= Error::success();
664 Elf_Note_Iterator_Impl() {}
665 explicit Elf_Note_Iterator_Impl(Error
&Err
) : Err(&Err
) {}
666 Elf_Note_Iterator_Impl(const uint8_t *Start
, size_t Size
, Error
&Err
)
667 : RemainingSize(Size
), Err(&Err
) {
668 consumeError(std::move(Err
));
669 assert(Start
&& "ELF note iterator starting at NULL");
670 advanceNhdr(Start
, 0u);
674 Elf_Note_Iterator_Impl
&operator++() {
675 assert(Nhdr
&& "incremented ELF note end iterator");
676 const uint8_t *NhdrPos
= reinterpret_cast<const uint8_t *>(Nhdr
);
677 size_t NoteSize
= Nhdr
->getSize();
678 advanceNhdr(NhdrPos
, NoteSize
);
681 bool operator==(Elf_Note_Iterator_Impl Other
) const {
682 if (!Nhdr
&& Other
.Err
)
683 (void)(bool)(*Other
.Err
);
684 if (!Other
.Nhdr
&& Err
)
686 return Nhdr
== Other
.Nhdr
;
688 bool operator!=(Elf_Note_Iterator_Impl Other
) const {
689 return !(*this == Other
);
691 Elf_Note_Impl
<ELFT
> operator*() const {
692 assert(Nhdr
&& "dereferenced ELF note end iterator");
693 return Elf_Note_Impl
<ELFT
>(*Nhdr
);
697 template <class ELFT
> struct Elf_CGProfile_Impl
{
698 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
701 Elf_Xword cgp_weight
;
704 // MIPS .reginfo section
705 template <class ELFT
>
706 struct Elf_Mips_RegInfo
;
708 template <support::endianness TargetEndianness
>
709 struct Elf_Mips_RegInfo
<ELFType
<TargetEndianness
, false>> {
710 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
711 Elf_Word ri_gprmask
; // bit-mask of used general registers
712 Elf_Word ri_cprmask
[4]; // bit-mask of used co-processor registers
713 Elf_Addr ri_gp_value
; // gp register value
716 template <support::endianness TargetEndianness
>
717 struct Elf_Mips_RegInfo
<ELFType
<TargetEndianness
, true>> {
718 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
719 Elf_Word ri_gprmask
; // bit-mask of used general registers
720 Elf_Word ri_pad
; // unused padding field
721 Elf_Word ri_cprmask
[4]; // bit-mask of used co-processor registers
722 Elf_Addr ri_gp_value
; // gp register value
725 // .MIPS.options section
726 template <class ELFT
> struct Elf_Mips_Options
{
727 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
728 uint8_t kind
; // Determines interpretation of variable part of descriptor
729 uint8_t size
; // Byte size of descriptor, including this header
730 Elf_Half section
; // Section header index of section affected,
731 // or 0 for global options
732 Elf_Word info
; // Kind-specific information
734 Elf_Mips_RegInfo
<ELFT
> &getRegInfo() {
735 assert(kind
== ELF::ODK_REGINFO
);
736 return *reinterpret_cast<Elf_Mips_RegInfo
<ELFT
> *>(
737 (uint8_t *)this + sizeof(Elf_Mips_Options
));
739 const Elf_Mips_RegInfo
<ELFT
> &getRegInfo() const {
740 return const_cast<Elf_Mips_Options
*>(this)->getRegInfo();
744 // .MIPS.abiflags section content
745 template <class ELFT
> struct Elf_Mips_ABIFlags
{
746 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
747 Elf_Half version
; // Version of the structure
748 uint8_t isa_level
; // ISA level: 1-5, 32, and 64
749 uint8_t isa_rev
; // ISA revision (0 for MIPS I - MIPS V)
750 uint8_t gpr_size
; // General purpose registers size
751 uint8_t cpr1_size
; // Co-processor 1 registers size
752 uint8_t cpr2_size
; // Co-processor 2 registers size
753 uint8_t fp_abi
; // Floating-point ABI flag
754 Elf_Word isa_ext
; // Processor-specific extension
755 Elf_Word ases
; // ASEs flags
756 Elf_Word flags1
; // General flags
757 Elf_Word flags2
; // General flags
760 } // end namespace object.
761 } // end namespace llvm.
763 #endif // LLVM_OBJECT_ELFTYPES_H