bfd/
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 5 Apr 2005 04:01:12 +0000 (04:01 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 5 Apr 2005 04:01:12 +0000 (04:01 +0000)
2005-04-04  H.J. Lu  <hongjiu.lu@intel.com>

* elf.c (bfd_elf_set_group_contents): Ignore linker created
group section.
(assign_section_numbers): Accept link_info. Check SHT_GROUP
sections for relocatable files only. Remove the linker created
group sections.
(_bfd_elf_compute_section_file_positions): Pass link_info to
assign_section_numbers.

* elfxx-ia64.c (elfNN_ia64_object_p): New.
(elf_backend_object_p): Defined.

gas/

2005-04-04  H.J. Lu  <hongjiu.lu@intel.com>

* config/tc-ia64.c (start_unwind_section): Undo the change
of 2004-08-18.
(generate_unwind_image, dot_endp): Likewise.

bfd/ChangeLog
bfd/elf.c
bfd/elfxx-ia64.c
gas/ChangeLog
gas/config/tc-ia64.c

index 39282d0..928d1dd 100644 (file)
@@ -2,6 +2,14 @@
 
        * elf.c (bfd_elf_set_group_contents): Ignore linker created
        group section. 
+       (assign_section_numbers): Accept link_info. Check SHT_GROUP
+       sections for relocatable files only. Remove the linker created
+       group sections.
+       (_bfd_elf_compute_section_file_positions): Pass link_info to
+       assign_section_numbers.
+
+       * elfxx-ia64.c (elfNN_ia64_object_p): New.
+       (elf_backend_object_p): Defined.
 
 2005-04-04  H.J. Lu  <hongjiu.lu@intel.com>
 
index f1c5fdb..4c10096 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2728,7 +2728,7 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
    in here too, while we're at it.  */
 
 static bfd_boolean
-assign_section_numbers (bfd *abfd)
+assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 {
   struct elf_obj_tdata *t = elf_tdata (abfd);
   asection *sec;
@@ -2741,16 +2741,35 @@ assign_section_numbers (bfd *abfd)
 
   _bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
 
-  /* Put SHT_GROUP sections first.  */
-  for (sec = abfd->sections; sec; sec = sec->next)
+  /* SHT_GROUP sections are in relocatable files only.  */
+  if (link_info == NULL || link_info->relocatable)
     {
-      d = elf_section_data (sec);
+      asection **secp;
 
-      if (d->this_hdr.sh_type == SHT_GROUP)
+      /* Put SHT_GROUP sections first.  */
+      secp = &abfd->sections;
+      while (*secp)
        {
-         if (section_number == SHN_LORESERVE)
-           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
-         d->this_idx = section_number++;
+         d = elf_section_data (*secp);
+
+         if (d->this_hdr.sh_type == SHT_GROUP)
+           { 
+             if ((*secp)->flags & SEC_LINKER_CREATED)
+               {
+                 /* Remove the linker created SHT_GROUP sections.  */
+                 bfd_section_list_remove (abfd, secp);
+                 abfd->section_count--;
+                 continue;
+               }
+             else 
+               {
+                 if (section_number == SHN_LORESERVE)
+                   section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
+                 d->this_idx = section_number++;
+               }
+           }
+
+         secp = &(*secp)->next;
        }
     }
 
@@ -3277,7 +3296,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
   if (failed)
     return FALSE;
 
-  if (!assign_section_numbers (abfd))
+  if (!assign_section_numbers (abfd, link_info))
     return FALSE;
 
   /* The backend linker builds symbol table information itself.  */
index b19b172..01e4d9f 100644 (file)
@@ -4886,6 +4886,103 @@ static struct bfd_elf_special_section const elfNN_ia64_special_sections[]=
 };
 
 static bfd_boolean
+elfNN_ia64_object_p (bfd *abfd)
+{
+  asection *sec;
+  asection **tail;
+  asection *group, *unwi, *unw;
+  flagword flags;
+  const char *name;
+  char *unwi_name, *unw_name;
+  bfd_size_type amt;
+
+  if (abfd->flags & DYNAMIC)
+    return TRUE;
+
+  /* Flags for fake group section.  */
+  flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
+          | SEC_EXCLUDE);
+
+  /* We add a fake section group for each .gnu.linkonce.t.* section,
+     which isn't in a section group, and its unwind sections.  */
+  for (sec = abfd->sections; sec != NULL; sec = sec->next)
+    {
+      if (elf_sec_group (sec) == NULL
+         && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
+             == (SEC_LINK_ONCE | SEC_CODE))
+         && strncmp (sec->name, ".gnu.linkonce.t.", 16) == 0)
+       {
+         name = sec->name + 16;
+
+         amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
+         unwi_name = bfd_alloc (abfd, amt);
+         if (!unwi_name)
+           return FALSE;
+
+         strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
+         unwi = bfd_get_section_by_name (abfd, unwi_name);
+
+         amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
+         unw_name = bfd_alloc (abfd, amt);
+         if (!unw_name)
+           return FALSE;
+
+         strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
+         unw = bfd_get_section_by_name (abfd, unw_name);
+
+         tail = abfd->section_tail;
+
+         /* We need to create a fake group section for it and its
+            unwind sections.  */
+         group = bfd_make_section_anyway (abfd, name);
+         if (group == NULL
+             || ! bfd_set_section_flags (abfd, group, flags))
+           return FALSE;
+
+         /* Move the fake group section to the beginning.  */
+         BFD_ASSERT (*tail == group);
+         bfd_section_list_remove (abfd, tail);
+         bfd_section_list_insert (abfd, &abfd->sections, group);
+
+         elf_next_in_group (group) = sec;
+
+         elf_group_name (sec) = name;
+         elf_next_in_group (sec) = sec;
+         elf_sec_group (sec) = group;
+
+         if (unwi)
+           {
+             elf_group_name (unwi) = name;
+             elf_next_in_group (unwi) = sec;
+             elf_next_in_group (sec) = unwi;
+             elf_sec_group (unwi) = group;
+           }
+
+          if (unw)
+            {
+              elf_group_name (unw) = name;
+              if (unwi)
+                {
+                  elf_next_in_group (unw) = elf_next_in_group (unwi);
+                  elf_next_in_group (unwi) = unw;
+                }
+              else
+                {
+                  elf_next_in_group (unw) = sec;
+                  elf_next_in_group (sec) = unw;
+                }
+              elf_sec_group (unw) = group;
+            }
+
+          /* Fake SHT_GROUP section header.  */
+         elf_section_data (group)->this_hdr.bfd_section = group;
+         elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
+       }
+    }
+  return TRUE;
+}
+
+static bfd_boolean
 elfNN_ia64_hpux_vec (const bfd_target *vec)
 {
   extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
@@ -4968,6 +5065,9 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
 #define bfd_elfNN_bfd_relax_section \
        elfNN_ia64_relax_section
 
+#define elf_backend_object_p \
+       elfNN_ia64_object_p
+
 /* Stuff for the BFD linker: */
 #define bfd_elfNN_bfd_link_hash_table_create \
        elfNN_ia64_hash_table_create
index 00c3552..2fac0e8 100644 (file)
@@ -1,3 +1,9 @@
+2005-04-04  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/tc-ia64.c (start_unwind_section): Undo the change
+       of 2004-08-18.
+       (generate_unwind_image, dot_endp): Likewise.
+
 2005-04-01 David Mosberger  <davidm@hpl.hp.com>
 
        * config/tc-ia64.c (ia64_handle_align): Move le_nop and
index f458550..1286825 100644 (file)
@@ -3460,7 +3460,7 @@ static char *special_linkonce_name[] =
   };
 
 static void
-start_unwind_section (const segT text_seg, int sec_index, int linkonce_empty)
+start_unwind_section (const segT text_seg, int sec_index)
 {
   /*
     Use a slightly ugly scheme to derive the unwind section names from
@@ -3522,8 +3522,6 @@ start_unwind_section (const segT text_seg, int sec_index, int linkonce_empty)
       prefix = special_linkonce_name [sec_index - SPECIAL_SECTION_UNWIND];
       suffix += sizeof (".gnu.linkonce.t.") - 1;
     }
-  else if (linkonce_empty)
-    return;
 
   prefix_len = strlen (prefix);
   suffix_len = strlen (suffix);
@@ -3611,7 +3609,7 @@ generate_unwind_image (const segT text_seg)
       expressionS exp;
       bfd_reloc_code_real_type reloc;
 
-      start_unwind_section (text_seg, SPECIAL_SECTION_UNWIND_INFO, 0);
+      start_unwind_section (text_seg, SPECIAL_SECTION_UNWIND_INFO);
 
       /* Make sure the section has 4 byte alignment for ILP32 and
         8 byte alignment for LP64.  */
@@ -3652,8 +3650,6 @@ generate_unwind_image (const segT text_seg)
          unwind.personality_routine = 0;
        }
     }
-  else
-    start_unwind_section (text_seg, SPECIAL_SECTION_UNWIND_INFO, 1);
 
   free_saved_prologue_counts ();
   unwind.list = unwind.tail = unwind.current_entry = NULL;
@@ -4426,7 +4422,7 @@ dot_endp (dummy)
       subseg_set (md.last_text_seg, 0);
       proc_end = expr_build_dot ();
 
-      start_unwind_section (saved_seg, SPECIAL_SECTION_UNWIND, 0);
+      start_unwind_section (saved_seg, SPECIAL_SECTION_UNWIND);
 
       /* Make sure that section has 4 byte alignment for ILP32 and
          8 byte alignment for LP64.  */
@@ -4466,9 +4462,6 @@ dot_endp (dummy)
                            bytes_per_address);
 
     }
-  else
-    start_unwind_section (saved_seg, SPECIAL_SECTION_UNWIND, 1);
-
   subseg_set (saved_seg, saved_subseg);
 
   if (unwind.proc_start)