/* ELF support for BFD.
Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
- 2003, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2006, 2007, 2008 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
#ifndef _ELF_INTERNAL_H
#define _ELF_INTERNAL_H
+/* Special section indices, which may show up in st_shndx fields, among
+ other places. */
+
+#undef SHN_UNDEF
+#undef SHN_LORESERVE
+#undef SHN_LOPROC
+#undef SHN_HIPROC
+#undef SHN_LOOS
+#undef SHN_HIOS
+#undef SHN_ABS
+#undef SHN_COMMON
+#undef SHN_XINDEX
+#undef SHN_HIRESERVE
+#define SHN_UNDEF 0 /* Undefined section reference */
+#define SHN_LORESERVE (-0x100u) /* Begin range of reserved indices */
+#define SHN_LOPROC (-0x100u) /* Begin range of appl-specific */
+#define SHN_HIPROC (-0xE1u) /* End range of appl-specific */
+#define SHN_LOOS (-0xE0u) /* OS specific semantics, lo */
+#define SHN_HIOS (-0xC1u) /* OS specific semantics, hi */
+#define SHN_ABS (-0xFu) /* Associated symbol is absolute */
+#define SHN_COMMON (-0xEu) /* Associated symbol is in common */
+#define SHN_XINDEX (-0x1u) /* Section index is held elsewhere */
+#define SHN_HIRESERVE (-0x1u) /* End range of reserved indices */
+#define SHN_BAD (-0x101u) /* Used internally by bfd */
+
/* ELF Header */
#define EI_NIDENT 16 /* Size of e_ident[] */
unsigned int sh_type; /* Type of section */
bfd_vma sh_flags; /* Miscellaneous section attributes */
bfd_vma sh_addr; /* Section virtual addr at execution */
+ file_ptr sh_offset; /* Section file offset */
bfd_size_type sh_size; /* Size of section in bytes */
+ unsigned int sh_link; /* Index of another section */
+ unsigned int sh_info; /* Additional section information */
+ bfd_vma sh_addralign; /* Section alignment */
bfd_size_type sh_entsize; /* Entry size if section holds table */
- unsigned long sh_link; /* Index of another section */
- unsigned long sh_info; /* Additional section information */
- file_ptr sh_offset; /* Section file offset */
- unsigned int sh_addralign; /* Section alignment */
/* The internal rep also has some cached info associated with it. */
asection * bfd_section; /* Associated BFD section. */
bfd_vma p_vaddr_offset;
/* Program segment alignment. */
bfd_vma p_align;
+ /* Segment size in file and memory */
+ bfd_vma p_size;
+ /* Required size of filehdr + phdrs, if non-zero */
+ bfd_vma header_size;
/* Whether the p_flags field is valid; if not, the flags are based
on the section flags. */
unsigned int p_flags_valid : 1;
/* Whether the p_align field is valid; if not, PT_LOAD segment
alignment is based on the default maximum page size. */
unsigned int p_align_valid : 1;
+ /* Whether the p_size field is valid; if not, the size are based
+ on the section sizes. */
+ unsigned int p_size_valid : 1;
/* Whether this segment includes the file header. */
unsigned int includes_filehdr : 1;
/* Whether this segment includes the program headers. */
|| segment->p_type == PT_TLS) ? sec_hdr->sh_size : 0)
/* Decide if the given sec_hdr is in the given segment. PT_TLS segment
- contains only SHF_TLS sections. Only PT_LOAD and PT_TLS segments
- can contain SHF_TLS sections. */
+ contains only SHF_TLS sections. Only PT_LOAD, PT_GNU_RELRO and
+ and PT_TLS segments can contain SHF_TLS sections. */
#define ELF_IS_SECTION_IN_SEGMENT(sec_hdr, segment) \
(((((sec_hdr->sh_flags & SHF_TLS) != 0) \
&& (segment->p_type == PT_TLS \
+ || segment->p_type == PT_GNU_RELRO \
|| segment->p_type == PT_LOAD)) \
|| ((sec_hdr->sh_flags & SHF_TLS) == 0 \
&& segment->p_type != PT_TLS)) \
|| ((bfd_vma) sec_hdr->sh_offset >= segment->p_offset \
&& (sec_hdr->sh_offset + ELF_SECTION_SIZE(sec_hdr, segment) \
<= segment->p_offset + segment->p_filesz))) \
- /* SHF_ALLOC sections must have VMAs within the segment. */ \
+ /* SHF_ALLOC sections must have VMAs within the segment. Be \
+ careful about segments right at the end of memory. */ \
&& ((sec_hdr->sh_flags & SHF_ALLOC) == 0 \
|| (sec_hdr->sh_addr >= segment->p_vaddr \
- && (sec_hdr->sh_addr + ELF_SECTION_SIZE(sec_hdr, segment) \
- <= segment->p_vaddr + segment->p_memsz))))
+ && (sec_hdr->sh_addr - segment->p_vaddr \
+ + ELF_SECTION_SIZE(sec_hdr, segment) <= segment->p_memsz))))
/* Decide if the given sec_hdr is in the given segment in file. */
#define ELF_IS_SECTION_IN_SEGMENT_FILE(sec_hdr, segment) \