* elf-bfd.h (struct elf_backend_data): Add
authorAlan Modra <amodra@gmail.com>
Tue, 20 Jun 2006 14:34:08 +0000 (14:34 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 20 Jun 2006 14:34:08 +0000 (14:34 +0000)
elf_backend_modify_program_headers.
* elfxx-target.h (elf_backend_modify_program_headers): Define.
(elfNN_bed): Init new field.
* elf.c (elf_modify_segment_map): Remove comment.
(assign_file_positions_for_load_sections): Only call
elf_modify_segment_map for objcopy/strip.
(assign_file_positions_except_relocs): Call
elf_backend_modify_program_headers.
* elf32-frv.c (elf32_frvfdpic_always_size_sections): Don't make
.stack section.
(elf32_frvfdpic_modify_segment_map): Delete.
(elf32_frvfdpic_modify_program_headers): New.
(elf_backend_modify_segment_map): Don't define.
(elf_backend_modify_program_headers): Define.
* elf32-bfin.c (elf32_bfinfdpic_always_size_sections): Don't make
.stack section.
(elf32_bfinfdpic_modify_segment_map): Delete.
(elf32_bfinfdpic_modify_program_headers): New.
(elf_backend_modify_segment_map): Don't define.
(elf_backend_modify_program_headers): Define.
* elfxx-ia64.c (elfNN_ia64_modify_program_headers): New function.
Split out from..
(elfNN_ia64_modify_segment_map): ..here.
(elf_backend_modify_program_headers): Define.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elf32-bfin.c
bfd/elf32-frv.c
bfd/elfxx-ia64.c
bfd/elfxx-target.h

index a1265d81488286f11394ebe197b045e9b288e2a4..b6996a868dd830bf17d83ba9eb1d12d2600817a3 100644 (file)
@@ -1,3 +1,31 @@
+2006-06-21  Alan Modra  <amodra@bigpond.net.au>
+
+       * elf-bfd.h (struct elf_backend_data): Add
+       elf_backend_modify_program_headers.
+       * elfxx-target.h (elf_backend_modify_program_headers): Define.
+       (elfNN_bed): Init new field.
+       * elf.c (elf_modify_segment_map): Remove comment.
+       (assign_file_positions_for_load_sections): Only call
+       elf_modify_segment_map for objcopy/strip.
+       (assign_file_positions_except_relocs): Call
+       elf_backend_modify_program_headers.
+       * elf32-frv.c (elf32_frvfdpic_always_size_sections): Don't make
+       .stack section.
+       (elf32_frvfdpic_modify_segment_map): Delete.
+       (elf32_frvfdpic_modify_program_headers): New.
+       (elf_backend_modify_segment_map): Don't define.
+       (elf_backend_modify_program_headers): Define.
+       * elf32-bfin.c (elf32_bfinfdpic_always_size_sections): Don't make
+       .stack section.
+       (elf32_bfinfdpic_modify_segment_map): Delete.
+       (elf32_bfinfdpic_modify_program_headers): New.
+       (elf_backend_modify_segment_map): Don't define.
+       (elf_backend_modify_program_headers): Define.
+       * elfxx-ia64.c (elfNN_ia64_modify_program_headers): New function.
+       Split out from..
+       (elfNN_ia64_modify_segment_map): ..here.
+       (elf_backend_modify_program_headers): Define.
+
 2006-06-20  Jakub Jelinek  <jakub@redhat.com>
 
        * bfd.c (bfd_record_phdr): Clear p_align and p_align_valid fields.
index 98134161f7335c3c253e04593fefac0faaf275a4..95686d3d502c4731ececa1f34043d072bc54f527 100644 (file)
@@ -836,6 +836,11 @@ struct elf_backend_data
   bfd_boolean (*elf_backend_modify_segment_map)
     (bfd *, struct bfd_link_info *);
 
+  /* This function is called to modify program headers just before
+     they are written.  */
+  bfd_boolean (*elf_backend_modify_program_headers)
+    (bfd *, struct bfd_link_info *);
+
   /* This function is called during section garbage collection to
      mark sections that define global symbols.  */
   bfd_boolean (*gc_mark_dynamic_ref)
index 25570eccb96802e92080534d0ce7c8099c9ddcdc..8a725c39edf36e61a8c08842877e9ff6a10f9b97 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3734,8 +3734,6 @@ elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
        m->count = new_count;
     }
 
-  /* Yes, we call elf_backend_modify_segment_map at least two times
-     for the linker.  The final time the link_orders are available.  */
   bed = get_elf_backend_data (abfd);
   if (bed->elf_backend_modify_segment_map != NULL)
     {
@@ -4217,7 +4215,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
   unsigned int alloc;
   unsigned int i;
 
-  if (!elf_modify_segment_map (abfd, link_info))
+  if (link_info == NULL
+      && !elf_modify_segment_map (abfd, link_info))
     return FALSE;
 
   alloc = 0;
@@ -4720,8 +4719,8 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
                  if (lp->p_type == PT_LOAD
                      && lp->p_vaddr <= link_info->relro_end
                      && lp->p_vaddr >= link_info->relro_start
-                     && lp->p_vaddr + lp->p_filesz
-                        >= link_info->relro_end)
+                     && (lp->p_vaddr + lp->p_filesz
+                         >= link_info->relro_end))
                    break;
                }
 
@@ -4823,6 +4822,12 @@ assign_file_positions_except_relocs (bfd *abfd,
       if (!assign_file_positions_for_non_load_sections (abfd, link_info))
        return FALSE;
 
+      if (bed->elf_backend_modify_program_headers != NULL)
+       {
+         if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info))
+           return FALSE;
+       }
+
       /* Write out the program headers.  */
       alloc = tdata->program_header_size / bed->s->sizeof_phdr;
       if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
index ed3db10a2b4a0663ebcbfbed1e64128f7c7499de..54900d05c750e451dadfdfc3385c605d26b7291f 100644 (file)
@@ -4156,7 +4156,6 @@ elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
   if (!info->relocatable)
     {
       struct elf_link_hash_entry *h;
-      asection *sec;
 
       /* Force a PT_GNU_STACK segment to be created.  */
       if (! elf_tdata (output_bfd)->stack_flags)
@@ -4182,64 +4181,51 @@ elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
          h->def_regular = 1;
          h->type = STT_OBJECT;
        }
-
-      /* Create a stack section, and set its alignment.  */
-      sec = bfd_make_section (output_bfd, ".stack");
-
-      if (sec == NULL
-         || ! bfd_set_section_alignment (output_bfd, sec, 3))
-       return FALSE;
     }
 
   return TRUE;
 }
 
 static bfd_boolean
-elf32_bfinfdpic_modify_segment_map (bfd *output_bfd,
-                                  struct bfd_link_info *info)
+elf32_bfinfdpic_modify_program_headers (bfd *output_bfd,
+                                       struct bfd_link_info *info)
 {
+  struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
   struct elf_segment_map *m;
+  Elf_Internal_Phdr *p;
 
   /* objcopy and strip preserve what's already there using
      elf32_bfinfdpic_copy_private_bfd_data ().  */
   if (! info)
     return TRUE;
 
-  for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
+  for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
     if (m->p_type == PT_GNU_STACK)
       break;
 
   if (m)
     {
-      asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
       struct elf_link_hash_entry *h;
 
-      if (sec)
+      /* Obtain the pointer to the __stacksize symbol.  */
+      h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
+                               FALSE, FALSE, FALSE);
+      if (h)
        {
-         /* Obtain the pointer to the __stacksize symbol.  */
-         h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
-                                   FALSE, FALSE, FALSE);
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *)h->root.u.i.link;
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
          BFD_ASSERT (h->root.type == bfd_link_hash_defined);
+       }
 
-         /* Set the section size from the symbol value.  We
-            intentionally ignore the symbol section.  */
-         if (h->root.type == bfd_link_hash_defined)
-           sec->size = h->root.u.def.value;
-         else
-           sec->size = DEFAULT_STACK_SIZE;
+      /* Set the header p_memsz from the symbol value.  We
+        intentionally ignore the symbol section.  */
+      if (h && h->root.type == bfd_link_hash_defined)
+       p->p_memsz = h->root.u.def.value;
+      else
+       p->p_memsz = DEFAULT_STACK_SIZE;
 
-         /* Add the stack section to the PT_GNU_STACK segment,
-            such that its size and alignment requirements make it
-            to the segment.  */
-         if (m->count == 0)
-           {
-             m->sections[m->count] = sec;
-             m->count++;
-           }
-       }
+      p->p_align = 8;
     }
 
   return TRUE;
@@ -5594,9 +5580,9 @@ error_return:
 #undef elf_backend_always_size_sections
 #define elf_backend_always_size_sections \
                elf32_bfinfdpic_always_size_sections
-#undef elf_backend_modify_segment_map
-#define elf_backend_modify_segment_map \
-               elf32_bfinfdpic_modify_segment_map
+#undef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers \
+               elf32_bfinfdpic_modify_program_headers
 #undef bfd_elf32_bfd_copy_private_bfd_data
 #define bfd_elf32_bfd_copy_private_bfd_data \
                elf32_bfinfdpic_copy_private_bfd_data
index de2358be3479b3fde68cb066e8ef8537b6dc724b..5f83f81bfe336b764006c2ae60fd60f42550661b 100644 (file)
@@ -5603,7 +5603,6 @@ elf32_frvfdpic_always_size_sections (bfd *output_bfd,
   if (!info->relocatable)
     {
       struct elf_link_hash_entry *h;
-      asection *sec;
 
       /* Force a PT_GNU_STACK segment to be created.  */
       if (! elf_tdata (output_bfd)->stack_flags)
@@ -5630,13 +5629,6 @@ elf32_frvfdpic_always_size_sections (bfd *output_bfd,
          h->type = STT_OBJECT;
          /* This one must NOT be hidden.  */
        }
-
-      /* Create a stack section, and set its alignment.  */
-      sec = bfd_make_section (output_bfd, ".stack");
-
-      if (sec == NULL
-         || ! bfd_set_section_alignment (output_bfd, sec, 3))
-       return FALSE;
     }
 
   return TRUE;
@@ -5718,51 +5710,45 @@ elf32_frvfdpic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
 }
 
 static bfd_boolean
-elf32_frvfdpic_modify_segment_map (bfd *output_bfd,
-                                  struct bfd_link_info *info)
+elf32_frvfdpic_modify_program_headers (bfd *output_bfd,
+                                      struct bfd_link_info *info)
 {
+  struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
   struct elf_segment_map *m;
+  Elf_Internal_Phdr *p;
 
   /* objcopy and strip preserve what's already there using
      elf32_frvfdpic_copy_private_bfd_data ().  */
   if (! info)
     return TRUE;
 
-  for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next)
+  for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
     if (m->p_type == PT_GNU_STACK)
       break;
 
   if (m)
     {
-      asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
       struct elf_link_hash_entry *h;
 
-      if (sec)
+      /* Obtain the pointer to the __stacksize symbol.  */
+      h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
+                               FALSE, FALSE, FALSE);
+      if (h)
        {
-         /* Obtain the pointer to the __stacksize symbol.  */
-         h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
-                                   FALSE, FALSE, FALSE);
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *)h->root.u.i.link;
+           h = (struct elf_link_hash_entry *) h->root.u.i.link;
          BFD_ASSERT (h->root.type == bfd_link_hash_defined);
+       }
 
-         /* Set the section size from the symbol value.  We
-            intentionally ignore the symbol section.  */
-         if (h->root.type == bfd_link_hash_defined)
-           sec->size = h->root.u.def.value;
-         else
-           sec->size = DEFAULT_STACK_SIZE;
+      /* Set the header p_memsz from the symbol value.  We
+        intentionally ignore the symbol section.  */
+      if (h && h->root.type == bfd_link_hash_defined)
+       p->p_memsz = h->root.u.def.value;
+      else
+       p->p_memsz = DEFAULT_STACK_SIZE;
 
-         /* Add the stack section to the PT_GNU_STACK segment,
-            such that its size and alignment requirements make it
-            to the segment.  */
-         if (m->count == 0)
-           {
-             m->sections[m->count] = sec;
-             m->count++;
-           }
-       }
+      p->p_align = 8;
     }
 
   return TRUE;
@@ -6973,9 +6959,9 @@ elf32_frv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 #undef elf_backend_always_size_sections
 #define elf_backend_always_size_sections \
                elf32_frvfdpic_always_size_sections
-#undef elf_backend_modify_segment_map
-#define elf_backend_modify_segment_map \
-               elf32_frvfdpic_modify_segment_map
+#undef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers \
+               elf32_frvfdpic_modify_program_headers
 #undef bfd_elf32_bfd_copy_private_bfd_data
 #define bfd_elf32_bfd_copy_private_bfd_data \
                elf32_frvfdpic_copy_private_bfd_data
index c05796754e0f7032417c594670ac89761b74596f..32dea4c6149629dc5b8eb9c09eb2c3a1264847cc 100644 (file)
@@ -1737,17 +1737,30 @@ elfNN_ia64_modify_segment_map (bfd *abfd,
        }
     }
 
-  /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
-     the input sections for each output section in the segment and testing
-     for SHF_IA_64_NORECOV on each.  */
-  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+  return TRUE;
+}
+
+/* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
+   the input sections for each output section in the segment and testing
+   for SHF_IA_64_NORECOV on each.  */
+
+static bfd_boolean
+elfNN_ia64_modify_program_headers (bfd *abfd,
+                                  struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+  struct elf_obj_tdata *tdata = elf_tdata (abfd);
+  struct elf_segment_map *m;
+  Elf_Internal_Phdr *p;
+
+  for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
     if (m->p_type == PT_LOAD)
       {
        int i;
        for (i = m->count - 1; i >= 0; --i)
          {
            struct bfd_link_order *order = m->sections[i]->map_head.link_order;
-           while (order)
+
+           while (order != NULL)
              {
                if (order->type == bfd_indirect_link_order)
                  {
@@ -1755,7 +1768,7 @@ elfNN_ia64_modify_segment_map (bfd *abfd,
                    bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
                    if (flags & SHF_IA_64_NORECOV)
                      {
-                       m->p_flags |= PF_IA_64_NORECOV;
+                       p->p_flags |= PF_IA_64_NORECOV;
                        goto found;
                      }
                  }
@@ -5728,6 +5741,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
        elfNN_ia64_additional_program_headers
 #define elf_backend_modify_segment_map \
        elfNN_ia64_modify_segment_map
+#define elf_backend_modify_program_headers \
+       elfNN_ia64_modify_program_headers
 #define elf_info_to_howto \
        elfNN_ia64_info_to_howto
 
index fad00f2a0f58960a172cafb878f8f9e1bebd2b99..38aa3737f8290cf7b8d5a85bb0db7956e77103c5 100644 (file)
 #ifndef elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map 0
 #endif
+#ifndef elf_backend_modify_program_headers
+#define elf_backend_modify_program_headers     0
+#endif
 #ifndef elf_backend_ecoff_debug_swap
 #define elf_backend_ecoff_debug_swap   0
 #endif
@@ -603,6 +606,7 @@ static struct elf_backend_data elfNN_bed =
   elf_backend_final_write_processing,
   elf_backend_additional_program_headers,
   elf_backend_modify_segment_map,
+  elf_backend_modify_program_headers,
   elf_backend_gc_mark_dynamic_ref,
   elf_backend_gc_mark_hook,
   elf_backend_gc_sweep_hook,