Line data Source code
1 : //===- ELFTypes.h - Endian specific types for ELF ---------------*- 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 : #ifndef LLVM_OBJECT_ELFTYPES_H
11 : #define LLVM_OBJECT_ELFTYPES_H
12 :
13 : #include "llvm/ADT/ArrayRef.h"
14 : #include "llvm/ADT/StringRef.h"
15 : #include "llvm/BinaryFormat/ELF.h"
16 : #include "llvm/Object/Error.h"
17 : #include "llvm/Support/Endian.h"
18 : #include "llvm/Support/Error.h"
19 : #include <cassert>
20 : #include <cstdint>
21 : #include <cstring>
22 : #include <type_traits>
23 :
24 : namespace llvm {
25 : namespace object {
26 :
27 : using support::endianness;
28 :
29 : template <class ELFT> struct Elf_Ehdr_Impl;
30 : template <class ELFT> struct Elf_Shdr_Impl;
31 : template <class ELFT> struct Elf_Sym_Impl;
32 : template <class ELFT> struct Elf_Dyn_Impl;
33 : template <class ELFT> struct Elf_Phdr_Impl;
34 : template <class ELFT, bool isRela> struct Elf_Rel_Impl;
35 : template <class ELFT> struct Elf_Verdef_Impl;
36 : template <class ELFT> struct Elf_Verdaux_Impl;
37 : template <class ELFT> struct Elf_Verneed_Impl;
38 : template <class ELFT> struct Elf_Vernaux_Impl;
39 : template <class ELFT> struct Elf_Versym_Impl;
40 : template <class ELFT> struct Elf_Hash_Impl;
41 : template <class ELFT> struct Elf_GnuHash_Impl;
42 : template <class ELFT> struct Elf_Chdr_Impl;
43 : template <class ELFT> struct Elf_Nhdr_Impl;
44 : template <class ELFT> class Elf_Note_Impl;
45 : template <class ELFT> class Elf_Note_Iterator_Impl;
46 : template <class ELFT> struct Elf_CGProfile_Impl;
47 :
48 : template <endianness E, bool Is64> struct ELFType {
49 : private:
50 : template <typename Ty>
51 : using packed = support::detail::packed_endian_specific_integral<Ty, E, 1>;
52 :
53 : public:
54 : static const endianness TargetEndianness = E;
55 : static const bool Is64Bits = Is64;
56 :
57 : using uint = typename std::conditional<Is64, uint64_t, uint32_t>::type;
58 : using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
59 : using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
60 : using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
61 : using Dyn = Elf_Dyn_Impl<ELFType<E, Is64>>;
62 : using Phdr = Elf_Phdr_Impl<ELFType<E, Is64>>;
63 : using Rel = Elf_Rel_Impl<ELFType<E, Is64>, false>;
64 : using Rela = Elf_Rel_Impl<ELFType<E, Is64>, true>;
65 : using Relr = packed<uint>;
66 : using Verdef = Elf_Verdef_Impl<ELFType<E, Is64>>;
67 : using Verdaux = Elf_Verdaux_Impl<ELFType<E, Is64>>;
68 : using Verneed = Elf_Verneed_Impl<ELFType<E, Is64>>;
69 : using Vernaux = Elf_Vernaux_Impl<ELFType<E, Is64>>;
70 : using Versym = Elf_Versym_Impl<ELFType<E, Is64>>;
71 : using Hash = Elf_Hash_Impl<ELFType<E, Is64>>;
72 : using GnuHash = Elf_GnuHash_Impl<ELFType<E, Is64>>;
73 : using Chdr = Elf_Chdr_Impl<ELFType<E, Is64>>;
74 : using Nhdr = Elf_Nhdr_Impl<ELFType<E, Is64>>;
75 : using Note = Elf_Note_Impl<ELFType<E, Is64>>;
76 : using NoteIterator = Elf_Note_Iterator_Impl<ELFType<E, Is64>>;
77 : using CGProfile = Elf_CGProfile_Impl<ELFType<E, Is64>>;
78 : using DynRange = ArrayRef<Dyn>;
79 : using ShdrRange = ArrayRef<Shdr>;
80 : using SymRange = ArrayRef<Sym>;
81 : using RelRange = ArrayRef<Rel>;
82 : using RelaRange = ArrayRef<Rela>;
83 : using RelrRange = ArrayRef<Relr>;
84 : using PhdrRange = ArrayRef<Phdr>;
85 :
86 : using Half = packed<uint16_t>;
87 : using Word = packed<uint32_t>;
88 : using Sword = packed<int32_t>;
89 : using Xword = packed<uint64_t>;
90 : using Sxword = packed<int64_t>;
91 : using Addr = packed<uint>;
92 : using Off = packed<uint>;
93 : };
94 :
95 : using ELF32LE = ELFType<support::little, false>;
96 : using ELF32BE = ELFType<support::big, false>;
97 : using ELF64LE = ELFType<support::little, true>;
98 : using ELF64BE = ELFType<support::big, true>;
99 :
100 : // Use an alignment of 2 for the typedefs since that is the worst case for
101 : // ELF files in archives.
102 :
103 : // I really don't like doing this, but the alternative is copypasta.
104 : #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
105 : using Elf_Addr = typename ELFT::Addr; \
106 : using Elf_Off = typename ELFT::Off; \
107 : using Elf_Half = typename ELFT::Half; \
108 : using Elf_Word = typename ELFT::Word; \
109 : using Elf_Sword = typename ELFT::Sword; \
110 : using Elf_Xword = typename ELFT::Xword; \
111 : using Elf_Sxword = typename ELFT::Sxword;
112 :
113 : #define LLVM_ELF_COMMA ,
114 : #define LLVM_ELF_IMPORT_TYPES(E, W) \
115 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
116 :
117 : // Section header.
118 : template <class ELFT> struct Elf_Shdr_Base;
119 :
120 : template <endianness TargetEndianness>
121 : struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
122 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
123 : Elf_Word sh_name; // Section name (index into string table)
124 : Elf_Word sh_type; // Section type (SHT_*)
125 : Elf_Word sh_flags; // Section flags (SHF_*)
126 : Elf_Addr sh_addr; // Address where section is to be loaded
127 : Elf_Off sh_offset; // File offset of section data, in bytes
128 : Elf_Word sh_size; // Size of section, in bytes
129 : Elf_Word sh_link; // Section type-specific header table index link
130 : Elf_Word sh_info; // Section type-specific extra information
131 : Elf_Word sh_addralign; // Section address alignment
132 : Elf_Word sh_entsize; // Size of records contained within the section
133 : };
134 :
135 : template <endianness TargetEndianness>
136 : struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
137 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
138 : Elf_Word sh_name; // Section name (index into string table)
139 : Elf_Word sh_type; // Section type (SHT_*)
140 : Elf_Xword sh_flags; // Section flags (SHF_*)
141 : Elf_Addr sh_addr; // Address where section is to be loaded
142 : Elf_Off sh_offset; // File offset of section data, in bytes
143 : Elf_Xword sh_size; // Size of section, in bytes
144 : Elf_Word sh_link; // Section type-specific header table index link
145 : Elf_Word sh_info; // Section type-specific extra information
146 : Elf_Xword sh_addralign; // Section address alignment
147 : Elf_Xword sh_entsize; // Size of records contained within the section
148 : };
149 :
150 : template <class ELFT>
151 : struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
152 : using Elf_Shdr_Base<ELFT>::sh_entsize;
153 : using Elf_Shdr_Base<ELFT>::sh_size;
154 :
155 : /// Get the number of entities this section contains if it has any.
156 : unsigned getEntityCount() const {
157 517 : if (sh_entsize == 0)
158 : return 0;
159 514 : return sh_size / sh_entsize;
160 : }
161 : };
162 :
163 : template <class ELFT> struct Elf_Sym_Base;
164 :
165 : template <endianness TargetEndianness>
166 : struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
167 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
168 : Elf_Word st_name; // Symbol name (index into string table)
169 : Elf_Addr st_value; // Value or address associated with the symbol
170 : Elf_Word st_size; // Size of the symbol
171 : unsigned char st_info; // Symbol's type and binding attributes
172 : unsigned char st_other; // Must be zero; reserved
173 : Elf_Half st_shndx; // Which section (header table index) it's defined in
174 : };
175 :
176 : template <endianness TargetEndianness>
177 : struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
178 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
179 : Elf_Word st_name; // Symbol name (index into string table)
180 : unsigned char st_info; // Symbol's type and binding attributes
181 : unsigned char st_other; // Must be zero; reserved
182 : Elf_Half st_shndx; // Which section (header table index) it's defined in
183 : Elf_Addr st_value; // Value or address associated with the symbol
184 : Elf_Xword st_size; // Size of the symbol
185 : };
186 :
187 : template <class ELFT>
188 : struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
189 : using Elf_Sym_Base<ELFT>::st_info;
190 : using Elf_Sym_Base<ELFT>::st_shndx;
191 : using Elf_Sym_Base<ELFT>::st_other;
192 : using Elf_Sym_Base<ELFT>::st_value;
193 :
194 : // These accessors and mutators correspond to the ELF32_ST_BIND,
195 : // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
196 27313141 : unsigned char getBinding() const { return st_info >> 4; }
197 40517653 : unsigned char getType() const { return st_info & 0x0f; }
198 61 : uint64_t getValue() const { return st_value; }
199 326954 : void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
200 : void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
201 :
202 : void setBindingAndType(unsigned char b, unsigned char t) {
203 740552 : st_info = (b << 4) + (t & 0x0f);
204 : }
205 :
206 : /// Access to the STV_xxx flag stored in the first two bits of st_other.
207 : /// STV_DEFAULT: 0
208 : /// STV_INTERNAL: 1
209 : /// STV_HIDDEN: 2
210 : /// STV_PROTECTED: 3
211 13448484 : unsigned char getVisibility() const { return st_other & 0x3; }
212 : void setVisibility(unsigned char v) {
213 : assert(v < 4 && "Invalid value for visibility");
214 18366 : st_other = (st_other & ~0x3) | v;
215 : }
216 :
217 : bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
218 :
219 : bool isCommon() const {
220 0 : return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
221 : }
222 :
223 : bool isDefined() const { return !isUndefined(); }
224 :
225 : bool isProcessorSpecific() const {
226 0 : return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
227 : }
228 :
229 : bool isOSSpecific() const {
230 0 : return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
231 : }
232 :
233 : bool isReserved() const {
234 : // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
235 : // true and some compilers warn about it.
236 : return st_shndx >= ELF::SHN_LORESERVE;
237 : }
238 :
239 : bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
240 :
241 : bool isExternal() const {
242 : return getBinding() != ELF::STB_LOCAL;
243 : }
244 :
245 : Expected<StringRef> getName(StringRef StrTab) const;
246 : };
247 :
248 : template <class ELFT>
249 13742900 : Expected<StringRef> Elf_Sym_Impl<ELFT>::getName(StringRef StrTab) const {
250 : uint32_t Offset = this->st_name;
251 27485800 : if (Offset >= StrTab.size())
252 0 : return errorCodeToError(object_error::parse_failed);
253 13742900 : return StringRef(StrTab.data() + Offset);
254 : }
255 25286 :
256 : /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
257 50572 : /// (.gnu.version). This structure is identical for ELF32 and ELF64.
258 0 : template <class ELFT>
259 25286 : struct Elf_Versym_Impl {
260 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
261 140299 : Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
262 : };
263 280598 :
264 0 : /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
265 140299 : /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
266 : template <class ELFT>
267 13246872 : struct Elf_Verdef_Impl {
268 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
269 26493744 : using Elf_Verdaux = Elf_Verdaux_Impl<ELFT>;
270 0 : Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
271 13246872 : Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
272 : Elf_Half vd_ndx; // Version index, used in .gnu.version entries
273 330443 : Elf_Half vd_cnt; // Number of Verdaux entries
274 : Elf_Word vd_hash; // Hash of name
275 660886 : Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes)
276 0 : Elf_Word vd_next; // Offset to the next Verdef entry (in bytes)
277 330443 :
278 : /// Get the first Verdaux entry for this Verdef.
279 : const Elf_Verdaux *getAux() const {
280 14 : return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
281 : }
282 : };
283 :
284 : /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
285 : /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
286 : template <class ELFT>
287 : struct Elf_Verdaux_Impl {
288 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
289 : Elf_Word vda_name; // Version name (offset in string table)
290 : Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
291 : };
292 :
293 : /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
294 : /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
295 : template <class ELFT>
296 : struct Elf_Verneed_Impl {
297 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
298 : Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
299 : Elf_Half vn_cnt; // Number of associated Vernaux entries
300 : Elf_Word vn_file; // Library name (string table offset)
301 : Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes)
302 : Elf_Word vn_next; // Offset to next Verneed entry (in bytes)
303 : };
304 224 :
305 : /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
306 : /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
307 : template <class ELFT>
308 : struct Elf_Vernaux_Impl {
309 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
310 : Elf_Word vna_hash; // Hash of dependency name
311 : Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
312 : Elf_Half vna_other; // Version index, used in .gnu.version entries
313 : Elf_Word vna_name; // Dependency name
314 : Elf_Word vna_next; // Offset to next Vernaux entry (in bytes)
315 : };
316 :
317 : /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
318 : /// table section (.dynamic) look like.
319 : template <class ELFT> struct Elf_Dyn_Base;
320 :
321 : template <endianness TargetEndianness>
322 : struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
323 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
324 : Elf_Sword d_tag;
325 : union {
326 : Elf_Word d_val;
327 : Elf_Addr d_ptr;
328 : } d_un;
329 : };
330 :
331 : template <endianness TargetEndianness>
332 : struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
333 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
334 : Elf_Sxword d_tag;
335 : union {
336 : Elf_Xword d_val;
337 : Elf_Addr d_ptr;
338 : } d_un;
339 : };
340 :
341 : /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
342 : template <class ELFT>
343 : struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
344 : using Elf_Dyn_Base<ELFT>::d_tag;
345 : using Elf_Dyn_Base<ELFT>::d_un;
346 : using intX_t = typename std::conditional<ELFT::Is64Bits,
347 : int64_t, int32_t>::type;
348 : using uintX_t = typename std::conditional<ELFT::Is64Bits,
349 : uint64_t, uint32_t>::type;
350 : intX_t getTag() const { return d_tag; }
351 : uintX_t getVal() const { return d_un.d_val; }
352 : uintX_t getPtr() const { return d_un.d_ptr; }
353 : };
354 :
355 : template <endianness TargetEndianness>
356 : struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
357 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
358 : static const bool IsRela = false;
359 : Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
360 : Elf_Word r_info; // Symbol table index and type of relocation to apply
361 :
362 : uint32_t getRInfo(bool isMips64EL) const {
363 : assert(!isMips64EL);
364 : return r_info;
365 : }
366 : void setRInfo(uint32_t R, bool IsMips64EL) {
367 : assert(!IsMips64EL);
368 : r_info = R;
369 : }
370 :
371 : // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
372 : // and ELF32_R_INFO macros defined in the ELF specification:
373 : uint32_t getSymbol(bool isMips64EL) const {
374 66 : return this->getRInfo(isMips64EL) >> 8;
375 : }
376 : unsigned char getType(bool isMips64EL) const {
377 0 : return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
378 : }
379 : void setSymbol(uint32_t s, bool IsMips64EL) {
380 : setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
381 : }
382 : void setType(unsigned char t, bool IsMips64EL) {
383 : setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
384 : }
385 : void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
386 373 : this->setRInfo((s << 8) + t, IsMips64EL);
387 : }
388 : };
389 :
390 : template <endianness TargetEndianness>
391 : struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, true>
392 : : public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
393 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
394 : static const bool IsRela = true;
395 : Elf_Sword r_addend; // Compute value for relocatable field by adding this
396 : };
397 :
398 4072 : template <endianness TargetEndianness>
399 : struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
400 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
401 1055 : static const bool IsRela = false;
402 : Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
403 : Elf_Xword r_info; // Symbol table index and type of relocation to apply
404 :
405 : uint64_t getRInfo(bool isMips64EL) const {
406 : uint64_t t = r_info;
407 975 : if (!isMips64EL)
408 : return t;
409 : // Mips64 little endian has a "special" encoding of r_info. Instead of one
410 0 : // 64 bit little endian number, it is a little endian 32 bit number followed
411 : // by a 32 bit big endian number.
412 0 : return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
413 0 : ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
414 : }
415 :
416 : void setRInfo(uint64_t R, bool IsMips64EL) {
417 836 : if (IsMips64EL)
418 18 : r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
419 6 : ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
420 : else
421 : r_info = R;
422 : }
423 :
424 : // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
425 : // and ELF64_R_INFO macros defined in the ELF specification:
426 : uint32_t getSymbol(bool isMips64EL) const {
427 682 : return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
428 : }
429 : uint32_t getType(bool isMips64EL) const {
430 290 : return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
431 39706 : }
432 : void setSymbol(uint32_t s, bool IsMips64EL) {
433 : setSymbolAndType(s, getType(IsMips64EL), IsMips64EL);
434 : }
435 3 : void setType(uint32_t t, bool IsMips64EL) {
436 692 : setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
437 349 : }
438 57 : void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
439 833 : this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
440 57 : }
441 3 : };
442 :
443 3 : template <endianness TargetEndianness>
444 0 : struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, true>
445 3 : : public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
446 0 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
447 : static const bool IsRela = true;
448 : Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
449 : };
450 :
451 31907 : template <class ELFT>
452 : struct Elf_Ehdr_Impl {
453 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
454 27746 : unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
455 : Elf_Half e_type; // Type of file (see ET_*)
456 : Elf_Half e_machine; // Required architecture for this file (see EM_*)
457 : Elf_Word e_version; // Must be equal to 1
458 : Elf_Addr e_entry; // Address to jump to in order to start program
459 : Elf_Off e_phoff; // Program header table's file offset, in bytes
460 : Elf_Off e_shoff; // Section header table's file offset, in bytes
461 : Elf_Word e_flags; // Processor-specific flags
462 : Elf_Half e_ehsize; // Size of ELF header, in bytes
463 101 : Elf_Half e_phentsize; // Size of an entry in the program header table
464 : Elf_Half e_phnum; // Number of entries in the program header table
465 : Elf_Half e_shentsize; // Size of an entry in the section header table
466 : Elf_Half e_shnum; // Number of entries in the section header table
467 : Elf_Half e_shstrndx; // Section header table index of section name
468 : // string table
469 :
470 : bool checkMagic() const {
471 : return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
472 : }
473 :
474 : unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
475 : unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
476 : };
477 :
478 : template <endianness TargetEndianness>
479 : struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
480 0 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
481 0 : Elf_Word p_type; // Type of segment
482 : Elf_Off p_offset; // FileOffset where segment is located, in bytes
483 : Elf_Addr p_vaddr; // Virtual Address of beginning of segment
484 : Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
485 : Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
486 : Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
487 : Elf_Word p_flags; // Segment flags
488 : Elf_Word p_align; // Segment alignment constraint
489 : };
490 :
491 : template <endianness TargetEndianness>
492 : struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
493 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
494 : Elf_Word p_type; // Type of segment
495 : Elf_Word p_flags; // Segment flags
496 : Elf_Off p_offset; // FileOffset where segment is located, in bytes
497 : Elf_Addr p_vaddr; // Virtual Address of beginning of segment
498 0 : Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
499 0 : Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
500 : Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
501 : Elf_Xword p_align; // Segment alignment constraint
502 : };
503 :
504 : // ELFT needed for endianness.
505 : template <class ELFT>
506 : struct Elf_Hash_Impl {
507 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
508 : Elf_Word nbucket;
509 : Elf_Word nchain;
510 :
511 : ArrayRef<Elf_Word> buckets() const {
512 : return ArrayRef<Elf_Word>(&nbucket + 2, &nbucket + 2 + nbucket);
513 : }
514 :
515 : ArrayRef<Elf_Word> chains() const {
516 : return ArrayRef<Elf_Word>(&nbucket + 2 + nbucket,
517 : &nbucket + 2 + nbucket + nchain);
518 : }
519 : };
520 :
521 : // .gnu.hash section
522 : template <class ELFT>
523 : struct Elf_GnuHash_Impl {
524 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
525 : Elf_Word nbuckets;
526 : Elf_Word symndx;
527 : Elf_Word maskwords;
528 : Elf_Word shift2;
529 :
530 : ArrayRef<Elf_Off> filter() const {
531 : return ArrayRef<Elf_Off>(reinterpret_cast<const Elf_Off *>(&shift2 + 1),
532 : maskwords);
533 : }
534 :
535 : ArrayRef<Elf_Word> buckets() const {
536 18 : return ArrayRef<Elf_Word>(
537 : reinterpret_cast<const Elf_Word *>(filter().end()), nbuckets);
538 : }
539 :
540 : ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
541 9 : return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
542 : }
543 : };
544 :
545 : // Compressed section headers.
546 : // http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header
547 : template <endianness TargetEndianness>
548 : struct Elf_Chdr_Impl<ELFType<TargetEndianness, false>> {
549 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
550 : Elf_Word ch_type;
551 : Elf_Word ch_size;
552 : Elf_Word ch_addralign;
553 : };
554 :
555 36 : template <endianness TargetEndianness>
556 55 : struct Elf_Chdr_Impl<ELFType<TargetEndianness, true>> {
557 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
558 : Elf_Word ch_type;
559 : Elf_Word ch_reserved;
560 : Elf_Xword ch_size;
561 42 : Elf_Xword ch_addralign;
562 : };
563 :
564 : /// Note header
565 14 : template <class ELFT>
566 : struct Elf_Nhdr_Impl {
567 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
568 : Elf_Word n_namesz;
569 : Elf_Word n_descsz;
570 : Elf_Word n_type;
571 :
572 : /// The alignment of the name and descriptor.
573 : ///
574 : /// Implementations differ from the specification here: in practice all
575 : /// variants align both the name and descriptor to 4-bytes.
576 : static const unsigned int Align = 4;
577 :
578 : /// Get the size of the note, including name, descriptor, and padding.
579 : size_t getSize() const {
580 : return sizeof(*this) + alignTo<Align>(n_namesz) + alignTo<Align>(n_descsz);
581 : }
582 : };
583 :
584 : /// An ELF note.
585 : ///
586 0 : /// Wraps a note header, providing methods for accessing the name and
587 : /// descriptor safely.
588 : template <class ELFT>
589 : class Elf_Note_Impl {
590 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
591 :
592 : const Elf_Nhdr_Impl<ELFT> &Nhdr;
593 :
594 : template <class NoteIteratorELFT> friend class Elf_Note_Iterator_Impl;
595 :
596 : Elf_Note_Impl(const Elf_Nhdr_Impl<ELFT> &Nhdr) : Nhdr(Nhdr) {}
597 :
598 : public:
599 : /// Get the note's name, excluding the terminating null byte.
600 : StringRef getName() const {
601 : if (!Nhdr.n_namesz)
602 : return StringRef();
603 : return StringRef(reinterpret_cast<const char *>(&Nhdr) + sizeof(Nhdr),
604 384 : Nhdr.n_namesz - 1);
605 : }
606 :
607 : /// Get the note's descriptor.
608 : ArrayRef<Elf_Word> getDesc() const {
609 : if (!Nhdr.n_descsz)
610 : return ArrayRef<Elf_Word>();
611 : return ArrayRef<Elf_Word>(
612 : reinterpret_cast<const Elf_Word *>(
613 : reinterpret_cast<const uint8_t *>(&Nhdr) + sizeof(Nhdr) +
614 : alignTo<Elf_Nhdr_Impl<ELFT>::Align>(Nhdr.n_namesz)),
615 : Nhdr.n_descsz);
616 : }
617 :
618 : /// Get the note's type.
619 : Elf_Word getType() const { return Nhdr.n_type; }
620 : };
621 :
622 : template <class ELFT>
623 : class Elf_Note_Iterator_Impl
624 0 : : std::iterator<std::forward_iterator_tag, Elf_Note_Impl<ELFT>> {
625 0 : // Nhdr being a nullptr marks the end of iteration.
626 0 : const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
627 : size_t RemainingSize = 0u;
628 0 : Error *Err = nullptr;
629 :
630 0 : template <class ELFFileELFT> friend class ELFFile;
631 0 :
632 0 : // Stop iteration and indicate an overflow.
633 : void stopWithOverflowError() {
634 0 : Nhdr = nullptr;
635 : *Err = make_error<StringError>("ELF note overflows container",
636 0 : object_error::parse_failed);
637 0 : }
638 0 :
639 0 : // Advance Nhdr by NoteSize bytes, starting from NhdrPos.
640 0 : //
641 0 : // Assumes NoteSize <= RemainingSize. Ensures Nhdr->getSize() <= RemainingSize
642 0 : // upon returning. Handles stopping iteration when reaching the end of the
643 0 : // container, either cleanly or with an overflow error.
644 0 : void advanceNhdr(const uint8_t *NhdrPos, size_t NoteSize) {
645 0 : RemainingSize -= NoteSize;
646 0 : if (RemainingSize == 0u)
647 : Nhdr = nullptr;
648 0 : else if (sizeof(*Nhdr) > RemainingSize)
649 0 : stopWithOverflowError();
650 0 : else {
651 0 : Nhdr = reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *>(NhdrPos + NoteSize);
652 0 : if (Nhdr->getSize() > RemainingSize)
653 0 : stopWithOverflowError();
654 0 : }
655 0 : }
656 0 :
657 0 : Elf_Note_Iterator_Impl() {}
658 0 : explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
659 0 : Elf_Note_Iterator_Impl(const uint8_t *Start, size_t Size, Error &Err)
660 0 : : RemainingSize(Size), Err(&Err) {
661 0 : assert(Start && "ELF note iterator starting at NULL");
662 0 : advanceNhdr(Start, 0u);
663 0 : }
664 :
665 0 : public:
666 0 : Elf_Note_Iterator_Impl &operator++() {
667 0 : assert(Nhdr && "incremented ELF note end iterator");
668 : const uint8_t *NhdrPos = reinterpret_cast<const uint8_t *>(Nhdr);
669 : size_t NoteSize = Nhdr->getSize();
670 0 : advanceNhdr(NhdrPos, NoteSize);
671 0 : return *this;
672 0 : }
673 0 : bool operator==(Elf_Note_Iterator_Impl Other) const {
674 0 : return Nhdr == Other.Nhdr;
675 0 : }
676 0 : bool operator!=(Elf_Note_Iterator_Impl Other) const {
677 0 : return !(*this == Other);
678 0 : }
679 0 : Elf_Note_Impl<ELFT> operator*() const {
680 0 : assert(Nhdr && "dereferenced ELF note end iterator");
681 0 : return Elf_Note_Impl<ELFT>(*Nhdr);
682 0 : }
683 0 : };
684 0 :
685 0 : template <class ELFT> struct Elf_CGProfile_Impl {
686 0 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
687 : Elf_Word cgp_from;
688 0 : Elf_Word cgp_to;
689 0 : Elf_Xword cgp_weight;
690 0 : };
691 :
692 0 : // MIPS .reginfo section
693 0 : template <class ELFT>
694 0 : struct Elf_Mips_RegInfo;
695 0 :
696 0 : template <support::endianness TargetEndianness>
697 0 : struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
698 0 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
699 0 : Elf_Word ri_gprmask; // bit-mask of used general registers
700 : Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
701 0 : Elf_Addr ri_gp_value; // gp register value
702 0 : };
703 0 :
704 : template <support::endianness TargetEndianness>
705 0 : struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
706 0 : LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
707 0 : Elf_Word ri_gprmask; // bit-mask of used general registers
708 0 : Elf_Word ri_pad; // unused padding field
709 0 : Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
710 0 : Elf_Addr ri_gp_value; // gp register value
711 : };
712 :
713 0 : // .MIPS.options section
714 0 : template <class ELFT> struct Elf_Mips_Options {
715 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
716 : uint8_t kind; // Determines interpretation of variable part of descriptor
717 0 : uint8_t size; // Byte size of descriptor, including this header
718 0 : Elf_Half section; // Section header index of section affected,
719 0 : // or 0 for global options
720 0 : Elf_Word info; // Kind-specific information
721 0 :
722 0 : Elf_Mips_RegInfo<ELFT> &getRegInfo() {
723 0 : assert(kind == ELF::ODK_REGINFO);
724 0 : return *reinterpret_cast<Elf_Mips_RegInfo<ELFT> *>(
725 0 : (uint8_t *)this + sizeof(Elf_Mips_Options));
726 0 : }
727 0 : const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
728 0 : return const_cast<Elf_Mips_Options *>(this)->getRegInfo();
729 0 : }
730 : };
731 0 :
732 0 : // .MIPS.abiflags section content
733 0 : template <class ELFT> struct Elf_Mips_ABIFlags {
734 0 : LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
735 : Elf_Half version; // Version of the structure
736 0 : uint8_t isa_level; // ISA level: 1-5, 32, and 64
737 0 : uint8_t isa_rev; // ISA revision (0 for MIPS I - MIPS V)
738 0 : uint8_t gpr_size; // General purpose registers size
739 0 : uint8_t cpr1_size; // Co-processor 1 registers size
740 : uint8_t cpr2_size; // Co-processor 2 registers size
741 0 : uint8_t fp_abi; // Floating-point ABI flag
742 : Elf_Word isa_ext; // Processor-specific extension
743 : Elf_Word ases; // ASEs flags
744 : Elf_Word flags1; // General flags
745 : Elf_Word flags2; // General flags
746 : };
747 :
748 124 : } // end namespace object.
749 124 : } // end namespace llvm.
750 124 :
751 28 : #endif // LLVM_OBJECT_ELFTYPES_H
|