bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 5 Apr 2006 12:41:59 +0000 (12:41 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Wed, 5 Apr 2006 12:41:59 +0000 (12:41 +0000)
* config.bfd (sparc-*-vxworks*): New stanza.
* configure.in (bfd_elf32_sparc_vxworks_vec): New stanza.
(bfd_elf32_sparc_vec, bfd_elf64_sparc_vec): Add elf-vxworks.lo.
* configure: Regenerate.
* elf32-sparc.c: Include elf-vxworks.h.
(elf32_sparc_vxworks_link_hash_table_create: New.
(elf32_sparc_vxworks_final_write_processing): New.
(TARGET_BIG_SYM): Override for VxWorks.
(TARGET_BIG_NAME, ELF_MINPAGESIZE): Likewise.
(bfd_elf32_bfd_link_hash_table_create): Likewise.
(elf_backend_want_got_plt, elf_backend_plt_readonly): Likewise.
(elf_backend_got_header_size, elf_backend_add_symbol_hook): Likewise.
(elf_backend_link_output_symbol_hook): Likewise.
(elf_backend_emit_relocs): Likewise.
(elf_backend_final_write_processing, elf32_bed): Likewise.
* elfxx-sparc.c: Include libiberty.h and elf-vxworks.h.
(sparc_vxworks_exec_plt0_entry, sparc_vxworks_exec_plt_entry): New.
(sparc_vxworks_shared_plt0_entry, sparc_vxworks_shared_plt_entry): New.
(_bfd_sparc_elf_link_hash_table_create): Don't initialize
build_plt_entry here.
(create_got_section): Initialize sgotplt for VxWorks.
(_bfd_sparc_elf_create_dynamic_sections): Initialize build_plt_entry,
plt_header_size and plt_entry_size, with new VxWorks-specific settings.
Call elf_vxworks_create_dynamic_sections for VxWorks.
(allocate_dynrelocs): Use plt_header_size and plt_entry_size.
Allocate room for .got.plt and .rela.plt.unloaded entries on VxWorks.
(_bfd_sparc_elf_size_dynamic_sections): Don't allocate a nop in .plt
for VxWorks.  Check for the .got.plt section.
(sparc_vxworks_build_plt_entry): New function.
(_bfd_sparc_elf_finish_dynamic_symbol): Add handling of VxWorks PLTs.
Don't make _GLOBAL_OFFSET_TABLE_ and _PROCEDURE_LINKAGE_TABLE_
absolute on VxWorks.
(sparc32_finish_dyn): Add special handling for DT_RELASZ
and DT_PLTGOT on VxWorks.
(sparc_vxworks_finish_exec_plt): New.
(sparc_vxworks_finish_shared_plt): New.
(_bfd_sparc_elf_finish_dynamic_sections): Call them.
Use plt_header_size and plt_entry_size.
* elfxx-sparc.h (_bfd_sparc_elf_link_hash_table): Add is_vxworks,
srelplt2, sgotplt, plt_header_size and plt_entry_size fields.
* Makefile.am (elfxx-sparc.lo): Depend on elf-vxworks.h.
(elf32-sparc.lo): Likewise.
* Makefile.in: Regenerate.
* targets.c (bfd_elf32_sparc_vxworks_vec): Declare.
(_bfd_target_vector): Add a pointer to it.

gas/
* config/tc-sparc.c (sparc_target_format): Handle TE_VXWORKS.
(GOTT_BASE, GOTT_INDEX): New.
(tc_gen_reloc): Don't alter relocations against GOTT_BASE and
GOTT_INDEX when generating VxWorks PIC.
* configure.tgt (sparc*-*-vxworks*): Remove this special case;
use the generic *-*-vxworks* stanza instead.

gas/testsuite/
* gas/sparc/vxworks-pic.s, gas/sparc/vxworks-pic.d: New test.
* gas/sparc/sparc.exp: Run it.  Remove sparc*-*-vxworks* XFAILs.

ld/
* configure.tgt (sparc*-*-vxworks*): New stanza.
* emulparams/elf32_sparc_vxworks.sh: New file.
* Makefile.am (ALL_EMULATIONS): Add eelf32_sparc_vxworks.o.
(eelf32_sparc_vxworks.c): New rule.
* Makefile.in: Regenerate.

ld/testsuite/
* ld-sparc/vxworks1.dd, ld-sparc/vxworks1.ld, ld-sparc/vxworks1-lib.dd,
* ld-sparc/vxworks1-lib.nd, ld-sparc/vxworks1-lib.rd,
* ld-sparc/vxworks1-lib.s, ld-sparc/vxworks1.rd, ld-sparc/vxworks1.s,
* ld-sparc/vxworks1-static.d, ld-sparc/vxworks2.s,
* ld-sparc/vxworks2.sd, ld-sparc/vxworks2-static.sd: New tests.
* ld-sparc/sparc.exp: Run them.

36 files changed:
bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/config.bfd
bfd/configure
bfd/configure.in
bfd/elf32-sparc.c
bfd/elfxx-sparc.c
bfd/elfxx-sparc.h
bfd/targets.c
gas/ChangeLog
gas/config/tc-sparc.c
gas/configure.tgt
gas/testsuite/ChangeLog
gas/testsuite/gas/sparc/sparc.exp
gas/testsuite/gas/sparc/vxworks-pic.d [new file with mode: 0644]
gas/testsuite/gas/sparc/vxworks-pic.s [new file with mode: 0644]
ld/ChangeLog
ld/Makefile.am
ld/Makefile.in
ld/configure.tgt
ld/emulparams/elf32_sparc_vxworks.sh [new file with mode: 0644]
ld/testsuite/ChangeLog
ld/testsuite/ld-sparc/sparc.exp
ld/testsuite/ld-sparc/vxworks1-lib.dd [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1-lib.nd [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1-lib.rd [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1-lib.s [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1-static.d [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1.dd [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1.ld [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1.rd [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks1.s [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks2-static.sd [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks2.s [new file with mode: 0644]
ld/testsuite/ld-sparc/vxworks2.sd [new file with mode: 0644]

index 51157c0da7202256298ea3fbca55a93b01fc8806..322b77facd33949bd8feb62ec8d91c40fd06aab4 100644 (file)
@@ -1,3 +1,52 @@
+2006-04-05  Richard Sandiford  <richard@codesourcery.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * config.bfd (sparc-*-vxworks*): New stanza.
+       * configure.in (bfd_elf32_sparc_vxworks_vec): New stanza.
+       (bfd_elf32_sparc_vec, bfd_elf64_sparc_vec): Add elf-vxworks.lo.
+       * configure: Regenerate.
+       * elf32-sparc.c: Include elf-vxworks.h.
+       (elf32_sparc_vxworks_link_hash_table_create: New.
+       (elf32_sparc_vxworks_final_write_processing): New.
+       (TARGET_BIG_SYM): Override for VxWorks.
+       (TARGET_BIG_NAME, ELF_MINPAGESIZE): Likewise.
+       (bfd_elf32_bfd_link_hash_table_create): Likewise.
+       (elf_backend_want_got_plt, elf_backend_plt_readonly): Likewise.
+       (elf_backend_got_header_size, elf_backend_add_symbol_hook): Likewise.
+       (elf_backend_link_output_symbol_hook): Likewise.
+       (elf_backend_emit_relocs): Likewise.
+       (elf_backend_final_write_processing, elf32_bed): Likewise.
+       * elfxx-sparc.c: Include libiberty.h and elf-vxworks.h.
+       (sparc_vxworks_exec_plt0_entry, sparc_vxworks_exec_plt_entry): New.
+       (sparc_vxworks_shared_plt0_entry, sparc_vxworks_shared_plt_entry): New.
+       (_bfd_sparc_elf_link_hash_table_create): Don't initialize
+       build_plt_entry here.
+       (create_got_section): Initialize sgotplt for VxWorks.
+       (_bfd_sparc_elf_create_dynamic_sections): Initialize build_plt_entry,
+       plt_header_size and plt_entry_size, with new VxWorks-specific settings.
+       Call elf_vxworks_create_dynamic_sections for VxWorks.
+       (allocate_dynrelocs): Use plt_header_size and plt_entry_size.
+       Allocate room for .got.plt and .rela.plt.unloaded entries on VxWorks.
+       (_bfd_sparc_elf_size_dynamic_sections): Don't allocate a nop in .plt
+       for VxWorks.  Check for the .got.plt section.
+       (sparc_vxworks_build_plt_entry): New function.
+       (_bfd_sparc_elf_finish_dynamic_symbol): Add handling of VxWorks PLTs.
+       Don't make _GLOBAL_OFFSET_TABLE_ and _PROCEDURE_LINKAGE_TABLE_
+       absolute on VxWorks.
+       (sparc32_finish_dyn): Add special handling for DT_RELASZ
+       and DT_PLTGOT on VxWorks.
+       (sparc_vxworks_finish_exec_plt): New.
+       (sparc_vxworks_finish_shared_plt): New.
+       (_bfd_sparc_elf_finish_dynamic_sections): Call them.
+       Use plt_header_size and plt_entry_size.
+       * elfxx-sparc.h (_bfd_sparc_elf_link_hash_table): Add is_vxworks,
+       srelplt2, sgotplt, plt_header_size and plt_entry_size fields.
+       * Makefile.am (elfxx-sparc.lo): Depend on elf-vxworks.h.
+       (elf32-sparc.lo): Likewise.
+       * Makefile.in: Regenerate.
+       * targets.c (bfd_elf32_sparc_vxworks_vec): Declare.
+       (_bfd_target_vector): Add a pointer to it.
+
 2006-03-30  Ben Elliston  <bje@au.ibm.com>
 
        PR ld/2267
index a0d5edf67d9bc016f24506d896ae0f389e162fcf..bf32fbdffebca4b925980180767ec55042415d22 100644 (file)
@@ -1416,12 +1416,12 @@ elfxx-sparc.lo: elfxx-sparc.c $(INCDIR)/filenames.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/sparc.h \
   $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/sparc.h \
-  elfxx-sparc.h
+  elfxx-sparc.h elf-vxworks.h
 elf32-sparc.lo: elf32-sparc.c $(INCDIR)/filenames.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/sparc.h \
   $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/sparc.h \
-  elfxx-sparc.h elf32-target.h
+  elfxx-sparc.h elf32-target.h elf-vxworks.h
 elf32-v850.lo: elf32-v850.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/v850.h \
index 6b783333246462f703f7b708acc2c6ddd65284e5..0220d91b24ffe8e6f1ed49cb95f46a632d872741 100644 (file)
@@ -1983,12 +1983,12 @@ elfxx-sparc.lo: elfxx-sparc.c $(INCDIR)/filenames.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/sparc.h \
   $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/sparc.h \
-  elfxx-sparc.h
+  elfxx-sparc.h elf-vxworks.h
 elf32-sparc.lo: elf32-sparc.c $(INCDIR)/filenames.h \
   $(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/sparc.h \
   $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/sparc.h \
-  elfxx-sparc.h elf32-target.h
+  elfxx-sparc.h elf32-target.h elf-vxworks.h
 elf32-v850.lo: elf32-v850.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/elf/v850.h \
index ccd0de8dfab828f79bba0d821f4bc7a989e2ce9b..4fd72c1c152777f6cba5e90c059b5b454c92e35e 100644 (file)
@@ -1284,6 +1284,10 @@ case "${targ}" in
   sparc-*-sysv4*)
     targ_defvec=bfd_elf32_sparc_vec
     ;;
+  sparc-*-vxworks*)
+    targ_defvec=bfd_elf32_sparc_vxworks_vec
+    targ_selvecs="bfd_elf32_sparc_vec sunos_big_vec"
+    ;;
   sparc-*-netware*)
     targ_defvec=bfd_elf32_sparc_vec
     targ_selvecs="nlm32_sparc_vec sunos_big_vec"
index 5ad2bc45695b23e965f6a966e014426c54c3238d..dd8f2d0834ce200487b9394dde09f347f429633e 100755 (executable)
@@ -13159,7 +13159,8 @@ do
     bfd_elf32_shlin_vec)       tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
     bfd_elf32_shlnbsd_vec)     tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
     bfd_elf32_shnbsd_vec)      tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
-    bfd_elf32_sparc_vec)       tb="$tb elf32-sparc.lo elfxx-sparc.lo elf32.lo $elf" ;;
+    bfd_elf32_sparc_vec)       tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_sparc_vxworks_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_tradbigmips_vec)  tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_tradlittlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_us_cris_vec)     tb="$tb elf32-cris.lo elf32.lo $elf" ;;
@@ -13190,7 +13191,7 @@ do
     bfd_elf64_sh64blin_vec)    tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64lnbsd_vec)   tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64nbsd_vec)    tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
-    bfd_elf64_sparc_vec)       tb="$tb elf64-sparc.lo elfxx-sparc.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_sparc_vec)       tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_tradbigmips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_tradlittlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_x86_64_vec)      tb="$tb elf64-x86-64.lo elf64.lo $elf"; target_size=64 ;;
index bc8dabb4d51f5841a2d0cbd685164fd427b52d85..37282b714df3727118bdb6952bdc0f72a130a6b5 100644 (file)
@@ -672,7 +672,8 @@ do
     bfd_elf32_shlin_vec)       tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
     bfd_elf32_shlnbsd_vec)     tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
     bfd_elf32_shnbsd_vec)      tb="$tb elf32-sh.lo elf32.lo $elf coff-sh.lo cofflink.lo" ;;
-    bfd_elf32_sparc_vec)       tb="$tb elf32-sparc.lo elfxx-sparc.lo elf32.lo $elf" ;;
+    bfd_elf32_sparc_vec)       tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_sparc_vxworks_vec) tb="$tb elf32-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_tradbigmips_vec)  tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_tradlittlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_us_cris_vec)     tb="$tb elf32-cris.lo elf32.lo $elf" ;;
@@ -703,7 +704,7 @@ do
     bfd_elf64_sh64blin_vec)    tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64lnbsd_vec)   tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
     bfd_elf64_sh64nbsd_vec)    tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
-    bfd_elf64_sparc_vec)       tb="$tb elf64-sparc.lo elfxx-sparc.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_sparc_vec)       tb="$tb elf64-sparc.lo elfxx-sparc.lo elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_tradbigmips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_tradlittlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_x86_64_vec)      tb="$tb elf64-x86-64.lo elf64.lo $elf"; target_size=64 ;;
index 031b3034a8b60ce3200d47d840619d15c8c7843d..3bfb38a3d44ac8482b86d1afb840d6b4b9749f97 100644 (file)
@@ -26,6 +26,7 @@
 #include "elf/sparc.h"
 #include "opcode/sparc.h"
 #include "elfxx-sparc.h"
+#include "elf-vxworks.h"
 
 /* Support for core dump NOTE sections.  */
 
@@ -215,3 +216,68 @@ elf32_sparc_reloc_type_class (const Elf_Internal_Rela *rela)
 #define elf_backend_rela_normal 1
 
 #include "elf32-target.h"
+
+/* A wrapper around _bfd_sparc_elf_link_hash_table_create that identifies
+   the target system as VxWorks.  */
+
+static struct bfd_link_hash_table *
+elf32_sparc_vxworks_link_hash_table_create (bfd *abfd)
+{
+  struct bfd_link_hash_table *ret;
+
+  ret = _bfd_sparc_elf_link_hash_table_create (abfd);
+  if (ret)
+    {
+      struct _bfd_sparc_elf_link_hash_table *htab;
+
+      htab = (struct _bfd_sparc_elf_link_hash_table *) ret;
+      htab->is_vxworks = 1;
+    }
+  return ret;
+}
+
+/* A final_write_processing hook that does both the SPARC- and VxWorks-
+   specific handling.  */
+
+static void
+elf32_sparc_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+{
+  elf32_sparc_final_write_processing (abfd, linker);
+  elf_vxworks_final_write_processing (abfd, linker);
+}
+
+#undef TARGET_BIG_SYM
+#define TARGET_BIG_SYM bfd_elf32_sparc_vxworks_vec
+#undef TARGET_BIG_NAME
+#define TARGET_BIG_NAME        "elf32-sparc-vxworks"
+
+#undef ELF_MINPAGESIZE
+#define ELF_MINPAGESIZE        0x1000
+
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+  elf32_sparc_vxworks_link_hash_table_create
+
+#undef elf_backend_want_got_plt
+#define elf_backend_want_got_plt               1
+#undef elf_backend_plt_readonly
+#define elf_backend_plt_readonly               1
+#undef elf_backend_got_header_size
+#define elf_backend_got_header_size            12
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook \
+  elf_vxworks_add_symbol_hook
+#undef elf_backend_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+  elf_vxworks_link_output_symbol_hook
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs \
+  elf_vxworks_emit_relocs
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+  elf32_sparc_vxworks_final_write_processing
+
+#undef elf32_bed
+#define elf32_bed                              sparc_elf_vxworks_bed
+
+#include "elf32-target.h"
index cb5f7cbba9bf64a82144dd0b2f40482618b8fdca..ef7ff482d2ed0f787d4df7c8f5c49307d5bcdf3e 100644 (file)
 #include "sysdep.h"
 #include "bfdlink.h"
 #include "libbfd.h"
+#include "libiberty.h"
 #include "elf-bfd.h"
 #include "elf/sparc.h"
 #include "opcode/sparc.h"
 #include "elfxx-sparc.h"
+#include "elf-vxworks.h"
 
 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
 #define MINUS_ONE (~ (bfd_vma) 0)
@@ -697,6 +699,50 @@ sparc64_plt_entry_build (bfd *output_bfd, asection *splt, bfd_vma offset,
   return index - 4;
 }
 
+/* The format of the first PLT entry in a VxWorks executable.  */
+static const bfd_vma sparc_vxworks_exec_plt0_entry[] =
+  {
+    0x05000000,        /* sethi  %hi(_GLOBAL_OFFSET_TABLE_+8), %g2 */
+    0x8410a000,        /* or     %g2, %lo(_GLOBAL_OFFSET_TABLE_+8), %g2 */
+    0xc4008000,        /* ld     [ %g2 ], %g2 */
+    0x81c08000,        /* jmp    %g2 */
+    0x01000000 /* nop */
+  };
+
+/* The format of subsequent PLT entries.  */
+static const bfd_vma sparc_vxworks_exec_plt_entry[] =
+  {
+    0x03000000,        /* sethi  %hi(_GLOBAL_OFFSET_TABLE_+f@got), %g1 */
+    0x82106000,        /* or     %g1, %lo(_GLOBAL_OFFSET_TABLE_+f@got), %g1 */
+    0xc2004000,        /* ld     [ %g1 ], %g1 */
+    0x81c04000,        /* jmp    %g1 */
+    0x01000000,        /* nop */
+    0x03000000,        /* sethi  %hi(f@pltindex), %g1 */
+    0x10800000,        /* b      _PLT_resolve */
+    0x82106000 /* or     %g1, %lo(f@pltindex), %g1 */
+  };
+
+/* The format of the first PLT entry in a VxWorks shared object.  */
+static const bfd_vma sparc_vxworks_shared_plt0_entry[] =
+  {
+    0xc405e008,        /* ld     [ %l7 + 8 ], %g2 */
+    0x81c08000,        /* jmp    %g2 */
+    0x01000000 /* nop */
+  };
+
+/* The format of subsequent PLT entries.  */
+static const bfd_vma sparc_vxworks_shared_plt_entry[] =
+  {
+    0x03000000,        /* sethi  %hi(f@got), %g1 */
+    0x82106000,        /* or     %g1, %lo(f@got), %g1 */
+    0xc205c001,        /* ld     [ %l7 + %g1 ], %g1 */
+    0x81c04000,        /* jmp    %g1 */
+    0x01000000,        /* nop */
+    0x03000000,        /* sethi  %hi(f@pltindex), %g1 */
+    0x10800000,        /* b      _PLT_resolve */
+    0x82106000 /* or     %g1, %lo(f@pltindex), %g1 */
+  };
+
 #define SPARC_ELF_PUT_WORD(htab, bfd, val, ptr)        \
        htab->put_word(bfd, val, ptr)
 
@@ -781,7 +827,6 @@ _bfd_sparc_elf_link_hash_table_create (bfd *abfd)
       ret->append_rela = sparc_elf_append_rela_64;
       ret->r_info = sparc_elf_r_info_64;
       ret->r_symndx = sparc_elf_r_symndx_64;
-      ret->build_plt_entry = sparc64_plt_entry_build;
       ret->dtpoff_reloc = R_SPARC_TLS_DTPOFF64;
       ret->dtpmod_reloc = R_SPARC_TLS_DTPMOD64;
       ret->tpoff_reloc = R_SPARC_TLS_TPOFF64;
@@ -798,7 +843,6 @@ _bfd_sparc_elf_link_hash_table_create (bfd *abfd)
       ret->append_rela = sparc_elf_append_rela_32;
       ret->r_info = sparc_elf_r_info_32;
       ret->r_symndx = sparc_elf_r_symndx_32;
-      ret->build_plt_entry = sparc32_plt_entry_build;
       ret->dtpoff_reloc = R_SPARC_TLS_DTPOFF32;
       ret->dtpmod_reloc = R_SPARC_TLS_DTPMOD32;
       ret->tpoff_reloc = R_SPARC_TLS_TPOFF32;
@@ -846,6 +890,14 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
       || ! bfd_set_section_alignment (dynobj, htab->srelgot,
                                      htab->word_align_power))
     return FALSE;
+
+  if (htab->is_vxworks)
+    {
+      htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
+      if (!htab->sgotplt)
+       return FALSE;
+    }
+
   return TRUE;
 }
 
@@ -872,6 +924,41 @@ _bfd_sparc_elf_create_dynamic_sections (bfd *dynobj,
   if (!info->shared)
     htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
 
+  if (htab->is_vxworks)
+    {
+      if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
+       return FALSE;
+      if (info->shared)
+       {
+         htab->plt_header_size
+           = 4 * ARRAY_SIZE (sparc_vxworks_shared_plt0_entry);
+         htab->plt_entry_size
+           = 4 * ARRAY_SIZE (sparc_vxworks_shared_plt_entry);
+       }
+      else
+       {
+         htab->plt_header_size
+           = 4 * ARRAY_SIZE (sparc_vxworks_exec_plt0_entry);
+         htab->plt_entry_size
+           = 4 * ARRAY_SIZE (sparc_vxworks_exec_plt_entry);
+       }
+    }
+  else
+    {
+      if (ABI_64_P (dynobj))
+       {
+         htab->build_plt_entry = sparc64_plt_entry_build;
+         htab->plt_header_size = PLT64_HEADER_SIZE;
+         htab->plt_entry_size = PLT64_ENTRY_SIZE;
+       }
+      else
+       {
+         htab->build_plt_entry = sparc32_plt_entry_build;
+         htab->plt_header_size = PLT32_HEADER_SIZE;
+         htab->plt_entry_size = PLT32_ENTRY_SIZE;
+       }
+    }
+
   if (!htab->splt || !htab->srelplt || !htab->sdynbss
       || (!info->shared && !htab->srelbss))
     abort ();
@@ -1807,10 +1894,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
        {
          asection *s = htab->splt;
 
-         /* The first four entries in .plt is reserved.  */
+         /* Allocate room for the header.  */
          if (s->size == 0)
-           s->size = (SPARC_ELF_WORD_BYTES(htab) == 8 ?
-                      PLT64_HEADER_SIZE : PLT32_HEADER_SIZE);
+           {
+             s->size = htab->plt_header_size;
+
+             /* Allocate space for the .rela.plt.unloaded relocations.  */
+             if (htab->is_vxworks && !info->shared)
+               htab->srelplt2->size = sizeof (Elf32_External_Rela) * 2;
+           }
 
          /* The procedure linkage table size is bounded by the magnitude
             of the offset we can describe in the entry.  */
@@ -1847,11 +1939,20 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, PTR inf)
            }
 
          /* Make room for this entry.  */
-         s->size += (SPARC_ELF_WORD_BYTES(htab) == 8 ?
-                     PLT64_ENTRY_SIZE : PLT32_ENTRY_SIZE);
+         s->size += htab->plt_entry_size;
 
          /* We also need to make an entry in the .rela.plt section.  */
          htab->srelplt->size += SPARC_ELF_RELA_BYTES (htab);
+
+         if (htab->is_vxworks)
+           {
+             /* Allocate space for the .got.plt entry.  */
+             htab->sgotplt->size += 4;
+
+             /* ...and for the .rela.plt.unloaded relocations.  */
+             if (!info->shared)
+               htab->srelplt2->size += sizeof (Elf32_External_Rela) * 3;
+           }
        }
       else
        {
@@ -2153,6 +2254,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
 
   if (! ABI_64_P (output_bfd)
+      && !htab->is_vxworks
       && elf_hash_table (info)->dynamic_sections_created)
     {
       /* Make space for the trailing nop in .plt.  */
@@ -2179,7 +2281,8 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd,
 
       if (s == htab->splt
          || s == htab->sgot
-         || s == htab->sdynbss)
+         || s == htab->sdynbss
+         || s == htab->sgotplt)
        {
          /* Strip this section if we don't need it; see the
             comment below.  */
@@ -3428,6 +3531,97 @@ _bfd_sparc_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
   return TRUE;
 }
 
+/* Build a VxWorks PLT entry.  PLT_INDEX is the index of the PLT entry
+   and PLT_OFFSET is the byte offset from the start of .plt.  GOT_OFFSET
+   is the offset of the associated .got.plt entry from
+   _GLOBAL_OFFSET_TABLE_.  */
+
+static void
+sparc_vxworks_build_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
+                              bfd_vma plt_offset, bfd_vma plt_index,
+                              bfd_vma got_offset)
+{
+  bfd_vma got_base;
+  const bfd_vma *plt_entry;
+  struct _bfd_sparc_elf_link_hash_table *htab;
+  bfd_byte *loc;
+  Elf_Internal_Rela rela;
+
+  htab = _bfd_sparc_elf_hash_table (info);
+  if (info->shared)
+    {
+      plt_entry = sparc_vxworks_shared_plt_entry;
+      got_base = 0;
+    }
+  else
+    {
+      plt_entry = sparc_vxworks_exec_plt_entry;
+      got_base = (htab->elf.hgot->root.u.def.value
+                 + htab->elf.hgot->root.u.def.section->output_offset
+                 + htab->elf.hgot->root.u.def.section->output_section->vma);
+    }
+
+  /* Fill in the entry in the procedure linkage table.  */
+  bfd_put_32 (output_bfd, plt_entry[0] + ((got_base + got_offset) >> 10),
+             htab->splt->contents + plt_offset);
+  bfd_put_32 (output_bfd, plt_entry[1] + ((got_base + got_offset) & 0x3ff),
+             htab->splt->contents + plt_offset + 4);
+  bfd_put_32 (output_bfd, plt_entry[2],
+             htab->splt->contents + plt_offset + 8);
+  bfd_put_32 (output_bfd, plt_entry[3],
+             htab->splt->contents + plt_offset + 12);
+  bfd_put_32 (output_bfd, plt_entry[4],
+             htab->splt->contents + plt_offset + 16);
+  bfd_put_32 (output_bfd, plt_entry[5] + (plt_index >> 10),
+             htab->splt->contents + plt_offset + 20);
+  /* PC-relative displacement for a branch to the start of
+     the PLT section.  */
+  bfd_put_32 (output_bfd, plt_entry[6] + (((-plt_offset - 24) >> 2)
+                                         & 0x003fffff),
+             htab->splt->contents + plt_offset + 24);
+  bfd_put_32 (output_bfd, plt_entry[7] + (plt_index & 0x3ff),
+             htab->splt->contents + plt_offset + 28);
+
+  /* Fill in the .got.plt entry, pointing initially at the
+     second half of the PLT entry.  */
+  BFD_ASSERT (htab->sgotplt != NULL);
+  bfd_put_32 (output_bfd,
+             htab->splt->output_section->vma
+             + htab->splt->output_offset
+             + plt_offset + 20,
+             htab->sgotplt->contents + got_offset);
+
+  /* Add relocations to .rela.plt.unloaded.  */
+  if (!info->shared)
+    {
+      loc = (htab->srelplt2->contents
+            + (2 + 3 * plt_index) * sizeof (Elf32_External_Rela));
+
+      /* Relocate the initial sethi.  */
+      rela.r_offset = (htab->splt->output_section->vma
+                      + htab->splt->output_offset
+                      + plt_offset);
+      rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_HI22);
+      rela.r_addend = got_offset;
+      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+      loc += sizeof (Elf32_External_Rela);
+
+      /* Likewise the following or.  */
+      rela.r_offset += 4;
+      rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_LO10);
+      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+      loc += sizeof (Elf32_External_Rela);
+
+      /* Relocate the .got.plt entry.  */
+      rela.r_offset = (htab->sgotplt->output_section->vma
+                      + htab->sgotplt->output_offset
+                      + got_offset);
+      rela.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_SPARC_32);
+      rela.r_addend = plt_offset + 20;
+      bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+    }
+}
+
 /* Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
 
@@ -3449,7 +3643,7 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
       asection *srela;
       Elf_Internal_Rela rela;
       bfd_byte *loc;
-      bfd_vma r_offset;
+      bfd_vma r_offset, got_offset;
       int rela_index;
 
       /* This symbol has an entry in the PLT.  Set it up.  */
@@ -3460,23 +3654,48 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
       srela = htab->srelplt;
       BFD_ASSERT (splt != NULL && srela != NULL);
 
-      /* Fill in the entry in the procedure linkage table.  */
-      rela_index = SPARC_ELF_BUILD_PLT_ENTRY (htab, output_bfd, splt,
-                                             h->plt.offset, splt->size,
-                                             &r_offset);
-
       /* Fill in the entry in the .rela.plt section.  */
-      rela.r_offset = r_offset
-       + (splt->output_section->vma + splt->output_offset);
-      if (! ABI_64_P (output_bfd)
-         || h->plt.offset < (PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE))
+      if (htab->is_vxworks)
        {
+         /* Work out the index of this PLT entry.  */
+         rela_index = ((h->plt.offset - htab->plt_header_size)
+                       / htab->plt_entry_size);
+
+         /* Calculate the offset of the associated .got.plt entry.
+            The first three entries are reserved.  */
+         got_offset = (rela_index + 3) * 4;
+
+         sparc_vxworks_build_plt_entry (output_bfd, info, h->plt.offset,
+                                        rela_index, got_offset);
+
+
+         /* On VxWorks, the relocation points to the .got.plt entry,
+            not the .plt entry.  */
+         rela.r_offset = (htab->sgotplt->output_section->vma
+                          + htab->sgotplt->output_offset
+                          + got_offset);
          rela.r_addend = 0;
        }
       else
        {
-         rela.r_addend = -(h->plt.offset + 4)
-                         -(splt->output_section->vma + splt->output_offset);
+         /* Fill in the entry in the procedure linkage table.  */
+         rela_index = SPARC_ELF_BUILD_PLT_ENTRY (htab, output_bfd, splt,
+                                                 h->plt.offset, splt->size,
+                                                 &r_offset);
+
+         rela.r_offset = r_offset
+           + (splt->output_section->vma + splt->output_offset);
+         if (! ABI_64_P (output_bfd)
+             || h->plt.offset < (PLT64_LARGE_THRESHOLD * PLT64_ENTRY_SIZE))
+           {
+             rela.r_addend = 0;
+           }
+         else
+           {
+             rela.r_addend = (-(h->plt.offset + 4)
+                              - splt->output_section->vma
+                              - splt->output_offset);
+           }
        }
       rela.r_info = SPARC_ELF_R_INFO (htab, NULL, h->dynindx, R_SPARC_JMP_SLOT);
 
@@ -3577,10 +3796,12 @@ _bfd_sparc_elf_finish_dynamic_symbol (bfd *output_bfd,
       SPARC_ELF_APPEND_RELA (htab, output_bfd, s, &rela);
     }
 
-  /* Mark some specially defined symbols as absolute.  */
+  /* Mark some specially defined symbols as absolute.  On VxWorks,
+     _GLOBAL_OFFSET_TABLE_ is not absolute: it is relative to the
+     ".got" section.  Likewise _PROCEDURE_LINKAGE_TABLE_ and ".plt".  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || h == htab->elf.hgot
-      || h == htab->elf.hplt)
+      || (!htab->is_vxworks
+         && (h == htab->elf.hgot || h == htab->elf.hplt)))
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -3648,13 +3869,14 @@ sparc64_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
 #endif
 
 static bfd_boolean
-sparc32_finish_dyn (bfd *output_bfd,
-                   struct bfd_link_info *info ATTRIBUTE_UNUSED,
+sparc32_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
                    bfd *dynobj, asection *sdyn,
                    asection *splt ATTRIBUTE_UNUSED)
 {
   Elf32_External_Dyn *dyncon, *dynconend;
+  struct _bfd_sparc_elf_link_hash_table *htab;
 
+  htab = _bfd_sparc_elf_hash_table (info);
   dyncon = (Elf32_External_Dyn *) sdyn->contents;
   dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
   for (; dyncon < dynconend; dyncon++)
@@ -3665,34 +3887,150 @@ sparc32_finish_dyn (bfd *output_bfd,
 
       bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
 
-      switch (dyn.d_tag)
+      if (htab->is_vxworks && dyn.d_tag == DT_RELASZ)
        {
-       case DT_PLTGOT:   name = ".plt"; size = FALSE; break;
-       case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
-       case DT_JMPREL:   name = ".rela.plt"; size = FALSE; break;
-       default:          name = NULL; size = FALSE; break;
+         /* On VxWorks, DT_RELASZ should not include the relocations
+            in .rela.plt.  */
+         if (htab->srelplt)
+           {
+             dyn.d_un.d_val -= htab->srelplt->size;
+             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+           }
        }
-
-      if (name != NULL)
+      else if (htab->is_vxworks && dyn.d_tag == DT_PLTGOT)
        {
-         asection *s;
+         /* On VxWorks, DT_PLTGOT should point to the start of the GOT,
+            not to the start of the PLT.  */
+         if (htab->sgotplt)
+           {
+             dyn.d_un.d_val = (htab->sgotplt->output_section->vma
+                               + htab->sgotplt->output_offset);
+             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+           }
+       }
+      else
+       {
+         switch (dyn.d_tag)
+           {
+           case DT_PLTGOT:   name = ".plt"; size = FALSE; break;
+           case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
+           case DT_JMPREL:   name = ".rela.plt"; size = FALSE; break;
+           default:      name = NULL; size = FALSE; break;
+           }
 
-         s = bfd_get_section_by_name (output_bfd, name);
-         if (s == NULL)
-           dyn.d_un.d_val = 0;
-         else
+         if (name != NULL)
            {
-             if (! size)
-               dyn.d_un.d_ptr = s->vma;
+             asection *s;
+
+             s = bfd_get_section_by_name (output_bfd, name);
+             if (s == NULL)
+               dyn.d_un.d_val = 0;
              else
-               dyn.d_un.d_val = s->size;
+               {
+                 if (! size)
+                   dyn.d_un.d_ptr = s->vma;
+                 else
+                   dyn.d_un.d_val = s->size;
+               }
+             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
            }
-         bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
        }
     }
   return TRUE;
 }
 
+/* Install the first PLT entry in a VxWorks executable and make sure that
+   .rela.plt.unloaded relocations have the correct symbol indexes.  */
+
+static void
+sparc_vxworks_finish_exec_plt (bfd *output_bfd, struct bfd_link_info *info)
+{
+  struct _bfd_sparc_elf_link_hash_table *htab;
+  Elf_Internal_Rela rela;
+  bfd_vma got_base;
+  bfd_byte *loc;
+
+  htab = _bfd_sparc_elf_hash_table (info);
+
+  /* Calculate the absolute value of _GLOBAL_OFFSET_TABLE_.  */
+  got_base = (htab->elf.hgot->root.u.def.section->output_section->vma
+             + htab->elf.hgot->root.u.def.section->output_offset
+             + htab->elf.hgot->root.u.def.value);
+
+  /* Install the initial PLT entry.  */
+  bfd_put_32 (output_bfd,
+             sparc_vxworks_exec_plt0_entry[0] + ((got_base + 8) >> 10),
+             htab->splt->contents);
+  bfd_put_32 (output_bfd,
+             sparc_vxworks_exec_plt0_entry[1] + ((got_base + 8) & 0x3ff),
+             htab->splt->contents + 4);
+  bfd_put_32 (output_bfd,
+             sparc_vxworks_exec_plt0_entry[2],
+             htab->splt->contents + 8);
+  bfd_put_32 (output_bfd,
+             sparc_vxworks_exec_plt0_entry[3],
+             htab->splt->contents + 12);
+  bfd_put_32 (output_bfd,
+             sparc_vxworks_exec_plt0_entry[4],
+             htab->splt->contents + 16);
+
+  loc = htab->srelplt2->contents;
+
+  /* Add an unloaded relocation for the initial entry's "sethi".  */
+  rela.r_offset = (htab->splt->output_section->vma
+                  + htab->splt->output_offset);
+  rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_HI22);
+  rela.r_addend = 8;
+  bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+  loc += sizeof (Elf32_External_Rela);
+
+  /* Likewise the following "or".  */
+  rela.r_offset += 4;
+  rela.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_LO10);
+  bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
+  loc += sizeof (Elf32_External_Rela);
+
+  /* Fix up the remaining .rela.plt.unloaded relocations.  They may have
+     the wrong symbol index for _G_O_T_ or _P_L_T_ depending on the order
+     in which symbols were output.  */
+  while (loc < htab->srelplt2->contents + htab->srelplt2->size)
+    {
+      Elf_Internal_Rela rel;
+
+      /* The entry's initial "sethi" (against _G_O_T_).  */
+      bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_HI22);
+      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+      loc += sizeof (Elf32_External_Rela);
+
+      /* The following "or" (also against _G_O_T_).  */
+      bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+      rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_SPARC_LO10);
+      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+      loc += sizeof (Elf32_External_Rela);
+
+      /* The .got.plt entry (against _P_L_T_).  */
+      bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
+      rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_SPARC_32);
+      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+      loc += sizeof (Elf32_External_Rela);
+    }
+}
+
+/* Install the first PLT entry in a VxWorks shared object.  */
+
+static void
+sparc_vxworks_finish_shared_plt (bfd *output_bfd, struct bfd_link_info *info)
+{
+  struct _bfd_sparc_elf_link_hash_table *htab;
+  unsigned int i;
+
+  htab = _bfd_sparc_elf_hash_table (info);
+  for (i = 0; i < ARRAY_SIZE (sparc_vxworks_shared_plt0_entry); i++)
+    bfd_put_32 (output_bfd, sparc_vxworks_shared_plt0_entry[i],
+               htab->splt->contents + i * 4);
+}
+
 bfd_boolean
 _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 {
@@ -3726,18 +4064,24 @@ _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *i
       /* Initialize the contents of the .plt section.  */
       if (splt->size > 0)
        {
-         if (ABI_64_P (output_bfd))
-           memset (splt->contents, 0, 4 * PLT64_ENTRY_SIZE);
+         if (htab->is_vxworks)
+           {
+             if (info->shared)
+               sparc_vxworks_finish_shared_plt (output_bfd, info);
+             else
+               sparc_vxworks_finish_exec_plt (output_bfd, info);
+           }
          else
            {
-             memset (splt->contents, 0, 4 * PLT32_ENTRY_SIZE);
-             bfd_put_32 (output_bfd, (bfd_vma) SPARC_NOP,
-                         splt->contents + splt->size - 4);
+             memset (splt->contents, 0, htab->plt_header_size);
+             if (!ABI_64_P (output_bfd))
+               bfd_put_32 (output_bfd, (bfd_vma) SPARC_NOP,
+                           splt->contents + splt->size - 4);
            }
        }
 
-      elf_section_data (splt->output_section)->this_hdr.sh_entsize =
-       (ABI_64_P (output_bfd) ? PLT64_ENTRY_SIZE : PLT32_ENTRY_SIZE);
+      elf_section_data (splt->output_section)->this_hdr.sh_entsize
+       = htab->plt_entry_size;
     }
 
   /* Set the first entry in the global offset table to the address of
index 624aea52787ae9eb23a49013d9fe55715feb55d5..0a5a88b6fe36ec0d7b1ac946fb1b5b6a319073ea 100644 (file)
@@ -61,6 +61,15 @@ struct _bfd_sparc_elf_link_hash_table
   /* Small local sym to section mapping cache.  */
   struct sym_sec_cache sym_sec;
 
+  /* True if the target system is VxWorks.  */
+  int is_vxworks;
+
+  /* The (unloaded but important) .rela.plt.unloaded section, for VxWorks.  */
+  asection *srelplt2;
+
+  /* .got.plt is only used on VxWorks.  */
+  asection *sgotplt;
+
   void (*put_word) (bfd *, bfd_vma, void *);
   void (*append_rela) (bfd *, asection *, Elf_Internal_Rela *);
   bfd_vma (*r_info) (Elf_Internal_Rela *, bfd_vma, bfd_vma);
@@ -70,6 +79,8 @@ struct _bfd_sparc_elf_link_hash_table
   int dynamic_interpreter_size;
   unsigned int word_align_power;
   unsigned int align_power_max;
+  unsigned int plt_header_size;
+  unsigned int plt_entry_size;
   int bytes_per_word;
   int bytes_per_rela;
   int dtpoff_reloc;
index 0649179ba3347af01238b709651a194b6d8dbab2..849eb944fbeb74e6142fd794ac5b60b624d30de5 100644 (file)
@@ -634,6 +634,7 @@ extern const bfd_target bfd_elf32_shlin_vec;
 extern const bfd_target bfd_elf32_shlnbsd_vec;
 extern const bfd_target bfd_elf32_shnbsd_vec;
 extern const bfd_target bfd_elf32_sparc_vec;
+extern const bfd_target bfd_elf32_sparc_vxworks_vec;
 extern const bfd_target bfd_elf32_tradbigmips_vec;
 extern const bfd_target bfd_elf32_tradlittlemips_vec;
 extern const bfd_target bfd_elf32_us_cris_vec;
@@ -948,6 +949,7 @@ static const bfd_target * const _bfd_target_vector[] = {
        &bfd_elf32_sh64blin_vec,
 #endif
        &bfd_elf32_sparc_vec,
+       &bfd_elf32_sparc_vxworks_vec,
        &bfd_elf32_tradbigmips_vec,
        &bfd_elf32_tradlittlemips_vec,
        &bfd_elf32_us_cris_vec,
index fadd3e0fe1c312bf2aa76215c85a5fde59b1f2bc..3f759e08a80f30e7e0a7dd8172dd9bfc55a59a93 100644 (file)
@@ -1,3 +1,13 @@
+2006-04-05  Richard Sandiford  <richard@codesourcery.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * config/tc-sparc.c (sparc_target_format): Handle TE_VXWORKS.
+       (GOTT_BASE, GOTT_INDEX): New.
+       (tc_gen_reloc): Don't alter relocations against GOTT_BASE and
+       GOTT_INDEX when generating VxWorks PIC.
+       * configure.tgt (sparc*-*-vxworks*): Remove this special case;
+       use the generic *-*-vxworks* stanza instead.
+
 2006-04-04  Alan Modra  <amodra@bigpond.net.au>
 
        PR 997
index 04bfb53638eafc1505dc9d818fe4473960221ae0..10a1411b5260f677576f78e3d5729bc8181f7ad3 100644 (file)
@@ -334,6 +334,10 @@ sparc_target_format ()
 #endif
 #endif
 
+#ifdef TE_VXWORKS
+  return "elf32-sparc-vxworks";
+#endif
+
 #ifdef OBJ_ELF
   return sparc_arch_size == 64 ? "elf64-sparc" : "elf32-sparc";
 #endif
@@ -3527,6 +3531,10 @@ tc_gen_reloc (section, fixp)
 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
 #else
 #define GOT_NAME "__GLOBAL_OFFSET_TABLE_"
+#endif
+#ifdef TE_VXWORKS
+#define GOTT_BASE "__GOTT_BASE__"
+#define GOTT_INDEX "__GOTT_INDEX__"
 #endif
 
   /* This code must be parallel to the OBJ_ELF tc_fix_adjustable.  */
@@ -3540,18 +3548,30 @@ tc_gen_reloc (section, fixp)
            code = BFD_RELOC_SPARC_WPLT30;
          break;
        case BFD_RELOC_HI22:
-         if (fixp->fx_addsy != NULL
-             && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
-           code = BFD_RELOC_SPARC_PC22;
-         else
-           code = BFD_RELOC_SPARC_GOT22;
+         code = BFD_RELOC_SPARC_GOT22;
+         if (fixp->fx_addsy != NULL)
+           {
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+               code = BFD_RELOC_SPARC_PC22;
+#ifdef TE_VXWORKS
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_BASE) == 0
+                 || strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_INDEX) == 0)
+               code = BFD_RELOC_HI22; /* Unchanged.  */
+#endif
+           }
          break;
        case BFD_RELOC_LO10:
-         if (fixp->fx_addsy != NULL
-             && strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
-           code = BFD_RELOC_SPARC_PC10;
-         else
-           code = BFD_RELOC_SPARC_GOT10;
+         code = BFD_RELOC_SPARC_GOT10;
+         if (fixp->fx_addsy != NULL)
+           {
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOT_NAME) == 0)
+               code = BFD_RELOC_SPARC_PC10;
+#ifdef TE_VXWORKS
+             if (strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_BASE) == 0
+                 || strcmp (S_GET_NAME (fixp->fx_addsy), GOTT_INDEX) == 0)
+               code = BFD_RELOC_LO10; /* Unchanged.  */
+#endif
+           }
          break;
        case BFD_RELOC_SPARC13:
          code = BFD_RELOC_SPARC_GOT13;
index 6463631c7390f2b64c64a11570dc8526f4f1af90..696daaa128fba7edd0a948ad360a4b107744d06c 100644 (file)
@@ -335,7 +335,7 @@ case ${generic_target} in
 
   sparc-*-rtems*)                      fmt=elf ;;
   sparc-*-sunos4*)                     fmt=aout em=sun3 ;;
-  sparc-*-aout | sparc*-*-vxworks*)    fmt=aout em=sparcaout ;;
+  sparc-*-aout)                                fmt=aout em=sparcaout ;;
   sparc-*-coff)                                fmt=coff ;;
   sparc-*-linux*aout*)                 fmt=aout em=linux ;;
   sparc-*-linux-*)                     fmt=elf em=linux ;;
index c4b021747b0c2c13f1b47f82b23b12d8e577c57e..28bbea8e0e6e2484031486f4e9953632c49396be 100644 (file)
@@ -1,3 +1,8 @@
+2006-04-05  Richard Sandiford  <richard@codesourcery.com>
+
+       * gas/sparc/vxworks-pic.s, gas/sparc/vxworks-pic.d: New test.
+       * gas/sparc/sparc.exp: Run it.  Remove sparc*-*-vxworks* XFAILs.
+
 2006-03-23  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gas/i386/rep.s: Pad with .p2align.
index 4189ddbff731c8a7188c7181360e75f70a2f73cc..a2e362dbba115f8eea8c0792eb5a416ae6d34d49 100644 (file)
@@ -17,7 +17,7 @@ proc gas_64_check { } {
 }
 
 proc sparc_elf_setup { } {
-    setup_xfail "sparc*-*-*aout*" "sparc*-*-sunos4*" "sparc*-*-vxworks*"
+    setup_xfail "sparc*-*-*aout*" "sparc*-*-sunos4*"
     setup_xfail "sparc*-fujitsu-none" "sparc*-*-*n*bsd*"
     setup_xfail "sparc*-*-coff" "sparc*-*-lynxos*"
     clear_xfail "sparc64*-*-*n*bsd*"
@@ -50,6 +50,10 @@ if [istarget sparc*-*-*] {
     }
 }
 
+if [istarget sparc-*-vxworks*] {
+    run_dump_test "vxworks-pic"
+}
+
 if [istarget sparclet*-*-*] {
     run_dump_test "splet"
     run_dump_test "splet-2"
diff --git a/gas/testsuite/gas/sparc/vxworks-pic.d b/gas/testsuite/gas/sparc/vxworks-pic.d
new file mode 100644 (file)
index 0000000..7e238fb
--- /dev/null
@@ -0,0 +1,27 @@
+#as: -KPIC
+#objdump: -dr
+#name: VxWorks PIC
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <\.text>:
+   0:  2f 00 00 00     sethi  %hi\(0\), %l7
+                       0: R_SPARC_HI22 __GOTT_BASE__
+   4:  ee 05 e0 00     ld  \[ %l7 \], %l7
+                       4: R_SPARC_LO10 __GOTT_BASE__
+   8:  ee 05 e0 00     ld  \[ %l7 \], %l7
+                       8: R_SPARC_LO10 __GOTT_INDEX__
+   c:  03 00 00 00     sethi  %hi\(0\), %g1
+                       c: R_SPARC_HI22 __GOTT_BASE__
+  10:  82 10 60 00     mov  %g1, %g1   ! 0x0
+                       10: R_SPARC_LO10        __GOTT_BASE__
+  14:  03 00 00 00     sethi  %hi\(0\), %g1
+                       14: R_SPARC_HI22        __GOTT_INDEX__
+  18:  82 10 60 00     mov  %g1, %g1   ! 0x0
+                       18: R_SPARC_LO10        __GOTT_INDEX__
+  1c:  03 00 00 00     sethi  %hi\(0\), %g1
+                       1c: R_SPARC_GOT22       __GOT_BASE__
+  20:  82 10 60 00     mov  %g1, %g1   ! 0x0
+                       20: R_SPARC_GOT10       __GOT_BASE__
diff --git a/gas/testsuite/gas/sparc/vxworks-pic.s b/gas/testsuite/gas/sparc/vxworks-pic.s
new file mode 100644 (file)
index 0000000..9d49e00
--- /dev/null
@@ -0,0 +1,11 @@
+       sethi   %hi(__GOTT_BASE__), %l7
+       ld      [%l7+%lo(__GOTT_BASE__)],%l7
+       ld      [%l7+%lo(__GOTT_INDEX__)],%l7
+
+       sethi   %hi(__GOTT_BASE__), %g1
+       or      %g1, %lo(__GOTT_BASE__), %g1
+       sethi   %hi(__GOTT_INDEX__), %g1
+       or      %g1, %lo(__GOTT_INDEX__), %g1
+
+       sethi   %hi(__GOT_BASE__), %g1
+       or      %g1, %lo(__GOT_BASE__), %g1
index 690298e41751e09fb444e07d5718a7f2b2490986..7ce60d92fa992b2f4c7351cc7e44a44e3178ed93 100644 (file)
@@ -1,3 +1,12 @@
+2006-04-05  Richard Sandiford  <richard@codesourcery.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * configure.tgt (sparc*-*-vxworks*): New stanza.
+       * emulparams/elf32_sparc_vxworks.sh: New file.
+       * Makefile.am (ALL_EMULATIONS): Add eelf32_sparc_vxworks.o.
+       (eelf32_sparc_vxworks.c): New rule.
+       * Makefile.in: Regenerate.
+
 2006-04-04  Eric Botcazou  <ebotcazou@adacore.com>
 
        * ldlang.c (lang_map): Print the list of discarded input sections.
index fea8955e2370a16003952ef7829ea9a623277429..758dc7e2d9e1075a251d6c19afa0747936cf72b9 100644 (file)
@@ -147,6 +147,7 @@ ALL_EMULATIONS = \
        eelf32_i960.o \
        eelf32_i860.o \
        eelf32_sparc.o \
+       eelf32_sparc_vxworks.o \
        eelf32b4300.o \
        eelf32bfin.o \
        eelf32bfinfd.o \
@@ -687,6 +688,11 @@ em32rlelf_linux.c: $(srcdir)/emulparams/m32rlelf_linux.sh \
 eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} elf32_sparc "$(tdir_elf32_sparc)"
+eelf32_sparc_vxworks.c: $(srcdir)/emulparams/elf32_sparc_vxworks.sh \
+  $(srcdir)/emulparams/vxworks.sh $(srcdir)/emulparams/elf32_sparc.sh \
+  $(srcdir)/emultempl/vxworks.em $(srcdir)/emultempl/elf32.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+       ${GENSCRIPTS} elf32_sparc_vxworks "$(tdir_elf32_sparc_vxworks)"
 eelf32_i860.c: $(srcdir)/emulparams/elf32_i860.sh \
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} elf32_i860 "$(tdir_elf32_i860)"
index c3716c0250249bb68458e1c6d1bcd431e4c4076b..4564a8bf6b7b08694279400241f992f3653b55f4 100644 (file)
@@ -370,6 +370,7 @@ ALL_EMULATIONS = \
        eelf32_i960.o \
        eelf32_i860.o \
        eelf32_sparc.o \
+       eelf32_sparc_vxworks.o \
        eelf32b4300.o \
        eelf32bfin.o \
        eelf32bfinfd.o \
@@ -1493,6 +1494,11 @@ em32rlelf_linux.c: $(srcdir)/emulparams/m32rlelf_linux.sh \
 eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} elf32_sparc "$(tdir_elf32_sparc)"
+eelf32_sparc_vxworks.c: $(srcdir)/emulparams/elf32_sparc_vxworks.sh \
+  $(srcdir)/emulparams/vxworks.sh $(srcdir)/emulparams/elf32_sparc.sh \
+  $(srcdir)/emultempl/vxworks.em $(srcdir)/emultempl/elf32.em \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+       ${GENSCRIPTS} elf32_sparc_vxworks "$(tdir_elf32_sparc_vxworks)"
 eelf32_i860.c: $(srcdir)/emulparams/elf32_i860.sh \
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} elf32_i860 "$(tdir_elf32_i860)"
index 8504c9b948896bbe1c068c4102bbb23f9c8527ef..d324e4ece25a09763b05479f0c8af72f4c6de224 100644 (file)
@@ -494,6 +494,7 @@ sparc*-*-aout)              targ_emul=sparcaout ;;
 sparc*-*-coff)         targ_emul=coff_sparc ;;
 sparc*-*-elf)          targ_emul=elf32_sparc ;;
 sparc*-*-sysv4*)       targ_emul=elf32_sparc ;;
+sparc*-*-vxworks*)     targ_emul=elf32_sparc_vxworks ;;
 sparc64-*-freebsd* | sparcv9-*-freebsd* | sparc64-*-kfreebsd*-gnu | sparcv9-*-kfreebsd*-gnu)
                        targ_emul=elf64_sparc_fbsd
                        targ_extra_emuls="elf64_sparc elf32_sparc"
diff --git a/ld/emulparams/elf32_sparc_vxworks.sh b/ld/emulparams/elf32_sparc_vxworks.sh
new file mode 100644 (file)
index 0000000..12a9b38
--- /dev/null
@@ -0,0 +1,4 @@
+. ${srcdir}/emulparams/elf32_sparc.sh
+OUTPUT_FORMAT="elf32-sparc-vxworks"
+unset DATA_PLT
+. ${srcdir}/emulparams/vxworks.sh
index 78935751f3990ec2d9db303f6d8a0a5870f645f4..b851e597b6756ce0798cd7f50287b8521df9cbc4 100644 (file)
@@ -1,3 +1,12 @@
+2006-04-05  Richard Sandiford  <richard@codesourcery.com>
+
+       * ld-sparc/vxworks1.dd, ld-sparc/vxworks1.ld, ld-sparc/vxworks1-lib.dd,
+       * ld-sparc/vxworks1-lib.nd, ld-sparc/vxworks1-lib.rd,
+       * ld-sparc/vxworks1-lib.s, ld-sparc/vxworks1.rd, ld-sparc/vxworks1.s,
+       * ld-sparc/vxworks1-static.d, ld-sparc/vxworks2.s,
+       * ld-sparc/vxworks2.sd, ld-sparc/vxworks2-static.sd: New tests.
+       * ld-sparc/sparc.exp: Run them.
+
 2006-04-05  Ben Elliston  <bje@au.ibm.com>
 
        * lib/ld-lib.exp: Comment cleanups.
index aa4c869a198d16b6d6f1f8c9316a3d9c7d52028f..6e7e95cc563e470df2a21936670a9ec51c0b8a43 100644 (file)
 # Test SPARC linking; all types of relocs.  This tests the assembler and
 # tools like objdump as well as the linker.
 
+if {[istarget "sparc-*-vxworks"]} {
+    set sparcvxworkstests {
+       {"VxWorks shared library test 1" "-shared -Tvxworks1.ld"
+        "-KPIC" {vxworks1-lib.s}
+        {{readelf --relocs vxworks1-lib.rd} {objdump -dr vxworks1-lib.dd}
+         {readelf --symbols vxworks1-lib.nd}}
+        "libvxworks1.so"}
+       {"VxWorks executable test 1 (dynamic)" \
+        "tmpdir/libvxworks1.so -Tvxworks1.ld -q --force-dynamic"
+        "" {vxworks1.s}
+        {{readelf --relocs vxworks1.rd} {objdump -dr vxworks1.dd}}
+        "vxworks1"}
+       {"VxWorks executable test 2 (dynamic)" \
+        "-Tvxworks1.ld -q --force-dynamic"
+        "" {vxworks2.s}
+        {{readelf --segments vxworks2.sd}}
+        "vxworks2"}
+       {"VxWorks executable test 2 (static)"
+        "-Tvxworks1.ld"
+        "" {vxworks2.s}
+        {{readelf --segments vxworks2-static.sd}}
+        "vxworks2"}
+    }
+    run_ld_link_tests $sparcvxworkstests
+    run_dump_test "vxworks1-static"
+}
+
 if { !([istarget "sparc*-*-elf*"]
        || [istarget "sparc*-sun-solaris*"]
        || ([istarget "sparc*-*-linux*"]
diff --git a/ld/testsuite/ld-sparc/vxworks1-lib.dd b/ld/testsuite/ld-sparc/vxworks1-lib.dd
new file mode 100644 (file)
index 0000000..49dab7b
--- /dev/null
@@ -0,0 +1,45 @@
+
+.*:     file format .*
+
+Disassembly of section \.plt:
+
+00080800 <_PROCEDURE_LINKAGE_TABLE_>:
+   80800:      c4 05 e0 08     ld  \[ %l7 \+ 8 \], %g2
+   80804:      81 c0 80 00     jmp  %g2
+   80808:      01 00 00 00     nop 
+   8080c:      03 00 00 00     sethi  %hi\(0\), %g1
+   80810:      82 10 60 0c     or  %g1, 0xc, %g1       ! c <_PROCEDURE_LINKAGE_TABLE_-0x807f4>
+   80814:      c2 05 c0 01     ld  \[ %l7 \+ %g1 \], %g1
+   80818:      81 c0 40 00     jmp  %g1
+   8081c:      01 00 00 00     nop 
+   80820:      03 00 00 00     sethi  %hi\(0\), %g1
+   80824:      10 bf ff f7     b  80800 <_PROCEDURE_LINKAGE_TABLE_>
+   80828:      82 10 60 00     mov  %g1, %g1   ! 0 <_PROCEDURE_LINKAGE_TABLE_-0x80800>
+Disassembly of section \.text:
+
+00080c00 <foo>:
+   80c00:      9d e3 bf 98     save  %sp, -104, %sp
+   80c04:      2f 00 00 00     sethi  %hi\(0\), %l7
+   80c08:      ee 05 e0 00     ld  \[ %l7 \], %l7
+   80c0c:      ee 05 e0 00     ld  \[ %l7 \], %l7
+   80c10:      03 00 00 00     sethi  %hi\(0\), %g1
+   80c14:      82 10 60 10     or  %g1, 0x10, %g1      ! 10 <_PROCEDURE_LINKAGE_TABLE_-0x807f0>
+   80c18:      c2 05 c0 01     ld  \[ %l7 \+ %g1 \], %g1
+   80c1c:      c4 00 40 00     ld  \[ %g1 \], %g2
+   80c20:      84 00 a0 01     inc  %g2
+   80c24:      40 00 00 08     call  80c44 <slocal>
+   80c28:      c4 20 40 00     st  %g2, \[ %g1 \]
+   80c2c:      7f ff fe f8     call  8080c <_PROCEDURE_LINKAGE_TABLE_\+0xc>
+   80c30:      01 00 00 00     nop 
+   80c34:      7f ff fe f6     call  8080c <_PROCEDURE_LINKAGE_TABLE_\+0xc>
+   80c38:      01 00 00 00     nop 
+   80c3c:      81 c7 e0 08     ret 
+   80c40:      81 e8 00 00     restore 
+
+00080c44 <slocal>:
+   80c44:      81 c3 e0 08     retl 
+   80c48:      01 00 00 00     nop 
+
+00080c4c <sglobal>:
+   80c4c:      81 c3 e0 08     retl 
+   80c50:      01 00 00 00     nop 
diff --git a/ld/testsuite/ld-sparc/vxworks1-lib.nd b/ld/testsuite/ld-sparc/vxworks1-lib.nd
new file mode 100644 (file)
index 0000000..cbc1c8c
--- /dev/null
@@ -0,0 +1,9 @@
+#...
+Symbol table '\.dynsym' .*:
+#...
+.*: 00090400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#...
+Symbol table '\.symtab' .*:
+#...
+.*: 00090400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#pass
diff --git a/ld/testsuite/ld-sparc/vxworks1-lib.rd b/ld/testsuite/ld-sparc/vxworks1-lib.rd
new file mode 100644 (file)
index 0000000..1390e78
--- /dev/null
@@ -0,0 +1,12 @@
+
+Relocation section '\.rela\.plt' at offset .* contains 1 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+0009040c  .*15 R_SPARC_JMP_SLOT  00000000   sexternal \+ 0
+
+Relocation section '\.rela\.dyn' at offset .* contains 5 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+00090c00  00000016 R_SPARC_RELATIVE                             00080c44
+00080c04  .*09 R_SPARC_HI22      00000000   __GOTT_BASE__ \+ 0
+00080c08  .*0c R_SPARC_LO10      00000000   __GOTT_BASE__ \+ 0
+00080c0c  .*0c R_SPARC_LO10      00000000   __GOTT_INDEX__ \+ 0
+00090410  .*14 R_SPARC_GLOB_DAT  00090800   x \+ 0
diff --git a/ld/testsuite/ld-sparc/vxworks1-lib.s b/ld/testsuite/ld-sparc/vxworks1-lib.s
new file mode 100644 (file)
index 0000000..e1221a2
--- /dev/null
@@ -0,0 +1,44 @@
+       .text
+       .globl  foo
+       .type   foo, %function
+foo:
+       save    %sp, -104, %sp
+       sethi   %hi(__GOTT_BASE__), %l7
+       ld      [%l7+%lo(__GOTT_BASE__)],%l7
+       ld      [%l7+%lo(__GOTT_INDEX__)],%l7
+       sethi   %hi(x), %g1
+       or      %g1, %lo(x), %g1
+       ld      [%l7+%g1], %g1
+       ld      [%g1], %g2
+       add     %g2, 1, %g2
+
+       call    slocal, 0
+       st      %g2, [%g1]
+
+       call    sexternal, 0
+       nop
+
+       call    sexternal, 0
+       nop
+
+       ret
+       restore
+       .size   foo, .-foo
+
+       .type   slocal, %function
+slocal:
+       retl
+       nop
+       .size   slocal, .-slocal
+
+       .globl  sglobal
+       .type   sglobal, %function
+sglobal:
+       retl
+       nop
+       .size   sglobal, .-sglobal
+
+       .data
+       .4byte  slocal
+
+       .comm   x,4,4
diff --git a/ld/testsuite/ld-sparc/vxworks1-static.d b/ld/testsuite/ld-sparc/vxworks1-static.d
new file mode 100644 (file)
index 0000000..88c0baf
--- /dev/null
@@ -0,0 +1,4 @@
+#name: VxWorks executable test 1 (static)
+#source: vxworks1.s
+#ld: tmpdir/libvxworks1.so -Tvxworks1.ld
+#error: Dynamic sections created in non-dynamic link
diff --git a/ld/testsuite/ld-sparc/vxworks1.dd b/ld/testsuite/ld-sparc/vxworks1.dd
new file mode 100644 (file)
index 0000000..16e72fd
--- /dev/null
@@ -0,0 +1,52 @@
+
+.*:     file format .*
+
+Disassembly of section \.plt:
+
+00080800 <_PROCEDURE_LINKAGE_TABLE_>:
+   80800:      05 00 02 41     sethi  %hi\(0x90400\), %g2
+                       80800: R_SPARC_HI22     _GLOBAL_OFFSET_TABLE_\+0x8
+   80804:      84 10 a0 08     or  %g2, 8, %g2 ! 90408 <_GLOBAL_OFFSET_TABLE_\+0x8>
+                       80804: R_SPARC_LO10     _GLOBAL_OFFSET_TABLE_\+0x8
+   80808:      c4 00 80 00     ld  \[ %g2 \], %g2
+   8080c:      81 c0 80 00     jmp  %g2
+   80810:      01 00 00 00     nop 
+   80814:      03 00 02 41     sethi  %hi\(0x90400\), %g1
+                       80814: R_SPARC_HI22     _GLOBAL_OFFSET_TABLE_\+0xc
+   80818:      82 10 60 0c     or  %g1, 0xc, %g1       ! 9040c <sglobal@plt>
+                       80818: R_SPARC_LO10     _GLOBAL_OFFSET_TABLE_\+0xc
+   8081c:      c2 00 40 00     ld  \[ %g1 \], %g1
+   80820:      81 c0 40 00     jmp  %g1
+   80824:      01 00 00 00     nop 
+   80828:      03 00 00 00     sethi  %hi\(0\), %g1
+   8082c:      10 bf ff f5     b  80800 <_PROCEDURE_LINKAGE_TABLE_>
+   80830:      82 10 60 00     mov  %g1, %g1   ! 0 <_PROCEDURE_LINKAGE_TABLE_-0x80800>
+   80834:      03 00 02 41     sethi  %hi\(0x90400\), %g1
+                       80834: R_SPARC_HI22     _GLOBAL_OFFSET_TABLE_\+0x10
+   80838:      82 10 60 10     or  %g1, 0x10, %g1      ! 90410 <foo@plt>
+                       80838: R_SPARC_LO10     _GLOBAL_OFFSET_TABLE_\+0x10
+   8083c:      c2 00 40 00     ld  \[ %g1 \], %g1
+   80840:      81 c0 40 00     jmp  %g1
+   80844:      01 00 00 00     nop 
+   80848:      03 00 00 00     sethi  %hi\(0\), %g1
+   8084c:      10 bf ff ed     b  80800 <_PROCEDURE_LINKAGE_TABLE_>
+   80850:      82 10 60 01     or  %g1, 1, %g1 ! 1 <_PROCEDURE_LINKAGE_TABLE_-0x807ff>
+Disassembly of section \.text:
+
+00080c00 <_start>:
+   80c00:      9d e3 bf 98     save  %sp, -104, %sp
+   80c04:      7f ff ff 0c     call  80834 <_PROCEDURE_LINKAGE_TABLE_\+0x34>
+                       80c04: R_SPARC_WDISP30  \.plt\+0x34
+   80c08:      01 00 00 00     nop 
+   80c0c:      40 00 00 06     call  80c24 <sexternal>
+                       80c0c: R_SPARC_WDISP30  sexternal
+   80c10:      01 00 00 00     nop 
+   80c14:      7f ff ff 00     call  80814 <_PROCEDURE_LINKAGE_TABLE_\+0x14>
+                       80c14: R_SPARC_WDISP30  \.plt\+0x14
+   80c18:      01 00 00 00     nop 
+   80c1c:      81 c7 e0 08     ret 
+   80c20:      81 e8 00 00     restore 
+
+00080c24 <sexternal>:
+   80c24:      81 c3 e0 08     retl 
+   80c28:      01 00 00 00     nop 
diff --git a/ld/testsuite/ld-sparc/vxworks1.ld b/ld/testsuite/ld-sparc/vxworks1.ld
new file mode 100644 (file)
index 0000000..979d773
--- /dev/null
@@ -0,0 +1,30 @@
+SECTIONS
+{
+  . = 0x80000;
+  .interp : { *(.interp) }
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+
+  . = ALIGN (0x400);
+  .rela.dyn : { *(.rela.dyn) }
+  .rela.plt : { *(.rela.plt) }
+
+  . = ALIGN (0x400);
+  .plt : { *(.plt) }
+
+  . = ALIGN (0x400);
+  .text : { *(.text) }
+
+  . = ALIGN (0x10000);
+  .dynamic : { *(.dynamic) }
+
+  . = ALIGN (0x400);
+  .got : { *(.got.plt) *(.got) }
+
+  . = ALIGN (0x400);
+  .bss : { *(.bss) }
+
+  . = ALIGN (0x400);
+  .data : { *(.data) }
+}
diff --git a/ld/testsuite/ld-sparc/vxworks1.rd b/ld/testsuite/ld-sparc/vxworks1.rd
new file mode 100644 (file)
index 0000000..e02146b
--- /dev/null
@@ -0,0 +1,22 @@
+
+Relocation section '\.rela\.plt' at offset .* contains 2 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+0009040c  .*15 R_SPARC_JMP_SLOT  00080814   sglobal \+ 0
+00090410  .*15 R_SPARC_JMP_SLOT  00080834   foo \+ 0
+
+Relocation section '\.rela\.text' at offset .* contains 3 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+00080c04  .*07 R_SPARC_WDISP30   00080800   \.plt \+ 34
+00080c0c  .*07 R_SPARC_WDISP30   00080c24   sexternal \+ 0
+00080c14  .*07 R_SPARC_WDISP30   00080800   \.plt \+ 14
+
+Relocation section '\.rela\.plt\.unloaded' at offset .* contains 8 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+00080800  .*09 R_SPARC_HI22      00090400   _GLOBAL_OFFSET_TABLE_ \+ 8
+00080804  .*0c R_SPARC_LO10      00090400   _GLOBAL_OFFSET_TABLE_ \+ 8
+00080814  .*09 R_SPARC_HI22      00090400   _GLOBAL_OFFSET_TABLE_ \+ c
+00080818  .*0c R_SPARC_LO10      00090400   _GLOBAL_OFFSET_TABLE_ \+ c
+0009040c  .*03 R_SPARC_32        00080800   _PROCEDURE_LINKAGE_TAB.* \+ 28
+00080834  .*09 R_SPARC_HI22      00090400   _GLOBAL_OFFSET_TABLE_ \+ 10
+00080838  .*0c R_SPARC_LO10      00090400   _GLOBAL_OFFSET_TABLE_ \+ 10
+00090410  .*03 R_SPARC_32        00080800   _PROCEDURE_LINKAGE_TAB.* \+ 48
diff --git a/ld/testsuite/ld-sparc/vxworks1.s b/ld/testsuite/ld-sparc/vxworks1.s
new file mode 100644 (file)
index 0000000..82106c8
--- /dev/null
@@ -0,0 +1,25 @@
+       .text
+       .globl  _start
+       .type   _start, %function
+_start:
+       save    %sp, -104, %sp
+
+       call    foo, 0
+       nop
+
+       call    sexternal, 0
+       nop
+
+       call    sglobal, 0
+       nop
+
+       ret
+       restore
+       .size   _start, .-_start
+
+       .globl  sexternal
+       .type   sexternal, %function
+sexternal:
+       retl
+       nop
+       .size   sexternal, .-sexternal
diff --git a/ld/testsuite/ld-sparc/vxworks2-static.sd b/ld/testsuite/ld-sparc/vxworks2-static.sd
new file mode 100644 (file)
index 0000000..55fc529
--- /dev/null
@@ -0,0 +1,9 @@
+#...
+Elf file type is EXEC \(Executable file\)
+Entry point 0x80000
+#...
+Program Headers:
+  Type .*
+  LOAD .* 0x00080000 0x00080000 .* R E 0x10000
+
+#...
diff --git a/ld/testsuite/ld-sparc/vxworks2.s b/ld/testsuite/ld-sparc/vxworks2.s
new file mode 100644 (file)
index 0000000..0a883a9
--- /dev/null
@@ -0,0 +1,6 @@
+       .globl  _start
+       .type   _start, %function
+_start:
+       retl
+       nop
+       .end    _start
diff --git a/ld/testsuite/ld-sparc/vxworks2.sd b/ld/testsuite/ld-sparc/vxworks2.sd
new file mode 100644 (file)
index 0000000..0876568
--- /dev/null
@@ -0,0 +1,13 @@
+#...
+Elf file type is EXEC \(Executable file\)
+Entry point 0x80400
+#...
+Program Headers:
+  Type .*
+  PHDR .*
+#...
+  LOAD .* 0x00080000 0x00080000 .* R E 0x10000
+  LOAD .* 0x00090000 0x00090000 .* RW  0x10000
+  DYNAMIC .*
+
+#...