sparc-vxworks support

Richard Sandiford richard@codesourcery.com
Tue Mar 7 10:18:00 GMT 2006


This patch adds support for sparc-vxworks.  The main changes
(all conditional on VxWorks) are:

  - Using the elf-vxworks bfd hooks.
  - Handling the VxWorks PLT layout.
  - Allowing R_SPARC_HI22 and R_SPARC_LO10 relocations against
    __GOTT_BASE__ and __GOTT_INDEX__.

The main one is the PLT layout, which is very different from the other
SPARC ABIs.  In fact, it's so different that it doesn't really fit the
build_plt_entry callback mechanism used in elfxx-sparc.c: as well as the
PLT entry itself, we need a .got.plt entry, and (for executables) a
bunch of .rela.plt.unloaded relocations.  Also, the .rela.plt relocation
refers to the .got.plt entry, not to the .plt itself.  I've therefore
bypassed the build_plt_entry stuff and handled VxWorks directly in
finish_dynamic_symbol.

Also, there are now 4 possible sizes of PLT header and 3 possible
sizes of PLT entry, so I've added link_hash_table fields for them.
The VxWorks choice depends on whether we're generating a shared
object or not, so the fields are initialised in create_dynamic_sections
(the place where we initialise splt).  For consistency, I moved the
build_plt_entry initialisation there too; the hook isn't needed
before then.

Tested on sparc-vxworks, sparc-linux-gnu, sparc64-linux-gnu and
sparc-sun-solaris2.6 (a 32-bit-only target).  OK to install?

Richard


2006-03-07  Richard Sandiford  <richard@codesourcery.com>
	    Daniel Jacobowitz  <dan@codesourcery.com>

bfd/
	* 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.

diff -cprN ../binutils.fsf.1/bfd/config.bfd ./bfd/config.bfd
*** ../binutils.fsf.1/bfd/config.bfd	2006-03-06 08:56:21.000000000 -0800
--- ./bfd/config.bfd	2006-03-07 01:02:05.000000000 -0800
*************** case "${targ}" in
*** 1273,1278 ****
--- 1273,1282 ----
    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"
diff -cprN ../binutils.fsf.1/bfd/configure ./bfd/configure
*** ../binutils.fsf.1/bfd/configure	2006-03-06 08:59:23.000000000 -0800
--- ./bfd/configure	2006-03-06 06:12:47.000000000 -0800
*************** do
*** 13154,13160 ****
      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_tradbigmips_vec)  tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_tradlittlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_us_cris_vec)	tb="$tb elf32-cris.lo elf32.lo $elf" ;;
--- 13154,13161 ----
      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 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 elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_tradlittlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_us_cris_vec)	tb="$tb elf32-cris.lo elf32.lo $elf" ;;
*************** do
*** 13185,13191 ****
      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_tradbigmips_vec)	tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
      bfd_elf64_tradlittlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.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 ;;
--- 13186,13192 ----
      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 elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
      bfd_elf64_tradbigmips_vec)	tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
      bfd_elf64_tradlittlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.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 ;;
diff -cprN ../binutils.fsf.1/bfd/configure.in ./bfd/configure.in
*** ../binutils.fsf.1/bfd/configure.in	2006-03-06 08:59:23.000000000 -0800
--- ./bfd/configure.in	2006-03-06 06:12:40.000000000 -0800
*************** do
*** 667,673 ****
      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_tradbigmips_vec)  tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_tradlittlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_us_cris_vec)	tb="$tb elf32-cris.lo elf32.lo $elf" ;;
--- 667,674 ----
      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 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 elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_tradlittlemips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
      bfd_elf32_us_cris_vec)	tb="$tb elf32-cris.lo elf32.lo $elf" ;;
*************** do
*** 698,704 ****
      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_tradbigmips_vec)	tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
      bfd_elf64_tradlittlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.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 ;;
--- 699,705 ----
      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 elf-vxworks.lo elf64.lo $elf"; target_size=64 ;;
      bfd_elf64_tradbigmips_vec)	tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
      bfd_elf64_tradlittlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.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 ;;
diff -cprN ../binutils.fsf.1/bfd/elf32-sparc.c ./bfd/elf32-sparc.c
*** ../binutils.fsf.1/bfd/elf32-sparc.c	2006-03-06 08:56:21.000000000 -0800
--- ./bfd/elf32-sparc.c	2006-03-06 23:51:12.000000000 -0800
***************
*** 26,31 ****
--- 26,32 ----
  #include "elf/sparc.h"
  #include "opcode/sparc.h"
  #include "elfxx-sparc.h"
+ #include "elf-vxworks.h"
  
  /* Support for core dump NOTE sections.  */
  
*************** elf32_sparc_reloc_type_class (const Elf_
*** 215,217 ****
--- 216,283 ----
  #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"
diff -cprN ../binutils.fsf.1/bfd/elfxx-sparc.c ./bfd/elfxx-sparc.c
*** ../binutils.fsf.1/bfd/elfxx-sparc.c	2006-03-06 08:56:21.000000000 -0800
--- ./bfd/elfxx-sparc.c	2006-03-07 01:57:08.000000000 -0800
***************
*** 23,32 ****
--- 23,34 ----
  #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)
*************** sparc64_plt_entry_build (bfd *output_bfd
*** 697,702 ****
--- 699,748 ----
    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)
  
*************** _bfd_sparc_elf_link_hash_table_create (b
*** 781,787 ****
        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;
--- 827,832 ----
*************** _bfd_sparc_elf_link_hash_table_create (b
*** 798,804 ****
        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;
--- 843,848 ----
*************** create_got_section (bfd *dynobj, struct 
*** 845,850 ****
--- 889,902 ----
        || ! 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;
  }
  
*************** _bfd_sparc_elf_create_dynamic_sections (
*** 871,876 ****
--- 923,963 ----
    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 ();
*************** allocate_dynrelocs (struct elf_link_hash
*** 1806,1815 ****
  	{
  	  asection *s = htab->splt;
  
! 	  /* The first four entries in .plt is reserved.  */
  	  if (s->size == 0)
! 	    s->size = (SPARC_ELF_WORD_BYTES(htab) == 8 ?
! 		       PLT64_HEADER_SIZE : PLT32_HEADER_SIZE);
  
  	  /* The procedure linkage table size is bounded by the magnitude
  	     of the offset we can describe in the entry.  */
--- 1893,1907 ----
  	{
  	  asection *s = htab->splt;
  
! 	  /* Allocate room for the header.  */
  	  if (s->size == 0)
! 	    {
! 	      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.  */
*************** allocate_dynrelocs (struct elf_link_hash
*** 1846,1856 ****
  	    }
  
  	  /* Make room for this entry.  */
! 	  s->size += (SPARC_ELF_WORD_BYTES(htab) == 8 ?
! 		      PLT64_ENTRY_SIZE : PLT32_ENTRY_SIZE);
  
  	  /* We also need to make an entry in the .rela.plt section.  */
  	  htab->srelplt->size += SPARC_ELF_RELA_BYTES (htab);
  	}
        else
  	{
--- 1938,1957 ----
  	    }
  
  	  /* Make room for this entry.  */
! 	  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
  	{
*************** _bfd_sparc_elf_size_dynamic_sections (bf
*** 2152,2157 ****
--- 2253,2259 ----
    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.  */
*************** _bfd_sparc_elf_size_dynamic_sections (bf
*** 2178,2184 ****
  
        if (s == htab->splt
  	  || s == htab->sgot
! 	  || s == htab->sdynbss)
  	{
  	  /* Strip this section if we don't need it; see the
  	     comment below.  */
--- 2280,2287 ----
  
        if (s == htab->splt
  	  || s == htab->sgot
! 	  || s == htab->sdynbss
! 	  || s == htab->sgotplt)
  	{
  	  /* Strip this section if we don't need it; see the
  	     comment below.  */
*************** _bfd_sparc_elf_relocate_section (bfd *ou
*** 3427,3432 ****
--- 3530,3626 ----
    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.  */
  
*************** _bfd_sparc_elf_finish_dynamic_symbol (bf
*** 3448,3454 ****
        asection *srela;
        Elf_Internal_Rela rela;
        bfd_byte *loc;
!       bfd_vma r_offset;
        int rela_index;
  
        /* This symbol has an entry in the PLT.  Set it up.  */
--- 3642,3648 ----
        asection *srela;
        Elf_Internal_Rela rela;
        bfd_byte *loc;
!       bfd_vma r_offset, got_offset;
        int rela_index;
  
        /* This symbol has an entry in the PLT.  Set it up.  */
*************** _bfd_sparc_elf_finish_dynamic_symbol (bf
*** 3459,3481 ****
        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))
  	{
  	  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);
  
--- 3653,3700 ----
        srela = htab->srelplt;
        BFD_ASSERT (splt != NULL && srela != NULL);
  
        /* Fill in the entry in the .rela.plt section.  */
!       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
  	{
! 	  /* 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);
  
*************** _bfd_sparc_elf_finish_dynamic_symbol (bf
*** 3576,3585 ****
        SPARC_ELF_APPEND_RELA (htab, output_bfd, s, &rela);
      }
  
!   /* Mark some specially defined symbols as absolute.  */
    if (strcmp (h->root.root.string, "_DYNAMIC") == 0
!       || h == htab->elf.hgot
!       || h == htab->elf.hplt)
      sym->st_shndx = SHN_ABS;
  
    return TRUE;
--- 3795,3806 ----
        SPARC_ELF_APPEND_RELA (htab, output_bfd, s, &rela);
      }
  
!   /* 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
!       || (!htab->is_vxworks
! 	  && (h == htab->elf.hgot || h == htab->elf.hplt)))
      sym->st_shndx = SHN_ABS;
  
    return TRUE;
*************** sparc64_finish_dyn (bfd *output_bfd, str
*** 3647,3659 ****
  #endif
  
  static bfd_boolean
! sparc32_finish_dyn (bfd *output_bfd,
! 		    struct bfd_link_info *info ATTRIBUTE_UNUSED,
  		    bfd *dynobj, asection *sdyn,
  		    asection *splt ATTRIBUTE_UNUSED)
  {
    Elf32_External_Dyn *dyncon, *dynconend;
  
    dyncon = (Elf32_External_Dyn *) sdyn->contents;
    dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
    for (; dyncon < dynconend; dyncon++)
--- 3868,3881 ----
  #endif
  
  static bfd_boolean
! 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++)
*************** sparc32_finish_dyn (bfd *output_bfd,
*** 3664,3697 ****
  
        bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
  
!       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;
  	}
! 
!       if (name != NULL)
  	{
! 	  asection *s;
  
! 	  s = bfd_get_section_by_name (output_bfd, name);
! 	  if (s == NULL)
! 	    dyn.d_un.d_val = 0;
! 	  else
  	    {
! 	      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);
  	}
      }
    return TRUE;
  }
  
  bfd_boolean
  _bfd_sparc_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
  {
--- 3886,4035 ----
  
        bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
  
!       if (htab->is_vxworks && dyn.d_tag == DT_RELASZ)
  	{
! 	  /* 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);
! 	    }
  	}
!       else if (htab->is_vxworks && dyn.d_tag == DT_PLTGOT)
  	{
! 	  /* 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;
! 	    }
  
! 	  if (name != NULL)
  	    {
! 	      asection *s;
! 
! 	      s = bfd_get_section_by_name (output_bfd, name);
! 	      if (s == NULL)
! 		dyn.d_un.d_val = 0;
  	      else
! 		{
! 		  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);
  	    }
  	}
      }
    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)
  {
*************** _bfd_sparc_elf_finish_dynamic_sections (
*** 3725,3742 ****
        /* 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);
  	  else
  	    {
! 	      memset (splt->contents, 0, 4 * PLT32_ENTRY_SIZE);
! 	      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);
      }
  
    /* Set the first entry in the global offset table to the address of
--- 4063,4086 ----
        /* Initialize the contents of the .plt section.  */
        if (splt->size > 0)
  	{
! 	  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, 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
! 	= htab->plt_entry_size;
      }
  
    /* Set the first entry in the global offset table to the address of
diff -cprN ../binutils.fsf.1/bfd/elfxx-sparc.h ./bfd/elfxx-sparc.h
*** ../binutils.fsf.1/bfd/elfxx-sparc.h	2006-03-06 08:56:21.000000000 -0800
--- ./bfd/elfxx-sparc.h	2006-03-07 00:54:34.000000000 -0800
*************** struct _bfd_sparc_elf_link_hash_table
*** 61,66 ****
--- 61,75 ----
    /* 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);
*************** struct _bfd_sparc_elf_link_hash_table
*** 70,75 ****
--- 79,86 ----
    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;
diff -cprN ../binutils.fsf.1/bfd/Makefile.am ./bfd/Makefile.am
*** ../binutils.fsf.1/bfd/Makefile.am	2006-03-06 08:59:24.000000000 -0800
--- ./bfd/Makefile.am	2006-03-06 06:35:04.000000000 -0800
*************** elfxx-sparc.lo: elfxx-sparc.c $(INCDIR)/
*** 1413,1424 ****
    $(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-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
  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 \
--- 1413,1424 ----
    $(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 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 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 \
diff -cprN ../binutils.fsf.1/bfd/Makefile.in ./bfd/Makefile.in
*** ../binutils.fsf.1/bfd/Makefile.in	2006-03-06 08:59:24.000000000 -0800
--- ./bfd/Makefile.in	2006-03-06 06:35:12.000000000 -0800
*************** elfxx-sparc.lo: elfxx-sparc.c $(INCDIR)/
*** 1980,1991 ****
    $(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-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
  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 \
--- 1980,1991 ----
    $(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 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 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 \
diff -cprN ../binutils.fsf.1/bfd/targets.c ./bfd/targets.c
*** ../binutils.fsf.1/bfd/targets.c	2006-03-06 08:56:21.000000000 -0800
--- ./bfd/targets.c	2006-03-06 02:14:24.000000000 -0800
*************** extern const bfd_target bfd_elf32_shlin_
*** 631,636 ****
--- 631,637 ----
  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;
*************** static const bfd_target * const _bfd_tar
*** 942,947 ****
--- 943,949 ----
  	&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,
diff -cprN ../binutils.fsf.1/gas/config/tc-sparc.c ./gas/config/tc-sparc.c
*** ../binutils.fsf.1/gas/config/tc-sparc.c	2006-03-06 08:56:21.000000000 -0800
--- ./gas/config/tc-sparc.c	2006-03-07 01:41:04.000000000 -0800
*************** sparc_target_format ()
*** 334,339 ****
--- 334,343 ----
  #endif
  #endif
  
+ #ifdef TE_VXWORKS
+   return "elf32-sparc-vxworks";
+ #endif
+ 
  #ifdef OBJ_ELF
    return sparc_arch_size == 64 ? "elf64-sparc" : "elf32-sparc";
  #endif
*************** tc_gen_reloc (section, fixp)
*** 3528,3533 ****
--- 3532,3541 ----
  #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.  */
  
*************** tc_gen_reloc (section, fixp)
*** 3540,3557 ****
  	    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;
  	  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;
  	  break;
  	case BFD_RELOC_SPARC13:
  	  code = BFD_RELOC_SPARC_GOT13;
--- 3548,3577 ----
  	    code = BFD_RELOC_SPARC_WPLT30;
  	  break;
  	case BFD_RELOC_HI22:
! 	  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:
! 	  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;
diff -cprN ../binutils.fsf.1/gas/configure.tgt ./gas/configure.tgt
*** ../binutils.fsf.1/gas/configure.tgt	2006-03-06 08:56:21.000000000 -0800
--- ./gas/configure.tgt	2006-03-06 09:33:45.000000000 -0800
*************** case ${generic_target} in
*** 335,341 ****
  
    sparc-*-rtems*)			fmt=elf ;;
    sparc-*-sunos4*)			fmt=aout em=sun3 ;;
!   sparc-*-aout | sparc*-*-vxworks*)	fmt=aout em=sparcaout ;;
    sparc-*-coff)				fmt=coff ;;
    sparc-*-linux*aout*)			fmt=aout em=linux ;;
    sparc-*-linux-*)			fmt=elf em=linux ;;
--- 335,341 ----
  
    sparc-*-rtems*)			fmt=elf ;;
    sparc-*-sunos4*)			fmt=aout em=sun3 ;;
!   sparc-*-aout)				fmt=aout em=sparcaout ;;
    sparc-*-coff)				fmt=coff ;;
    sparc-*-linux*aout*)			fmt=aout em=linux ;;
    sparc-*-linux-*)			fmt=elf em=linux ;;
diff -cprN ../binutils.fsf.1/gas/testsuite/gas/sparc/sparc.exp ./gas/testsuite/gas/sparc/sparc.exp
*** ../binutils.fsf.1/gas/testsuite/gas/sparc/sparc.exp	2006-02-27 02:38:05.000000000 -0800
--- ./gas/testsuite/gas/sparc/sparc.exp	2006-03-07 01:09:44.000000000 -0800
*************** proc gas_64_check { } {
*** 17,23 ****
  }
  
  proc sparc_elf_setup { } {
!     setup_xfail "sparc*-*-*aout*" "sparc*-*-sunos4*" "sparc*-*-vxworks*"
      setup_xfail "sparc*-fujitsu-none" "sparc*-*-*n*bsd*"
      setup_xfail "sparc*-*-coff" "sparc*-*-lynxos*"
      clear_xfail "sparc64*-*-*n*bsd*"
--- 17,23 ----
  }
  
  proc sparc_elf_setup { } {
!     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*"
*************** if [istarget sparc*-*-*] {
*** 50,55 ****
--- 50,59 ----
      }
  }
  
+ if [istarget sparc-*-vxworks*] {
+     run_dump_test "vxworks-pic"
+ }
+ 
  if [istarget sparclet*-*-*] {
      run_dump_test "splet"
      run_dump_test "splet-2"
diff -cprN ../binutils.fsf.1/gas/testsuite/gas/sparc/vxworks-pic.d ./gas/testsuite/gas/sparc/vxworks-pic.d
*** ../binutils.fsf.1/gas/testsuite/gas/sparc/vxworks-pic.d	1969-12-31 16:00:00.000000000 -0800
--- ./gas/testsuite/gas/sparc/vxworks-pic.d	2006-03-07 01:09:06.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/gas/testsuite/gas/sparc/vxworks-pic.s ./gas/testsuite/gas/sparc/vxworks-pic.s
*** ../binutils.fsf.1/gas/testsuite/gas/sparc/vxworks-pic.s	1969-12-31 16:00:00.000000000 -0800
--- ./gas/testsuite/gas/sparc/vxworks-pic.s	2006-03-07 01:07:25.000000000 -0800
***************
*** 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
diff -cprN ../binutils.fsf.1/ld/configure.tgt ./ld/configure.tgt
*** ../binutils.fsf.1/ld/configure.tgt	2006-03-06 08:56:21.000000000 -0800
--- ./ld/configure.tgt	2006-03-06 06:40:05.000000000 -0800
*************** sparc*-*-aout)		targ_emul=sparcaout ;;
*** 493,498 ****
--- 493,499 ----
  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 -cprN ../binutils.fsf.1/ld/emulparams/elf32_sparc_vxworks.sh ./ld/emulparams/elf32_sparc_vxworks.sh
*** ../binutils.fsf.1/ld/emulparams/elf32_sparc_vxworks.sh	1969-12-31 16:00:00.000000000 -0800
--- ./ld/emulparams/elf32_sparc_vxworks.sh	2006-03-06 07:59:39.000000000 -0800
***************
*** 0 ****
--- 1,4 ----
+ . ${srcdir}/emulparams/elf32_sparc.sh
+ OUTPUT_FORMAT="elf32-sparc-vxworks"
+ unset DATA_PLT
+ . ${srcdir}/emulparams/vxworks.sh
diff -cprN ../binutils.fsf.1/ld/Makefile.am ./ld/Makefile.am
*** ../binutils.fsf.1/ld/Makefile.am	2006-03-06 08:59:24.000000000 -0800
--- ./ld/Makefile.am	2006-03-06 06:39:33.000000000 -0800
*************** ALL_EMULATIONS = \
*** 147,152 ****
--- 147,153 ----
  	eelf32_i960.o \
  	eelf32_i860.o \
  	eelf32_sparc.o \
+ 	eelf32_sparc_vxworks.o \
  	eelf32b4300.o \
  	eelf32bfin.o \
  	eelf32cr16c.o \
*************** em32rlelf_linux.c: $(srcdir)/emulparams/
*** 680,685 ****
--- 681,691 ----
  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)"
diff -cprN ../binutils.fsf.1/ld/Makefile.in ./ld/Makefile.in
*** ../binutils.fsf.1/ld/Makefile.in	2006-03-06 08:59:24.000000000 -0800
--- ./ld/Makefile.in	2006-03-06 06:40:35.000000000 -0800
*************** ALL_EMULATIONS = \
*** 370,375 ****
--- 370,376 ----
  	eelf32_i960.o \
  	eelf32_i860.o \
  	eelf32_sparc.o \
+ 	eelf32_sparc_vxworks.o \
  	eelf32b4300.o \
  	eelf32bfin.o \
  	eelf32cr16c.o \
*************** em32rlelf_linux.c: $(srcdir)/emulparams/
*** 1486,1491 ****
--- 1487,1497 ----
  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)"
diff -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/sparc.exp ./ld/testsuite/ld-sparc/sparc.exp
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/sparc.exp	2006-03-06 08:56:21.000000000 -0800
--- ./ld/testsuite/ld-sparc/sparc.exp	2006-03-06 07:45:38.000000000 -0800
***************
*** 19,24 ****
--- 19,51 ----
  # 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.dd ./ld/testsuite/ld-sparc/vxworks1.dd
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.dd	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1.dd	2006-03-06 08:04:37.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.ld ./ld/testsuite/ld-sparc/vxworks1.ld
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.ld	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1.ld	2006-03-06 08:00:04.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.dd ./ld/testsuite/ld-sparc/vxworks1-lib.dd
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.dd	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1-lib.dd	2006-03-06 08:03:23.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.nd ./ld/testsuite/ld-sparc/vxworks1-lib.nd
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.nd	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1-lib.nd	2006-03-06 08:05:34.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.rd ./ld/testsuite/ld-sparc/vxworks1-lib.rd
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.rd	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1-lib.rd	2006-03-06 08:09:00.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.s ./ld/testsuite/ld-sparc/vxworks1-lib.s
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-lib.s	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1-lib.s	2006-03-06 07:49:46.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.rd ./ld/testsuite/ld-sparc/vxworks1.rd
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.rd	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1.rd	2006-03-06 08:08:46.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.s ./ld/testsuite/ld-sparc/vxworks1.s
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1.s	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1.s	2006-03-06 07:19:49.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-static.d ./ld/testsuite/ld-sparc/vxworks1-static.d
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks1-static.d	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks1-static.d	2006-03-06 07:15:23.000000000 -0800
***************
*** 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 -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks2.s ./ld/testsuite/ld-sparc/vxworks2.s
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks2.s	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks2.s	2006-03-06 07:56:22.000000000 -0800
***************
*** 0 ****
--- 1,6 ----
+ 	.globl	_start
+ 	.type	_start, %function
+ _start:
+ 	retl
+ 	nop
+ 	.end	_start
diff -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks2.sd ./ld/testsuite/ld-sparc/vxworks2.sd
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks2.sd	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks2.sd	2006-03-06 08:15:16.000000000 -0800
***************
*** 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 .*
+ 
+ #...
diff -cprN ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks2-static.sd ./ld/testsuite/ld-sparc/vxworks2-static.sd
*** ../binutils.fsf.1/ld/testsuite/ld-sparc/vxworks2-static.sd	1969-12-31 16:00:00.000000000 -0800
--- ./ld/testsuite/ld-sparc/vxworks2-static.sd	2006-03-06 08:00:34.000000000 -0800
***************
*** 0 ****
--- 1,9 ----
+ #...
+ Elf file type is EXEC \(Executable file\)
+ Entry point 0x80000
+ #...
+ Program Headers:
+   Type .*
+   LOAD .* 0x00080000 0x00080000 .* R E 0x10000
+ 
+ #...



More information about the Binutils mailing list