Mention PR ld/4701.
[deliverable/binutils-gdb.git] / include / elf / internal.h
index e4eba7d6cb348a81ec343448c0441a72885f90c1..152171136c198ba56118fb548caaaef53742cef9 100644 (file)
@@ -1,6 +1,6 @@
 /* ELF support for BFD.
    Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
-   2003 Free Software Foundation, Inc.
+   2003, 2006, 2007 Free Software Foundation, Inc.
 
    Written by Fred Fish @ Cygnus Support, from information published
    in "UNIX System V Release 4, Programmers Guide: ANSI C and
@@ -235,12 +235,19 @@ struct elf_segment_map
   unsigned long p_flags;
   /* Program segment physical address.  */
   bfd_vma p_paddr;
+  /* Program segment virtual address offset from section vma.  */
+  bfd_vma p_vaddr_offset;
+  /* Program segment alignment.  */
+  bfd_vma p_align;
   /* 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_paddr field is valid; if not, the physical address
      is based on the section lma values.  */
   unsigned int p_paddr_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 this segment includes the file header.  */
   unsigned int includes_filehdr : 1;
   /* Whether this segment includes the program headers.  */
@@ -251,29 +258,42 @@ struct elf_segment_map
   asection *sections[1];
 };
 
+/* .tbss is special.  It doesn't contribute memory space to normal
+   segments and it doesn't take file space in normal segments.  */
+#define ELF_SECTION_SIZE(sec_hdr, segment)                     \
+   (((sec_hdr->sh_flags & SHF_TLS) == 0                                \
+     || sec_hdr->sh_type != SHT_NOBITS                         \
+     || 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.  */
+#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_LOAD))                                \
+    || ((sec_hdr->sh_flags & SHF_TLS) == 0                             \
+       && segment->p_type != PT_TLS))                                  \
+   /* Any section besides one of type SHT_NOBITS must have a file      \
+      offset within the segment.  */                                   \
+   && (sec_hdr->sh_type == SHT_NOBITS                                  \
+       || ((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.  */                \
+   && ((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))))
+
 /* Decide if the given sec_hdr is in the given segment in file.  */
 #define ELF_IS_SECTION_IN_SEGMENT_FILE(sec_hdr, segment)       \
   (sec_hdr->sh_size > 0                                                \
-   /* PT_TLS segment contains only SHF_TLS sections.  */       \
-   && (segment->p_type != PT_TLS                               \
-       || (sec_hdr->sh_flags & SHF_TLS) != 0)                  \
-   /* Compare allocated sec_hdrs by VMA, unallocated sec_hdrs  \
-      by file offset.  */                                      \
-   && (sec_hdr->sh_flags & SHF_ALLOC                           \
-       ? (sec_hdr->sh_addr >= segment->p_vaddr                 \
-         && sec_hdr->sh_addr + sec_hdr->sh_size                \
-         <= segment->p_vaddr + segment->p_memsz)               \
-       : ((bfd_vma) sec_hdr->sh_offset >= segment->p_offset    \
-         && (sec_hdr->sh_offset + sec_hdr->sh_size             \
-             <= segment->p_offset + segment->p_filesz))))
+   && ELF_IS_SECTION_IN_SEGMENT (sec_hdr, segment))
 
 /* Decide if the given sec_hdr is in the given segment in memory.  */
 #define ELF_IS_SECTION_IN_SEGMENT_MEMORY(sec_hdr, segment)     \
-  (ELF_IS_SECTION_IN_SEGMENT_FILE (sec_hdr, segment)           \
-   /* .tbss is special.  It doesn't contribute memory space to \
-      normal segments.  */                                     \
-   && (!((sec_hdr->sh_flags & SHF_TLS) != 0                    \
-        && sec_hdr->sh_type == SHT_NOBITS)                     \
-       || segment->p_type == PT_TLS))
+  (ELF_SECTION_SIZE(sec_hdr, segment) > 0                      \
+   && ELF_IS_SECTION_IN_SEGMENT (sec_hdr, segment))
 
 #endif /* _ELF_INTERNAL_H */
This page took 0.028125 seconds and 4 git commands to generate.