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 errorCodeToError(object_error::parse_failed
);
252 return StringRef(StrTab
.data() + Offset
);
255 /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
256 /// (.gnu.version). This structure is identical for ELF32 and ELF64.
257 template <class ELFT
>
258 struct Elf_Versym_Impl
{
259 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
260 Elf_Half vs_index
; // Version index with flags (e.g. VERSYM_HIDDEN)
263 /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
264 /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
265 template <class ELFT
>
266 struct Elf_Verdef_Impl
{
267 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
268 using Elf_Verdaux
= Elf_Verdaux_Impl
<ELFT
>;
269 Elf_Half vd_version
; // Version of this structure (e.g. VER_DEF_CURRENT)
270 Elf_Half vd_flags
; // Bitwise flags (VER_DEF_*)
271 Elf_Half vd_ndx
; // Version index, used in .gnu.version entries
272 Elf_Half vd_cnt
; // Number of Verdaux entries
273 Elf_Word vd_hash
; // Hash of name
274 Elf_Word vd_aux
; // Offset to the first Verdaux entry (in bytes)
275 Elf_Word vd_next
; // Offset to the next Verdef entry (in bytes)
277 /// Get the first Verdaux entry for this Verdef.
278 const Elf_Verdaux
*getAux() const {
279 return reinterpret_cast<const Elf_Verdaux
*>((const char *)this + vd_aux
);
283 /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
284 /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
285 template <class ELFT
>
286 struct Elf_Verdaux_Impl
{
287 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
288 Elf_Word vda_name
; // Version name (offset in string table)
289 Elf_Word vda_next
; // Offset to next Verdaux entry (in bytes)
292 /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
293 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
294 template <class ELFT
>
295 struct Elf_Verneed_Impl
{
296 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
297 Elf_Half vn_version
; // Version of this structure (e.g. VER_NEED_CURRENT)
298 Elf_Half vn_cnt
; // Number of associated Vernaux entries
299 Elf_Word vn_file
; // Library name (string table offset)
300 Elf_Word vn_aux
; // Offset to first Vernaux entry (in bytes)
301 Elf_Word vn_next
; // Offset to next Verneed entry (in bytes)
304 /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
305 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
306 template <class ELFT
>
307 struct Elf_Vernaux_Impl
{
308 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
309 Elf_Word vna_hash
; // Hash of dependency name
310 Elf_Half vna_flags
; // Bitwise Flags (VER_FLAG_*)
311 Elf_Half vna_other
; // Version index, used in .gnu.version entries
312 Elf_Word vna_name
; // Dependency name
313 Elf_Word vna_next
; // Offset to next Vernaux entry (in bytes)
316 /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
317 /// table section (.dynamic) look like.
318 template <class ELFT
> struct Elf_Dyn_Base
;
320 template <endianness TargetEndianness
>
321 struct Elf_Dyn_Base
<ELFType
<TargetEndianness
, false>> {
322 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
330 template <endianness TargetEndianness
>
331 struct Elf_Dyn_Base
<ELFType
<TargetEndianness
, true>> {
332 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
340 /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
341 template <class ELFT
>
342 struct Elf_Dyn_Impl
: Elf_Dyn_Base
<ELFT
> {
343 using Elf_Dyn_Base
<ELFT
>::d_tag
;
344 using Elf_Dyn_Base
<ELFT
>::d_un
;
345 using intX_t
= typename
std::conditional
<ELFT::Is64Bits
,
346 int64_t, int32_t>::type
;
347 using uintX_t
= typename
std::conditional
<ELFT::Is64Bits
,
348 uint64_t, uint32_t>::type
;
349 intX_t
getTag() const { return d_tag
; }
350 uintX_t
getVal() const { return d_un
.d_val
; }
351 uintX_t
getPtr() const { return d_un
.d_ptr
; }
354 template <endianness TargetEndianness
>
355 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, false>, false> {
356 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
357 static const bool IsRela
= false;
358 Elf_Addr r_offset
; // Location (file byte offset, or program virtual addr)
359 Elf_Word r_info
; // Symbol table index and type of relocation to apply
361 uint32_t getRInfo(bool isMips64EL
) const {
365 void setRInfo(uint32_t R
, bool IsMips64EL
) {
370 // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
371 // and ELF32_R_INFO macros defined in the ELF specification:
372 uint32_t getSymbol(bool isMips64EL
) const {
373 return this->getRInfo(isMips64EL
) >> 8;
375 unsigned char getType(bool isMips64EL
) const {
376 return (unsigned char)(this->getRInfo(isMips64EL
) & 0x0ff);
378 void setSymbol(uint32_t s
, bool IsMips64EL
) {
379 setSymbolAndType(s
, getType(IsMips64EL
), IsMips64EL
);
381 void setType(unsigned char t
, bool IsMips64EL
) {
382 setSymbolAndType(getSymbol(IsMips64EL
), t
, IsMips64EL
);
384 void setSymbolAndType(uint32_t s
, unsigned char t
, bool IsMips64EL
) {
385 this->setRInfo((s
<< 8) + t
, IsMips64EL
);
389 template <endianness TargetEndianness
>
390 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, false>, true>
391 : public Elf_Rel_Impl
<ELFType
<TargetEndianness
, false>, false> {
392 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
393 static const bool IsRela
= true;
394 Elf_Sword r_addend
; // Compute value for relocatable field by adding this
397 template <endianness TargetEndianness
>
398 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, true>, false> {
399 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
400 static const bool IsRela
= false;
401 Elf_Addr r_offset
; // Location (file byte offset, or program virtual addr)
402 Elf_Xword r_info
; // Symbol table index and type of relocation to apply
404 uint64_t getRInfo(bool isMips64EL
) const {
408 // Mips64 little endian has a "special" encoding of r_info. Instead of one
409 // 64 bit little endian number, it is a little endian 32 bit number followed
410 // by a 32 bit big endian number.
411 return (t
<< 32) | ((t
>> 8) & 0xff000000) | ((t
>> 24) & 0x00ff0000) |
412 ((t
>> 40) & 0x0000ff00) | ((t
>> 56) & 0x000000ff);
415 void setRInfo(uint64_t R
, bool IsMips64EL
) {
417 r_info
= (R
>> 32) | ((R
& 0xff000000) << 8) | ((R
& 0x00ff0000) << 24) |
418 ((R
& 0x0000ff00) << 40) | ((R
& 0x000000ff) << 56);
423 // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
424 // and ELF64_R_INFO macros defined in the ELF specification:
425 uint32_t getSymbol(bool isMips64EL
) const {
426 return (uint32_t)(this->getRInfo(isMips64EL
) >> 32);
428 uint32_t getType(bool isMips64EL
) const {
429 return (uint32_t)(this->getRInfo(isMips64EL
) & 0xffffffffL
);
431 void setSymbol(uint32_t s
, bool IsMips64EL
) {
432 setSymbolAndType(s
, getType(IsMips64EL
), IsMips64EL
);
434 void setType(uint32_t t
, bool IsMips64EL
) {
435 setSymbolAndType(getSymbol(IsMips64EL
), t
, IsMips64EL
);
437 void setSymbolAndType(uint32_t s
, uint32_t t
, bool IsMips64EL
) {
438 this->setRInfo(((uint64_t)s
<< 32) + (t
& 0xffffffffL
), IsMips64EL
);
442 template <endianness TargetEndianness
>
443 struct Elf_Rel_Impl
<ELFType
<TargetEndianness
, true>, true>
444 : public Elf_Rel_Impl
<ELFType
<TargetEndianness
, true>, false> {
445 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
446 static const bool IsRela
= true;
447 Elf_Sxword r_addend
; // Compute value for relocatable field by adding this.
450 template <class ELFT
>
451 struct Elf_Ehdr_Impl
{
452 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
453 unsigned char e_ident
[ELF::EI_NIDENT
]; // ELF Identification bytes
454 Elf_Half e_type
; // Type of file (see ET_*)
455 Elf_Half e_machine
; // Required architecture for this file (see EM_*)
456 Elf_Word e_version
; // Must be equal to 1
457 Elf_Addr e_entry
; // Address to jump to in order to start program
458 Elf_Off e_phoff
; // Program header table's file offset, in bytes
459 Elf_Off e_shoff
; // Section header table's file offset, in bytes
460 Elf_Word e_flags
; // Processor-specific flags
461 Elf_Half e_ehsize
; // Size of ELF header, in bytes
462 Elf_Half e_phentsize
; // Size of an entry in the program header table
463 Elf_Half e_phnum
; // Number of entries in the program header table
464 Elf_Half e_shentsize
; // Size of an entry in the section header table
465 Elf_Half e_shnum
; // Number of entries in the section header table
466 Elf_Half e_shstrndx
; // Section header table index of section name
469 bool checkMagic() const {
470 return (memcmp(e_ident
, ELF::ElfMagic
, strlen(ELF::ElfMagic
))) == 0;
473 unsigned char getFileClass() const { return e_ident
[ELF::EI_CLASS
]; }
474 unsigned char getDataEncoding() const { return e_ident
[ELF::EI_DATA
]; }
477 template <endianness TargetEndianness
>
478 struct Elf_Phdr_Impl
<ELFType
<TargetEndianness
, false>> {
479 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
480 Elf_Word p_type
; // Type of segment
481 Elf_Off p_offset
; // FileOffset where segment is located, in bytes
482 Elf_Addr p_vaddr
; // Virtual Address of beginning of segment
483 Elf_Addr p_paddr
; // Physical address of beginning of segment (OS-specific)
484 Elf_Word p_filesz
; // Num. of bytes in file image of segment (may be zero)
485 Elf_Word p_memsz
; // Num. of bytes in mem image of segment (may be zero)
486 Elf_Word p_flags
; // Segment flags
487 Elf_Word p_align
; // Segment alignment constraint
490 template <endianness TargetEndianness
>
491 struct Elf_Phdr_Impl
<ELFType
<TargetEndianness
, true>> {
492 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
493 Elf_Word p_type
; // Type of segment
494 Elf_Word p_flags
; // Segment flags
495 Elf_Off p_offset
; // FileOffset where segment is located, in bytes
496 Elf_Addr p_vaddr
; // Virtual Address of beginning of segment
497 Elf_Addr p_paddr
; // Physical address of beginning of segment (OS-specific)
498 Elf_Xword p_filesz
; // Num. of bytes in file image of segment (may be zero)
499 Elf_Xword p_memsz
; // Num. of bytes in mem image of segment (may be zero)
500 Elf_Xword p_align
; // Segment alignment constraint
503 // ELFT needed for endianness.
504 template <class ELFT
>
505 struct Elf_Hash_Impl
{
506 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
510 ArrayRef
<Elf_Word
> buckets() const {
511 return ArrayRef
<Elf_Word
>(&nbucket
+ 2, &nbucket
+ 2 + nbucket
);
514 ArrayRef
<Elf_Word
> chains() const {
515 return ArrayRef
<Elf_Word
>(&nbucket
+ 2 + nbucket
,
516 &nbucket
+ 2 + nbucket
+ nchain
);
521 template <class ELFT
>
522 struct Elf_GnuHash_Impl
{
523 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
529 ArrayRef
<Elf_Off
> filter() const {
530 return ArrayRef
<Elf_Off
>(reinterpret_cast<const Elf_Off
*>(&shift2
+ 1),
534 ArrayRef
<Elf_Word
> buckets() const {
535 return ArrayRef
<Elf_Word
>(
536 reinterpret_cast<const Elf_Word
*>(filter().end()), nbuckets
);
539 ArrayRef
<Elf_Word
> values(unsigned DynamicSymCount
) const {
540 return ArrayRef
<Elf_Word
>(buckets().end(), DynamicSymCount
- symndx
);
544 // Compressed section headers.
545 // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
546 template <endianness TargetEndianness
>
547 struct Elf_Chdr_Impl
<ELFType
<TargetEndianness
, false>> {
548 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
551 Elf_Word ch_addralign
;
554 template <endianness TargetEndianness
>
555 struct Elf_Chdr_Impl
<ELFType
<TargetEndianness
, true>> {
556 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
558 Elf_Word ch_reserved
;
560 Elf_Xword ch_addralign
;
564 template <class ELFT
>
565 struct Elf_Nhdr_Impl
{
566 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
571 /// The alignment of the name and descriptor.
573 /// Implementations differ from the specification here: in practice all
574 /// variants align both the name and descriptor to 4-bytes.
575 static const unsigned int Align
= 4;
577 /// Get the size of the note, including name, descriptor, and padding.
578 size_t getSize() const {
579 return sizeof(*this) + alignTo
<Align
>(n_namesz
) + alignTo
<Align
>(n_descsz
);
585 /// Wraps a note header, providing methods for accessing the name and
586 /// descriptor safely.
587 template <class ELFT
>
588 class Elf_Note_Impl
{
589 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
591 const Elf_Nhdr_Impl
<ELFT
> &Nhdr
;
593 template <class NoteIteratorELFT
> friend class Elf_Note_Iterator_Impl
;
595 Elf_Note_Impl(const Elf_Nhdr_Impl
<ELFT
> &Nhdr
) : Nhdr(Nhdr
) {}
598 /// Get the note's name, excluding the terminating null byte.
599 StringRef
getName() const {
602 return StringRef(reinterpret_cast<const char *>(&Nhdr
) + sizeof(Nhdr
),
606 /// Get the note's descriptor.
607 ArrayRef
<uint8_t> getDesc() const {
609 return ArrayRef
<uint8_t>();
610 return ArrayRef
<uint8_t>(
611 reinterpret_cast<const uint8_t *>(&Nhdr
) + sizeof(Nhdr
) +
612 alignTo
<Elf_Nhdr_Impl
<ELFT
>::Align
>(Nhdr
.n_namesz
),
616 /// Get the note's type.
617 Elf_Word
getType() const { return Nhdr
.n_type
; }
620 template <class ELFT
>
621 class Elf_Note_Iterator_Impl
622 : std::iterator
<std::forward_iterator_tag
, Elf_Note_Impl
<ELFT
>> {
623 // Nhdr being a nullptr marks the end of iteration.
624 const Elf_Nhdr_Impl
<ELFT
> *Nhdr
= nullptr;
625 size_t RemainingSize
= 0u;
626 Error
*Err
= nullptr;
628 template <class ELFFileELFT
> friend class ELFFile
;
630 // Stop iteration and indicate an overflow.
631 void stopWithOverflowError() {
633 *Err
= make_error
<StringError
>("ELF note overflows container",
634 object_error::parse_failed
);
637 // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
639 // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
640 // upon returning. Handles stopping iteration when reaching the end of the
641 // container, either cleanly or with an overflow error.
642 void advanceNhdr(const uint8_t *NhdrPos
, size_t NoteSize
) {
643 RemainingSize
-= NoteSize
;
644 if (RemainingSize
== 0u) {
645 // Ensure that if the iterator walks to the end, the error is checked
647 *Err
= Error::success();
649 } else if (sizeof(*Nhdr
) > RemainingSize
)
650 stopWithOverflowError();
652 Nhdr
= reinterpret_cast<const Elf_Nhdr_Impl
<ELFT
> *>(NhdrPos
+ NoteSize
);
653 if (Nhdr
->getSize() > RemainingSize
)
654 stopWithOverflowError();
656 *Err
= Error::success();
660 Elf_Note_Iterator_Impl() {}
661 explicit Elf_Note_Iterator_Impl(Error
&Err
) : Err(&Err
) {}
662 Elf_Note_Iterator_Impl(const uint8_t *Start
, size_t Size
, Error
&Err
)
663 : RemainingSize(Size
), Err(&Err
) {
664 consumeError(std::move(Err
));
665 assert(Start
&& "ELF note iterator starting at NULL");
666 advanceNhdr(Start
, 0u);
670 Elf_Note_Iterator_Impl
&operator++() {
671 assert(Nhdr
&& "incremented ELF note end iterator");
672 const uint8_t *NhdrPos
= reinterpret_cast<const uint8_t *>(Nhdr
);
673 size_t NoteSize
= Nhdr
->getSize();
674 advanceNhdr(NhdrPos
, NoteSize
);
677 bool operator==(Elf_Note_Iterator_Impl Other
) const {
678 if (!Nhdr
&& Other
.Err
)
679 (void)(bool)(*Other
.Err
);
680 if (!Other
.Nhdr
&& Err
)
682 return Nhdr
== Other
.Nhdr
;
684 bool operator!=(Elf_Note_Iterator_Impl Other
) const {
685 return !(*this == Other
);
687 Elf_Note_Impl
<ELFT
> operator*() const {
688 assert(Nhdr
&& "dereferenced ELF note end iterator");
689 return Elf_Note_Impl
<ELFT
>(*Nhdr
);
693 template <class ELFT
> struct Elf_CGProfile_Impl
{
694 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
697 Elf_Xword cgp_weight
;
700 // MIPS .reginfo section
701 template <class ELFT
>
702 struct Elf_Mips_RegInfo
;
704 template <support::endianness TargetEndianness
>
705 struct Elf_Mips_RegInfo
<ELFType
<TargetEndianness
, false>> {
706 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, false)
707 Elf_Word ri_gprmask
; // bit-mask of used general registers
708 Elf_Word ri_cprmask
[4]; // bit-mask of used co-processor registers
709 Elf_Addr ri_gp_value
; // gp register value
712 template <support::endianness TargetEndianness
>
713 struct Elf_Mips_RegInfo
<ELFType
<TargetEndianness
, true>> {
714 LLVM_ELF_IMPORT_TYPES(TargetEndianness
, true)
715 Elf_Word ri_gprmask
; // bit-mask of used general registers
716 Elf_Word ri_pad
; // unused padding field
717 Elf_Word ri_cprmask
[4]; // bit-mask of used co-processor registers
718 Elf_Addr ri_gp_value
; // gp register value
721 // .MIPS.options section
722 template <class ELFT
> struct Elf_Mips_Options
{
723 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
724 uint8_t kind
; // Determines interpretation of variable part of descriptor
725 uint8_t size
; // Byte size of descriptor, including this header
726 Elf_Half section
; // Section header index of section affected,
727 // or 0 for global options
728 Elf_Word info
; // Kind-specific information
730 Elf_Mips_RegInfo
<ELFT
> &getRegInfo() {
731 assert(kind
== ELF::ODK_REGINFO
);
732 return *reinterpret_cast<Elf_Mips_RegInfo
<ELFT
> *>(
733 (uint8_t *)this + sizeof(Elf_Mips_Options
));
735 const Elf_Mips_RegInfo
<ELFT
> &getRegInfo() const {
736 return const_cast<Elf_Mips_Options
*>(this)->getRegInfo();
740 // .MIPS.abiflags section content
741 template <class ELFT
> struct Elf_Mips_ABIFlags
{
742 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT
)
743 Elf_Half version
; // Version of the structure
744 uint8_t isa_level
; // ISA level: 1-5, 32, and 64
745 uint8_t isa_rev
; // ISA revision (0 for MIPS I - MIPS V)
746 uint8_t gpr_size
; // General purpose registers size
747 uint8_t cpr1_size
; // Co-processor 1 registers size
748 uint8_t cpr2_size
; // Co-processor 2 registers size
749 uint8_t fp_abi
; // Floating-point ABI flag
750 Elf_Word isa_ext
; // Processor-specific extension
751 Elf_Word ases
; // ASEs flags
752 Elf_Word flags1
; // General flags
753 Elf_Word flags2
; // General flags
756 } // end namespace object.
757 } // end namespace llvm.
759 #endif // LLVM_OBJECT_ELFTYPES_H