include/elf/
authorAlan Modra <amodra@gmail.com>
Wed, 2 May 2007 13:44:37 +0000 (13:44 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 2 May 2007 13:44:37 +0000 (13:44 +0000)
* internal.h (ELF_IS_SECTION_IN_SEGMENT): Check both file offset
and vma for appropriate sections.
bfd/
* elf.c (assign_file_positions_for_load_sections): Set sh_offset
here.  Set sh_type to SHT_NOBITS if we won't be allocating
file space.  Don't bump p_memsz for non-alloc sections.  Adjust
section-in-segment check.
(assign_file_positions_for_non_load_sections): Don't set sh_offset
here for sections that have already been handled above.

bfd/ChangeLog
bfd/elf.c
include/elf/ChangeLog
include/elf/internal.h

index 73257527c20e7b62dd6931d1aecc6aba245c486a..1c00088371e3a1754e93b1d261d4ac07c80de20c 100644 (file)
@@ -1,3 +1,12 @@
+2007-05-02  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf.c (assign_file_positions_for_load_sections): Set sh_offset
+       here.  Set sh_type to SHT_NOBITS if we won't be allocating
+       file space.  Don't bump p_memsz for non-alloc sections.  Adjust
+       section-in-segment check.
+       (assign_file_positions_for_non_load_sections): Don't set sh_offset
+       here for sections that have already been handled above.
+
 2007-04-30  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-spu.c (struct spu_link_hash_table): Add stack_analysis
index 3501f3dc6d88aa01d8573cd075374bb7aaffba8d..1314bba7449808bb2a1690471452ead2f1591894 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4511,6 +4511,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
          asection *sec;
          flagword flags;
          bfd_size_type align;
+         Elf_Internal_Shdr *this_hdr;
 
          sec = *secpp;
          flags = sec->flags;
@@ -4543,13 +4544,14 @@ assign_file_positions_for_load_sections (bfd *abfd,
                }
            }
 
+         this_hdr = &elf_section_data (sec)->this_hdr;
          if (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core)
            {
              /* The section at i == 0 is the one that actually contains
                 everything.  */
              if (i == 0)
                {
-                 sec->filepos = off;
+                 this_hdr->sh_offset = sec->filepos = off;
                  off += sec->size;
                  p->p_filesz = sec->size;
                  p->p_memsz = 0;
@@ -4568,7 +4570,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
            {
              if (p->p_type == PT_LOAD)
                {
-                 sec->filepos = off + voff;
+                 this_hdr->sh_offset = sec->filepos = off + voff;
                  /* FIXME: The SEC_HAS_CONTENTS test here dates back to
                     1997, and the exact reason for it isn't clear.  One
                     plausible explanation is that it is to work around
@@ -4586,12 +4588,22 @@ assign_file_positions_for_load_sections (bfd *abfd,
                  if ((flags & SEC_LOAD) != 0
                      || (flags & SEC_HAS_CONTENTS) != 0)
                    off += sec->size;
+                 else
+                   /* If we aren't making room for this section, then
+                      it must be SHT_NOBITS regardless of what we've
+                      set via struct bfd_elf_special_section.  */
+                   this_hdr->sh_type = SHT_NOBITS;
                }
 
              if ((flags & SEC_LOAD) != 0)
                {
                  p->p_filesz += sec->size;
-                 p->p_memsz += sec->size;
+                 /* SEC_LOAD without SEC_ALLOC is a weird combination
+                    used by note sections to signify that a PT_NOTE
+                    segment should be created.  These take file space
+                    but are not actually loaded into memory.  */
+                 if ((flags & SEC_ALLOC) != 0)
+                   p->p_memsz += sec->size;
                }
 
              /* .tbss is special.  It doesn't contribute to p_memsz of
@@ -4629,11 +4641,9 @@ assign_file_positions_for_load_sections (bfd *abfd,
            }
        }
 
-      /* Check if all sections are in the segment.  Skip PT_GNU_RELRO
-        and PT_NOTE segments since they will be processed by
-        assign_file_positions_for_non_load_sections later.  */
-      if (p->p_type != PT_GNU_RELRO
-         && p->p_type != PT_NOTE)
+      /* Check that all sections are in the segment.  */
+      if (p->p_type == PT_LOAD
+         || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
        for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
          {
            Elf_Internal_Shdr *this_hdr;
@@ -4689,7 +4699,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
          && (hdr->bfd_section->filepos != 0
              || (hdr->sh_type == SHT_NOBITS
                  && hdr->contents == NULL)))
-       hdr->sh_offset = hdr->bfd_section->filepos;
+       BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
       else if ((hdr->sh_flags & SHF_ALLOC) != 0)
        {
          if (hdr->sh_size != 0)
index 89deb482b30544e3b4a9475285bb260979aa86e9..c214009738c12d0162547f8a225643cf51acb5e0 100644 (file)
@@ -1,3 +1,8 @@
+2007-05-02  Alan Modra  <amodra@bigpond.net.au>
+
+       * internal.h (ELF_IS_SECTION_IN_SEGMENT): Check both file offset
+       and vma for appropriate sections.
+
 2007-04-26  Jan Beulich  <jbeulich@novell.com>
 
        * common.h (DT_ENCODING): Correct value (back to spec mandated
index f2161ff9d8e362125d84ae2c6e4493eefbc0241f..152171136c198ba56118fb548caaaef53742cef9 100644 (file)
@@ -1,6 +1,6 @@
 /* ELF support for BFD.
    Copyright 1991, 1992, 1993, 1994, 1995, 1997, 1998, 2000, 2001, 2002,
-   2003, 2006 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
@@ -268,23 +268,23 @@ struct elf_segment_map
 /* 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))                          \
-   /* 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                                  \
-             + ELF_SECTION_SIZE(sec_hdr, segment)              \
-             <= segment->p_vaddr + segment->p_memsz))          \
-       : ((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))))
+#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)       \