This is the mail archive of the binutils@sourceware.org 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]

Add _GLOBAL_OFFSET_TABLE_ to .dynsym for VxWorks


VxWorks shared libraries use table lookups of the form
__GOTT_BASE__[__GOTT_INDEX__] to access the GOT.  One quirk is that the
loader initialises this table from the value of the _GLOBAL_OFFSET_TABLE_
dynamic symbol rather than from some form of dynamic tag.  This means that
_GLOBAL_OFFSET_TABLE_ must always be entered into .dynsym for VxWorks
shared libraries.

I don't know of a specific reason to require the same thing
for executables, but _G_O_T_ has traditionally been entered
into executables' .dynsyms too (by other toolchains as well
as the GNU ones).  I therefore don't see a strong reason to
treat executables and shared libraries any differently; this
patch does the same thing for both.

The only two user-mode ports to have been submitted so far are
i?86-vxworks and powerpc-vxworks.  The required code is the same
for both targets, and will be the same for other VxWorks targets
too, so I've put it in a new elf-vxworks hook.

While I was there, I factored the creation of .rel(a).plt.unloaded
into this new hook, as again the principle will be the same for all
VxWorks targets.

Also, VxWorks targets need to make sure that they can generate
relocations against _G_O_T_ and _P_L_T_.  The code to do this is
currently in size_dynamic_sections, but it can be done just as easily
in create_dynamic_sections, and I think it makes sense to do it at the
same time as we create the associated .rel(a).plt.unloaded section.
This also avoids the need for a second hook.

Finally, VxWorks targets would give _P_L_T_ type STT_FUNC only if .plt
had the SEC_CODE flag set.  This check was left over from an earlier
attempt to do something that would be acceptable for all targets (both
VxWorks and non-VxWorks).  It's actually redundant on VxWorks, where
_P_L_T_ should always have type STT_FUNC.

Tested on i586-vxworks, powerpc-vxworks, powerpc64-linux-gnu
and i686-pc-linux-gnu (--enable-targets=all --enable-64-bit-bfd).
OK to install?

Richard


bfd/
	* elf32-i386.c (elf_i386_create_dynamic_sections): Use
	elf_vxworks_create_dynamic_sections.
	(elf_i386_size_dynamic_sections): Remove VxWorks GOT and PLT
	symbol handling.
	* elf32-ppc.c (ppc_elf_create_dynamic_sections): Use
	elf_vxworks_create_dynamic_sections.
	(ppc_elf_size_dynamic_sections): Remove VxWorks GOT and PLT
	symbol handling.
	* elf-vxworks.c (elf_vxworks_create_dynamic_sections): New function.
	* elf-vxworks.h (elf_vxworks_create_dynamic_sections): Declare.

ld/testsuite/
	* ld-i386/ld-i386/vxworks1-lib.nd: New test.
	* ld-i386/i386.exp: Run it.
	* ld-powerpc/ld-powerpc/vxworks1-lib.nd: New test.
	* ld-powerpc/powerc.exp: Run it.

diff -uprN ../src.3/bfd/elf32-i386.c ./bfd/elf32-i386.c
--- ./bfd/elf32-i386.c	2006-03-01 17:27:36.000000000 +0000
+++ ./bfd/elf32-i386.c	2006-03-01 17:38:51.000000000 +0000
@@ -782,9 +782,6 @@ static bfd_boolean
 elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
 {
   struct elf_i386_link_hash_table *htab;
-  asection * s;
-  int flags;
-  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
 
   htab = elf_i386_hash_table (info);
   if (!htab->sgot && !create_got_section (dynobj, info))
@@ -803,17 +800,9 @@ elf_i386_create_dynamic_sections (bfd *d
       || (!info->shared && !htab->srelbss))
     abort ();
 
-  if (htab->is_vxworks && !info->shared)
-    {
-      s = bfd_make_section (dynobj, ".rel.plt.unloaded");
-      flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY
-	      | SEC_LINKER_CREATED);
-      if (s == NULL
-	 || ! bfd_set_section_flags (dynobj, s, flags)
-	 || ! bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
-       return FALSE;
-      htab->srelplt2 = s;
-    }
+  if (htab->is_vxworks
+      && !elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
+    return FALSE;
 
   return TRUE;
 }
@@ -2000,21 +1989,6 @@ elf_i386_size_dynamic_sections (bfd *out
   else
     htab->tls_ldm_got.offset = -1;
 
-  if (htab->is_vxworks)
-    {
-      /* Mark the GOT and PLT symbols as having relocations; they might
-	 not, but we won't know for sure until we build the GOT in
-	 finish_dynamic_symbol.  */
-      if (htab->elf.hgot)
-	htab->elf.hgot->indx = -2;
-      if (htab->elf.hplt)
-	{
-	  htab->elf.hplt->indx = -2;
-	  if (htab->splt->flags & SEC_CODE)
-	    htab->elf.hplt->type = STT_FUNC;
-	}
-    }
-
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
diff -uprN ../src.3/bfd/elf32-ppc.c ./bfd/elf32-ppc.c
--- ./bfd/elf32-ppc.c	2006-03-01 17:27:36.000000000 +0000
+++ ./bfd/elf32-ppc.c	2006-03-01 17:38:52.000000000 +0000
@@ -2548,19 +2548,9 @@ ppc_elf_create_dynamic_sections (bfd *ab
 	return FALSE;
     }
 
-  /* Create the section for VxWorks static plt relocations.  */
-  if (htab->is_vxworks && !info->shared)
-    {
-      s = bfd_make_section (abfd, ".rela.plt.unloaded");
-      flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY
-	       | SEC_LINKER_CREATED);
-      if (s == NULL
-	  || ! bfd_set_section_flags (abfd, s, flags)
-	  || ! bfd_set_section_alignment (abfd, s,
-		  get_elf_backend_data (abfd)->s->log_file_align))
-	return FALSE;
-      htab->srelplt2 = s;
-    }
+  if (htab->is_vxworks
+      && !elf_vxworks_create_dynamic_sections (abfd, info, &htab->srelplt2))
+    return FALSE;
 
   htab->relplt = bfd_get_section_by_name (abfd, ".rela.plt");
   htab->plt = s = bfd_get_section_by_name (abfd, ".plt");
@@ -4764,21 +4754,6 @@ ppc_elf_size_dynamic_sections (bfd *outp
   else
     htab->tlsld_got.offset = (bfd_vma) -1;
 
-  if (htab->is_vxworks)
-    {
-      /* Mark the GOT and PLT symbols as having relocations; they might
-	 not, but we won't know for sure until we build the GOT in
-	 finish_dynamic_symbol.  */
-      if (htab->elf.hgot)
-	htab->elf.hgot->indx = -2;
-      if (htab->elf.hplt)
-	{
-	  htab->elf.hplt->indx = -2;
-	  if (htab->plt->flags & SEC_CODE)
-	    htab->elf.hplt->type = STT_FUNC;
-	}
-    }
-
   /* Allocate space for global sym dynamic relocs.  */
   elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
 
diff -uprN ../src.3/bfd/elf-vxworks.c ./bfd/elf-vxworks.c
--- ./bfd/elf-vxworks.c	2006-03-01 17:27:35.000000000 +0000
+++ ./bfd/elf-vxworks.c	2006-03-01 18:00:43.000000000 +0000
@@ -55,6 +55,57 @@ elf_vxworks_add_symbol_hook (bfd *abfd A
   return TRUE;
 }
 
+/* Perform VxWorks-specific handling of the create_dynamic_sections hook.
+   When creating an executable, set *SRELPLT2_OUT to the .rel(a).plt.unloaded
+   section.  */
+
+bfd_boolean
+elf_vxworks_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info,
+				     asection **srelplt2_out)
+{
+  struct elf_link_hash_table *htab;
+  const struct elf_backend_data *bed;
+  asection *s;
+
+  htab = elf_hash_table (info);
+  bed = get_elf_backend_data (dynobj);
+
+  if (!info->shared)
+    {
+      s = bfd_make_section_with_flags (dynobj,
+				       bed->default_use_rela_p
+				       ? ".rela.plt.unloaded"
+				       : ".rel.plt.unloaded",
+				       SEC_HAS_CONTENTS | SEC_IN_MEMORY
+				       | SEC_READONLY | SEC_LINKER_CREATED);
+      if (s == NULL
+	  || !bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
+	return FALSE;
+
+      *srelplt2_out = s;
+    }
+
+  /* Mark the GOT and PLT symbols as having relocations; they might
+     not, but we won't know for sure until we build the GOT in
+     finish_dynamic_symbol.  Also make sure that the GOT symbol
+     is entered into the dynamic symbol table; the loader uses it
+     to initialize __GOTT_BASE__[__GOTT_INDEX__].  */
+  if (htab->hgot)
+    {
+      htab->hgot->indx = -2;
+      htab->hgot->other &= ~ELF_ST_VISIBILITY (-1);
+      htab->hgot->forced_local = 0;
+      if (!bfd_elf_link_record_dynamic_symbol (info, htab->hgot))
+	return FALSE;
+    }
+  if (htab->hplt)
+    {
+      htab->hplt->indx = -2;
+      htab->hplt->type = STT_FUNC;
+    }
+
+  return TRUE;
+}
 
 /* Tweak magic VxWorks symbols as they are written to the output file.  */
 bfd_boolean
diff -uprN ../src.3/bfd/elf-vxworks.h ./bfd/elf-vxworks.h
--- ./bfd/elf-vxworks.h	2006-03-01 17:27:35.000000000 +0000
+++ ./bfd/elf-vxworks.h	2006-03-01 17:38:51.000000000 +0000
@@ -31,3 +31,5 @@ bfd_boolean elf_vxworks_emit_relocs
   (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
    struct elf_link_hash_entry **);
 void elf_vxworks_final_write_processing (bfd *, bfd_boolean);
+bfd_boolean elf_vxworks_create_dynamic_sections
+  (bfd *, struct bfd_link_info *, asection **);
diff -uprN ../src.3/ld/testsuite/ld-i386/i386.exp ./ld/testsuite/ld-i386/i386.exp
--- ./ld/testsuite/ld-i386/i386.exp	2006-02-28 07:16:22.000000000 +0000
+++ ./ld/testsuite/ld-i386/i386.exp	2006-03-01 18:01:56.000000000 +0000
@@ -23,7 +23,8 @@ if {[istarget "i?86-*-vxworks"]} {
     set i386tests {
 	{"VxWorks shared library test 1" "-shared -Tvxworks1.ld"
 	 "" {vxworks1-lib.s}
-	 {{readelf --relocs vxworks1-lib.rd} {objdump -dr vxworks1-lib.dd}}
+	 {{readelf --relocs vxworks1-lib.rd} {objdump -dr vxworks1-lib.dd}
+	  {readelf --symbols vxworks1-lib.nd}}
 	 "libvxworks1.so"}
 	{"VxWorks dynamic executable test 1" \
 	 "tmpdir/libvxworks1.so -Tvxworks1.ld -q" "" {vxworks1.s}
diff -uprN ../src.3/ld/testsuite/ld-i386/vxworks1-lib.nd ./ld/testsuite/ld-i386/vxworks1-lib.nd
--- ./ld/testsuite/ld-i386/vxworks1-lib.nd	1970-01-01 01:00:00.000000000 +0100
+++ ./ld/testsuite/ld-i386/vxworks1-lib.nd	2006-03-01 18:10:25.000000000 +0000
@@ -0,0 +1,9 @@
+#...
+Symbol table '\.dynsym' .*:
+#...
+.*: 00081400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#...
+Symbol table '\.symtab' .*:
+#...
+.*: 00081400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#pass
diff -uprN ../src.3/ld/testsuite/ld-powerpc/powerpc.exp ./ld/testsuite/ld-powerpc/powerpc.exp
--- ./ld/testsuite/ld-powerpc/powerpc.exp	2006-03-01 15:50:19.000000000 +0000
+++ ./ld/testsuite/ld-powerpc/powerpc.exp	2006-03-01 18:05:27.000000000 +0000
@@ -28,7 +28,8 @@ if {[istarget "*-*-vxworks"]} {
 	 "libvxworks1.so"}
 	{"VxWorks shared library test 1" "-shared -Tvxworks1.ld"
 	 "-mregnames" {vxworks1-lib.s}
-	 {{readelf --relocs vxworks1-lib.rd} {objdump -dr vxworks1-lib.dd}}
+	 {{readelf --relocs vxworks1-lib.rd} {objdump -dr vxworks1-lib.dd}
+	  {readelf --symbols vxworks1-lib.nd}}
 	 "libvxworks1.so"}
 	{"VxWorks dynamic executable test 1" \
 	 "tmpdir/libvxworks1.so -Tvxworks1.ld -q" "-mregnames" {vxworks1.s}
diff -uprN ../src.3/ld/testsuite/ld-powerpc/vxworks1-lib.nd ./ld/testsuite/ld-powerpc/vxworks1-lib.nd
--- ./ld/testsuite/ld-powerpc/vxworks1-lib.nd	1970-01-01 01:00:00.000000000 +0100
+++ ./ld/testsuite/ld-powerpc/vxworks1-lib.nd	2006-03-01 18:10:10.000000000 +0000
@@ -0,0 +1,9 @@
+#...
+Symbol table '\.dynsym' .*:
+#...
+.*: 00081400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#...
+Symbol table '\.symtab' .*:
+#...
+.*: 00081400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#pass


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