From 910600e9c7e78f59a8e89638016b70837a1ea622 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 5 Apr 2006 12:41:59 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 49 +++ bfd/Makefile.am | 4 +- bfd/Makefile.in | 4 +- bfd/config.bfd | 4 + bfd/configure | 5 +- bfd/configure.in | 5 +- bfd/elf32-sparc.c | 66 ++++ bfd/elfxx-sparc.c | 440 ++++++++++++++++++++--- bfd/elfxx-sparc.h | 11 + bfd/targets.c | 2 + gas/ChangeLog | 10 + gas/config/tc-sparc.c | 40 ++- gas/configure.tgt | 2 +- gas/testsuite/ChangeLog | 5 + gas/testsuite/gas/sparc/sparc.exp | 6 +- gas/testsuite/gas/sparc/vxworks-pic.d | 27 ++ gas/testsuite/gas/sparc/vxworks-pic.s | 11 + ld/ChangeLog | 9 + ld/Makefile.am | 6 + ld/Makefile.in | 6 + ld/configure.tgt | 1 + ld/emulparams/elf32_sparc_vxworks.sh | 4 + ld/testsuite/ChangeLog | 9 + ld/testsuite/ld-sparc/sparc.exp | 27 ++ ld/testsuite/ld-sparc/vxworks1-lib.dd | 45 +++ ld/testsuite/ld-sparc/vxworks1-lib.nd | 9 + ld/testsuite/ld-sparc/vxworks1-lib.rd | 12 + ld/testsuite/ld-sparc/vxworks1-lib.s | 44 +++ ld/testsuite/ld-sparc/vxworks1-static.d | 4 + ld/testsuite/ld-sparc/vxworks1.dd | 52 +++ ld/testsuite/ld-sparc/vxworks1.ld | 30 ++ ld/testsuite/ld-sparc/vxworks1.rd | 22 ++ ld/testsuite/ld-sparc/vxworks1.s | 25 ++ ld/testsuite/ld-sparc/vxworks2-static.sd | 9 + ld/testsuite/ld-sparc/vxworks2.s | 6 + ld/testsuite/ld-sparc/vxworks2.sd | 13 + 36 files changed, 956 insertions(+), 68 deletions(-) create mode 100644 gas/testsuite/gas/sparc/vxworks-pic.d create mode 100644 gas/testsuite/gas/sparc/vxworks-pic.s create mode 100644 ld/emulparams/elf32_sparc_vxworks.sh create mode 100644 ld/testsuite/ld-sparc/vxworks1-lib.dd create mode 100644 ld/testsuite/ld-sparc/vxworks1-lib.nd create mode 100644 ld/testsuite/ld-sparc/vxworks1-lib.rd create mode 100644 ld/testsuite/ld-sparc/vxworks1-lib.s create mode 100644 ld/testsuite/ld-sparc/vxworks1-static.d create mode 100644 ld/testsuite/ld-sparc/vxworks1.dd create mode 100644 ld/testsuite/ld-sparc/vxworks1.ld create mode 100644 ld/testsuite/ld-sparc/vxworks1.rd create mode 100644 ld/testsuite/ld-sparc/vxworks1.s create mode 100644 ld/testsuite/ld-sparc/vxworks2-static.sd create mode 100644 ld/testsuite/ld-sparc/vxworks2.s create mode 100644 ld/testsuite/ld-sparc/vxworks2.sd diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 51157c0da72..322b77facd3 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,52 @@ +2006-04-05 Richard Sandiford + Daniel Jacobowitz + + * 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 PR ld/2267 diff --git a/bfd/Makefile.am b/bfd/Makefile.am index a0d5edf67d9..bf32fbdffeb 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -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 \ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 6b783333246..0220d91b24f 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -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 \ diff --git a/bfd/config.bfd b/bfd/config.bfd index ccd0de8dfab..4fd72c1c152 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -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" diff --git a/bfd/configure b/bfd/configure index 5ad2bc45695..dd8f2d0834c 100755 --- a/bfd/configure +++ b/bfd/configure @@ -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 ;; diff --git a/bfd/configure.in b/bfd/configure.in index bc8dabb4d51..37282b714df 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -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 ;; diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index 031b3034a8b..3bfb38a3d44 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -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" diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index cb5f7cbba9b..ef7ff482d2e 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -23,10 +23,12 @@ #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 diff --git a/bfd/elfxx-sparc.h b/bfd/elfxx-sparc.h index 624aea52787..0a5a88b6fe3 100644 --- a/bfd/elfxx-sparc.h +++ b/bfd/elfxx-sparc.h @@ -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; diff --git a/bfd/targets.c b/bfd/targets.c index 0649179ba33..849eb944fbe 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -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, diff --git a/gas/ChangeLog b/gas/ChangeLog index fadd3e0fe1c..3f759e08a80 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,13 @@ +2006-04-05 Richard Sandiford + Daniel Jacobowitz + + * 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 PR 997 diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 04bfb53638e..10a1411b526 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -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; diff --git a/gas/configure.tgt b/gas/configure.tgt index 6463631c739..696daaa128f 100644 --- a/gas/configure.tgt +++ b/gas/configure.tgt @@ -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 ;; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index c4b021747b0..28bbea8e0e6 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-04-05 Richard Sandiford + + * 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 * gas/i386/rep.s: Pad with .p2align. diff --git a/gas/testsuite/gas/sparc/sparc.exp b/gas/testsuite/gas/sparc/sparc.exp index 4189ddbff73..a2e362dbba1 100644 --- a/gas/testsuite/gas/sparc/sparc.exp +++ b/gas/testsuite/gas/sparc/sparc.exp @@ -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 index 00000000000..7e238fbdc45 --- /dev/null +++ b/gas/testsuite/gas/sparc/vxworks-pic.d @@ -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 index 00000000000..9d49e007904 --- /dev/null +++ b/gas/testsuite/gas/sparc/vxworks-pic.s @@ -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 diff --git a/ld/ChangeLog b/ld/ChangeLog index 690298e4175..7ce60d92fa9 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2006-04-05 Richard Sandiford + Daniel Jacobowitz + + * 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 * ldlang.c (lang_map): Print the list of discarded input sections. diff --git a/ld/Makefile.am b/ld/Makefile.am index fea8955e237..758dc7e2d9e 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -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)" diff --git a/ld/Makefile.in b/ld/Makefile.in index c3716c02502..4564a8bf6b7 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -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)" diff --git a/ld/configure.tgt b/ld/configure.tgt index 8504c9b9488..d324e4ece25 100644 --- a/ld/configure.tgt +++ b/ld/configure.tgt @@ -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 index 00000000000..12a9b384408 --- /dev/null +++ b/ld/emulparams/elf32_sparc_vxworks.sh @@ -0,0 +1,4 @@ +. ${srcdir}/emulparams/elf32_sparc.sh +OUTPUT_FORMAT="elf32-sparc-vxworks" +unset DATA_PLT +. ${srcdir}/emulparams/vxworks.sh diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 78935751f39..b851e597b67 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2006-04-05 Richard Sandiford + + * 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 * lib/ld-lib.exp: Comment cleanups. diff --git a/ld/testsuite/ld-sparc/sparc.exp b/ld/testsuite/ld-sparc/sparc.exp index aa4c869a198..6e7e95cc563 100644 --- a/ld/testsuite/ld-sparc/sparc.exp +++ b/ld/testsuite/ld-sparc/sparc.exp @@ -19,6 +19,33 @@ # 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 index 00000000000..49dab7bc4a8 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1-lib.dd @@ -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 : + 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 + 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 : + 80c44: 81 c3 e0 08 retl + 80c48: 01 00 00 00 nop + +00080c4c : + 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 index 00000000000..cbc1c8c40f8 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1-lib.nd @@ -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 index 00000000000..1390e78ab36 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1-lib.rd @@ -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 index 00000000000..e1221a22153 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1-lib.s @@ -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 index 00000000000..88c0baf1bbb --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1-static.d @@ -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 index 00000000000..16e72fdac31 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1.dd @@ -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 + 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 + 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 + 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 : + 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 index 00000000000..979d7733548 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1.ld @@ -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 index 00000000000..e02146b4f87 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1.rd @@ -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 index 00000000000..82106c8107b --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks1.s @@ -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 index 00000000000..55fc529619b --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks2-static.sd @@ -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 index 00000000000..0a883a97d38 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks2.s @@ -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 index 00000000000..087656882a0 --- /dev/null +++ b/ld/testsuite/ld-sparc/vxworks2.sd @@ -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 .* + +#... -- 2.39.2