This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

alpha linker fix


This fixes an alpha backend problem discovered when looking at testsuite
results with http://sources.redhat.com/ml/binutils/2005-06/msg00257.html
applied locally.  The problem is that create_dynamic_sections will create
the linker .got, .plt etc. sections in the bfd that happens to trigger
the create_dynamic_sections call.  When the bfd is one for a shared lib,
you very likely already have a .got section, breaking the assumption
in elf64_alpha_create_got_section that .got is linker created.  I think
we can test tdata->gotobj rather than doing bfd_get_section_by_name,
but I may be missing some reason why gotobj should not be set on all
elf64_alpha_create_got_section calls.  Richard?

	* elf64-alpha.c (elf64_alpha_create_got_section): Always create
	a new .got section.  Assign gotobj here.
	(elf64_alpha_create_dynamic_sections): Always make new sections
	by using bfd_make_section_anyway_with_flags.  Check that .got not
	already created.
	(elf64_alpha_check_relocs): Delete "got_created".  Use tdata->gotobj
	instead.

Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.141
diff -u -p -r1.141 elf64-alpha.c
--- bfd/elf64-alpha.c	31 May 2005 22:53:44 -0000	1.141
+++ bfd/elf64-alpha.c	23 Jun 2005 02:01:15 -0000
@@ -1204,26 +1204,23 @@ static bfd_boolean
 elf64_alpha_create_got_section (bfd *abfd,
 				struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
+  flagword flags;
   asection *s;
 
-  if ((s = bfd_get_section_by_name (abfd, ".got")))
-    {
-      /* Check for a non-linker created .got?  */
-      if (alpha_elf_tdata (abfd)->got == NULL)
-	alpha_elf_tdata (abfd)->got = s;
-      return TRUE;
-    }
-
-  s = bfd_make_section_with_flags (abfd, ".got", (SEC_ALLOC | SEC_LOAD
-						  | SEC_HAS_CONTENTS
-						  | SEC_IN_MEMORY
-						  | SEC_LINKER_CREATED));
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+	   | SEC_LINKER_CREATED);
+  s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, 3))
     return FALSE;
 
   alpha_elf_tdata (abfd)->got = s;
 
+  /* Make sure the object's gotobj is set to itself so that we default
+     to every object with its own .got.  We'll merge .gots later once
+     we've collected each object's info.  */
+  alpha_elf_tdata (abfd)->gotobj = abfd;
+
   return TRUE;
 }
 
@@ -1233,18 +1230,16 @@ static bfd_boolean
 elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 {
   asection *s;
+  flagword flags;
   struct elf_link_hash_entry *h;
   struct bfd_link_hash_entry *bh;
 
   /* We need to create .plt, .rela.plt, .got, and .rela.got sections.  */
 
-  s = bfd_make_section_with_flags (abfd, ".plt",
-				   (SEC_ALLOC | SEC_LOAD | SEC_CODE
-				    | SEC_HAS_CONTENTS
-				    | SEC_IN_MEMORY
-				    | SEC_LINKER_CREATED
-				    | (elf64_alpha_use_secureplt
-				       ? SEC_READONLY : 0)));
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+	   | SEC_LINKER_CREATED
+	   | (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
+  s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
   if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
     return FALSE;
 
@@ -1263,19 +1258,16 @@ elf64_alpha_create_dynamic_sections (bfd
   if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
     return FALSE;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.plt",
-				   (SEC_ALLOC | SEC_LOAD
-				    | SEC_HAS_CONTENTS
-				    | SEC_IN_MEMORY
-				    | SEC_LINKER_CREATED
-				    | SEC_READONLY));
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+	   | SEC_LINKER_CREATED | SEC_READONLY);
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
   if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
     return FALSE;
 
   if (elf64_alpha_use_secureplt)
     {
-      s = bfd_make_section_with_flags (abfd, ".got.plt",
-				       SEC_ALLOC | SEC_LINKER_CREATED);
+      flags = SEC_ALLOC | SEC_LINKER_CREATED;
+      s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
       if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
 	return FALSE;
     }
@@ -1283,15 +1275,15 @@ elf64_alpha_create_dynamic_sections (bfd
   /* We may or may not have created a .got section for this object, but
      we definitely havn't done the rest of the work.  */
 
-  if (!elf64_alpha_create_got_section (abfd, info))
-    return FALSE;
+  if (alpha_elf_tdata(abfd)->gotobj == NULL)
+    {
+      if (!elf64_alpha_create_got_section (abfd, info))
+	return FALSE;
+    }
 
-  s = bfd_make_section_with_flags (abfd, ".rela.got",
-				   (SEC_ALLOC | SEC_LOAD
-				    | SEC_HAS_CONTENTS
-				    | SEC_IN_MEMORY
-				    | SEC_LINKER_CREATED
-				    | SEC_READONLY));
+  flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+	   | SEC_LINKER_CREATED | SEC_READONLY);
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, 3))
     return FALSE;
@@ -1746,7 +1738,6 @@ elf64_alpha_check_relocs (bfd *abfd, str
   Elf_Internal_Shdr *symtab_hdr;
   struct alpha_elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel, *relend;
-  bfd_boolean got_created;
   bfd_size_type amt;
 
   if (info->relocatable)
@@ -1769,7 +1760,6 @@ elf64_alpha_check_relocs (bfd *abfd, str
   rel_sec_name = NULL;
   symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
   sym_hashes = alpha_elf_sym_hashes(abfd);
-  got_created = FALSE;
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; ++rel)
@@ -1881,18 +1871,10 @@ elf64_alpha_check_relocs (bfd *abfd, str
 
       if (need & NEED_GOT)
 	{
-	  if (!got_created)
+	  if (alpha_elf_tdata(abfd)->gotobj == NULL)
 	    {
 	      if (!elf64_alpha_create_got_section (abfd, info))
 		return FALSE;
-
-	      /* Make sure the object's gotobj is set to itself so
-		 that we default to every object with its own .got.
-		 We'll merge .gots later once we've collected each
-		 object's info.  */
-	      alpha_elf_tdata(abfd)->gotobj = abfd;
-
-	      got_created = 1;
 	    }
 	}
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]