Your bfd & ld patch breaks --as-needed on SPARC (and some other targets)

Alan Modra amodra@bigpond.net.au
Fri Aug 12 13:33:00 GMT 2005


I made a followup patch to fix a similar problem with _DYNAMIC.  Looks
like we need to do the same for other syms.

This patch also makes _DYANAMIC and _PROCEDURE_LINKAGE_TABLE_ hidden,
as Hans-Peter Nilsson did for _GLOBAL_OFFSET_TABLE_ on 2004-11-02.
I think this is a good thing to do, but haven't yet done much
testing..  In any case, this change will require another bunch of ld
testsuite updates, because we'll have fewer dynamic symbols.  I won't
apply it until I've also fixed the testsuite, but could you please test
it in the meantime?

	* elflink.c (define_linkage_sym): New function, extracted from..
	(_bfd_elf_create_got_section): ..here.
	(_bfd_elf_link_create_dynamic_sections): Call it for _DYNAMIC.
	(_bfd_elf_create_dynamic_sections): ..and _PROCEDURE_LINKAGE_TABLE_.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.187
diff -u -p -r1.187 elflink.c
--- bfd/elflink.c	4 Aug 2005 06:22:06 -0000	1.187
+++ bfd/elflink.c	12 Aug 2005 12:58:39 -0000
@@ -27,13 +27,51 @@
 #include "safe-ctype.h"
 #include "libiberty.h"
 
+/* Define a symbol in a dynamic linkage section.  */
+
+static struct elf_link_hash_entry *
+define_linkage_sym (bfd *abfd,
+		    struct bfd_link_info *info,
+		    asection *sec,
+		    const char *name)
+{
+  struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *bh;
+
+  h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
+  if (h != NULL)
+    {
+      /* Zap symbol defined in an as-needed lib that wasn't linked.
+	 This is a symptom of a larger problem:  Absolute symbols
+	 defined in shared libraries can't be overridden, because we
+	 lose the link to the bfd which is via the symbol section.  */
+      h->root.type = bfd_link_hash_new;
+    }
+
+  bh = &h->root;
+  if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL,
+					 sec, 0, NULL, FALSE,
+					 get_elf_backend_data (abfd)->collect,
+					 &bh))
+    return NULL;
+  h = (struct elf_link_hash_entry *) bh;
+  h->def_regular = 1;
+  h->type = STT_OBJECT;
+  h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
+
+  if (!info->executable
+      && !bfd_elf_link_record_dynamic_symbol (info, h))
+    return NULL;
+
+  return h;
+}
+
 bfd_boolean
 _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
 {
   flagword flags;
   asection *s;
   struct elf_link_hash_entry *h;
-  struct bfd_link_hash_entry *bh;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   int ptralign;
 
@@ -78,21 +116,10 @@ _bfd_elf_create_got_section (bfd *abfd, 
 	 (or .got.plt) section.  We don't do this in the linker script
 	 because we don't want to define the symbol if we are not creating
 	 a global offset table.  */
-      bh = NULL;
-      if (!(_bfd_generic_link_add_one_symbol
-	    (info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
-	     0, NULL, FALSE, bed->collect, &bh)))
-	return FALSE;
-      h = (struct elf_link_hash_entry *) bh;
-      h->def_regular = 1;
-      h->type = STT_OBJECT;
-      h->other = STV_HIDDEN;
-
-      if (! info->executable
-	  && ! bfd_elf_link_record_dynamic_symbol (info, h))
-	return FALSE;
-
+      h = define_linkage_sym (abfd, info, s, "_GLOBAL_OFFSET_TABLE_");
       elf_hash_table (info)->hgot = h;
+      if (h == NULL)
+	return FALSE;
     }
 
   /* The first bit of the global offset table is the header.  */
@@ -132,8 +159,6 @@ _bfd_elf_link_create_dynamic_sections (b
 {
   flagword flags;
   register asection *s;
-  struct elf_link_hash_entry *h;
-  struct bfd_link_hash_entry *bh;
   const struct elf_backend_data *bed;
 
   if (! is_elf_hash_table (info->hash))
@@ -212,27 +237,7 @@ _bfd_elf_link_create_dynamic_sections (b
      section.  We don't want to define it if there is no .dynamic
      section, since on some ELF platforms the start up code examines it
      to decide how to initialize the process.  */
-  h = elf_link_hash_lookup (elf_hash_table (info), "_DYNAMIC",
-			    FALSE, FALSE, FALSE);
-  if (h != NULL)
-    {
-      /* Zap symbol defined in an as-needed lib that wasn't linked.
-	 This is a symptom of a larger problem:  Absolute symbols
-	 defined in shared libraries can't be overridden, because we
-	 lose the link to the bfd which is via the symbol section.  */
-      h->root.type = bfd_link_hash_new;
-    }
-  bh = &h->root;
-  if (! (_bfd_generic_link_add_one_symbol
-	 (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, 0, NULL, FALSE,
-	  get_elf_backend_data (abfd)->collect, &bh)))
-    return FALSE;
-  h = (struct elf_link_hash_entry *) bh;
-  h->def_regular = 1;
-  h->type = STT_OBJECT;
-
-  if (! info->executable
-      && ! bfd_elf_link_record_dynamic_symbol (info, h))
+  if (!define_linkage_sym (abfd, info, s, "_DYNAMIC"))
     return FALSE;
 
   s = bfd_make_section_with_flags (abfd, ".hash",
@@ -287,18 +292,9 @@ _bfd_elf_create_dynamic_sections (bfd *a
       /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the
 	 .plt section.  */
       struct elf_link_hash_entry *h;
-      struct bfd_link_hash_entry *bh = NULL;
-
-      if (! (_bfd_generic_link_add_one_symbol
-	     (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, 0, NULL,
-	      FALSE, get_elf_backend_data (abfd)->collect, &bh)))
-	return FALSE;
-      h = (struct elf_link_hash_entry *) bh;
-      h->def_regular = 1;
-      h->type = STT_OBJECT;
 
-      if (! info->executable
-	  && ! bfd_elf_link_record_dynamic_symbol (info, h))
+      h = define_linkage_sym (abfd, info, s, "_PROCEDURE_LINKAGE_TABLE_");
+      if (h == NULL)
 	return FALSE;
     }
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list