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