1 //===- ELFTypes.h - Endian specific types for ELF ---------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_OBJECT_ELFTYPES_H
11 #define LLVM_OBJECT_ELFTYPES_H
13 #include "llvm/Support/DataTypes.h"
14 #include "llvm/Support/ELF.h"
15 #include "llvm/Support/Endian.h"
20 using support::endianness;
22 template <endianness target_endianness, bool is64Bits> struct ELFType {
23 static const endianness TargetEndianness = target_endianness;
24 static const bool Is64Bits = is64Bits;
27 typedef ELFType<support::little, false> ELF32LE;
28 typedef ELFType<support::big, false> ELF32BE;
29 typedef ELFType<support::little, true> ELF64LE;
30 typedef ELFType<support::big, true> ELF64BE;
32 // Use an alignment of 2 for the typedefs since that is the worst case for
33 // ELF files in archives.
35 // Templates to choose Elf_Addr and Elf_Off depending on is64Bits.
36 template <endianness target_endianness> struct ELFDataTypeTypedefHelperCommon {
37 typedef support::detail::packed_endian_specific_integral<
38 uint16_t, target_endianness, 2> Elf_Half;
39 typedef support::detail::packed_endian_specific_integral<
40 uint32_t, target_endianness, 2> Elf_Word;
41 typedef support::detail::packed_endian_specific_integral<
42 int32_t, target_endianness, 2> Elf_Sword;
43 typedef support::detail::packed_endian_specific_integral<
44 uint64_t, target_endianness, 2> Elf_Xword;
45 typedef support::detail::packed_endian_specific_integral<
46 int64_t, target_endianness, 2> Elf_Sxword;
49 template <class ELFT> struct ELFDataTypeTypedefHelper;
52 template <endianness TargetEndianness>
53 struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, false>>
54 : ELFDataTypeTypedefHelperCommon<TargetEndianness> {
55 typedef uint32_t value_type;
56 typedef support::detail::packed_endian_specific_integral<
57 value_type, TargetEndianness, 2> Elf_Addr;
58 typedef support::detail::packed_endian_specific_integral<
59 value_type, TargetEndianness, 2> Elf_Off;
63 template <endianness TargetEndianness>
64 struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, true>>
65 : ELFDataTypeTypedefHelperCommon<TargetEndianness> {
66 typedef uint64_t value_type;
67 typedef support::detail::packed_endian_specific_integral<
68 value_type, TargetEndianness, 2> Elf_Addr;
69 typedef support::detail::packed_endian_specific_integral<
70 value_type, TargetEndianness, 2> Elf_Off;
73 // I really don't like doing this, but the alternative is copypasta.
74 #define LLVM_ELF_IMPORT_TYPES(E, W) \
75 typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Addr Elf_Addr; \
76 typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Off Elf_Off; \
77 typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Half Elf_Half; \
78 typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Word Elf_Word; \
80 typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sword Elf_Sword; \
82 typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Xword Elf_Xword; \
84 typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sxword Elf_Sxword;
86 #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
87 LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::Is64Bits)
90 template <class ELFT> struct Elf_Shdr_Base;
92 template <endianness TargetEndianness>
93 struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> {
94 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
95 Elf_Word sh_name; // Section name (index into string table)
96 Elf_Word sh_type; // Section type (SHT_*)
97 Elf_Word sh_flags; // Section flags (SHF_*)
98 Elf_Addr sh_addr; // Address where section is to be loaded
99 Elf_Off sh_offset; // File offset of section data, in bytes
100 Elf_Word sh_size; // Size of section, in bytes
101 Elf_Word sh_link; // Section type-specific header table index link
102 Elf_Word sh_info; // Section type-specific extra information
103 Elf_Word sh_addralign; // Section address alignment
104 Elf_Word sh_entsize; // Size of records contained within the section
107 template <endianness TargetEndianness>
108 struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> {
109 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
110 Elf_Word sh_name; // Section name (index into string table)
111 Elf_Word sh_type; // Section type (SHT_*)
112 Elf_Xword sh_flags; // Section flags (SHF_*)
113 Elf_Addr sh_addr; // Address where section is to be loaded
114 Elf_Off sh_offset; // File offset of section data, in bytes
115 Elf_Xword sh_size; // Size of section, in bytes
116 Elf_Word sh_link; // Section type-specific header table index link
117 Elf_Word sh_info; // Section type-specific extra information
118 Elf_Xword sh_addralign; // Section address alignment
119 Elf_Xword sh_entsize; // Size of records contained within the section
122 template <class ELFT>
123 struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
124 using Elf_Shdr_Base<ELFT>::sh_entsize;
125 using Elf_Shdr_Base<ELFT>::sh_size;
127 /// @brief Get the number of entities this section contains if it has any.
128 unsigned getEntityCount() const {
131 return sh_size / sh_entsize;
135 template <class ELFT> struct Elf_Sym_Base;
137 template <endianness TargetEndianness>
138 struct Elf_Sym_Base<ELFType<TargetEndianness, false>> {
139 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
140 Elf_Word st_name; // Symbol name (index into string table)
141 Elf_Addr st_value; // Value or address associated with the symbol
142 Elf_Word st_size; // Size of the symbol
143 unsigned char st_info; // Symbol's type and binding attributes
144 unsigned char st_other; // Must be zero; reserved
145 Elf_Half st_shndx; // Which section (header table index) it's defined in
148 template <endianness TargetEndianness>
149 struct Elf_Sym_Base<ELFType<TargetEndianness, true>> {
150 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
151 Elf_Word st_name; // Symbol name (index into string table)
152 unsigned char st_info; // Symbol's type and binding attributes
153 unsigned char st_other; // Must be zero; reserved
154 Elf_Half st_shndx; // Which section (header table index) it's defined in
155 Elf_Addr st_value; // Value or address associated with the symbol
156 Elf_Xword st_size; // Size of the symbol
159 template <class ELFT>
160 struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
161 using Elf_Sym_Base<ELFT>::st_info;
162 using Elf_Sym_Base<ELFT>::st_shndx;
163 using Elf_Sym_Base<ELFT>::st_other;
164 using Elf_Sym_Base<ELFT>::st_value;
166 // These accessors and mutators correspond to the ELF32_ST_BIND,
167 // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
168 unsigned char getBinding() const { return st_info >> 4; }
169 unsigned char getType() const { return st_info & 0x0f; }
170 uint64_t getValue() const { return st_value; }
171 void setBinding(unsigned char b) { setBindingAndType(b, getType()); }
172 void setType(unsigned char t) { setBindingAndType(getBinding(), t); }
173 void setBindingAndType(unsigned char b, unsigned char t) {
174 st_info = (b << 4) + (t & 0x0f);
177 /// Access to the STV_xxx flag stored in the first two bits of st_other.
182 unsigned char getVisibility() const { return st_other & 0x3; }
183 void setVisibility(unsigned char v) {
184 assert(v < 4 && "Invalid value for visibility");
185 st_other = (st_other & ~0x3) | v;
188 bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; }
189 bool isCommon() const {
190 return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
192 bool isDefined() const { return !isUndefined(); }
193 bool isProcessorSpecific() const {
194 return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
196 bool isOSSpecific() const {
197 return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
199 bool isReserved() const {
200 // ELF::SHN_HIRESERVE is 0xffff so st_shndx <= ELF::SHN_HIRESERVE is always
201 // true and some compilers warn about it.
202 return st_shndx >= ELF::SHN_LORESERVE;
204 bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; }
205 bool isExternal() const {
206 return getBinding() != ELF::STB_LOCAL;
210 /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
211 /// (.gnu.version). This structure is identical for ELF32 and ELF64.
212 template <class ELFT>
213 struct Elf_Versym_Impl {
214 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
215 Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
218 template <class ELFT> struct Elf_Verdaux_Impl;
220 /// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
221 /// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
222 template <class ELFT>
223 struct Elf_Verdef_Impl {
224 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
225 typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
226 Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
227 Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
228 Elf_Half vd_ndx; // Version index, used in .gnu.version entries
229 Elf_Half vd_cnt; // Number of Verdaux entries
230 Elf_Word vd_hash; // Hash of name
231 Elf_Word vd_aux; // Offset to the first Verdaux entry (in bytes)
232 Elf_Word vd_next; // Offset to the next Verdef entry (in bytes)
234 /// Get the first Verdaux entry for this Verdef.
235 const Elf_Verdaux *getAux() const {
236 return reinterpret_cast<const Elf_Verdaux *>((const char *)this + vd_aux);
240 /// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
241 /// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
242 template <class ELFT>
243 struct Elf_Verdaux_Impl {
244 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
245 Elf_Word vda_name; // Version name (offset in string table)
246 Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
249 /// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
250 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
251 template <class ELFT>
252 struct Elf_Verneed_Impl {
253 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
254 Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
255 Elf_Half vn_cnt; // Number of associated Vernaux entries
256 Elf_Word vn_file; // Library name (string table offset)
257 Elf_Word vn_aux; // Offset to first Vernaux entry (in bytes)
258 Elf_Word vn_next; // Offset to next Verneed entry (in bytes)
261 /// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
262 /// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
263 template <class ELFT>
264 struct Elf_Vernaux_Impl {
265 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
266 Elf_Word vna_hash; // Hash of dependency name
267 Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
268 Elf_Half vna_other; // Version index, used in .gnu.version entries
269 Elf_Word vna_name; // Dependency name
270 Elf_Word vna_next; // Offset to next Vernaux entry (in bytes)
273 /// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
274 /// table section (.dynamic) look like.
275 template <class ELFT> struct Elf_Dyn_Base;
277 template <endianness TargetEndianness>
278 struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> {
279 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
287 template <endianness TargetEndianness>
288 struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> {
289 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
297 /// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters.
298 template <class ELFT>
299 struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
300 using Elf_Dyn_Base<ELFT>::d_tag;
301 using Elf_Dyn_Base<ELFT>::d_un;
302 int64_t getTag() const { return d_tag; }
303 uint64_t getVal() const { return d_un.d_val; }
304 uint64_t getPtr() const { return d_un.d_ptr; }
307 // Elf_Rel: Elf Relocation
308 template <class ELFT, bool isRela> struct Elf_Rel_Base;
310 template <endianness TargetEndianness>
311 struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> {
312 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
313 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
314 Elf_Word r_info; // Symbol table index and type of relocation to apply
316 uint32_t getRInfo(bool isMips64EL) const {
320 void setRInfo(uint32_t R, bool IsMips64EL) {
326 template <endianness TargetEndianness>
327 struct Elf_Rel_Base<ELFType<TargetEndianness, true>, false> {
328 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
329 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
330 Elf_Xword r_info; // Symbol table index and type of relocation to apply
332 uint64_t getRInfo(bool isMips64EL) const {
336 // Mips64 little endian has a "special" encoding of r_info. Instead of one
337 // 64 bit little endian number, it is a little endian 32 bit number followed
338 // by a 32 bit big endian number.
339 return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
340 ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
342 void setRInfo(uint64_t R, bool IsMips64EL) {
344 r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
345 ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
351 template <endianness TargetEndianness>
352 struct Elf_Rel_Base<ELFType<TargetEndianness, false>, true> {
353 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
354 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
355 Elf_Word r_info; // Symbol table index and type of relocation to apply
356 Elf_Sword r_addend; // Compute value for relocatable field by adding this
358 uint32_t getRInfo(bool isMips64EL) const {
362 void setRInfo(uint32_t R, bool IsMips64EL) {
368 template <endianness TargetEndianness>
369 struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> {
370 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
371 Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
372 Elf_Xword r_info; // Symbol table index and type of relocation to apply
373 Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
375 uint64_t getRInfo(bool isMips64EL) const {
376 // Mips64 little endian has a "special" encoding of r_info. Instead of one
377 // 64 bit little endian number, it is a little endian 32 bit number followed
378 // by a 32 bit big endian number.
382 return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
383 ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
385 void setRInfo(uint64_t R, bool IsMips64EL) {
387 r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
388 ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
394 template <class ELFT, bool isRela> struct Elf_Rel_Impl;
396 template <endianness TargetEndianness, bool isRela>
397 struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela>
398 : Elf_Rel_Base<ELFType<TargetEndianness, true>, isRela> {
399 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
401 // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
402 // and ELF64_R_INFO macros defined in the ELF specification:
403 uint32_t getSymbol(bool isMips64EL) const {
404 return (uint32_t)(this->getRInfo(isMips64EL) >> 32);
406 uint32_t getType(bool isMips64EL) const {
407 return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL);
409 void setSymbol(uint32_t s, bool IsMips64EL) {
410 setSymbolAndType(s, getType(), IsMips64EL);
412 void setType(uint32_t t, bool IsMips64EL) {
413 setSymbolAndType(getSymbol(), t, IsMips64EL);
415 void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) {
416 this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
420 template <endianness TargetEndianness, bool isRela>
421 struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, isRela>
422 : Elf_Rel_Base<ELFType<TargetEndianness, false>, isRela> {
423 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
425 // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
426 // and ELF32_R_INFO macros defined in the ELF specification:
427 uint32_t getSymbol(bool isMips64EL) const {
428 return this->getRInfo(isMips64EL) >> 8;
430 unsigned char getType(bool isMips64EL) const {
431 return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff);
433 void setSymbol(uint32_t s, bool IsMips64EL) {
434 setSymbolAndType(s, getType(), IsMips64EL);
436 void setType(unsigned char t, bool IsMips64EL) {
437 setSymbolAndType(getSymbol(), t, IsMips64EL);
439 void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) {
440 this->setRInfo((s << 8) + t, IsMips64EL);
444 template <class ELFT>
445 struct Elf_Ehdr_Impl {
446 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
447 unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
448 Elf_Half e_type; // Type of file (see ET_*)
449 Elf_Half e_machine; // Required architecture for this file (see EM_*)
450 Elf_Word e_version; // Must be equal to 1
451 Elf_Addr e_entry; // Address to jump to in order to start program
452 Elf_Off e_phoff; // Program header table's file offset, in bytes
453 Elf_Off e_shoff; // Section header table's file offset, in bytes
454 Elf_Word e_flags; // Processor-specific flags
455 Elf_Half e_ehsize; // Size of ELF header, in bytes
456 Elf_Half e_phentsize; // Size of an entry in the program header table
457 Elf_Half e_phnum; // Number of entries in the program header table
458 Elf_Half e_shentsize; // Size of an entry in the section header table
459 Elf_Half e_shnum; // Number of entries in the section header table
460 Elf_Half e_shstrndx; // Section header table index of section name
462 bool checkMagic() const {
463 return (memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
465 unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
466 unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
469 template <class ELFT> struct Elf_Phdr_Impl;
471 template <endianness TargetEndianness>
472 struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> {
473 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
474 Elf_Word p_type; // Type of segment
475 Elf_Off p_offset; // FileOffset where segment is located, in bytes
476 Elf_Addr p_vaddr; // Virtual Address of beginning of segment
477 Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
478 Elf_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
479 Elf_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
480 Elf_Word p_flags; // Segment flags
481 Elf_Word p_align; // Segment alignment constraint
484 template <endianness TargetEndianness>
485 struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> {
486 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
487 Elf_Word p_type; // Type of segment
488 Elf_Word p_flags; // Segment flags
489 Elf_Off p_offset; // FileOffset where segment is located, in bytes
490 Elf_Addr p_vaddr; // Virtual Address of beginning of segment
491 Elf_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
492 Elf_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
493 Elf_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
494 Elf_Xword p_align; // Segment alignment constraint
497 // MIPS .reginfo section
498 template <class ELFT>
499 struct Elf_Mips_RegInfo;
501 template <llvm::support::endianness TargetEndianness>
502 struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> {
503 LLVM_ELF_IMPORT_TYPES(TargetEndianness, false)
504 Elf_Word ri_gprmask; // bit-mask of used general registers
505 Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
506 Elf_Addr ri_gp_value; // gp register value
509 template <llvm::support::endianness TargetEndianness>
510 struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> {
511 LLVM_ELF_IMPORT_TYPES(TargetEndianness, true)
512 Elf_Word ri_gprmask; // bit-mask of used general registers
513 Elf_Word ri_pad; // unused padding field
514 Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers
515 Elf_Addr ri_gp_value; // gp register value
518 // .MIPS.options section
519 template <class ELFT> struct Elf_Mips_Options {
520 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
521 uint8_t kind; // Determines interpretation of variable part of descriptor
522 uint8_t size; // Byte size of descriptor, including this header
523 Elf_Half section; // Section header index of section affected,
524 // or 0 for global options
525 Elf_Word info; // Kind-specific information
527 const Elf_Mips_RegInfo<ELFT> &getRegInfo() const {
528 assert(kind == llvm::ELF::ODK_REGINFO);
529 return *reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(
530 (const uint8_t *)this + sizeof(Elf_Mips_Options));
534 // .MIPS.abiflags section content
535 template <class ELFT> struct Elf_Mips_ABIFlags {
536 LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
537 Elf_Half version; // Version of the structure
538 uint8_t isa_level; // ISA level: 1-5, 32, and 64
539 uint8_t isa_rev; // ISA revision (0 for MIPS I - MIPS V)
540 uint8_t gpr_size; // General purpose registers size
541 uint8_t cpr1_size; // Co-processor 1 registers size
542 uint8_t cpr2_size; // Co-processor 2 registers size
543 uint8_t fp_abi; // Floating-point ABI flag
544 Elf_Word isa_ext; // Processor-specific extension
545 Elf_Word ases; // ASEs flags
546 Elf_Word flags1; // General flags
547 Elf_Word flags2; // General flags
550 } // end namespace object.
551 } // end namespace llvm.