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]

Hidden dynamic symbols


The elf spec says that dynamic symbols with STV_HIDDEN or STV_INTERNAL 
visibility must either be removed or given STB_LOCAL binding.

We currently get this wrong when a hidden/internal symbol is provided by a 
linker script.

The attached patch fixes this by forcing such symbols to be local, and 
modifying the symbol renumbering to cope with this. I chose this alternative 
because (a) it seemed simpler, and (b) I have a target that needs to output 
dynamic relocations against these symbols.

Tested on i686-linux --enable-targets=all.
Ok?

Paul

2005-02-09  Paul Brook  <paul@codesourcery.com>

 * elflink.c (bfd_elf_record_link_assignment): Make hidden and internal
 symbols local.
 (elf_link_renumber_hash_table_dynsyms): Ignore local symbols.
 (elf_link_renumber_local_hash_table_dynsyms): New function.
 (_bfd_elf_link_renumber_dynsyms): Number local dynamic symbols.
ld/testsuite/
 * ld-elfvsb/hidden2.s: New file
 * ld-elfvsb/hidden2.d: New file
 * ld-elfvsb/hidden2.ld: New file
Index: bfd/elflink.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elflink.c,v
retrieving revision 1.131
diff -u -p -r1.131 elflink.c
--- bfd/elflink.c	8 Feb 2005 13:33:56 -0000	1.131
+++ bfd/elflink.c	9 Feb 2005 17:13:56 -0000
@@ -484,6 +484,14 @@ bfd_elf_record_link_assignment (bfd *out
 
   h->def_regular = 1;
 
+  /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
+     and executables.  */
+  if (!info->relocatable
+      && h->dynindx != -1
+      && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+	  || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
+    h->forced_local = 1;
+
   if ((h->def_dynamic
        || h->ref_dynamic
        || info->shared)
@@ -624,6 +632,31 @@ elf_link_renumber_hash_table_dynsyms (st
   if (h->root.type == bfd_link_hash_warning)
     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
+  if (h->forced_local)
+    return TRUE;
+
+  if (h->dynindx != -1)
+    h->dynindx = ++(*count);
+
+  return TRUE;
+}
+
+
+/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with
+   STB_LOCAL binding.  */
+
+static bfd_boolean
+elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h,
+					    void *data)
+{
+  size_t *count = data;
+
+  if (h->root.type == bfd_link_hash_warning)
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+  if (!h->forced_local)
+    return TRUE;
+
   if (h->dynindx != -1)
     h->dynindx = ++(*count);
 
@@ -667,9 +700,10 @@ _bfd_elf_link_omit_section_dynsym (bfd *
 }
 
 /* Assign dynsym indices.  In a shared library we generate a section
-   symbol for each output section, which come first.  Next come all of
-   the back-end allocated local dynamic syms, followed by the rest of
-   the global symbols.  */
+   symbol for each output section, which come first.  Next come symbols
+   which have been forced to local binding.  Then all of the back-end
+   allocated local dynamic syms, followed by the rest of the global
+   symbols.  */
 
 unsigned long
 _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
@@ -687,6 +721,10 @@ _bfd_elf_link_renumber_dynsyms (bfd *out
 	  elf_section_data (p)->dynindx = ++dynsymcount;
     }
 
+  elf_link_hash_traverse (elf_hash_table (info),
+			  elf_link_renumber_local_hash_table_dynsyms,
+			  &dynsymcount);
+
   if (elf_hash_table (info)->dynlocal)
     {
       struct elf_link_local_dynamic_entry *p;
Index: ld/testsuite/ld-elfvsb/hidden2.d
===================================================================
RCS file: ld/testsuite/ld-elfvsb/hidden2.d
diff -N ld/testsuite/ld-elfvsb/hidden2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elfvsb/hidden2.d	9 Feb 2005 17:13:27 -0000
@@ -0,0 +1,9 @@
+#source: hidden2.s
+#ld: -shared -T hidden2.ld
+#readelf: -Ds
+# It is also ok to remove this symbol, but we currently make it local.
+
+Symbol table for image:
+#...
+[ 	]*[0-9]+ +[0-9]+: [0-9a-fA-F]* +0  NOTYPE  LOCAL HIDDEN +ABS foo
+#pass
Index: ld/testsuite/ld-elfvsb/hidden2.ld
===================================================================
RCS file: ld/testsuite/ld-elfvsb/hidden2.ld
diff -N ld/testsuite/ld-elfvsb/hidden2.ld
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elfvsb/hidden2.ld	9 Feb 2005 16:27:18 -0000
@@ -0,0 +1,6 @@
+SECTIONS
+{
+  . = 0x1000;
+  PROVIDE (foo = .);
+  .data : { *(.data) }
+}
Index: ld/testsuite/ld-elfvsb/hidden2.s
===================================================================
RCS file: ld/testsuite/ld-elfvsb/hidden2.s
diff -N ld/testsuite/ld-elfvsb/hidden2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elfvsb/hidden2.s	9 Feb 2005 16:12:40 -0000
@@ -0,0 +1,4 @@
+	.data
+	.hidden foo
+	.global foo
+	.word foo

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