1// elfcpp.h -- main header file for elfcpp    -*- C++ -*-
2
3// Copyright (C) 2006-2020 Free Software Foundation, Inc.
4// Written by Ian Lance Taylor <iant@google.com>.
5
6// This file is part of elfcpp.
7
8// This program is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public License
10// as published by the Free Software Foundation; either version 2, or
11// (at your option) any later version.
12
13// In addition to the permissions in the GNU Library General Public
14// License, the Free Software Foundation gives you unlimited
15// permission to link the compiled version of this file into
16// combinations with other programs, and to distribute those
17// combinations without any restriction coming from the use of this
18// file.  (The Library Public License restrictions do apply in other
19// respects; for example, they cover modification of the file, and
20// distribution when not linked into a combined executable.)
21
22// This program is distributed in the hope that it will be useful, but
23// WITHOUT ANY WARRANTY; without even the implied warranty of
24// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25// Library General Public License for more details.
26
27// You should have received a copy of the GNU Library General Public
28// License along with this program; if not, write to the Free Software
29// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
30// 02110-1301, USA.
31
32// This is the external interface for elfcpp.
33
34#ifndef ELFCPP_H
35#define ELFCPP_H
36
37#include "elfcpp_swap.h"
38
39#include <stdint.h>
40
41namespace elfcpp
42{
43
44// Basic ELF types.
45
46// These types are always the same size.
47
48typedef uint16_t Elf_Half;
49typedef uint32_t Elf_Word;
50typedef int32_t Elf_Sword;
51typedef uint64_t Elf_Xword;
52typedef int64_t Elf_Sxword;
53
54// These types vary in size depending on the ELF file class.  The
55// template parameter should be 32 or 64.
56
57template<int size>
58struct Elf_types;
59
60template<>
61struct Elf_types<32>
62{
63  typedef uint32_t Elf_Addr;
64  typedef uint32_t Elf_Off;
65  typedef uint32_t Elf_WXword;
66  typedef int32_t Elf_Swxword;
67};
68
69template<>
70struct Elf_types<64>
71{
72  typedef uint64_t Elf_Addr;
73  typedef uint64_t Elf_Off;
74  typedef uint64_t Elf_WXword;
75  typedef int64_t Elf_Swxword;
76};
77
78// Offsets within the Ehdr e_ident field.
79
80const int EI_MAG0 = 0;
81const int EI_MAG1 = 1;
82const int EI_MAG2 = 2;
83const int EI_MAG3 = 3;
84const int EI_CLASS = 4;
85const int EI_DATA = 5;
86const int EI_VERSION = 6;
87const int EI_OSABI = 7;
88const int EI_ABIVERSION = 8;
89const int EI_PAD = 9;
90const int EI_NIDENT = 16;
91
92// The valid values found in Ehdr e_ident[EI_MAG0 through EI_MAG3].
93
94const int ELFMAG0 = 0x7f;
95const int ELFMAG1 = 'E';
96const int ELFMAG2 = 'L';
97const int ELFMAG3 = 'F';
98
99// The valid values found in Ehdr e_ident[EI_CLASS].
100
101enum
102{
103  ELFCLASSNONE = 0,
104  ELFCLASS32 = 1,
105  ELFCLASS64 = 2
106};
107
108// The valid values found in Ehdr e_ident[EI_DATA].
109
110enum
111{
112  ELFDATANONE = 0,
113  ELFDATA2LSB = 1,
114  ELFDATA2MSB = 2
115};
116
117// The valid values found in Ehdr e_ident[EI_VERSION] and e_version.
118
119enum
120{
121  EV_NONE = 0,
122  EV_CURRENT = 1
123};
124
125// The valid values found in Ehdr e_ident[EI_OSABI].
126
127enum ELFOSABI
128{
129  ELFOSABI_NONE = 0,
130  ELFOSABI_HPUX = 1,
131  ELFOSABI_NETBSD = 2,
132  ELFOSABI_GNU = 3,
133  // ELFOSABI_LINUX is an alias for ELFOSABI_GNU.
134  ELFOSABI_LINUX = 3,
135  ELFOSABI_SOLARIS = 6,
136  ELFOSABI_AIX = 7,
137  ELFOSABI_IRIX = 8,
138  ELFOSABI_FREEBSD = 9,
139  ELFOSABI_TRU64 = 10,
140  ELFOSABI_MODESTO = 11,
141  ELFOSABI_OPENBSD = 12,
142  ELFOSABI_OPENVMS = 13,
143  ELFOSABI_NSK = 14,
144  ELFOSABI_AROS = 15,
145  // A GNU extension for the ARM.
146  ELFOSABI_ARM = 97,
147  // A GNU extension for the MSP.
148  ELFOSABI_STANDALONE = 255
149};
150
151// The valid values found in the Ehdr e_type field.
152
153enum ET
154{
155  ET_NONE = 0,
156  ET_REL = 1,
157  ET_EXEC = 2,
158  ET_DYN = 3,
159  ET_CORE = 4,
160  ET_LOOS = 0xfe00,
161  ET_HIOS = 0xfeff,
162  ET_LOPROC = 0xff00,
163  ET_HIPROC = 0xffff
164};
165
166// The valid values found in the Ehdr e_machine field.
167
168enum EM
169{
170  EM_NONE = 0,
171  EM_M32 = 1,
172  EM_SPARC = 2,
173  EM_386 = 3,
174  EM_68K = 4,
175  EM_88K = 5,
176  EM_IAMCU = 6,
177  EM_860 = 7,
178  EM_MIPS = 8,
179  EM_S370 = 9,
180  EM_MIPS_RS3_LE = 10,
181  // 11 was the old Sparc V9 ABI.
182  // 12 through 14 are reserved.
183  EM_PARISC = 15,
184  // 16 is reserved.
185  // Some old PowerPC object files use 17.
186  EM_VPP500 = 17,
187  EM_SPARC32PLUS = 18,
188  EM_960 = 19,
189  EM_PPC = 20,
190  EM_PPC64 = 21,
191  EM_S390 = 22,
192  // 23 through 35 are served.
193  EM_V800 = 36,
194  EM_FR20 = 37,
195  EM_RH32 = 38,
196  EM_RCE = 39,
197  EM_ARM = 40,
198  EM_ALPHA = 41,
199  EM_SH = 42,
200  EM_SPARCV9 = 43,
201  EM_TRICORE = 44,
202  EM_ARC = 45,
203  EM_H8_300 = 46,
204  EM_H8_300H = 47,
205  EM_H8S = 48,
206  EM_H8_500 = 49,
207  EM_IA_64 = 50,
208  EM_MIPS_X = 51,
209  EM_COLDFIRE = 52,
210  EM_68HC12 = 53,
211  EM_MMA = 54,
212  EM_PCP = 55,
213  EM_NCPU = 56,
214  EM_NDR1 = 57,
215  EM_STARCORE = 58,
216  EM_ME16 = 59,
217  EM_ST100 = 60,
218  EM_TINYJ = 61,
219  EM_X86_64 = 62,
220  EM_PDSP = 63,
221  EM_PDP10 = 64,
222  EM_PDP11 = 65,
223  EM_FX66 = 66,
224  EM_ST9PLUS = 67,
225  EM_ST7 = 68,
226  EM_68HC16 = 69,
227  EM_68HC11 = 70,
228  EM_68HC08 = 71,
229  EM_68HC05 = 72,
230  EM_SVX = 73,
231  EM_ST19 = 74,
232  EM_VAX = 75,
233  EM_CRIS = 76,
234  EM_JAVELIN = 77,
235  EM_FIREPATH = 78,
236  EM_ZSP = 79,
237  EM_MMIX = 80,
238  EM_HUANY = 81,
239  EM_PRISM = 82,
240  EM_AVR = 83,
241  EM_FR30 = 84,
242  EM_D10V = 85,
243  EM_D30V = 86,
244  EM_V850 = 87,
245  EM_M32R = 88,
246  EM_MN10300 = 89,
247  EM_MN10200 = 90,
248  EM_PJ = 91,
249  EM_OR1K = 92,
250  EM_ARC_A5 = 93,
251  EM_XTENSA = 94,
252  EM_VIDEOCORE = 95,
253  EM_TMM_GPP = 96,
254  EM_NS32K = 97,
255  EM_TPC = 98,
256  // Some old picoJava object files use 99 (EM_PJ is correct).
257  EM_SNP1K = 99,
258  EM_ST200 = 100,
259  EM_IP2K = 101,
260  EM_MAX = 102,
261  EM_CR = 103,
262  EM_F2MC16 = 104,
263  EM_MSP430 = 105,
264  EM_BLACKFIN = 106,
265  EM_SE_C33 = 107,
266  EM_SEP = 108,
267  EM_ARCA = 109,
268  EM_UNICORE = 110,
269  EM_ALTERA_NIOS2 = 113,
270  EM_CRX = 114,
271  EM_TI_PRU = 144,
272  EM_AARCH64 = 183,
273  EM_TILEGX = 191,
274  // The Morph MT.
275  EM_MT = 0x2530,
276  // DLX.
277  EM_DLX = 0x5aa5,
278  // FRV.
279  EM_FRV = 0x5441,
280  // Infineon Technologies 16-bit microcontroller with C166-V2 core.
281  EM_X16X = 0x4688,
282  // Xstorym16
283  EM_XSTORMY16 = 0xad45,
284  // Renesas M32C
285  EM_M32C = 0xfeb0,
286  // Vitesse IQ2000
287  EM_IQ2000 = 0xfeba,
288  // NIOS
289  EM_NIOS32 = 0xfebb
290  // Old AVR objects used 0x1057 (EM_AVR is correct).
291  // Old MSP430 objects used 0x1059 (EM_MSP430 is correct).
292  // Old FR30 objects used 0x3330 (EM_FR30 is correct).
293  // Old OpenRISC objects used 0x3426 and 0x8472 (EM_OR1K is correct).
294  // Old D10V objects used 0x7650 (EM_D10V is correct).
295  // Old D30V objects used 0x7676 (EM_D30V is correct).
296  // Old IP2X objects used 0x8217 (EM_IP2K is correct).
297  // Old PowerPC objects used 0x9025 (EM_PPC is correct).
298  // Old Alpha objects used 0x9026 (EM_ALPHA is correct).
299  // Old M32R objects used 0x9041 (EM_M32R is correct).
300  // Old V850 objects used 0x9080 (EM_V850 is correct).
301  // Old S/390 objects used 0xa390 (EM_S390 is correct).
302  // Old Xtensa objects used 0xabc7 (EM_XTENSA is correct).
303  // Old MN10300 objects used 0xbeef (EM_MN10300 is correct).
304  // Old MN10200 objects used 0xdead (EM_MN10200 is correct).
305};
306
307// A special value found in the Ehdr e_phnum field.
308
309enum
310{
311  // Number of program segments stored in sh_info field of first
312  // section headre.
313  PN_XNUM = 0xffff
314};
315
316// Special section indices.
317
318enum
319{
320  SHN_UNDEF = 0,
321  SHN_LORESERVE = 0xff00,
322  SHN_LOPROC = 0xff00,
323  SHN_HIPROC = 0xff1f,
324  SHN_LOOS = 0xff20,
325  SHN_HIOS = 0xff3f,
326  SHN_ABS = 0xfff1,
327  SHN_COMMON = 0xfff2,
328  SHN_XINDEX = 0xffff,
329  SHN_HIRESERVE = 0xffff,
330
331  // Provide for initial and final section ordering in conjunction
332  // with the SHF_LINK_ORDER and SHF_ORDERED section flags.
333  SHN_BEFORE = 0xff00,
334  SHN_AFTER = 0xff01,
335
336  // x86_64 specific large common symbol.
337  SHN_X86_64_LCOMMON = 0xff02
338};
339
340// The valid values found in the Shdr sh_type field.
341
342enum SHT
343{
344  SHT_NULL = 0,
345  SHT_PROGBITS = 1,
346  SHT_SYMTAB = 2,
347  SHT_STRTAB = 3,
348  SHT_RELA = 4,
349  SHT_HASH = 5,
350  SHT_DYNAMIC = 6,
351  SHT_NOTE = 7,
352  SHT_NOBITS = 8,
353  SHT_REL = 9,
354  SHT_SHLIB = 10,
355  SHT_DYNSYM = 11,
356  SHT_INIT_ARRAY = 14,
357  SHT_FINI_ARRAY = 15,
358  SHT_PREINIT_ARRAY = 16,
359  SHT_GROUP = 17,
360  SHT_SYMTAB_SHNDX = 18,
361  SHT_LOOS = 0x60000000,
362  SHT_HIOS = 0x6fffffff,
363  SHT_LOPROC = 0x70000000,
364  SHT_HIPROC = 0x7fffffff,
365  SHT_LOUSER = 0x80000000,
366  SHT_HIUSER = 0xffffffff,
367  // The remaining values are not in the standard.
368  // Incremental build data.
369  SHT_GNU_INCREMENTAL_INPUTS = 0x6fff4700,
370  SHT_GNU_INCREMENTAL_SYMTAB = 0x6fff4701,
371  SHT_GNU_INCREMENTAL_RELOCS = 0x6fff4702,
372  SHT_GNU_INCREMENTAL_GOT_PLT = 0x6fff4703,
373  // Object attributes.
374  SHT_GNU_ATTRIBUTES = 0x6ffffff5,
375  // GNU style dynamic hash table.
376  SHT_GNU_HASH = 0x6ffffff6,
377  // List of prelink dependencies.
378  SHT_GNU_LIBLIST = 0x6ffffff7,
379  // Versions defined by file.
380  SHT_SUNW_verdef = 0x6ffffffd,
381  SHT_GNU_verdef = 0x6ffffffd,
382  // Versions needed by file.
383  SHT_SUNW_verneed = 0x6ffffffe,
384  SHT_GNU_verneed = 0x6ffffffe,
385  // Symbol versions,
386  SHT_SUNW_versym = 0x6fffffff,
387  SHT_GNU_versym = 0x6fffffff,
388
389  SHT_SPARC_GOTDATA = 0x70000000,
390
391  // ARM-specific section types.
392  // Exception Index table.
393  SHT_ARM_EXIDX = 0x70000001,
394  // BPABI DLL dynamic linking pre-emption map.
395  SHT_ARM_PREEMPTMAP = 0x70000002,
396  // Object file compatibility attributes.
397  SHT_ARM_ATTRIBUTES = 0x70000003,
398  // Support for debugging overlaid programs.
399  SHT_ARM_DEBUGOVERLAY = 0x70000004,
400  SHT_ARM_OVERLAYSECTION = 0x70000005,
401
402  // x86_64 unwind information.
403  SHT_X86_64_UNWIND = 0x70000001,
404
405  // MIPS-specific section types.
406  // Section contains register usage information.
407  SHT_MIPS_REGINFO = 0x70000006,
408  // Section contains miscellaneous options.
409  SHT_MIPS_OPTIONS = 0x7000000d,
410  // ABI related flags section.
411  SHT_MIPS_ABIFLAGS = 0x7000002a,
412
413  // AARCH64-specific section type.
414  SHT_AARCH64_ATTRIBUTES = 0x70000003,
415
416  // CSKY-specific section types.
417  // Object file compatibility attributes.
418  SHT_CSKY_ATTRIBUTES = 0x70000001,
419
420  // Link editor is to sort the entries in this section based on the
421  // address specified in the associated symbol table entry.
422  SHT_ORDERED = 0x7fffffff
423};
424
425// The valid bit flags found in the Shdr sh_flags field.
426
427enum SHF
428{
429  SHF_WRITE = 0x1,
430  SHF_ALLOC = 0x2,
431  SHF_EXECINSTR = 0x4,
432  SHF_MERGE = 0x10,
433  SHF_STRINGS = 0x20,
434  SHF_INFO_LINK = 0x40,
435  SHF_LINK_ORDER = 0x80,
436  SHF_OS_NONCONFORMING = 0x100,
437  SHF_GROUP = 0x200,
438  SHF_TLS = 0x400,
439  SHF_COMPRESSED = 0x800,
440  SHF_MASKOS = 0x0ff00000,
441  SHF_MASKPROC = 0xf0000000,
442
443  // Indicates this section requires ordering in relation to
444  // other sections of the same type.  Ordered sections are
445  // combined within the section pointed to by the sh_link entry.
446  // The sh_info values SHN_BEFORE and SHN_AFTER imply that the
447  // sorted section is to precede or follow, respectively, all
448  // other sections in the set being ordered.
449  SHF_ORDERED = 0x40000000,
450  // This section is excluded from input to the link-edit of an
451  // executable or shared object.  This flag is ignored if SHF_ALLOC
452  // is also set, or if relocations exist against the section.
453  SHF_EXCLUDE = 0x80000000,
454
455  // Section with data that is GP relative addressable.
456  SHF_MIPS_GPREL = 0x10000000,
457
458  // x86_64 specific large section.
459  SHF_X86_64_LARGE = 0x10000000
460};
461
462// Values which appear in the first Elf_WXword of the section data
463// of a SHF_COMPRESSED section.
464enum
465{
466  ELFCOMPRESS_ZLIB = 1,
467  ELFCOMPRESS_LOOS = 0x60000000,
468  ELFCOMPRESS_HIOS = 0x6fffffff,
469  ELFCOMPRESS_LOPROC = 0x70000000,
470  ELFCOMPRESS_HIPROC = 0x7fffffff,
471};
472
473// Bit flags which appear in the first 32-bit word of the section data
474// of a SHT_GROUP section.
475
476enum
477{
478  GRP_COMDAT = 0x1,
479  GRP_MASKOS = 0x0ff00000,
480  GRP_MASKPROC = 0xf0000000
481};
482
483// The valid values found in the Phdr p_type field.
484
485enum PT
486{
487  PT_NULL = 0,
488  PT_LOAD = 1,
489  PT_DYNAMIC = 2,
490  PT_INTERP = 3,
491  PT_NOTE = 4,
492  PT_SHLIB = 5,
493  PT_PHDR = 6,
494  PT_TLS = 7,
495  PT_LOOS = 0x60000000,
496  PT_HIOS = 0x6fffffff,
497  PT_LOPROC = 0x70000000,
498  PT_HIPROC = 0x7fffffff,
499  // The remaining values are not in the standard.
500  // Frame unwind information.
501  PT_GNU_EH_FRAME = 0x6474e550,
502  PT_SUNW_EH_FRAME = 0x6474e550,
503  // Stack flags.
504  PT_GNU_STACK = 0x6474e551,
505  // Read only after relocation.
506  PT_GNU_RELRO = 0x6474e552,
507  // Platform architecture compatibility information
508  PT_ARM_ARCHEXT = 0x70000000,
509  // Exception unwind tables
510  PT_ARM_EXIDX = 0x70000001,
511  // Register usage information.  Identifies one .reginfo section.
512  PT_MIPS_REGINFO =0x70000000,
513  // Runtime procedure table.
514  PT_MIPS_RTPROC = 0x70000001,
515  // .MIPS.options section.
516  PT_MIPS_OPTIONS = 0x70000002,
517  // .MIPS.abiflags section.
518  PT_MIPS_ABIFLAGS = 0x70000003,
519  // Platform architecture compatibility information
520  PT_AARCH64_ARCHEXT = 0x70000000,
521  // Exception unwind tables
522  PT_AARCH64_UNWIND = 0x70000001,
523  // 4k page table size
524  PT_S390_PGSTE = 0x70000000,
525};
526
527// The valid bit flags found in the Phdr p_flags field.
528
529enum PF
530{
531  PF_X = 0x1,
532  PF_W = 0x2,
533  PF_R = 0x4,
534  PF_MASKOS = 0x0ff00000,
535  PF_MASKPROC = 0xf0000000
536};
537
538// Symbol binding from Sym st_info field.
539
540enum STB
541{
542  STB_LOCAL = 0,
543  STB_GLOBAL = 1,
544  STB_WEAK = 2,
545  STB_LOOS = 10,
546  STB_GNU_UNIQUE = 10,
547  STB_HIOS = 12,
548  STB_LOPROC = 13,
549  STB_HIPROC = 15
550};
551
552// Symbol types from Sym st_info field.
553
554enum STT
555{
556  STT_NOTYPE = 0,
557  STT_OBJECT = 1,
558  STT_FUNC = 2,
559  STT_SECTION = 3,
560  STT_FILE = 4,
561  STT_COMMON = 5,
562  STT_TLS = 6,
563
564  // GNU extension: symbol value points to a function which is called
565  // at runtime to determine the final value of the symbol.
566  STT_GNU_IFUNC = 10,
567
568  STT_LOOS = 10,
569  STT_HIOS = 12,
570  STT_LOPROC = 13,
571  STT_HIPROC = 15,
572
573  // The section type that must be used for register symbols on
574  // Sparc.  These symbols initialize a global register.
575  STT_SPARC_REGISTER = 13,
576
577  // ARM: a THUMB function.  This is not defined in ARM ELF Specification but
578  // used by the GNU tool-chain.
579  STT_ARM_TFUNC = 13
580};
581
582inline STB
583elf_st_bind(unsigned char info)
584{
585  return static_cast<STB>(info >> 4);
586}
587
588inline STT
589elf_st_type(unsigned char info)
590{
591  return static_cast<STT>(info & 0xf);
592}
593
594inline unsigned char
595elf_st_info(STB bind, STT type)
596{
597  return ((static_cast<unsigned char>(bind) << 4)
598	  + (static_cast<unsigned char>(type) & 0xf));
599}
600
601// Symbol visibility from Sym st_other field.
602
603enum STV
604{
605  STV_DEFAULT = 0,
606  STV_INTERNAL = 1,
607  STV_HIDDEN = 2,
608  STV_PROTECTED = 3
609};
610
611inline STV
612elf_st_visibility(unsigned char other)
613{
614  return static_cast<STV>(other & 0x3);
615}
616
617inline unsigned char
618elf_st_nonvis(unsigned char other)
619{
620  return static_cast<STV>(other >> 2);
621}
622
623inline unsigned char
624elf_st_other(STV vis, unsigned char nonvis)
625{
626  return ((nonvis << 2)
627	  + (static_cast<unsigned char>(vis) & 3));
628}
629
630// Reloc information from Rel/Rela r_info field.
631
632template<int size>
633unsigned int
634elf_r_sym(typename Elf_types<size>::Elf_WXword);
635
636template<>
637inline unsigned int
638elf_r_sym<32>(Elf_Word v)
639{
640  return v >> 8;
641}
642
643template<>
644inline unsigned int
645elf_r_sym<64>(Elf_Xword v)
646{
647  return v >> 32;
648}
649
650template<int size>
651unsigned int
652elf_r_type(typename Elf_types<size>::Elf_WXword);
653
654template<>
655inline unsigned int
656elf_r_type<32>(Elf_Word v)
657{
658  return v & 0xff;
659}
660
661template<>
662inline unsigned int
663elf_r_type<64>(Elf_Xword v)
664{
665  return v & 0xffffffff;
666}
667
668template<int size>
669typename Elf_types<size>::Elf_WXword
670elf_r_info(unsigned int s, unsigned int t);
671
672template<>
673inline Elf_Word
674elf_r_info<32>(unsigned int s, unsigned int t)
675{
676  return (s << 8) + (t & 0xff);
677}
678
679template<>
680inline Elf_Xword
681elf_r_info<64>(unsigned int s, unsigned int t)
682{
683  return (static_cast<Elf_Xword>(s) << 32) + (t & 0xffffffff);
684}
685
686// Dynamic tags found in the PT_DYNAMIC segment.
687
688enum DT
689{
690  DT_NULL = 0,
691  DT_NEEDED = 1,
692  DT_PLTRELSZ = 2,
693  DT_PLTGOT = 3,
694  DT_HASH = 4,
695  DT_STRTAB = 5,
696  DT_SYMTAB = 6,
697  DT_RELA = 7,
698  DT_RELASZ = 8,
699  DT_RELAENT = 9,
700  DT_STRSZ = 10,
701  DT_SYMENT = 11,
702  DT_INIT = 12,
703  DT_FINI = 13,
704  DT_SONAME = 14,
705  DT_RPATH = 15,
706  DT_SYMBOLIC = 16,
707  DT_REL = 17,
708  DT_RELSZ = 18,
709  DT_RELENT = 19,
710  DT_PLTREL = 20,
711  DT_DEBUG = 21,
712  DT_TEXTREL = 22,
713  DT_JMPREL = 23,
714  DT_BIND_NOW = 24,
715  DT_INIT_ARRAY = 25,
716  DT_FINI_ARRAY = 26,
717  DT_INIT_ARRAYSZ = 27,
718  DT_FINI_ARRAYSZ = 28,
719  DT_RUNPATH = 29,
720  DT_FLAGS = 30,
721
722  // This is used to mark a range of dynamic tags.  It is not really
723  // a tag value.
724  DT_ENCODING = 32,
725
726  DT_PREINIT_ARRAY = 32,
727  DT_PREINIT_ARRAYSZ = 33,
728  DT_LOOS = 0x6000000d,
729  DT_HIOS = 0x6ffff000,
730  DT_LOPROC = 0x70000000,
731  DT_HIPROC = 0x7fffffff,
732
733  // The remaining values are extensions used by GNU or Solaris.
734  DT_VALRNGLO = 0x6ffffd00,
735  DT_GNU_PRELINKED = 0x6ffffdf5,
736  DT_GNU_CONFLICTSZ = 0x6ffffdf6,
737  DT_GNU_LIBLISTSZ = 0x6ffffdf7,
738  DT_CHECKSUM = 0x6ffffdf8,
739  DT_PLTPADSZ = 0x6ffffdf9,
740  DT_MOVEENT = 0x6ffffdfa,
741  DT_MOVESZ = 0x6ffffdfb,
742  DT_FEATURE = 0x6ffffdfc,
743  DT_POSFLAG_1 = 0x6ffffdfd,
744  DT_SYMINSZ = 0x6ffffdfe,
745  DT_SYMINENT = 0x6ffffdff,
746  DT_VALRNGHI = 0x6ffffdff,
747
748  DT_ADDRRNGLO = 0x6ffffe00,
749  DT_GNU_HASH = 0x6ffffef5,
750  DT_TLSDESC_PLT = 0x6ffffef6,
751  DT_TLSDESC_GOT = 0x6ffffef7,
752  DT_GNU_CONFLICT = 0x6ffffef8,
753  DT_GNU_LIBLIST = 0x6ffffef9,
754  DT_CONFIG = 0x6ffffefa,
755  DT_DEPAUDIT = 0x6ffffefb,
756  DT_AUDIT = 0x6ffffefc,
757  DT_PLTPAD = 0x6ffffefd,
758  DT_MOVETAB = 0x6ffffefe,
759  DT_SYMINFO = 0x6ffffeff,
760  DT_ADDRRNGHI = 0x6ffffeff,
761
762  DT_RELACOUNT = 0x6ffffff9,
763  DT_RELCOUNT = 0x6ffffffa,
764  DT_FLAGS_1 = 0x6ffffffb,
765  DT_VERDEF = 0x6ffffffc,
766  DT_VERDEFNUM = 0x6ffffffd,
767  DT_VERNEED = 0x6ffffffe,
768  DT_VERNEEDNUM = 0x6fffffff,
769
770  DT_VERSYM = 0x6ffffff0,
771
772  // Specify the value of _GLOBAL_OFFSET_TABLE_.
773  DT_PPC_GOT = 0x70000000,
774
775  // Specify whether various optimisations are possible.
776  DT_PPC_OPT = 0x70000001,
777
778  // Specify the start of the .glink section.
779  DT_PPC64_GLINK = 0x70000000,
780
781  // Specify the start and size of the .opd section.
782  DT_PPC64_OPD = 0x70000001,
783  DT_PPC64_OPDSZ = 0x70000002,
784
785  // Specify whether various optimisations are possible.
786  DT_PPC64_OPT = 0x70000003,
787
788  // The index of an STT_SPARC_REGISTER symbol within the DT_SYMTAB
789  // symbol table.  One dynamic entry exists for every STT_SPARC_REGISTER
790  // symbol in the symbol table.
791  DT_SPARC_REGISTER = 0x70000001,
792
793  // MIPS specific dynamic array tags.
794  // 32 bit version number for runtime linker interface.
795  DT_MIPS_RLD_VERSION = 0x70000001,
796  // Time stamp.
797  DT_MIPS_TIME_STAMP = 0x70000002,
798  // Checksum of external strings and common sizes.
799  DT_MIPS_ICHECKSUM = 0x70000003,
800  // Index of version string in string table.
801  DT_MIPS_IVERSION = 0x70000004,
802  // 32 bits of flags.
803  DT_MIPS_FLAGS = 0x70000005,
804  // Base address of the segment.
805  DT_MIPS_BASE_ADDRESS = 0x70000006,
806  // ???
807  DT_MIPS_MSYM = 0x70000007,
808  // Address of .conflict section.
809  DT_MIPS_CONFLICT = 0x70000008,
810  // Address of .liblist section.
811  DT_MIPS_LIBLIST = 0x70000009,
812  // Number of local global offset table entries.
813  DT_MIPS_LOCAL_GOTNO = 0x7000000a,
814  // Number of entries in the .conflict section.
815  DT_MIPS_CONFLICTNO = 0x7000000b,
816  // Number of entries in the .liblist section.
817  DT_MIPS_LIBLISTNO = 0x70000010,
818  // Number of entries in the .dynsym section.
819  DT_MIPS_SYMTABNO = 0x70000011,
820  // Index of first external dynamic symbol not referenced locally.
821  DT_MIPS_UNREFEXTNO = 0x70000012,
822  // Index of first dynamic symbol in global offset table.
823  DT_MIPS_GOTSYM = 0x70000013,
824  // Number of page table entries in global offset table.
825  DT_MIPS_HIPAGENO = 0x70000014,
826  // Address of run time loader map, used for debugging.
827  DT_MIPS_RLD_MAP = 0x70000016,
828  // Delta C++ class definition.
829  DT_MIPS_DELTA_CLASS = 0x70000017,
830  // Number of entries in DT_MIPS_DELTA_CLASS.
831  DT_MIPS_DELTA_CLASS_NO = 0x70000018,
832  // Delta C++ class instances.
833  DT_MIPS_DELTA_INSTANCE = 0x70000019,
834  // Number of entries in DT_MIPS_DELTA_INSTANCE.
835  DT_MIPS_DELTA_INSTANCE_NO = 0x7000001a,
836  // Delta relocations.
837  DT_MIPS_DELTA_RELOC = 0x7000001b,
838  // Number of entries in DT_MIPS_DELTA_RELOC.
839  DT_MIPS_DELTA_RELOC_NO = 0x7000001c,
840  // Delta symbols that Delta relocations refer to.
841  DT_MIPS_DELTA_SYM = 0x7000001d,
842  // Number of entries in DT_MIPS_DELTA_SYM.
843  DT_MIPS_DELTA_SYM_NO = 0x7000001e,
844  // Delta symbols that hold class declarations.
845  DT_MIPS_DELTA_CLASSSYM = 0x70000020,
846  // Number of entries in DT_MIPS_DELTA_CLASSSYM.
847  DT_MIPS_DELTA_CLASSSYM_NO = 0x70000021,
848  // Flags indicating information about C++ flavor.
849  DT_MIPS_CXX_FLAGS = 0x70000022,
850  // Pixie information (???).
851  DT_MIPS_PIXIE_INIT = 0x70000023,
852  // Address of .MIPS.symlib
853  DT_MIPS_SYMBOL_LIB = 0x70000024,
854  // The GOT index of the first PTE for a segment
855  DT_MIPS_LOCALPAGE_GOTIDX = 0x70000025,
856  // The GOT index of the first PTE for a local symbol
857  DT_MIPS_LOCAL_GOTIDX = 0x70000026,
858  // The GOT index of the first PTE for a hidden symbol
859  DT_MIPS_HIDDEN_GOTIDX = 0x70000027,
860  // The GOT index of the first PTE for a protected symbol
861  DT_MIPS_PROTECTED_GOTIDX = 0x70000028,
862  // Address of `.MIPS.options'.
863  DT_MIPS_OPTIONS = 0x70000029,
864  // Address of `.interface'.
865  DT_MIPS_INTERFACE = 0x7000002a,
866  // ???
867  DT_MIPS_DYNSTR_ALIGN = 0x7000002b,
868  // Size of the .interface section.
869  DT_MIPS_INTERFACE_SIZE = 0x7000002c,
870  // Size of rld_text_resolve function stored in the GOT.
871  DT_MIPS_RLD_TEXT_RESOLVE_ADDR = 0x7000002d,
872  // Default suffix of DSO to be added by rld on dlopen() calls.
873  DT_MIPS_PERF_SUFFIX = 0x7000002e,
874  // Size of compact relocation section (O32).
875  DT_MIPS_COMPACT_SIZE = 0x7000002f,
876  // GP value for auxiliary GOTs.
877  DT_MIPS_GP_VALUE = 0x70000030,
878  // Address of auxiliary .dynamic.
879  DT_MIPS_AUX_DYNAMIC = 0x70000031,
880  // Address of the base of the PLTGOT.
881  DT_MIPS_PLTGOT = 0x70000032,
882  // Points to the base of a writable PLT.
883  DT_MIPS_RWPLT = 0x70000034,
884  // Relative offset of run time loader map, used for debugging.
885  DT_MIPS_RLD_MAP_REL = 0x70000035,
886
887  DT_AUXILIARY = 0x7ffffffd,
888  DT_USED = 0x7ffffffe,
889  DT_FILTER = 0x7fffffff
890};
891
892// Flags found in the DT_FLAGS dynamic element.
893
894enum DF
895{
896  DF_ORIGIN = 0x1,
897  DF_SYMBOLIC = 0x2,
898  DF_TEXTREL = 0x4,
899  DF_BIND_NOW = 0x8,
900  DF_STATIC_TLS = 0x10
901};
902
903// Flags found in the DT_FLAGS_1 dynamic element.
904
905enum DF_1
906{
907  DF_1_NOW = 0x1,
908  DF_1_GLOBAL = 0x2,
909  DF_1_GROUP = 0x4,
910  DF_1_NODELETE = 0x8,
911  DF_1_LOADFLTR = 0x10,
912  DF_1_INITFIRST = 0x20,
913  DF_1_NOOPEN = 0x40,
914  DF_1_ORIGIN = 0x80,
915  DF_1_DIRECT = 0x100,
916  DF_1_TRANS = 0x200,
917  DF_1_INTERPOSE = 0x400,
918  DF_1_NODEFLIB = 0x800,
919  DF_1_NODUMP = 0x1000,
920  DF_1_CONLFAT = 0x2000,
921  DF_1_PIE = 0x08000000
922};
923
924// Version numbers which appear in the vd_version field of a Verdef
925// structure.
926
927const int VER_DEF_NONE = 0;
928const int VER_DEF_CURRENT = 1;
929
930// Version numbers which appear in the vn_version field of a Verneed
931// structure.
932
933const int VER_NEED_NONE = 0;
934const int VER_NEED_CURRENT = 1;
935
936// Bit flags which appear in vd_flags of Verdef and vna_flags of
937// Vernaux.
938
939const int VER_FLG_BASE = 0x1;
940const int VER_FLG_WEAK = 0x2;
941const int VER_FLG_INFO = 0x4;
942
943// Special constants found in the SHT_GNU_versym entries.
944
945const int VER_NDX_LOCAL = 0;
946const int VER_NDX_GLOBAL = 1;
947
948// A SHT_GNU_versym section holds 16-bit words.  This bit is set if
949// the symbol is hidden and can only be seen when referenced using an
950// explicit version number.  This is a GNU extension.
951
952const int VERSYM_HIDDEN = 0x8000;
953
954// This is the mask for the rest of the data in a word read from a
955// SHT_GNU_versym section.
956
957const int VERSYM_VERSION = 0x7fff;
958
959// Note descriptor type codes for notes in a non-core file with an
960// empty name.
961
962enum
963{
964  // A version string.
965  NT_VERSION = 1,
966  // An architecture string.
967  NT_ARCH = 2
968};
969
970// Note descriptor type codes for notes in a non-core file with the
971// name "GNU".
972
973enum
974{
975  // The minimum ABI level.  This is used by the dynamic linker to
976  // describe the minimal kernel version on which a shared library may
977  // be used.  Th value should be four words.  Word 0 is an OS
978  // descriptor (see below).  Word 1 is the major version of the ABI.
979  // Word 2 is the minor version.  Word 3 is the subminor version.
980  NT_GNU_ABI_TAG = 1,
981  // Hardware capabilities information.  Word 0 is the number of
982  // entries.  Word 1 is a bitmask of enabled entries.  The rest of
983  // the descriptor is a series of entries, where each entry is a
984  // single byte followed by a nul terminated string.  The byte gives
985  // the bit number to test if enabled in the bitmask.
986  NT_GNU_HWCAP = 2,
987  // The build ID as set by the linker's --build-id option.  The
988  // format of the descriptor depends on the build ID style.
989  NT_GNU_BUILD_ID = 3,
990  // The version of gold used to link.  Th descriptor is just a
991  // string.
992  NT_GNU_GOLD_VERSION = 4,
993  // Program property note, as described in "Linux Extensions to the gABI".
994  NT_GNU_PROPERTY_TYPE_0 = 5
995};
996
997// The OS values which may appear in word 0 of a NT_GNU_ABI_TAG note.
998
999enum
1000{
1001  ELF_NOTE_OS_LINUX = 0,
1002  ELF_NOTE_OS_GNU = 1,
1003  ELF_NOTE_OS_SOLARIS2 = 2,
1004  ELF_NOTE_OS_FREEBSD = 3,
1005  ELF_NOTE_OS_NETBSD = 4,
1006  ELF_NOTE_OS_SYLLABLE = 5
1007};
1008
1009// Program property types for NT_GNU_PROPERTY_TYPE_0.
1010
1011enum
1012{
1013  GNU_PROPERTY_STACK_SIZE = 1,
1014  GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2,
1015  GNU_PROPERTY_LOPROC = 0xc0000000,
1016  GNU_PROPERTY_X86_ISA_1_USED = 0xc0000000,
1017  GNU_PROPERTY_X86_ISA_1_NEEDED = 0xc0000001,
1018  GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002,
1019  GNU_PROPERTY_HIPROC = 0xdfffffff,
1020  GNU_PROPERTY_LOUSER = 0xe0000000,
1021  GNU_PROPERTY_HIUSER = 0xffffffff
1022};
1023
1024} // End namespace elfcpp.
1025
1026// Include internal details after defining the types.
1027#include "elfcpp_internal.h"
1028
1029namespace elfcpp
1030{
1031
1032// The offset of the ELF file header in the ELF file.
1033
1034const int file_header_offset = 0;
1035
1036// ELF structure sizes.
1037
1038template<int size>
1039struct Elf_sizes
1040{
1041  // Size of ELF file header.
1042  static const int ehdr_size = sizeof(internal::Ehdr_data<size>);
1043  // Size of ELF segment header.
1044  static const int phdr_size = sizeof(internal::Phdr_data<size>);
1045  // Size of ELF section header.
1046  static const int shdr_size = sizeof(internal::Shdr_data<size>);
1047  // Size of ELF compression header.
1048  static const int chdr_size = sizeof(internal::Chdr_data<size>);
1049  // Size of ELF symbol table entry.
1050  static const int sym_size = sizeof(internal::Sym_data<size>);
1051  // Sizes of ELF reloc entries.
1052  static const int rel_size = sizeof(internal::Rel_data<size>);
1053  static const int rela_size = sizeof(internal::Rela_data<size>);
1054  // Size of ELF dynamic entry.
1055  static const int dyn_size = sizeof(internal::Dyn_data<size>);
1056  // Size of ELF version structures.
1057  static const int verdef_size = sizeof(internal::Verdef_data);
1058  static const int verdaux_size = sizeof(internal::Verdaux_data);
1059  static const int verneed_size = sizeof(internal::Verneed_data);
1060  static const int vernaux_size = sizeof(internal::Vernaux_data);
1061};
1062
1063// Accessor class for the ELF file header.
1064
1065template<int size, bool big_endian>
1066class Ehdr
1067{
1068 public:
1069  Ehdr(const unsigned char* p)
1070    : p_(reinterpret_cast<const internal::Ehdr_data<size>*>(p))
1071  { }
1072
1073  template<typename File>
1074  Ehdr(File* file, typename File::Location loc)
1075    : p_(reinterpret_cast<const internal::Ehdr_data<size>*>(
1076	   file->view(loc.file_offset, loc.data_size).data()))
1077  { }
1078
1079  const unsigned char*
1080  get_e_ident() const
1081  { return this->p_->e_ident; }
1082
1083  Elf_Half
1084  get_e_type() const
1085  { return Convert<16, big_endian>::convert_host(this->p_->e_type); }
1086
1087  Elf_Half
1088  get_e_machine() const
1089  { return Convert<16, big_endian>::convert_host(this->p_->e_machine); }
1090
1091  Elf_Word
1092  get_e_version() const
1093  { return Convert<32, big_endian>::convert_host(this->p_->e_version); }
1094
1095  typename Elf_types<size>::Elf_Addr
1096  get_e_entry() const
1097  { return Convert<size, big_endian>::convert_host(this->p_->e_entry); }
1098
1099  typename Elf_types<size>::Elf_Off
1100  get_e_phoff() const
1101  { return Convert<size, big_endian>::convert_host(this->p_->e_phoff); }
1102
1103  typename Elf_types<size>::Elf_Off
1104  get_e_shoff() const
1105  { return Convert<size, big_endian>::convert_host(this->p_->e_shoff); }
1106
1107  Elf_Word
1108  get_e_flags() const
1109  { return Convert<32, big_endian>::convert_host(this->p_->e_flags); }
1110
1111  Elf_Half
1112  get_e_ehsize() const
1113  { return Convert<16, big_endian>::convert_host(this->p_->e_ehsize); }
1114
1115  Elf_Half
1116  get_e_phentsize() const
1117  { return Convert<16, big_endian>::convert_host(this->p_->e_phentsize); }
1118
1119  Elf_Half
1120  get_e_phnum() const
1121  { return Convert<16, big_endian>::convert_host(this->p_->e_phnum); }
1122
1123  Elf_Half
1124  get_e_shentsize() const
1125  { return Convert<16, big_endian>::convert_host(this->p_->e_shentsize); }
1126
1127  Elf_Half
1128  get_e_shnum() const
1129  { return Convert<16, big_endian>::convert_host(this->p_->e_shnum); }
1130
1131  Elf_Half
1132  get_e_shstrndx() const
1133  { return Convert<16, big_endian>::convert_host(this->p_->e_shstrndx); }
1134
1135 private:
1136  const internal::Ehdr_data<size>* p_;
1137};
1138
1139// Write class for the ELF file header.
1140
1141template<int size, bool big_endian>
1142class Ehdr_write
1143{
1144 public:
1145  Ehdr_write(unsigned char* p)
1146    : p_(reinterpret_cast<internal::Ehdr_data<size>*>(p))
1147  { }
1148
1149  void
1150  put_e_ident(const unsigned char v[EI_NIDENT]) const
1151  { memcpy(this->p_->e_ident, v, EI_NIDENT); }
1152
1153  void
1154  put_e_type(Elf_Half v)
1155  { this->p_->e_type = Convert<16, big_endian>::convert_host(v); }
1156
1157  void
1158  put_e_machine(Elf_Half v)
1159  { this->p_->e_machine = Convert<16, big_endian>::convert_host(v); }
1160
1161  void
1162  put_e_version(Elf_Word v)
1163  { this->p_->e_version = Convert<32, big_endian>::convert_host(v); }
1164
1165  void
1166  put_e_entry(typename Elf_types<size>::Elf_Addr v)
1167  { this->p_->e_entry = Convert<size, big_endian>::convert_host(v); }
1168
1169  void
1170  put_e_phoff(typename Elf_types<size>::Elf_Off v)
1171  { this->p_->e_phoff = Convert<size, big_endian>::convert_host(v); }
1172
1173  void
1174  put_e_shoff(typename Elf_types<size>::Elf_Off v)
1175  { this->p_->e_shoff = Convert<size, big_endian>::convert_host(v); }
1176
1177  void
1178  put_e_flags(Elf_Word v)
1179  { this->p_->e_flags = Convert<32, big_endian>::convert_host(v); }
1180
1181  void
1182  put_e_ehsize(Elf_Half v)
1183  { this->p_->e_ehsize = Convert<16, big_endian>::convert_host(v); }
1184
1185  void
1186  put_e_phentsize(Elf_Half v)
1187  { this->p_->e_phentsize = Convert<16, big_endian>::convert_host(v); }
1188
1189  void
1190  put_e_phnum(Elf_Half v)
1191  { this->p_->e_phnum = Convert<16, big_endian>::convert_host(v); }
1192
1193  void
1194  put_e_shentsize(Elf_Half v)
1195  { this->p_->e_shentsize = Convert<16, big_endian>::convert_host(v); }
1196
1197  void
1198  put_e_shnum(Elf_Half v)
1199  { this->p_->e_shnum = Convert<16, big_endian>::convert_host(v); }
1200
1201  void
1202  put_e_shstrndx(Elf_Half v)
1203  { this->p_->e_shstrndx = Convert<16, big_endian>::convert_host(v); }
1204
1205 private:
1206  internal::Ehdr_data<size>* p_;
1207};
1208
1209// Accessor class for an ELF section header.
1210
1211template<int size, bool big_endian>
1212class Shdr
1213{
1214 public:
1215  Shdr(const unsigned char* p)
1216    : p_(reinterpret_cast<const internal::Shdr_data<size>*>(p))
1217  { }
1218
1219  template<typename File>
1220  Shdr(File* file, typename File::Location loc)
1221    : p_(reinterpret_cast<const internal::Shdr_data<size>*>(
1222	   file->view(loc.file_offset, loc.data_size).data()))
1223  { }
1224
1225  Elf_Word
1226  get_sh_name() const
1227  { return Convert<32, big_endian>::convert_host(this->p_->sh_name); }
1228
1229  Elf_Word
1230  get_sh_type() const
1231  { return Convert<32, big_endian>::convert_host(this->p_->sh_type); }
1232
1233  typename Elf_types<size>::Elf_WXword
1234  get_sh_flags() const
1235  { return Convert<size, big_endian>::convert_host(this->p_->sh_flags); }
1236
1237  typename Elf_types<size>::Elf_Addr
1238  get_sh_addr() const
1239  { return Convert<size, big_endian>::convert_host(this->p_->sh_addr); }
1240
1241  typename Elf_types<size>::Elf_Off
1242  get_sh_offset() const
1243  { return Convert<size, big_endian>::convert_host(this->p_->sh_offset); }
1244
1245  typename Elf_types<size>::Elf_WXword
1246  get_sh_size() const
1247  { return Convert<size, big_endian>::convert_host(this->p_->sh_size); }
1248
1249  Elf_Word
1250  get_sh_link() const
1251  { return Convert<32, big_endian>::convert_host(this->p_->sh_link); }
1252
1253  Elf_Word
1254  get_sh_info() const
1255  { return Convert<32, big_endian>::convert_host(this->p_->sh_info); }
1256
1257  typename Elf_types<size>::Elf_WXword
1258  get_sh_addralign() const
1259  { return
1260      Convert<size, big_endian>::convert_host(this->p_->sh_addralign); }
1261
1262  typename Elf_types<size>::Elf_WXword
1263  get_sh_entsize() const
1264  { return Convert<size, big_endian>::convert_host(this->p_->sh_entsize); }
1265
1266 private:
1267  const internal::Shdr_data<size>* p_;
1268};
1269
1270// Write class for an ELF section header.
1271
1272template<int size, bool big_endian>
1273class Shdr_write
1274{
1275 public:
1276  Shdr_write(unsigned char* p)
1277    : p_(reinterpret_cast<internal::Shdr_data<size>*>(p))
1278  { }
1279
1280  void
1281  put_sh_name(Elf_Word v)
1282  { this->p_->sh_name = Convert<32, big_endian>::convert_host(v); }
1283
1284  void
1285  put_sh_type(Elf_Word v)
1286  { this->p_->sh_type = Convert<32, big_endian>::convert_host(v); }
1287
1288  void
1289  put_sh_flags(typename Elf_types<size>::Elf_WXword v)
1290  { this->p_->sh_flags = Convert<size, big_endian>::convert_host(v); }
1291
1292  void
1293  put_sh_addr(typename Elf_types<size>::Elf_Addr v)
1294  { this->p_->sh_addr = Convert<size, big_endian>::convert_host(v); }
1295
1296  void
1297  put_sh_offset(typename Elf_types<size>::Elf_Off v)
1298  { this->p_->sh_offset = Convert<size, big_endian>::convert_host(v); }
1299
1300  void
1301  put_sh_size(typename Elf_types<size>::Elf_WXword v)
1302  { this->p_->sh_size = Convert<size, big_endian>::convert_host(v); }
1303
1304  void
1305  put_sh_link(Elf_Word v)
1306  { this->p_->sh_link = Convert<32, big_endian>::convert_host(v); }
1307
1308  void
1309  put_sh_info(Elf_Word v)
1310  { this->p_->sh_info = Convert<32, big_endian>::convert_host(v); }
1311
1312  void
1313  put_sh_addralign(typename Elf_types<size>::Elf_WXword v)
1314  { this->p_->sh_addralign = Convert<size, big_endian>::convert_host(v); }
1315
1316  void
1317  put_sh_entsize(typename Elf_types<size>::Elf_WXword v)
1318  { this->p_->sh_entsize = Convert<size, big_endian>::convert_host(v); }
1319
1320 private:
1321  internal::Shdr_data<size>* p_;
1322};
1323
1324// Accessor class for an ELF compression header.
1325
1326template<int size, bool big_endian>
1327class Chdr
1328{
1329 public:
1330  Chdr(const unsigned char* p)
1331    : p_(reinterpret_cast<const internal::Chdr_data<size>*>(p))
1332  { }
1333
1334  template<typename File>
1335  Chdr(File* file, typename File::Location loc)
1336    : p_(reinterpret_cast<const internal::Chdr_data<size>*>(
1337	   file->view(loc.file_offset, loc.data_size).data()))
1338  { }
1339
1340  Elf_Word
1341  get_ch_type() const
1342  { return Convert<size, big_endian>::convert_host(this->p_->ch_type); }
1343
1344  typename Elf_types<size>::Elf_WXword
1345  get_ch_size() const
1346  { return Convert<size, big_endian>::convert_host(this->p_->ch_size); }
1347
1348  typename Elf_types<size>::Elf_WXword
1349  get_ch_addralign() const
1350  { return
1351      Convert<size, big_endian>::convert_host(this->p_->ch_addralign); }
1352
1353 private:
1354  const internal::Chdr_data<size>* p_;
1355};
1356
1357// Write class for an ELF compression header.
1358
1359template<int size, bool big_endian>
1360class Chdr_write
1361{
1362 public:
1363  Chdr_write(unsigned char* p)
1364    : p_(reinterpret_cast<internal::Chdr_data<size>*>(p))
1365  { }
1366
1367  void
1368  put_ch_type(typename Elf_types<size>::Elf_WXword v)
1369  { this->p_->ch_type = Convert<size, big_endian>::convert_host(v); }
1370
1371  void
1372  put_ch_size(typename Elf_types<size>::Elf_WXword v)
1373  { this->p_->ch_size = Convert<size, big_endian>::convert_host(v); }
1374
1375  void
1376  put_ch_addralign(typename Elf_types<size>::Elf_WXword v)
1377  { this->p_->ch_addralign = Convert<size, big_endian>::convert_host(v); }
1378
1379  void
1380  put_ch_reserved(Elf_Word);
1381
1382 private:
1383  internal::Chdr_data<size>* p_;
1384};
1385
1386template<>
1387inline void
1388elfcpp::Chdr_write<64, true>::put_ch_reserved(Elf_Word v)
1389{
1390  this->p_->ch_reserved = v;
1391}
1392
1393template<>
1394inline void
1395elfcpp::Chdr_write<64, false>::put_ch_reserved(Elf_Word v)
1396{
1397  this->p_->ch_reserved = v;
1398}
1399
1400// Accessor class for an ELF segment header.
1401
1402template<int size, bool big_endian>
1403class Phdr
1404{
1405 public:
1406  Phdr(const unsigned char* p)
1407    : p_(reinterpret_cast<const internal::Phdr_data<size>*>(p))
1408  { }
1409
1410  template<typename File>
1411  Phdr(File* file, typename File::Location loc)
1412    : p_(reinterpret_cast<internal::Phdr_data<size>*>(
1413	   file->view(loc.file_offset, loc.data_size).data()))
1414  { }
1415
1416  Elf_Word
1417  get_p_type() const
1418  { return Convert<32, big_endian>::convert_host(this->p_->p_type); }
1419
1420  typename Elf_types<size>::Elf_Off
1421  get_p_offset() const
1422  { return Convert<size, big_endian>::convert_host(this->p_->p_offset); }
1423
1424  typename Elf_types<size>::Elf_Addr
1425  get_p_vaddr() const
1426  { return Convert<size, big_endian>::convert_host(this->p_->p_vaddr); }
1427
1428  typename Elf_types<size>::Elf_Addr
1429  get_p_paddr() const
1430  { return Convert<size, big_endian>::convert_host(this->p_->p_paddr); }
1431
1432  typename Elf_types<size>::Elf_WXword
1433  get_p_filesz() const
1434  { return Convert<size, big_endian>::convert_host(this->p_->p_filesz); }
1435
1436  typename Elf_types<size>::Elf_WXword
1437  get_p_memsz() const
1438  { return Convert<size, big_endian>::convert_host(this->p_->p_memsz); }
1439
1440  Elf_Word
1441  get_p_flags() const
1442  { return Convert<32, big_endian>::convert_host(this->p_->p_flags); }
1443
1444  typename Elf_types<size>::Elf_WXword
1445  get_p_align() const
1446  { return Convert<size, big_endian>::convert_host(this->p_->p_align); }
1447
1448 private:
1449  const internal::Phdr_data<size>* p_;
1450};
1451
1452// Write class for an ELF segment header.
1453
1454template<int size, bool big_endian>
1455class Phdr_write
1456{
1457 public:
1458  Phdr_write(unsigned char* p)
1459    : p_(reinterpret_cast<internal::Phdr_data<size>*>(p))
1460  { }
1461
1462  void
1463  put_p_type(Elf_Word v)
1464  { this->p_->p_type = Convert<32, big_endian>::convert_host(v); }
1465
1466  void
1467  put_p_offset(typename Elf_types<size>::Elf_Off v)
1468  { this->p_->p_offset = Convert<size, big_endian>::convert_host(v); }
1469
1470  void
1471  put_p_vaddr(typename Elf_types<size>::Elf_Addr v)
1472  { this->p_->p_vaddr = Convert<size, big_endian>::convert_host(v); }
1473
1474  void
1475  put_p_paddr(typename Elf_types<size>::Elf_Addr v)
1476  { this->p_->p_paddr = Convert<size, big_endian>::convert_host(v); }
1477
1478  void
1479  put_p_filesz(typename Elf_types<size>::Elf_WXword v)
1480  { this->p_->p_filesz = Convert<size, big_endian>::convert_host(v); }
1481
1482  void
1483  put_p_memsz(typename Elf_types<size>::Elf_WXword v)
1484  { this->p_->p_memsz = Convert<size, big_endian>::convert_host(v); }
1485
1486  void
1487  put_p_flags(Elf_Word v)
1488  { this->p_->p_flags = Convert<32, big_endian>::convert_host(v); }
1489
1490  void
1491  put_p_align(typename Elf_types<size>::Elf_WXword v)
1492  { this->p_->p_align = Convert<size, big_endian>::convert_host(v); }
1493
1494 private:
1495  internal::Phdr_data<size>* p_;
1496};
1497
1498// Accessor class for an ELF symbol table entry.
1499
1500template<int size, bool big_endian>
1501class Sym
1502{
1503 public:
1504  Sym(const unsigned char* p)
1505    : p_(reinterpret_cast<const internal::Sym_data<size>*>(p))
1506  { }
1507
1508  template<typename File>
1509  Sym(File* file, typename File::Location loc)
1510    : p_(reinterpret_cast<const internal::Sym_data<size>*>(
1511	   file->view(loc.file_offset, loc.data_size).data()))
1512  { }
1513
1514  Elf_Word
1515  get_st_name() const
1516  { return Convert<32, big_endian>::convert_host(this->p_->st_name); }
1517
1518  typename Elf_types<size>::Elf_Addr
1519  get_st_value() const
1520  { return Convert<size, big_endian>::convert_host(this->p_->st_value); }
1521
1522  typename Elf_types<size>::Elf_WXword
1523  get_st_size() const
1524  { return Convert<size, big_endian>::convert_host(this->p_->st_size); }
1525
1526  unsigned char
1527  get_st_info() const
1528  { return this->p_->st_info; }
1529
1530  STB
1531  get_st_bind() const
1532  { return elf_st_bind(this->get_st_info()); }
1533
1534  STT
1535  get_st_type() const
1536  { return elf_st_type(this->get_st_info()); }
1537
1538  unsigned char
1539  get_st_other() const
1540  { return this->p_->st_other; }
1541
1542  STV
1543  get_st_visibility() const
1544  { return elf_st_visibility(this->get_st_other()); }
1545
1546  unsigned char
1547  get_st_nonvis() const
1548  { return elf_st_nonvis(this->get_st_other()); }
1549
1550  Elf_Half
1551  get_st_shndx() const
1552  { return Convert<16, big_endian>::convert_host(this->p_->st_shndx); }
1553
1554 private:
1555  const internal::Sym_data<size>* p_;
1556};
1557
1558// Writer class for an ELF symbol table entry.
1559
1560template<int size, bool big_endian>
1561class Sym_write
1562{
1563 public:
1564  Sym_write(unsigned char* p)
1565    : p_(reinterpret_cast<internal::Sym_data<size>*>(p))
1566  { }
1567
1568  void
1569  put_st_name(Elf_Word v)
1570  { this->p_->st_name = Convert<32, big_endian>::convert_host(v); }
1571
1572  void
1573  put_st_value(typename Elf_types<size>::Elf_Addr v)
1574  { this->p_->st_value = Convert<size, big_endian>::convert_host(v); }
1575
1576  void
1577  put_st_size(typename Elf_types<size>::Elf_WXword v)
1578  { this->p_->st_size = Convert<size, big_endian>::convert_host(v); }
1579
1580  void
1581  put_st_info(unsigned char v)
1582  { this->p_->st_info = v; }
1583
1584  void
1585  put_st_info(STB bind, STT type)
1586  { this->p_->st_info = elf_st_info(bind, type); }
1587
1588  void
1589  put_st_other(unsigned char v)
1590  { this->p_->st_other = v; }
1591
1592  void
1593  put_st_other(STV vis, unsigned char nonvis)
1594  { this->p_->st_other = elf_st_other(vis, nonvis); }
1595
1596  void
1597  put_st_shndx(Elf_Half v)
1598  { this->p_->st_shndx = Convert<16, big_endian>::convert_host(v); }
1599
1600  Sym<size, big_endian>
1601  sym()
1602  { return Sym<size, big_endian>(reinterpret_cast<unsigned char*>(this->p_)); }
1603
1604 private:
1605  internal::Sym_data<size>* p_;
1606};
1607
1608// Accessor classes for an ELF REL relocation entry.
1609
1610template<int size, bool big_endian>
1611class Rel
1612{
1613 public:
1614  Rel(const unsigned char* p)
1615    : p_(reinterpret_cast<const internal::Rel_data<size>*>(p))
1616  { }
1617
1618  template<typename File>
1619  Rel(File* file, typename File::Location loc)
1620    : p_(reinterpret_cast<const internal::Rel_data<size>*>(
1621	   file->view(loc.file_offset, loc.data_size).data()))
1622  { }
1623
1624  typename Elf_types<size>::Elf_Addr
1625  get_r_offset() const
1626  { return Convert<size, big_endian>::convert_host(this->p_->r_offset); }
1627
1628  typename Elf_types<size>::Elf_WXword
1629  get_r_info() const
1630  { return Convert<size, big_endian>::convert_host(this->p_->r_info); }
1631
1632 private:
1633  const internal::Rel_data<size>* p_;
1634};
1635
1636// Writer class for an ELF Rel relocation.
1637
1638template<int size, bool big_endian>
1639class Rel_write
1640{
1641 public:
1642  Rel_write(unsigned char* p)
1643    : p_(reinterpret_cast<internal::Rel_data<size>*>(p))
1644  { }
1645
1646  void
1647  put_r_offset(typename Elf_types<size>::Elf_Addr v)
1648  { this->p_->r_offset = Convert<size, big_endian>::convert_host(v); }
1649
1650  void
1651  put_r_info(typename Elf_types<size>::Elf_WXword v)
1652  { this->p_->r_info = Convert<size, big_endian>::convert_host(v); }
1653
1654 private:
1655  internal::Rel_data<size>* p_;
1656};
1657
1658// Accessor class for an ELF Rela relocation.
1659
1660template<int size, bool big_endian>
1661class Rela
1662{
1663 public:
1664  Rela(const unsigned char* p)
1665    : p_(reinterpret_cast<const internal::Rela_data<size>*>(p))
1666  { }
1667
1668  template<typename File>
1669  Rela(File* file, typename File::Location loc)
1670    : p_(reinterpret_cast<const internal::Rela_data<size>*>(
1671	   file->view(loc.file_offset, loc.data_size).data()))
1672  { }
1673
1674  typename Elf_types<size>::Elf_Addr
1675  get_r_offset() const
1676  { return Convert<size, big_endian>::convert_host(this->p_->r_offset); }
1677
1678  typename Elf_types<size>::Elf_WXword
1679  get_r_info() const
1680  { return Convert<size, big_endian>::convert_host(this->p_->r_info); }
1681
1682  typename Elf_types<size>::Elf_Swxword
1683  get_r_addend() const
1684  { return Convert<size, big_endian>::convert_host(this->p_->r_addend); }
1685
1686 private:
1687  const internal::Rela_data<size>* p_;
1688};
1689
1690// Writer class for an ELF Rela relocation.
1691
1692template<int size, bool big_endian>
1693class Rela_write
1694{
1695 public:
1696  Rela_write(unsigned char* p)
1697    : p_(reinterpret_cast<internal::Rela_data<size>*>(p))
1698  { }
1699
1700  void
1701  put_r_offset(typename Elf_types<size>::Elf_Addr v)
1702  { this->p_->r_offset = Convert<size, big_endian>::convert_host(v); }
1703
1704  void
1705  put_r_info(typename Elf_types<size>::Elf_WXword v)
1706  { this->p_->r_info = Convert<size, big_endian>::convert_host(v); }
1707
1708  void
1709  put_r_addend(typename Elf_types<size>::Elf_Swxword v)
1710  { this->p_->r_addend = Convert<size, big_endian>::convert_host(v); }
1711
1712 private:
1713  internal::Rela_data<size>* p_;
1714};
1715
1716// MIPS-64 has a non-standard relocation layout.
1717
1718template<bool big_endian>
1719class Mips64_rel
1720{
1721 public:
1722  Mips64_rel(const unsigned char* p)
1723    : p_(reinterpret_cast<const internal::Mips64_rel_data*>(p))
1724  { }
1725
1726  template<typename File>
1727  Mips64_rel(File* file, typename File::Location loc)
1728    : p_(reinterpret_cast<const internal::Mips64_rel_data*>(
1729	   file->view(loc.file_offset, loc.data_size).data()))
1730  { }
1731
1732  typename Elf_types<64>::Elf_Addr
1733  get_r_offset() const
1734  { return Convert<64, big_endian>::convert_host(this->p_->r_offset); }
1735
1736  Elf_Word
1737  get_r_sym() const
1738  { return Convert<32, big_endian>::convert_host(this->p_->r_sym); }
1739
1740  unsigned char
1741  get_r_ssym() const
1742  { return this->p_->r_ssym; }
1743
1744  unsigned char
1745  get_r_type() const
1746  { return this->p_->r_type; }
1747
1748  unsigned char
1749  get_r_type2() const
1750  { return this->p_->r_type2; }
1751
1752  unsigned char
1753  get_r_type3() const
1754  { return this->p_->r_type3; }
1755
1756 private:
1757  const internal::Mips64_rel_data* p_;
1758};
1759
1760template<bool big_endian>
1761class Mips64_rel_write
1762{
1763 public:
1764  Mips64_rel_write(unsigned char* p)
1765    : p_(reinterpret_cast<internal::Mips64_rel_data*>(p))
1766  { }
1767
1768  void
1769  put_r_offset(typename Elf_types<64>::Elf_Addr v)
1770  { this->p_->r_offset = Convert<64, big_endian>::convert_host(v); }
1771
1772  void
1773  put_r_sym(Elf_Word v)
1774  { this->p_->r_sym = Convert<32, big_endian>::convert_host(v); }
1775
1776  void
1777  put_r_ssym(unsigned char v)
1778  { this->p_->r_ssym = v; }
1779
1780  void
1781  put_r_type(unsigned char v)
1782  { this->p_->r_type = v; }
1783
1784  void
1785  put_r_type2(unsigned char v)
1786  { this->p_->r_type2 = v; }
1787
1788  void
1789  put_r_type3(unsigned char v)
1790  { this->p_->r_type3 = v; }
1791
1792 private:
1793  internal::Mips64_rel_data* p_;
1794};
1795
1796template<bool big_endian>
1797class Mips64_rela
1798{
1799 public:
1800  Mips64_rela(const unsigned char* p)
1801    : p_(reinterpret_cast<const internal::Mips64_rela_data*>(p))
1802  { }
1803
1804  template<typename File>
1805  Mips64_rela(File* file, typename File::Location loc)
1806    : p_(reinterpret_cast<const internal::Mips64_rela_data*>(
1807	   file->view(loc.file_offset, loc.data_size).data()))
1808  { }
1809
1810  typename Elf_types<64>::Elf_Addr
1811  get_r_offset() const
1812  { return Convert<64, big_endian>::convert_host(this->p_->r_offset); }
1813
1814  Elf_Word
1815  get_r_sym() const
1816  { return Convert<32, big_endian>::convert_host(this->p_->r_sym); }
1817
1818  unsigned char
1819  get_r_ssym() const
1820  { return this->p_->r_ssym; }
1821
1822  unsigned char
1823  get_r_type() const
1824  { return this->p_->r_type; }
1825
1826  unsigned char
1827  get_r_type2() const
1828  { return this->p_->r_type2; }
1829
1830  unsigned char
1831  get_r_type3() const
1832  { return this->p_->r_type3; }
1833
1834  typename Elf_types<64>::Elf_Swxword
1835  get_r_addend() const
1836  { return Convert<64, big_endian>::convert_host(this->p_->r_addend); }
1837
1838 private:
1839  const internal::Mips64_rela_data* p_;
1840};
1841
1842template<bool big_endian>
1843class Mips64_rela_write
1844{
1845 public:
1846  Mips64_rela_write(unsigned char* p)
1847    : p_(reinterpret_cast<internal::Mips64_rela_data*>(p))
1848  { }
1849
1850  void
1851  put_r_offset(typename Elf_types<64>::Elf_Addr v)
1852  { this->p_->r_offset = Convert<64, big_endian>::convert_host(v); }
1853
1854  void
1855  put_r_sym(Elf_Word v)
1856  { this->p_->r_sym = Convert<32, big_endian>::convert_host(v); }
1857
1858  void
1859  put_r_ssym(unsigned char v)
1860  { this->p_->r_ssym = v; }
1861
1862  void
1863  put_r_type(unsigned char v)
1864  { this->p_->r_type = v; }
1865
1866  void
1867  put_r_type2(unsigned char v)
1868  { this->p_->r_type2 = v; }
1869
1870  void
1871  put_r_type3(unsigned char v)
1872  { this->p_->r_type3 = v; }
1873
1874  void
1875  put_r_addend(typename Elf_types<64>::Elf_Swxword v)
1876  { this->p_->r_addend = Convert<64, big_endian>::convert_host(v); }
1877
1878 private:
1879  internal::Mips64_rela_data* p_;
1880};
1881
1882// Accessor classes for entries in the ELF SHT_DYNAMIC section aka
1883// PT_DYNAMIC segment.
1884
1885template<int size, bool big_endian>
1886class Dyn
1887{
1888 public:
1889  Dyn(const unsigned char* p)
1890    : p_(reinterpret_cast<const internal::Dyn_data<size>*>(p))
1891  { }
1892
1893  template<typename File>
1894  Dyn(File* file, typename File::Location loc)
1895    : p_(reinterpret_cast<const internal::Dyn_data<size>*>(
1896	   file->view(loc.file_offset, loc.data_size).data()))
1897  { }
1898
1899  typename Elf_types<size>::Elf_Swxword
1900  get_d_tag() const
1901  { return Convert<size, big_endian>::convert_host(this->p_->d_tag); }
1902
1903  typename Elf_types<size>::Elf_WXword
1904  get_d_val() const
1905  { return Convert<size, big_endian>::convert_host(this->p_->d_val); }
1906
1907  typename Elf_types<size>::Elf_Addr
1908  get_d_ptr() const
1909  { return Convert<size, big_endian>::convert_host(this->p_->d_val); }
1910
1911 private:
1912  const internal::Dyn_data<size>* p_;
1913};
1914
1915// Write class for an entry in the SHT_DYNAMIC section.
1916
1917template<int size, bool big_endian>
1918class Dyn_write
1919{
1920 public:
1921  Dyn_write(unsigned char* p)
1922    : p_(reinterpret_cast<internal::Dyn_data<size>*>(p))
1923  { }
1924
1925  void
1926  put_d_tag(typename Elf_types<size>::Elf_Swxword v)
1927  { this->p_->d_tag = Convert<size, big_endian>::convert_host(v); }
1928
1929  void
1930  put_d_val(typename Elf_types<size>::Elf_WXword v)
1931  { this->p_->d_val = Convert<size, big_endian>::convert_host(v); }
1932
1933  void
1934  put_d_ptr(typename Elf_types<size>::Elf_Addr v)
1935  { this->p_->d_val = Convert<size, big_endian>::convert_host(v); }
1936
1937 private:
1938  internal::Dyn_data<size>* p_;
1939};
1940
1941// Accessor classes for entries in the ELF SHT_GNU_verdef section.
1942
1943template<int size, bool big_endian>
1944class Verdef
1945{
1946 public:
1947  Verdef(const unsigned char* p)
1948    : p_(reinterpret_cast<const internal::Verdef_data*>(p))
1949  { }
1950
1951  template<typename File>
1952  Verdef(File* file, typename File::Location loc)
1953    : p_(reinterpret_cast<const internal::Verdef_data*>(
1954	   file->view(loc.file_offset, loc.data_size).data()))
1955  { }
1956
1957  Elf_Half
1958  get_vd_version() const
1959  { return Convert<16, big_endian>::convert_host(this->p_->vd_version); }
1960
1961  Elf_Half
1962  get_vd_flags() const
1963  { return Convert<16, big_endian>::convert_host(this->p_->vd_flags); }
1964
1965  Elf_Half
1966  get_vd_ndx() const
1967  { return Convert<16, big_endian>::convert_host(this->p_->vd_ndx); }
1968
1969  Elf_Half
1970  get_vd_cnt() const
1971  { return Convert<16, big_endian>::convert_host(this->p_->vd_cnt); }
1972
1973  Elf_Word
1974  get_vd_hash() const
1975  { return Convert<32, big_endian>::convert_host(this->p_->vd_hash); }
1976
1977  Elf_Word
1978  get_vd_aux() const
1979  { return Convert<32, big_endian>::convert_host(this->p_->vd_aux); }
1980
1981  Elf_Word
1982  get_vd_next() const
1983  { return Convert<32, big_endian>::convert_host(this->p_->vd_next); }
1984
1985 private:
1986  const internal::Verdef_data* p_;
1987};
1988
1989template<int size, bool big_endian>
1990class Verdef_write
1991{
1992 public:
1993  Verdef_write(unsigned char* p)
1994    : p_(reinterpret_cast<internal::Verdef_data*>(p))
1995  { }
1996
1997  void
1998  set_vd_version(Elf_Half v)
1999  { this->p_->vd_version = Convert<16, big_endian>::convert_host(v); }
2000
2001  void
2002  set_vd_flags(Elf_Half v)
2003  { this->p_->vd_flags = Convert<16, big_endian>::convert_host(v); }
2004
2005  void
2006  set_vd_ndx(Elf_Half v)
2007  { this->p_->vd_ndx = Convert<16, big_endian>::convert_host(v); }
2008
2009  void
2010  set_vd_cnt(Elf_Half v)
2011  { this->p_->vd_cnt = Convert<16, big_endian>::convert_host(v); }
2012
2013  void
2014  set_vd_hash(Elf_Word v)
2015  { this->p_->vd_hash = Convert<32, big_endian>::convert_host(v); }
2016
2017  void
2018  set_vd_aux(Elf_Word v)
2019  { this->p_->vd_aux = Convert<32, big_endian>::convert_host(v); }
2020
2021  void
2022  set_vd_next(Elf_Word v)
2023  { this->p_->vd_next = Convert<32, big_endian>::convert_host(v); }
2024
2025 private:
2026  internal::Verdef_data* p_;
2027};
2028
2029// Accessor classes for auxiliary entries in the ELF SHT_GNU_verdef
2030// section.
2031
2032template<int size, bool big_endian>
2033class Verdaux
2034{
2035 public:
2036  Verdaux(const unsigned char* p)
2037    : p_(reinterpret_cast<const internal::Verdaux_data*>(p))
2038  { }
2039
2040  template<typename File>
2041  Verdaux(File* file, typename File::Location loc)
2042    : p_(reinterpret_cast<const internal::Verdaux_data*>(
2043	   file->view(loc.file_offset, loc.data_size).data()))
2044  { }
2045
2046  Elf_Word
2047  get_vda_name() const
2048  { return Convert<32, big_endian>::convert_host(this->p_->vda_name); }
2049
2050  Elf_Word
2051  get_vda_next() const
2052  { return Convert<32, big_endian>::convert_host(this->p_->vda_next); }
2053
2054 private:
2055  const internal::Verdaux_data* p_;
2056};
2057
2058template<int size, bool big_endian>
2059class Verdaux_write
2060{
2061 public:
2062  Verdaux_write(unsigned char* p)
2063    : p_(reinterpret_cast<internal::Verdaux_data*>(p))
2064  { }
2065
2066  void
2067  set_vda_name(Elf_Word v)
2068  { this->p_->vda_name = Convert<32, big_endian>::convert_host(v); }
2069
2070  void
2071  set_vda_next(Elf_Word v)
2072  { this->p_->vda_next = Convert<32, big_endian>::convert_host(v); }
2073
2074 private:
2075  internal::Verdaux_data* p_;
2076};
2077
2078// Accessor classes for entries in the ELF SHT_GNU_verneed section.
2079
2080template<int size, bool big_endian>
2081class Verneed
2082{
2083 public:
2084  Verneed(const unsigned char* p)
2085    : p_(reinterpret_cast<const internal::Verneed_data*>(p))
2086  { }
2087
2088  template<typename File>
2089  Verneed(File* file, typename File::Location loc)
2090    : p_(reinterpret_cast<const internal::Verneed_data*>(
2091	   file->view(loc.file_offset, loc.data_size).data()))
2092  { }
2093
2094  Elf_Half
2095  get_vn_version() const
2096  { return Convert<16, big_endian>::convert_host(this->p_->vn_version); }
2097
2098  Elf_Half
2099  get_vn_cnt() const
2100  { return Convert<16, big_endian>::convert_host(this->p_->vn_cnt); }
2101
2102  Elf_Word
2103  get_vn_file() const
2104  { return Convert<32, big_endian>::convert_host(this->p_->vn_file); }
2105
2106  Elf_Word
2107  get_vn_aux() const
2108  { return Convert<32, big_endian>::convert_host(this->p_->vn_aux); }
2109
2110  Elf_Word
2111  get_vn_next() const
2112  { return Convert<32, big_endian>::convert_host(this->p_->vn_next); }
2113
2114 private:
2115  const internal::Verneed_data* p_;
2116};
2117
2118template<int size, bool big_endian>
2119class Verneed_write
2120{
2121 public:
2122  Verneed_write(unsigned char* p)
2123    : p_(reinterpret_cast<internal::Verneed_data*>(p))
2124  { }
2125
2126  void
2127  set_vn_version(Elf_Half v)
2128  { this->p_->vn_version = Convert<16, big_endian>::convert_host(v); }
2129
2130  void
2131  set_vn_cnt(Elf_Half v)
2132  { this->p_->vn_cnt = Convert<16, big_endian>::convert_host(v); }
2133
2134  void
2135  set_vn_file(Elf_Word v)
2136  { this->p_->vn_file = Convert<32, big_endian>::convert_host(v); }
2137
2138  void
2139  set_vn_aux(Elf_Word v)
2140  { this->p_->vn_aux = Convert<32, big_endian>::convert_host(v); }
2141
2142  void
2143  set_vn_next(Elf_Word v)
2144  { this->p_->vn_next = Convert<32, big_endian>::convert_host(v); }
2145
2146 private:
2147  internal::Verneed_data* p_;
2148};
2149
2150// Accessor classes for auxiliary entries in the ELF SHT_GNU_verneed
2151// section.
2152
2153template<int size, bool big_endian>
2154class Vernaux
2155{
2156 public:
2157  Vernaux(const unsigned char* p)
2158    : p_(reinterpret_cast<const internal::Vernaux_data*>(p))
2159  { }
2160
2161  template<typename File>
2162  Vernaux(File* file, typename File::Location loc)
2163    : p_(reinterpret_cast<const internal::Vernaux_data*>(
2164	   file->view(loc.file_offset, loc.data_size).data()))
2165  { }
2166
2167  Elf_Word
2168  get_vna_hash() const
2169  { return Convert<32, big_endian>::convert_host(this->p_->vna_hash); }
2170
2171  Elf_Half
2172  get_vna_flags() const
2173  { return Convert<16, big_endian>::convert_host(this->p_->vna_flags); }
2174
2175  Elf_Half
2176  get_vna_other() const
2177  { return Convert<16, big_endian>::convert_host(this->p_->vna_other); }
2178
2179  Elf_Word
2180  get_vna_name() const
2181  { return Convert<32, big_endian>::convert_host(this->p_->vna_name); }
2182
2183  Elf_Word
2184  get_vna_next() const
2185  { return Convert<32, big_endian>::convert_host(this->p_->vna_next); }
2186
2187 private:
2188  const internal::Vernaux_data* p_;
2189};
2190
2191template<int size, bool big_endian>
2192class Vernaux_write
2193{
2194 public:
2195  Vernaux_write(unsigned char* p)
2196    : p_(reinterpret_cast<internal::Vernaux_data*>(p))
2197  { }
2198
2199  void
2200  set_vna_hash(Elf_Word v)
2201  { this->p_->vna_hash = Convert<32, big_endian>::convert_host(v); }
2202
2203  void
2204  set_vna_flags(Elf_Half v)
2205  { this->p_->vna_flags = Convert<16, big_endian>::convert_host(v); }
2206
2207  void
2208  set_vna_other(Elf_Half v)
2209  { this->p_->vna_other = Convert<16, big_endian>::convert_host(v); }
2210
2211  void
2212  set_vna_name(Elf_Word v)
2213  { this->p_->vna_name = Convert<32, big_endian>::convert_host(v); }
2214
2215  void
2216  set_vna_next(Elf_Word v)
2217  { this->p_->vna_next = Convert<32, big_endian>::convert_host(v); }
2218
2219 private:
2220  internal::Vernaux_data* p_;
2221};
2222
2223} // End namespace elfcpp.
2224
2225#endif // !defined(ELFPCP_H)
2226