xref: /dflybsd-src/contrib/gdb-7/include/elf/internal.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1*86d7f5d3SJohn Marino /* ELF support for BFD.
2*86d7f5d3SJohn Marino    Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
3*86d7f5d3SJohn Marino    2003, 2006, 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
4*86d7f5d3SJohn Marino 
5*86d7f5d3SJohn Marino    Written by Fred Fish @ Cygnus Support, from information published
6*86d7f5d3SJohn Marino    in "UNIX System V Release 4, Programmers Guide: ANSI C and
7*86d7f5d3SJohn Marino    Programming Support Tools".
8*86d7f5d3SJohn Marino 
9*86d7f5d3SJohn Marino    This file is part of BFD, the Binary File Descriptor library.
10*86d7f5d3SJohn Marino 
11*86d7f5d3SJohn Marino    This program is free software; you can redistribute it and/or modify
12*86d7f5d3SJohn Marino    it under the terms of the GNU General Public License as published by
13*86d7f5d3SJohn Marino    the Free Software Foundation; either version 3 of the License, or
14*86d7f5d3SJohn Marino    (at your option) any later version.
15*86d7f5d3SJohn Marino 
16*86d7f5d3SJohn Marino    This program is distributed in the hope that it will be useful,
17*86d7f5d3SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
18*86d7f5d3SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19*86d7f5d3SJohn Marino    GNU General Public License for more details.
20*86d7f5d3SJohn Marino 
21*86d7f5d3SJohn Marino    You should have received a copy of the GNU General Public License
22*86d7f5d3SJohn Marino    along with this program; if not, write to the Free Software
23*86d7f5d3SJohn Marino    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24*86d7f5d3SJohn Marino    MA 02110-1301, USA.  */
25*86d7f5d3SJohn Marino 
26*86d7f5d3SJohn Marino /* This file is part of ELF support for BFD, and contains the portions
27*86d7f5d3SJohn Marino    that describe how ELF is represented internally in the BFD library.
28*86d7f5d3SJohn Marino    I.E. it describes the in-memory representation of ELF.  It requires
29*86d7f5d3SJohn Marino    the elf-common.h file which contains the portions that are common to
30*86d7f5d3SJohn Marino    both the internal and external representations.  */
31*86d7f5d3SJohn Marino 
32*86d7f5d3SJohn Marino /* NOTE that these structures are not kept in the same order as they appear
33*86d7f5d3SJohn Marino    in the object file.  In some cases they've been reordered for more optimal
34*86d7f5d3SJohn Marino    packing under various circumstances.  */
35*86d7f5d3SJohn Marino 
36*86d7f5d3SJohn Marino #ifndef _ELF_INTERNAL_H
37*86d7f5d3SJohn Marino #define _ELF_INTERNAL_H
38*86d7f5d3SJohn Marino 
39*86d7f5d3SJohn Marino /* Special section indices, which may show up in st_shndx fields, among
40*86d7f5d3SJohn Marino    other places.  */
41*86d7f5d3SJohn Marino 
42*86d7f5d3SJohn Marino #undef SHN_UNDEF
43*86d7f5d3SJohn Marino #undef SHN_LORESERVE
44*86d7f5d3SJohn Marino #undef SHN_LOPROC
45*86d7f5d3SJohn Marino #undef SHN_HIPROC
46*86d7f5d3SJohn Marino #undef SHN_LOOS
47*86d7f5d3SJohn Marino #undef SHN_HIOS
48*86d7f5d3SJohn Marino #undef SHN_ABS
49*86d7f5d3SJohn Marino #undef SHN_COMMON
50*86d7f5d3SJohn Marino #undef SHN_XINDEX
51*86d7f5d3SJohn Marino #undef SHN_HIRESERVE
52*86d7f5d3SJohn Marino #define SHN_UNDEF	0		/* Undefined section reference */
53*86d7f5d3SJohn Marino #define SHN_LORESERVE	(-0x100u)	/* Begin range of reserved indices */
54*86d7f5d3SJohn Marino #define SHN_LOPROC	(-0x100u)	/* Begin range of appl-specific */
55*86d7f5d3SJohn Marino #define SHN_HIPROC	(-0xE1u)	/* End range of appl-specific */
56*86d7f5d3SJohn Marino #define SHN_LOOS	(-0xE0u)	/* OS specific semantics, lo */
57*86d7f5d3SJohn Marino #define SHN_HIOS	(-0xC1u)	/* OS specific semantics, hi */
58*86d7f5d3SJohn Marino #define SHN_ABS		(-0xFu)		/* Associated symbol is absolute */
59*86d7f5d3SJohn Marino #define SHN_COMMON	(-0xEu)		/* Associated symbol is in common */
60*86d7f5d3SJohn Marino #define SHN_XINDEX	(-0x1u)		/* Section index is held elsewhere */
61*86d7f5d3SJohn Marino #define SHN_HIRESERVE	(-0x1u)		/* End range of reserved indices */
62*86d7f5d3SJohn Marino #define SHN_BAD		(-0x101u)	/* Used internally by bfd */
63*86d7f5d3SJohn Marino 
64*86d7f5d3SJohn Marino /* ELF Header */
65*86d7f5d3SJohn Marino 
66*86d7f5d3SJohn Marino #define EI_NIDENT	16		/* Size of e_ident[] */
67*86d7f5d3SJohn Marino 
68*86d7f5d3SJohn Marino typedef struct elf_internal_ehdr {
69*86d7f5d3SJohn Marino   unsigned char		e_ident[EI_NIDENT]; /* ELF "magic number" */
70*86d7f5d3SJohn Marino   bfd_vma		e_entry;	/* Entry point virtual address */
71*86d7f5d3SJohn Marino   bfd_size_type		e_phoff;	/* Program header table file offset */
72*86d7f5d3SJohn Marino   bfd_size_type		e_shoff;	/* Section header table file offset */
73*86d7f5d3SJohn Marino   unsigned long		e_version;	/* Identifies object file version */
74*86d7f5d3SJohn Marino   unsigned long		e_flags;	/* Processor-specific flags */
75*86d7f5d3SJohn Marino   unsigned short	e_type;		/* Identifies object file type */
76*86d7f5d3SJohn Marino   unsigned short	e_machine;	/* Specifies required architecture */
77*86d7f5d3SJohn Marino   unsigned int		e_ehsize;	/* ELF header size in bytes */
78*86d7f5d3SJohn Marino   unsigned int		e_phentsize;	/* Program header table entry size */
79*86d7f5d3SJohn Marino   unsigned int		e_phnum;	/* Program header table entry count */
80*86d7f5d3SJohn Marino   unsigned int		e_shentsize;	/* Section header table entry size */
81*86d7f5d3SJohn Marino   unsigned int		e_shnum;	/* Section header table entry count */
82*86d7f5d3SJohn Marino   unsigned int		e_shstrndx;	/* Section header string table index */
83*86d7f5d3SJohn Marino } Elf_Internal_Ehdr;
84*86d7f5d3SJohn Marino 
85*86d7f5d3SJohn Marino /* Program header */
86*86d7f5d3SJohn Marino 
87*86d7f5d3SJohn Marino struct elf_internal_phdr {
88*86d7f5d3SJohn Marino   unsigned long	p_type;			/* Identifies program segment type */
89*86d7f5d3SJohn Marino   unsigned long	p_flags;		/* Segment flags */
90*86d7f5d3SJohn Marino   bfd_vma	p_offset;		/* Segment file offset */
91*86d7f5d3SJohn Marino   bfd_vma	p_vaddr;		/* Segment virtual address */
92*86d7f5d3SJohn Marino   bfd_vma	p_paddr;		/* Segment physical address */
93*86d7f5d3SJohn Marino   bfd_vma	p_filesz;		/* Segment size in file */
94*86d7f5d3SJohn Marino   bfd_vma	p_memsz;		/* Segment size in memory */
95*86d7f5d3SJohn Marino   bfd_vma	p_align;		/* Segment alignment, file & memory */
96*86d7f5d3SJohn Marino };
97*86d7f5d3SJohn Marino 
98*86d7f5d3SJohn Marino typedef struct elf_internal_phdr Elf_Internal_Phdr;
99*86d7f5d3SJohn Marino 
100*86d7f5d3SJohn Marino /* Section header */
101*86d7f5d3SJohn Marino 
102*86d7f5d3SJohn Marino typedef struct elf_internal_shdr {
103*86d7f5d3SJohn Marino   unsigned int	sh_name;		/* Section name, index in string tbl */
104*86d7f5d3SJohn Marino   unsigned int	sh_type;		/* Type of section */
105*86d7f5d3SJohn Marino   bfd_vma	sh_flags;		/* Miscellaneous section attributes */
106*86d7f5d3SJohn Marino   bfd_vma	sh_addr;		/* Section virtual addr at execution */
107*86d7f5d3SJohn Marino   file_ptr	sh_offset;		/* Section file offset */
108*86d7f5d3SJohn Marino   bfd_size_type	sh_size;		/* Size of section in bytes */
109*86d7f5d3SJohn Marino   unsigned int	sh_link;		/* Index of another section */
110*86d7f5d3SJohn Marino   unsigned int	sh_info;		/* Additional section information */
111*86d7f5d3SJohn Marino   bfd_vma	sh_addralign;		/* Section alignment */
112*86d7f5d3SJohn Marino   bfd_size_type	sh_entsize;		/* Entry size if section holds table */
113*86d7f5d3SJohn Marino 
114*86d7f5d3SJohn Marino   /* The internal rep also has some cached info associated with it. */
115*86d7f5d3SJohn Marino   asection *	bfd_section;		/* Associated BFD section.  */
116*86d7f5d3SJohn Marino   unsigned char *contents;		/* Section contents.  */
117*86d7f5d3SJohn Marino } Elf_Internal_Shdr;
118*86d7f5d3SJohn Marino 
119*86d7f5d3SJohn Marino /* Symbol table entry */
120*86d7f5d3SJohn Marino 
121*86d7f5d3SJohn Marino struct elf_internal_sym {
122*86d7f5d3SJohn Marino   bfd_vma	st_value;		/* Value of the symbol */
123*86d7f5d3SJohn Marino   bfd_vma	st_size;		/* Associated symbol size */
124*86d7f5d3SJohn Marino   unsigned long	st_name;		/* Symbol name, index in string tbl */
125*86d7f5d3SJohn Marino   unsigned char	st_info;		/* Type and binding attributes */
126*86d7f5d3SJohn Marino   unsigned char	st_other;		/* Visibilty, and target specific */
127*86d7f5d3SJohn Marino   unsigned char st_target_internal;	/* Internal-only information */
128*86d7f5d3SJohn Marino   unsigned int  st_shndx;		/* Associated section index */
129*86d7f5d3SJohn Marino };
130*86d7f5d3SJohn Marino 
131*86d7f5d3SJohn Marino typedef struct elf_internal_sym Elf_Internal_Sym;
132*86d7f5d3SJohn Marino 
133*86d7f5d3SJohn Marino /* Note segments */
134*86d7f5d3SJohn Marino 
135*86d7f5d3SJohn Marino typedef struct elf_internal_note {
136*86d7f5d3SJohn Marino   unsigned long	namesz;			/* Size of entry's owner string */
137*86d7f5d3SJohn Marino   unsigned long	descsz;			/* Size of the note descriptor */
138*86d7f5d3SJohn Marino   unsigned long	type;			/* Interpretation of the descriptor */
139*86d7f5d3SJohn Marino   char *	namedata;		/* Start of the name+desc data */
140*86d7f5d3SJohn Marino   char *	descdata;		/* Start of the desc data */
141*86d7f5d3SJohn Marino   bfd_vma	descpos;		/* File offset of the descdata */
142*86d7f5d3SJohn Marino } Elf_Internal_Note;
143*86d7f5d3SJohn Marino 
144*86d7f5d3SJohn Marino /* Relocation Entries */
145*86d7f5d3SJohn Marino 
146*86d7f5d3SJohn Marino typedef struct elf_internal_rela {
147*86d7f5d3SJohn Marino   bfd_vma	r_offset;	/* Location at which to apply the action */
148*86d7f5d3SJohn Marino   bfd_vma	r_info;		/* Index and Type of relocation */
149*86d7f5d3SJohn Marino   bfd_vma	r_addend;	/* Constant addend used to compute value */
150*86d7f5d3SJohn Marino } Elf_Internal_Rela;
151*86d7f5d3SJohn Marino 
152*86d7f5d3SJohn Marino /* dynamic section structure */
153*86d7f5d3SJohn Marino 
154*86d7f5d3SJohn Marino typedef struct elf_internal_dyn {
155*86d7f5d3SJohn Marino   /* This needs to support 64-bit values in elf64.  */
156*86d7f5d3SJohn Marino   bfd_vma d_tag;		/* entry tag value */
157*86d7f5d3SJohn Marino   union {
158*86d7f5d3SJohn Marino     /* This needs to support 64-bit values in elf64.  */
159*86d7f5d3SJohn Marino     bfd_vma	d_val;
160*86d7f5d3SJohn Marino     bfd_vma	d_ptr;
161*86d7f5d3SJohn Marino   } d_un;
162*86d7f5d3SJohn Marino } Elf_Internal_Dyn;
163*86d7f5d3SJohn Marino 
164*86d7f5d3SJohn Marino /* This structure appears in a SHT_GNU_verdef section.  */
165*86d7f5d3SJohn Marino 
166*86d7f5d3SJohn Marino typedef struct elf_internal_verdef {
167*86d7f5d3SJohn Marino   unsigned short vd_version;	/* Version number of structure.  */
168*86d7f5d3SJohn Marino   unsigned short vd_flags;	/* Flags (VER_FLG_*).  */
169*86d7f5d3SJohn Marino   unsigned short vd_ndx;	/* Version index.  */
170*86d7f5d3SJohn Marino   unsigned short vd_cnt;	/* Number of verdaux entries.  */
171*86d7f5d3SJohn Marino   unsigned long	 vd_hash;	/* Hash of name.  */
172*86d7f5d3SJohn Marino   unsigned long	 vd_aux;	/* Offset to verdaux entries.  */
173*86d7f5d3SJohn Marino   unsigned long	 vd_next;	/* Offset to next verdef.  */
174*86d7f5d3SJohn Marino 
175*86d7f5d3SJohn Marino   /* These fields are set up when BFD reads in the structure.  FIXME:
176*86d7f5d3SJohn Marino      It would be cleaner to store these in a different structure.  */
177*86d7f5d3SJohn Marino   bfd			      *vd_bfd;		/* BFD.  */
178*86d7f5d3SJohn Marino   const char		      *vd_nodename;	/* Version name.  */
179*86d7f5d3SJohn Marino   struct elf_internal_verdef  *vd_nextdef;	/* vd_next as pointer.  */
180*86d7f5d3SJohn Marino   struct elf_internal_verdaux *vd_auxptr;	/* vd_aux as pointer.  */
181*86d7f5d3SJohn Marino   unsigned int		       vd_exp_refno;	/* Used by the linker.  */
182*86d7f5d3SJohn Marino } Elf_Internal_Verdef;
183*86d7f5d3SJohn Marino 
184*86d7f5d3SJohn Marino /* This structure appears in a SHT_GNU_verdef section.  */
185*86d7f5d3SJohn Marino 
186*86d7f5d3SJohn Marino typedef struct elf_internal_verdaux {
187*86d7f5d3SJohn Marino   unsigned long vda_name;	/* String table offset of name.  */
188*86d7f5d3SJohn Marino   unsigned long vda_next;	/* Offset to next verdaux.  */
189*86d7f5d3SJohn Marino 
190*86d7f5d3SJohn Marino   /* These fields are set up when BFD reads in the structure.  FIXME:
191*86d7f5d3SJohn Marino      It would be cleaner to store these in a different structure.  */
192*86d7f5d3SJohn Marino   const char *vda_nodename;			/* vda_name as pointer.  */
193*86d7f5d3SJohn Marino   struct elf_internal_verdaux *vda_nextptr;	/* vda_next as pointer.  */
194*86d7f5d3SJohn Marino } Elf_Internal_Verdaux;
195*86d7f5d3SJohn Marino 
196*86d7f5d3SJohn Marino /* This structure appears in a SHT_GNU_verneed section.  */
197*86d7f5d3SJohn Marino 
198*86d7f5d3SJohn Marino typedef struct elf_internal_verneed {
199*86d7f5d3SJohn Marino   unsigned short vn_version;	/* Version number of structure.  */
200*86d7f5d3SJohn Marino   unsigned short vn_cnt;	/* Number of vernaux entries.  */
201*86d7f5d3SJohn Marino   unsigned long	 vn_file;	/* String table offset of library name.  */
202*86d7f5d3SJohn Marino   unsigned long	 vn_aux;	/* Offset to vernaux entries.  */
203*86d7f5d3SJohn Marino   unsigned long	 vn_next;	/* Offset to next verneed.  */
204*86d7f5d3SJohn Marino 
205*86d7f5d3SJohn Marino   /* These fields are set up when BFD reads in the structure.  FIXME:
206*86d7f5d3SJohn Marino      It would be cleaner to store these in a different structure.  */
207*86d7f5d3SJohn Marino   bfd			      *vn_bfd;		/* BFD.  */
208*86d7f5d3SJohn Marino   const char                  *vn_filename;	/* vn_file as pointer.  */
209*86d7f5d3SJohn Marino   struct elf_internal_vernaux *vn_auxptr;	/* vn_aux as pointer.  */
210*86d7f5d3SJohn Marino   struct elf_internal_verneed *vn_nextref;	/* vn_nextref as pointer.  */
211*86d7f5d3SJohn Marino } Elf_Internal_Verneed;
212*86d7f5d3SJohn Marino 
213*86d7f5d3SJohn Marino /* This structure appears in a SHT_GNU_verneed section.  */
214*86d7f5d3SJohn Marino 
215*86d7f5d3SJohn Marino typedef struct elf_internal_vernaux {
216*86d7f5d3SJohn Marino   unsigned long	 vna_hash;	/* Hash of dependency name.  */
217*86d7f5d3SJohn Marino   unsigned short vna_flags;	/* Flags (VER_FLG_*).  */
218*86d7f5d3SJohn Marino   unsigned short vna_other;	/* Unused.  */
219*86d7f5d3SJohn Marino   unsigned long	 vna_name;	/* String table offset to version name.  */
220*86d7f5d3SJohn Marino   unsigned long	 vna_next;	/* Offset to next vernaux.  */
221*86d7f5d3SJohn Marino 
222*86d7f5d3SJohn Marino   /* These fields are set up when BFD reads in the structure.  FIXME:
223*86d7f5d3SJohn Marino      It would be cleaner to store these in a different structure.  */
224*86d7f5d3SJohn Marino   const char                  *vna_nodename;	/* vna_name as pointer.  */
225*86d7f5d3SJohn Marino   struct elf_internal_vernaux *vna_nextptr;	/* vna_next as pointer.  */
226*86d7f5d3SJohn Marino } Elf_Internal_Vernaux;
227*86d7f5d3SJohn Marino 
228*86d7f5d3SJohn Marino /* This structure appears in a SHT_GNU_versym section.  This is not a
229*86d7f5d3SJohn Marino    standard ELF structure; ELF just uses Elf32_Half.  */
230*86d7f5d3SJohn Marino 
231*86d7f5d3SJohn Marino typedef struct elf_internal_versym {
232*86d7f5d3SJohn Marino   unsigned short vs_vers;
233*86d7f5d3SJohn Marino } Elf_Internal_Versym;
234*86d7f5d3SJohn Marino 
235*86d7f5d3SJohn Marino /* Structure for syminfo section.  */
236*86d7f5d3SJohn Marino typedef struct
237*86d7f5d3SJohn Marino {
238*86d7f5d3SJohn Marino   unsigned short int 	si_boundto;
239*86d7f5d3SJohn Marino   unsigned short int	si_flags;
240*86d7f5d3SJohn Marino } Elf_Internal_Syminfo;
241*86d7f5d3SJohn Marino 
242*86d7f5d3SJohn Marino /* This structure appears on the stack and in NT_AUXV core file notes.  */
243*86d7f5d3SJohn Marino typedef struct
244*86d7f5d3SJohn Marino {
245*86d7f5d3SJohn Marino   bfd_vma a_type;
246*86d7f5d3SJohn Marino   bfd_vma a_val;
247*86d7f5d3SJohn Marino } Elf_Internal_Auxv;
248*86d7f5d3SJohn Marino 
249*86d7f5d3SJohn Marino 
250*86d7f5d3SJohn Marino /* This structure is used to describe how sections should be assigned
251*86d7f5d3SJohn Marino    to program segments.  */
252*86d7f5d3SJohn Marino 
253*86d7f5d3SJohn Marino struct elf_segment_map
254*86d7f5d3SJohn Marino {
255*86d7f5d3SJohn Marino   /* Next program segment.  */
256*86d7f5d3SJohn Marino   struct elf_segment_map *next;
257*86d7f5d3SJohn Marino   /* Program segment type.  */
258*86d7f5d3SJohn Marino   unsigned long p_type;
259*86d7f5d3SJohn Marino   /* Program segment flags.  */
260*86d7f5d3SJohn Marino   unsigned long p_flags;
261*86d7f5d3SJohn Marino   /* Program segment physical address.  */
262*86d7f5d3SJohn Marino   bfd_vma p_paddr;
263*86d7f5d3SJohn Marino   /* Program segment virtual address offset from section vma.  */
264*86d7f5d3SJohn Marino   bfd_vma p_vaddr_offset;
265*86d7f5d3SJohn Marino   /* Program segment alignment.  */
266*86d7f5d3SJohn Marino   bfd_vma p_align;
267*86d7f5d3SJohn Marino   /* Segment size in file and memory */
268*86d7f5d3SJohn Marino   bfd_vma p_size;
269*86d7f5d3SJohn Marino   /* Required size of filehdr + phdrs, if non-zero */
270*86d7f5d3SJohn Marino   bfd_vma header_size;
271*86d7f5d3SJohn Marino   /* Whether the p_flags field is valid; if not, the flags are based
272*86d7f5d3SJohn Marino      on the section flags.  */
273*86d7f5d3SJohn Marino   unsigned int p_flags_valid : 1;
274*86d7f5d3SJohn Marino   /* Whether the p_paddr field is valid; if not, the physical address
275*86d7f5d3SJohn Marino      is based on the section lma values.  */
276*86d7f5d3SJohn Marino   unsigned int p_paddr_valid : 1;
277*86d7f5d3SJohn Marino   /* Whether the p_align field is valid; if not, PT_LOAD segment
278*86d7f5d3SJohn Marino      alignment is based on the default maximum page size.  */
279*86d7f5d3SJohn Marino   unsigned int p_align_valid : 1;
280*86d7f5d3SJohn Marino   /* Whether the p_size field is valid; if not, the size are based
281*86d7f5d3SJohn Marino      on the section sizes.  */
282*86d7f5d3SJohn Marino   unsigned int p_size_valid : 1;
283*86d7f5d3SJohn Marino   /* Whether this segment includes the file header.  */
284*86d7f5d3SJohn Marino   unsigned int includes_filehdr : 1;
285*86d7f5d3SJohn Marino   /* Whether this segment includes the program headers.  */
286*86d7f5d3SJohn Marino   unsigned int includes_phdrs : 1;
287*86d7f5d3SJohn Marino   /* Number of sections (may be 0).  */
288*86d7f5d3SJohn Marino   unsigned int count;
289*86d7f5d3SJohn Marino   /* Sections.  Actual number of elements is in count field.  */
290*86d7f5d3SJohn Marino   asection *sections[1];
291*86d7f5d3SJohn Marino };
292*86d7f5d3SJohn Marino 
293*86d7f5d3SJohn Marino /* .tbss is special.  It doesn't contribute memory space to normal
294*86d7f5d3SJohn Marino    segments and it doesn't take file space in normal segments.  */
295*86d7f5d3SJohn Marino #define ELF_TBSS_SPECIAL(sec_hdr, segment)			\
296*86d7f5d3SJohn Marino   (((sec_hdr)->sh_flags & SHF_TLS) != 0				\
297*86d7f5d3SJohn Marino    && (sec_hdr)->sh_type == SHT_NOBITS				\
298*86d7f5d3SJohn Marino    && (segment)->p_type != PT_TLS)
299*86d7f5d3SJohn Marino 
300*86d7f5d3SJohn Marino #define ELF_SECTION_SIZE(sec_hdr, segment)			\
301*86d7f5d3SJohn Marino   (ELF_TBSS_SPECIAL(sec_hdr, segment) ? 0 : (sec_hdr)->sh_size)
302*86d7f5d3SJohn Marino 
303*86d7f5d3SJohn Marino /* Decide if the section SEC_HDR is in SEGMENT.  If CHECK_VMA, then
304*86d7f5d3SJohn Marino    VMAs are checked for alloc sections.  If STRICT, then a zero size
305*86d7f5d3SJohn Marino    section won't match at the end of a segment, unless the segment
306*86d7f5d3SJohn Marino    is also zero size.  Regardless of STRICT and CHECK_VMA, zero size
307*86d7f5d3SJohn Marino    sections won't match at the start or end of PT_DYNAMIC, unless
308*86d7f5d3SJohn Marino    PT_DYNAMIC is itself zero sized.  */
309*86d7f5d3SJohn Marino #define ELF_SECTION_IN_SEGMENT_1(sec_hdr, segment, check_vma, strict)	\
310*86d7f5d3SJohn Marino   ((/* Only PT_LOAD, PT_GNU_RELRO and PT_TLS segments can contain	\
311*86d7f5d3SJohn Marino        SHF_TLS sections.  */						\
312*86d7f5d3SJohn Marino     ((((sec_hdr)->sh_flags & SHF_TLS) != 0)				\
313*86d7f5d3SJohn Marino      && ((segment)->p_type == PT_TLS					\
314*86d7f5d3SJohn Marino 	 || (segment)->p_type == PT_GNU_RELRO				\
315*86d7f5d3SJohn Marino 	 || (segment)->p_type == PT_LOAD))				\
316*86d7f5d3SJohn Marino     /* PT_TLS segment contains only SHF_TLS sections, PT_PHDR no	\
317*86d7f5d3SJohn Marino        sections at all.  */						\
318*86d7f5d3SJohn Marino     || (((sec_hdr)->sh_flags & SHF_TLS) == 0				\
319*86d7f5d3SJohn Marino 	&& (segment)->p_type != PT_TLS					\
320*86d7f5d3SJohn Marino 	&& (segment)->p_type != PT_PHDR))				\
321*86d7f5d3SJohn Marino    /* Any section besides one of type SHT_NOBITS must have file		\
322*86d7f5d3SJohn Marino       offsets within the segment.  */					\
323*86d7f5d3SJohn Marino    && ((sec_hdr)->sh_type == SHT_NOBITS					\
324*86d7f5d3SJohn Marino        || ((bfd_vma) (sec_hdr)->sh_offset >= (segment)->p_offset	\
325*86d7f5d3SJohn Marino 	   && (!(strict)						\
326*86d7f5d3SJohn Marino 	       || ((sec_hdr)->sh_offset - (segment)->p_offset		\
327*86d7f5d3SJohn Marino 		   <= (segment)->p_filesz - 1))				\
328*86d7f5d3SJohn Marino 	   && (((sec_hdr)->sh_offset - (segment)->p_offset		\
329*86d7f5d3SJohn Marino 		+ ELF_SECTION_SIZE(sec_hdr, segment))			\
330*86d7f5d3SJohn Marino 	       <= (segment)->p_filesz)))				\
331*86d7f5d3SJohn Marino    /* SHF_ALLOC sections must have VMAs within the segment.  */		\
332*86d7f5d3SJohn Marino    && (!(check_vma)							\
333*86d7f5d3SJohn Marino        || ((sec_hdr)->sh_flags & SHF_ALLOC) == 0			\
334*86d7f5d3SJohn Marino        || ((sec_hdr)->sh_addr >= (segment)->p_vaddr			\
335*86d7f5d3SJohn Marino 	   && (!(strict)						\
336*86d7f5d3SJohn Marino 	       || ((sec_hdr)->sh_addr - (segment)->p_vaddr		\
337*86d7f5d3SJohn Marino 		   <= (segment)->p_memsz - 1))				\
338*86d7f5d3SJohn Marino 	   && (((sec_hdr)->sh_addr - (segment)->p_vaddr			\
339*86d7f5d3SJohn Marino 		+ ELF_SECTION_SIZE(sec_hdr, segment))			\
340*86d7f5d3SJohn Marino 	       <= (segment)->p_memsz)))					\
341*86d7f5d3SJohn Marino    /* No zero size sections at start or end of PT_DYNAMIC.  */		\
342*86d7f5d3SJohn Marino    && ((segment)->p_type != PT_DYNAMIC					\
343*86d7f5d3SJohn Marino        || (sec_hdr)->sh_size != 0					\
344*86d7f5d3SJohn Marino        || (segment)->p_memsz == 0					\
345*86d7f5d3SJohn Marino        || (((sec_hdr)->sh_type == SHT_NOBITS				\
346*86d7f5d3SJohn Marino 	    || ((bfd_vma) (sec_hdr)->sh_offset > (segment)->p_offset	\
347*86d7f5d3SJohn Marino 	        && ((sec_hdr)->sh_offset - (segment)->p_offset		\
348*86d7f5d3SJohn Marino 		    < (segment)->p_filesz)))				\
349*86d7f5d3SJohn Marino 	   && (((sec_hdr)->sh_flags & SHF_ALLOC) == 0			\
350*86d7f5d3SJohn Marino 	       || ((sec_hdr)->sh_addr > (segment)->p_vaddr		\
351*86d7f5d3SJohn Marino 		   && ((sec_hdr)->sh_addr - (segment)->p_vaddr		\
352*86d7f5d3SJohn Marino 		       < (segment)->p_memsz))))))
353*86d7f5d3SJohn Marino 
354*86d7f5d3SJohn Marino #define ELF_SECTION_IN_SEGMENT(sec_hdr, segment)			\
355*86d7f5d3SJohn Marino   (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 0))
356*86d7f5d3SJohn Marino 
357*86d7f5d3SJohn Marino #define ELF_SECTION_IN_SEGMENT_STRICT(sec_hdr, segment)			\
358*86d7f5d3SJohn Marino   (ELF_SECTION_IN_SEGMENT_1 (sec_hdr, segment, 1, 1))
359*86d7f5d3SJohn Marino 
360*86d7f5d3SJohn Marino #endif /* _ELF_INTERNAL_H */
361