bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Tue, 7 Mar 2006 08:39:21 +0000 (08:39 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Tue, 7 Mar 2006 08:39:21 +0000 (08:39 +0000)
* configure.in (bfd_elf32_bigarm_vec): Include elf-vxworks.lo.
(bfd_elf32_bigarm_symbian_vec): Likewise.
(bfd_elf32_bigarm_vxworks_vec): Likewise.
(bfd_elf32_littlearm_vec): Likewise.
(bfd_elf32_littlearm_symbian_vec): Likewise.
(bfd_elf32_littlearm_vxworks_vec): Likewise.
* configure: Regenerate.
* elf32-arm.c: Include libiberty.h and elf-vxworks.h.
(RELOC_SECTION, RELOC_SIZE, SWAP_RELOC_IN, SWAP_RELOC_OUT): New macros.
(elf32_arm_vxworks_bed): Add forward declaration.
(elf32_arm_howto_table_1): Fix the masks for R_ASM_ABS12.
(elf32_arm_vxworks_exec_plt0_entry): New table.
(elf32_arm_vxworks_exec_plt_entry): Likewise.
(elf32_arm_vxworks_shared_plt_entry): Likewise.
(elf32_arm_link_hash_table): Add vxworks_p and srelplt2 fields.
(reloc_section_p): New function.
(create_got_section): Use RELOC_SECTION.
(elf32_arm_create_dynamic_sections): Likewise.  Call
elf_vxworks_create_dynamic_sections for VxWorks targets.
Choose between the two possible values of plt_header_size
and plt_entry_size.
(elf32_arm_link_hash_table_create): Initialize vxworks_p and srelplt2.
(elf32_arm_abs12_reloc): New function.
(elf32_arm_final_link_relocate): Call it.  Allow the creation of
dynamic R_ARM_ABS12 relocs on VxWorks.  Use reloc_section_p,
RELOC_SIZE, SWAP_RELOC_OUT and RELOC_SECTION.  Initialize the
r_addend fields of relocs.  On rela targets, skip any code that
adjusts in-place addends.  When using _bfd_link_final_relocate
to perform a final relocation, pass rel->r_addend as the addend
argument.
(elf32_arm_merge_private_bfd_data): If one of the bfds is a VxWorks
object, ignore flags that are not standard on VxWorks.
(elf32_arm_check_relocs): Allow the creation of dynamic R_ARM_ABS12
relocs on VxWorks.  Use reloc_section_p.
(elf32_arm_adjust_dynamic_symbol): Use RELOC_SECTION and RELOC_SIZE.
(allocate_dynrelocs): Use RELOC_SIZE.  Account for the size of
.rela.plt.unloaded relocs on VxWorks targets.
(elf32_arm_size_dynamic_sections): Use RELOC_SIZE.  Check for
.rela.plt.unloaded as well as .rel(a).plt.  Add DT_RELA* tags
instead of DT_REL* tags on RELA targets.
(elf32_arm_finish_dynamic_symbol): Use RELOC_SECTION, RELOC_SIZE
and SWAP_RELOC_OUT.  Initialize r_addend fields.  Handle VxWorks
PLT entries.  Do not make _GLOBAL_OFFSET_TABLE_ absolute on VxWorks.
(elf32_arm_finish_dynamic_sections): Use RELOC_SECTION, RELOC_SIZE
and SWAP_RELOC_OUT.  Initialize r_addend fields.  Handle DT_RELASZ
like DT_RELSZ.  Handle the VxWorks form of initial PLT entry.
Correct the .rela.plt.unreloaded symbol indexes.
(elf32_arm_output_symbol_hook): Call the VxWorks version of this
hook on VxWorks targets.
(elf32_arm_vxworks_link_hash_table_create): Set vxworks_p to true.
Minor formatting tweak.
(elf32_arm_vxworks_final_write_processing): New function.
(elf_backend_add_symbol_hook): Override for VxWorks and reset
for Symbian.
(elf_backend_final_write_processing): Likewise.
(elf_backend_emit_relocs): Likewise.
(elf_backend_want_plt_sym): Likewise.
(ELF_MAXPAGESIZE): Likewise.
(elf_backend_may_use_rel_p): Minor formatting tweak.
(elf_backend_may_use_rela_p): Likewise.
(elf_backend_default_use_rela_p): Likewise.
(elf_backend_rela_normal): Likewise.
* Makefile.in (elf32-arm.lo): Depend on elf-vxworks.h.

gas/
* config/tc-arm.c (md_apply_fix): Install a value of zero into a
BFD_RELOC_ARM_OFFSET_IMM field if we're going to generate a RELA
R_ARM_ABS12 reloc.
(tc_gen_reloc): Keep the original fx_offset for RELA pc-relative
relocs, but adjust by md_pcrel_from_section.  Create R_ARM_ABS12
relocations for BFD_RELOC_ARM_OFFSET_IMM on RELA targets.

gas/testsuite/
* gas/arm/abs12.s, gas/arm/abs12.d: New test.
* gas/arm/pic.d: Skip for *-*-vxworks*...
* gas/arm/pic_vxworks.d: ...use this version instead.
* gas/arm/unwind_vxworks.d: Fix expected output.

ld/
* emulparams/armelf_vxworks.sh: Include vxworks.sh.
(MAXPAGESIZE): Define.
* emulparams/vxworks.sh: Undefine.
* Makefile.am (earmelf_vxworks.c): Depend on vxworks.sh and vxworks.em.
* Makefile.in: Regenerate.

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

33 files changed:
bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/configure
bfd/configure.in
bfd/elf32-arm.c
gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/abs12.d [new file with mode: 0644]
gas/testsuite/gas/arm/abs12.s [new file with mode: 0644]
gas/testsuite/gas/arm/pic.d
gas/testsuite/gas/arm/pic_vxworks.d [new file with mode: 0644]
gas/testsuite/gas/arm/unwind_vxworks.d
ld/ChangeLog
ld/Makefile.am
ld/Makefile.in
ld/emulparams/armelf_vxworks.sh
ld/emulparams/vxworks.sh
ld/testsuite/ChangeLog
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/vxworks1-lib.dd [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1-lib.nd [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1-lib.rd [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1-lib.s [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1-static.d [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1.dd [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1.ld [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1.rd [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks1.s [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks2-static.sd [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks2.s [new file with mode: 0644]
ld/testsuite/ld-arm/vxworks2.sd [new file with mode: 0644]

index f0c7a8629c405688f01aaad602ee90e771d2fa5d..e91d267a1442108ed35af6d621f466b04877fb01 100644 (file)
@@ -1,3 +1,75 @@
+2006-03-07  Richard Sandiford  <richard@codesourcery.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+           Zack Weinberg  <zack@codesourcery.com>
+           Nathan Sidwell  <nathan@codesourcery.com>
+           Paul Brook  <paul@codesourcery.com>
+           Ricardo Anguiano  <anguiano@codesourcery.com>
+           Phil Edwards  <phil@codesourcery.com>
+
+       * configure.in (bfd_elf32_bigarm_vec): Include elf-vxworks.lo.
+       (bfd_elf32_bigarm_symbian_vec): Likewise.
+       (bfd_elf32_bigarm_vxworks_vec): Likewise.
+       (bfd_elf32_littlearm_vec): Likewise.
+       (bfd_elf32_littlearm_symbian_vec): Likewise.
+       (bfd_elf32_littlearm_vxworks_vec): Likewise.
+       * configure: Regenerate.
+       * elf32-arm.c: Include libiberty.h and elf-vxworks.h.
+       (RELOC_SECTION, RELOC_SIZE, SWAP_RELOC_IN, SWAP_RELOC_OUT): New macros.
+       (elf32_arm_vxworks_bed): Add forward declaration.
+       (elf32_arm_howto_table_1): Fix the masks for R_ASM_ABS12.
+       (elf32_arm_vxworks_exec_plt0_entry): New table.
+       (elf32_arm_vxworks_exec_plt_entry): Likewise.
+       (elf32_arm_vxworks_shared_plt_entry): Likewise.
+       (elf32_arm_link_hash_table): Add vxworks_p and srelplt2 fields.
+       (reloc_section_p): New function.
+       (create_got_section): Use RELOC_SECTION.
+       (elf32_arm_create_dynamic_sections): Likewise.  Call
+       elf_vxworks_create_dynamic_sections for VxWorks targets.
+       Choose between the two possible values of plt_header_size
+       and plt_entry_size.
+       (elf32_arm_link_hash_table_create): Initialize vxworks_p and srelplt2.
+       (elf32_arm_abs12_reloc): New function.
+       (elf32_arm_final_link_relocate): Call it.  Allow the creation of
+       dynamic R_ARM_ABS12 relocs on VxWorks.  Use reloc_section_p,
+       RELOC_SIZE, SWAP_RELOC_OUT and RELOC_SECTION.  Initialize the
+       r_addend fields of relocs.  On rela targets, skip any code that
+       adjusts in-place addends.  When using _bfd_link_final_relocate
+       to perform a final relocation, pass rel->r_addend as the addend
+       argument.
+       (elf32_arm_merge_private_bfd_data): If one of the bfds is a VxWorks
+       object, ignore flags that are not standard on VxWorks.
+       (elf32_arm_check_relocs): Allow the creation of dynamic R_ARM_ABS12
+       relocs on VxWorks.  Use reloc_section_p.
+       (elf32_arm_adjust_dynamic_symbol): Use RELOC_SECTION and RELOC_SIZE.
+       (allocate_dynrelocs): Use RELOC_SIZE.  Account for the size of
+       .rela.plt.unloaded relocs on VxWorks targets.
+       (elf32_arm_size_dynamic_sections): Use RELOC_SIZE.  Check for
+       .rela.plt.unloaded as well as .rel(a).plt.  Add DT_RELA* tags
+       instead of DT_REL* tags on RELA targets.
+       (elf32_arm_finish_dynamic_symbol): Use RELOC_SECTION, RELOC_SIZE
+       and SWAP_RELOC_OUT.  Initialize r_addend fields.  Handle VxWorks
+       PLT entries.  Do not make _GLOBAL_OFFSET_TABLE_ absolute on VxWorks.
+       (elf32_arm_finish_dynamic_sections): Use RELOC_SECTION, RELOC_SIZE
+       and SWAP_RELOC_OUT.  Initialize r_addend fields.  Handle DT_RELASZ
+       like DT_RELSZ.  Handle the VxWorks form of initial PLT entry.
+       Correct the .rela.plt.unreloaded symbol indexes.
+       (elf32_arm_output_symbol_hook): Call the VxWorks version of this
+       hook on VxWorks targets.
+       (elf32_arm_vxworks_link_hash_table_create): Set vxworks_p to true.
+       Minor formatting tweak.
+       (elf32_arm_vxworks_final_write_processing): New function.
+       (elf_backend_add_symbol_hook): Override for VxWorks and reset
+       for Symbian.
+       (elf_backend_final_write_processing): Likewise.
+       (elf_backend_emit_relocs): Likewise.
+       (elf_backend_want_plt_sym): Likewise.
+       (ELF_MAXPAGESIZE): Likewise.
+       (elf_backend_may_use_rel_p): Minor formatting tweak.
+       (elf_backend_may_use_rela_p): Likewise.
+       (elf_backend_default_use_rela_p): Likewise.
+       (elf_backend_rela_normal): Likewise.
+       * Makefile.in (elf32-arm.lo): Depend on elf-vxworks.h.
+
 2006-03-06  Nathan Sidwell  <nathan@codesourcery.com>
 
        * archures.c (bfd_mach_mcf_isa_a_nodiv, bfd_mach_mcf_isa_b_nousp):
index f793c9a468a82df88fdd345ff1610dfd57b0f1b0..b592cd436cf8c8588f11664868e4ca28c21ebb65 100644 (file)
@@ -1220,8 +1220,8 @@ elf32-arc.lo: elf32-arc.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf32-target.h
 elf32-arm.lo: elf32-arm.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
-  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/arm.h \
-  $(INCDIR)/elf/reloc-macros.h elf32-target.h
+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h elf-vxworks.h \
+  $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
 elf32-avr.lo: elf32-avr.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/avr.h \
index bd496aaf886cee2178464d4e755ef5f6fdbec79a..445e8f4129d858adf82759a62ee488b191ad252d 100644 (file)
@@ -1787,8 +1787,8 @@ elf32-arc.lo: elf32-arc.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf32-target.h
 elf32-arm.lo: elf32-arm.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
-  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/arm.h \
-  $(INCDIR)/elf/reloc-macros.h elf32-target.h
+  $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h elf-vxworks.h \
+  $(INCDIR)/elf/arm.h $(INCDIR)/elf/reloc-macros.h elf32-target.h
 elf32-avr.lo: elf32-avr.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
   elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
   $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h $(INCDIR)/elf/avr.h \
index b79f0da5970cf0b3482ef2182c366025f49f925d..ef1d5b50a2625f2bd863cb3a755d2853e00f0f52 100755 (executable)
     bfd_elf32_bfin_vec)                tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
     bfd_elf32_big_generic_vec)         tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_bigarc_vec)      tb="$tb elf32-arc.lo elf32.lo $elf" ;;
-    bfd_elf32_bigarm_vec)      tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+    bfd_elf32_bigarm_vec)      tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_symbian_vec)
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_vxworks_vec)
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigmips_vec)     tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_cr16c_vec)       tb="$tb elf32-cr16c.lo elf32.lo $elf" ;;
     bfd_elf32_cris_vec)                tb="$tb elf32-cris.lo elf32.lo $elf" ;;
     bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_littlearc_vec)   tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_littlearm_symbian_vec)
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlearm_vxworks_vec)
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
-    bfd_elf32_littlearm_vec)   tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
+    bfd_elf32_littlearm_vec)   tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlemips_vec)  tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_m32c_vec)         tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
     bfd_elf32_m32r_vec)                tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
index b90e1fa760ecaaaa1c2f1788364fc772ab3ed1e5..5aaf17db8fe0aaaec312fb6f08d35f7c97fd485d 100644 (file)
@@ -586,11 +586,11 @@ do
     bfd_elf32_bfin_vec)                tb="$tb elf32-bfin.lo elf32.lo $elf" ;;
     bfd_elf32_big_generic_vec)         tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_bigarc_vec)      tb="$tb elf32-arc.lo elf32.lo $elf" ;;
-    bfd_elf32_bigarm_vec)      tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+    bfd_elf32_bigarm_vec)      tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_symbian_vec)      
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigarm_vxworks_vec)      
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_bigmips_vec)     tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_cr16c_vec)       tb="$tb elf32-cr16c.lo elf32.lo $elf" ;;
     bfd_elf32_cris_vec)                tb="$tb elf32-cris.lo elf32.lo $elf" ;;
@@ -619,10 +619,10 @@ do
     bfd_elf32_little_generic_vec) tb="$tb elf32-gen.lo elf32.lo $elf" ;;
     bfd_elf32_littlearc_vec)   tb="$tb elf32-arc.lo elf32.lo $elf" ;;
     bfd_elf32_littlearm_symbian_vec)
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlearm_vxworks_vec)
-                                tb="$tb elf32-arm.lo elf32.lo $elf" ;;
-    bfd_elf32_littlearm_vec)   tb="$tb elf32-arm.lo elf32.lo $elf" ;;
+                                tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
+    bfd_elf32_littlearm_vec)   tb="$tb elf32-arm.lo elf32.lo elf-vxworks.lo $elf" ;;
     bfd_elf32_littlemips_vec)  tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;;
     bfd_elf32_m32c_vec)         tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
     bfd_elf32_m32r_vec)                tb="$tb elf32-m32r.lo elf32.lo $elf" ;;
index ef19e6efb07d63954866d6ceaf3d65fd2cd783eb..7a957e6cc8990d7efaf390ff82dfc75540f36d10 100644 (file)
 
 #include "bfd.h"
 #include "sysdep.h"
+#include "libiberty.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
+#include "elf-vxworks.h"
 #include "elf/arm.h"
 
 #ifndef NUM_ELEM
 #define NUM_ELEM(a)  (sizeof (a) / (sizeof (a)[0]))
 #endif
 
+/* Return the relocation section associated with NAME.  HTAB is the
+   bfd's elf32_arm_link_hash_entry.  */
+#define RELOC_SECTION(HTAB, NAME) \
+  ((HTAB)->use_rel ? ".rel" NAME : ".rela" NAME)
+
+/* Return size of a relocation entry.  HTAB is the bfd's
+   elf32_arm_link_hash_entry.  */
+#define RELOC_SIZE(HTAB) \
+  ((HTAB)->use_rel \
+   ? sizeof (Elf32_External_Rel) \
+   : sizeof (Elf32_External_Rela))
+
+/* Return function to swap relocations in.  HTAB is the bfd's
+   elf32_arm_link_hash_entry.  */
+#define SWAP_RELOC_IN(HTAB) \
+  ((HTAB)->use_rel \
+   ? bfd_elf32_swap_reloc_in \
+   : bfd_elf32_swap_reloca_in)
+
+/* Return function to swap relocations out.  HTAB is the bfd's
+   elf32_arm_link_hash_entry.  */
+#define SWAP_RELOC_OUT(HTAB) \
+  ((HTAB)->use_rel \
+   ? bfd_elf32_swap_reloc_out \
+   : bfd_elf32_swap_reloca_out)
+
 #define elf_info_to_howto               0
 #define elf_info_to_howto_rel           elf32_arm_info_to_howto
 
 #define ARM_ELF_ABI_VERSION            0
 #define ARM_ELF_OS_ABI_VERSION         ELFOSABI_ARM
 
+static const struct elf_backend_data elf32_arm_vxworks_bed;
+
 /* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
    R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
    in that slot.  */
@@ -140,8 +170,8 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_ABS12",         /* name */
         FALSE,                 /* partial_inplace */
-        0x000008ff,            /* src_mask */
-        0x000008ff,            /* dst_mask */
+        0x00000fff,            /* src_mask */
+        0x00000fff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   HOWTO (R_ARM_THM_ABS5,       /* type */
@@ -1491,6 +1521,38 @@ static const bfd_vma elf32_arm_plt_entry [] =
 
 #endif
 
+/* The format of the first entry in the procedure linkage table
+   for a VxWorks executable.  */
+static const bfd_vma elf32_arm_vxworks_exec_plt0_entry[] =
+  {
+    0xe52dc008,                /* str    ip,[sp,#-8]!                  */
+    0xe59fc000,         /* ldr    ip,[pc]                      */
+    0xe59cf008,         /* ldr    pc,[ip,#8]                   */
+    0x00000000,         /* .long  _GLOBAL_OFFSET_TABLE_                */
+  };
+
+/* The format of subsequent entries in a VxWorks executable.  */
+static const bfd_vma elf32_arm_vxworks_exec_plt_entry[] =
+  {
+    0xe59fc000,         /* ldr    ip,[pc]                      */
+    0xe59cf000,         /* ldr    pc,[ip]                      */
+    0x00000000,         /* .long  @got                         */
+    0xe59fc000,         /* ldr    ip,[pc]                      */
+    0xea000000,         /* b      _PLT                         */
+    0x00000000,         /* .long  @pltindex*sizeof(Elf32_Rela) */
+  };
+
+/* The format of entries in a VxWorks shared library.  */
+static const bfd_vma elf32_arm_vxworks_shared_plt_entry[] =
+  {
+    0xe59fc000,         /* ldr    ip,[pc]                      */
+    0xe79cf009,         /* ldr    pc,[ip,r9]                   */
+    0x00000000,         /* .long  @got                         */
+    0xe59fc000,         /* ldr    ip,[pc]                      */
+    0xe599f008,         /* ldr    pc,[r9,#8]                   */
+    0x00000000,         /* .long  @pltindex*sizeof(Elf32_Rela) */
+  };
+
 /* An initial stub used if the PLT entry is referenced from Thumb code.  */
 #define PLT_THUMB_STUB_SIZE 4
 static const bfd_vma elf32_arm_plt_thumb_stub [] =
@@ -1668,6 +1730,9 @@ struct elf32_arm_link_hash_table
     /* The number of bytes in the subsequent PLT etries.  */
     bfd_size_type plt_entry_size;
 
+    /* True if the target system is VxWorks.  */
+    int vxworks_p;
+
     /* True if the target system is Symbian OS.  */
     int symbian_p;
 
@@ -1683,6 +1748,9 @@ struct elf32_arm_link_hash_table
     asection *sdynbss;
     asection *srelbss;
 
+    /* The (unloaded but important) VxWorks .rela.plt.unloaded section.  */
+    asection *srelplt2;
+
     /* Data for R_ARM_TLS_LDM32 relocations.  */
     union {
       bfd_signed_vma refcount;
@@ -1728,7 +1796,20 @@ elf32_arm_link_hash_newfunc (struct bfd_hash_entry * entry,
   return (struct bfd_hash_entry *) ret;
 }
 
-/* Create .got, .gotplt, and .rel.got sections in DYNOBJ, and set up
+/* Return true if NAME is the name of the relocation section associated
+   with S.  */
+
+static bfd_boolean
+reloc_section_p (struct elf32_arm_link_hash_table *htab,
+                const char *name, asection *s)
+{
+  if (htab->use_rel)
+    return strncmp (name, ".rel", 4) == 0 && strcmp (s->name, name + 4) == 0;
+  else
+    return strncmp (name, ".rela", 5) == 0 && strcmp (s->name, name + 5) == 0;
+}
+
+/* Create .got, .gotplt, and .rel(a).got sections in DYNOBJ, and set up
    shortcuts to them in our hash table.  */
 
 static bfd_boolean
@@ -1749,7 +1830,8 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
   if (!htab->sgot || !htab->sgotplt)
     abort ();
 
-  htab->srelgot = bfd_make_section_with_flags (dynobj, ".rel.got",
+  htab->srelgot = bfd_make_section_with_flags (dynobj,
+                                              RELOC_SECTION (htab, ".got"),
                                               (SEC_ALLOC | SEC_LOAD
                                                | SEC_HAS_CONTENTS
                                                | SEC_IN_MEMORY
@@ -1761,8 +1843,8 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
   return TRUE;
 }
 
-/* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and
-   .rel.bss sections in DYNOBJ, and set up shortcuts to them in our
+/* Create .plt, .rel(a).plt, .got, .got.plt, .rel(a).got, .dynbss, and
+   .rel(a).bss sections in DYNOBJ, and set up shortcuts to them in our
    hash table.  */
 
 static bfd_boolean
@@ -1778,10 +1860,32 @@ elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
     return FALSE;
 
   htab->splt = bfd_get_section_by_name (dynobj, ".plt");
-  htab->srelplt = bfd_get_section_by_name (dynobj, ".rel.plt");
+  htab->srelplt = bfd_get_section_by_name (dynobj,
+                                          RELOC_SECTION (htab, ".plt"));
   htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
   if (!info->shared)
-    htab->srelbss = bfd_get_section_by_name (dynobj, ".rel.bss");
+    htab->srelbss = bfd_get_section_by_name (dynobj,
+                                            RELOC_SECTION (htab, ".bss"));
+
+  if (htab->vxworks_p)
+    {
+      if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
+       return FALSE;
+
+      if (info->shared)
+       {
+         htab->plt_header_size = 0;
+         htab->plt_entry_size
+           = 4 * ARRAY_SIZE (elf32_arm_vxworks_shared_plt_entry);
+       }
+      else
+       {
+         htab->plt_header_size
+           = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt0_entry);
+         htab->plt_entry_size
+           = 4 * ARRAY_SIZE (elf32_arm_vxworks_exec_plt_entry);
+       }
+    }
 
   if (!htab->splt 
       || !htab->srelplt
@@ -1875,6 +1979,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
   ret->srelplt = NULL;
   ret->sdynbss = NULL;
   ret->srelbss = NULL;
+  ret->srelplt2 = NULL;
   ret->thumb_glue_size = 0;
   ret->arm_glue_size = 0;
   ret->bfd_of_glue_owner = NULL;
@@ -1890,6 +1995,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
 #endif
   ret->fix_v4bx = 0;
   ret->use_blx = 0;
+  ret->vxworks_p = 0;
   ret->symbian_p = 0;
   ret->use_rel = 1;
   ret->sym_sec.abfd = NULL;
@@ -2805,6 +2911,20 @@ tpoff (struct bfd_link_info *info, bfd_vma address)
   return address - htab->tls_sec->vma + base;
 }
 
+/* Perform an R_ARM_ABS12 relocation on the field pointed to by DATA.
+   VALUE is the relocation value.  */
+
+static bfd_reloc_status_type
+elf32_arm_abs12_reloc (bfd *abfd, void *data, bfd_vma value)
+{
+  if (value > 0xfff)
+    return bfd_reloc_overflow;
+
+  value |= bfd_get_32 (abfd, data) & 0xfffff000;
+  bfd_put_32 (abfd, value, data);
+  return bfd_reloc_ok;
+}
+
 /* Perform a relocation as part of a final link.  */
 
 static bfd_reloc_status_type
@@ -2891,6 +3011,10 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       *unresolved_reloc_p = FALSE;
       return bfd_reloc_ok;
 
+    case R_ARM_ABS12:
+      if (!globals->vxworks_p)
+       return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
+
     case R_ARM_PC24:
     case R_ARM_ABS32:
     case R_ARM_REL32:
@@ -2925,7 +3049,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          *unresolved_reloc_p = FALSE;
          return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                           contents, rel->r_offset, value,
-                                          (bfd_vma) 0);
+                                          rel->r_addend);
        }
 
       /* When generating a shared object or relocatable executable, these
@@ -2961,10 +3085,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              if (name == NULL)
                return bfd_reloc_notsupported;
 
-             BFD_ASSERT (strncmp (name, ".rel", 4) == 0
-                         && strcmp (bfd_get_section_name (input_bfd,
-                                                          input_section),
-                                    name + 4) == 0);
+             BFD_ASSERT (reloc_section_p (globals, name, input_section));
 
              sreloc = bfd_get_section_by_name (dynobj, name);
              BFD_ASSERT (sreloc != NULL);
@@ -2973,6 +3094,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          skip = FALSE;
          relocate = FALSE;
 
+         outrel.r_addend = addend;
          outrel.r_offset =
            _bfd_elf_section_offset (output_bfd, info, input_section,
                                     rel->r_offset);
@@ -2996,7 +3118,6 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              int symbol;
 
              /* This symbol is local, or marked to become local.  */
-             relocate = TRUE;
              if (sym_flags == STT_ARM_TFUNC)
                value |= 1;
              if (globals->symbian_p)
@@ -3021,11 +3142,15 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                   so the symbol does not matter.  */
                symbol = 0;
              outrel.r_info = ELF32_R_INFO (symbol, R_ARM_RELATIVE);
+             if (globals->use_rel)
+               relocate = TRUE;
+             else
+               outrel.r_addend += value;
            }
 
          loc = sreloc->contents;
-         loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rel);
-         bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+         loc += sreloc->reloc_count++ * RELOC_SIZE (globals);
+         SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
 
          /* If this reloc is against an external symbol, we do not want to
             fiddle with the addend.  Otherwise, we need to include the symbol
@@ -3039,6 +3164,9 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        }
       else switch (r_type)
        {
+       case R_ARM_ABS12:
+         return elf32_arm_abs12_reloc (input_bfd, hit_data, value + addend);
+
        case R_ARM_XPC25:         /* Arm BLX instruction.  */
        case R_ARM_CALL:
        case R_ARM_JUMP24:
@@ -3186,18 +3314,6 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       bfd_put_16 (input_bfd, value, hit_data);
       return bfd_reloc_ok;
 
-    case R_ARM_ABS12:
-      /* Support ldr and str instruction for the arm */
-      /* Also thumb b (unconditional branch).  ??? Really?  */
-      value += addend;
-
-      if ((long) value > 0x7ff || (long) value < -0x800)
-       return bfd_reloc_overflow;
-
-      value |= (bfd_get_32 (input_bfd, hit_data) & 0xfffff000);
-      bfd_put_32 (input_bfd, value, hit_data);
-      return bfd_reloc_ok;
-
     case R_ARM_THM_ABS5:
       /* Support ldr and str instructions for the thumb.  */
       if (globals->use_rel)
@@ -3589,7 +3705,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       value -= sgot->output_section->vma;
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
-                                      (bfd_vma) 0);
+                                      rel->r_addend);
 
     case R_ARM_GOTPC:
       /* Use global offset table as symbol value.  */
@@ -3602,7 +3718,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       value = sgot->output_section->vma;
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
-                                      (bfd_vma) 0);
+                                      rel->r_addend);
 
     case R_ARM_GOT32:
     case R_ARM_GOT_PREL:
@@ -3632,7 +3748,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                 always be a multiple of 4, we use the least significant bit
                 to record whether we have initialized it already.
 
-                When doing a dynamic link, we create a .rel.got relocation
+                When doing a dynamic link, we create a .rel(a).got relocation
                 entry to initialize the value.  This is done in the
                 finish_dynamic_symbol routine.  */
              if ((off & 1) != 0)
@@ -3678,7 +3794,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              if (sym_flags == STT_ARM_TFUNC)
                value |= 1;
 
-             bfd_put_32 (output_bfd, value, sgot->contents + off);
+             if (globals->use_rel)
+               bfd_put_32 (output_bfd, value, sgot->contents + off);
 
              if (info->shared)
                {
@@ -3686,16 +3803,18 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                  Elf_Internal_Rela outrel;
                  bfd_byte *loc;
 
-                 srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
+                 srelgot = (bfd_get_section_by_name
+                            (dynobj, RELOC_SECTION (globals, ".got")));
                  BFD_ASSERT (srelgot != NULL);
 
+                 outrel.r_addend = addend + value;
                  outrel.r_offset = (sgot->output_section->vma
                                     + sgot->output_offset
                                     + off);
                  outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
                  loc = srelgot->contents;
-                 loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
-                 bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+                 loc += srelgot->reloc_count++ * RELOC_SIZE (globals);
+                 SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
                }
 
              local_got_offsets[r_symndx] |= 1;
@@ -3708,13 +3827,14 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
-                                      (bfd_vma) 0);
+                                      rel->r_addend);
 
     case R_ARM_TLS_LDO32:
       value = value - dtpoff_base (info);
 
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                      contents, rel->r_offset, value, (bfd_vma) 0);
+                                      contents, rel->r_offset, value,
+                                      rel->r_addend);
 
     case R_ARM_TLS_LDM32:
       {
@@ -3739,15 +3859,18 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                if (globals->srelgot == NULL)
                  abort ();
 
+               outrel.r_addend = 0;
                outrel.r_offset = (globals->sgot->output_section->vma
                                   + globals->sgot->output_offset + off);
                outrel.r_info = ELF32_R_INFO (0, R_ARM_TLS_DTPMOD32);
 
-               bfd_put_32 (output_bfd, 0, globals->sgot->contents + off);
+               if (globals->use_rel)
+                 bfd_put_32 (output_bfd, outrel.r_addend,
+                             globals->sgot->contents + off);
 
                loc = globals->srelgot->contents;
-               loc += globals->srelgot->reloc_count++ * sizeof (Elf32_External_Rel);
-               bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+               loc += globals->srelgot->reloc_count++ * RELOC_SIZE (globals);
+               SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
              }
            else
              bfd_put_32 (output_bfd, 1, globals->sgot->contents + off);
@@ -3760,7 +3883,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                         contents, rel->r_offset, value,
-                                        (bfd_vma) 0);
+                                        rel->r_addend);
       }
 
     case R_ARM_TLS_GD32:
@@ -3821,36 +3944,45 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                if (globals->srelgot == NULL)
                  abort ();
                loc = globals->srelgot->contents;
-               loc += globals->srelgot->reloc_count * sizeof (Elf32_External_Rel);
+               loc += globals->srelgot->reloc_count * RELOC_SIZE (globals);
              }
 
            if (tls_type & GOT_TLS_GD)
              {
                if (need_relocs)
                  {
+                   outrel.r_addend = 0;
                    outrel.r_offset = (globals->sgot->output_section->vma
-                                      + globals->sgot->output_offset + cur_off);
+                                      + globals->sgot->output_offset
+                                      + cur_off);
                    outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DTPMOD32);
-                   bfd_put_32 (output_bfd, 0, globals->sgot->contents + cur_off);
 
-                   bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+                   if (globals->use_rel)
+                     bfd_put_32 (output_bfd, outrel.r_addend,
+                                 globals->sgot->contents + cur_off);
+
+                   SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
                    globals->srelgot->reloc_count++;
-                   loc += sizeof (Elf32_External_Rel);
+                   loc += RELOC_SIZE (globals);
 
                    if (indx == 0)
                      bfd_put_32 (output_bfd, value - dtpoff_base (info),
                                  globals->sgot->contents + cur_off + 4);
                    else
                      {
-                       bfd_put_32 (output_bfd, 0,
-                                   globals->sgot->contents + cur_off + 4);
-
+                       outrel.r_addend = 0;
                        outrel.r_info = ELF32_R_INFO (indx,
                                                      R_ARM_TLS_DTPOFF32);
                        outrel.r_offset += 4;
-                       bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+
+                       if (globals->use_rel)
+                         bfd_put_32 (output_bfd, outrel.r_addend,
+                                     globals->sgot->contents + cur_off + 4);
+
+
+                       SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
                        globals->srelgot->reloc_count++;
-                       loc += sizeof (Elf32_External_Rel);
+                       loc += RELOC_SIZE (globals);
                      }
                  }
                else
@@ -3873,21 +4005,22 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              {
                if (need_relocs)
                  {
+                   if (indx == 0)
+                     outrel.r_addend = value - dtpoff_base (info);
+                   else
+                     outrel.r_addend = 0;
                    outrel.r_offset = (globals->sgot->output_section->vma
                                       + globals->sgot->output_offset
                                       + cur_off);
                    outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_TPOFF32);
 
-                   if (indx == 0)
-                     bfd_put_32 (output_bfd, value - dtpoff_base (info),
-                                 globals->sgot->contents + cur_off);
-                   else
-                     bfd_put_32 (output_bfd, 0,
+                   if (globals->use_rel)
+                     bfd_put_32 (output_bfd, outrel.r_addend,
                                  globals->sgot->contents + cur_off);
 
-                   bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
+                   SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
                    globals->srelgot->reloc_count++;
-                   loc += sizeof (Elf32_External_Rel);
+                   loc += RELOC_SIZE (globals);
                  }
                else
                  bfd_put_32 (output_bfd, tpoff (info, value),
@@ -3908,7 +4041,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                         contents, rel->r_offset, value,
-                                        (bfd_vma) 0);
+                                        rel->r_addend);
       }
 
     case R_ARM_TLS_LE32:
@@ -3924,7 +4057,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        value = tpoff (info, value);
       
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                      contents, rel->r_offset, value, (bfd_vma) 0);
+                                      contents, rel->r_offset, value,
+                                      rel->r_addend);
 
     case R_ARM_V4BX:
       if (globals->fix_v4bx)
@@ -5128,7 +5262,10 @@ elf32_arm_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
     }
 
   /* Not sure what needs to be checked for EABI versions >= 1.  */
-  if (EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
+  /* VxWorks libraries do not use these flags.  */
+  if (get_elf_backend_data (obfd) != &elf32_arm_vxworks_bed
+      && get_elf_backend_data (ibfd) != &elf32_arm_vxworks_bed
+      && EF_ARM_EABI_VERSION (in_flags) == EF_ARM_EABI_UNKNOWN)
     {
       if ((in_flags & EF_ARM_APCS_26) != (out_flags & EF_ARM_APCS_26))
        {
@@ -5683,6 +5820,13 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
              }
            break;
 
+         case R_ARM_ABS12:
+           /* VxWorks uses dynamic R_ARM_ABS12 relocations for
+              ldr __GOTT_INDEX__ offsets.  */
+           if (!htab->vxworks_p)
+             break;
+           /* Fall through */
+
          case R_ARM_ABS32:
          case R_ARM_REL32:
          case R_ARM_PC24:
@@ -5757,9 +5901,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
                    if (name == NULL)
                      return FALSE;
 
-                   BFD_ASSERT (strncmp (name, ".rel", 4) == 0
-                               && strcmp (bfd_get_section_name (abfd, sec),
-                                          name + 4) == 0);
+                   BFD_ASSERT (reloc_section_p (htab, name, sec));
 
                    sreloc = bfd_get_section_by_name (dynobj, name);
                    if (sreloc == NULL)
@@ -6094,14 +6236,14 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
   /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
-     .rel.bss section we are going to use.  */
+     .rel(a).bss section we are going to use.  */
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {
       asection *srel;
 
-      srel = bfd_get_section_by_name (dynobj, ".rel.bss");
+      srel = bfd_get_section_by_name (dynobj, RELOC_SECTION (globals, ".bss"));
       BFD_ASSERT (srel != NULL);
-      srel->size += sizeof (Elf32_External_Rel);
+      srel->size += RELOC_SIZE (globals);
       h->needs_copy = 1;
     }
 
@@ -6215,8 +6357,24 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
              htab->sgotplt->size += 4;
            }
 
-         /* We also need to make an entry in the .rel.plt section.  */
-         htab->srelplt->size += sizeof (Elf32_External_Rel);
+         /* We also need to make an entry in the .rel(a).plt section.  */
+         htab->srelplt->size += RELOC_SIZE (htab);
+
+         /* VxWorks executables have a second set of relocations for
+            each PLT entry.  They go in a separate relocation section,
+            which is processed by the kernel loader.  */
+         if (htab->vxworks_p && !info->shared)
+           {
+             /* There is a relocation for the initial PLT entry:
+                an R_ARM_32 relocation for _GLOBAL_OFFSET_TABLE_.  */
+             if (h->plt.offset == htab->plt_header_size)
+               htab->srelplt2->size += RELOC_SIZE (htab);
+
+             /* There are two extra relocations for each subsequent
+                PLT entry: an R_ARM_32 relocation for the GOT entry,
+                and an R_ARM_32 relocation for the PLT entry.  */
+             htab->srelplt2->size += RELOC_SIZE (htab) * 2;
+           }
        }
       else
        {
@@ -6281,19 +6439,19 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
                  || h->root.type != bfd_link_hash_undefweak))
            {
              if (tls_type & GOT_TLS_IE)
-               htab->srelgot->size += sizeof (Elf32_External_Rel);
+               htab->srelgot->size += RELOC_SIZE (htab);
 
              if (tls_type & GOT_TLS_GD)
-               htab->srelgot->size += sizeof (Elf32_External_Rel);
+               htab->srelgot->size += RELOC_SIZE (htab);
 
              if ((tls_type & GOT_TLS_GD) && indx != 0)
-               htab->srelgot->size += sizeof (Elf32_External_Rel);
+               htab->srelgot->size += RELOC_SIZE (htab);
            }
          else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                    || h->root.type != bfd_link_hash_undefweak)
                   && (info->shared
                   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
-           htab->srelgot->size += sizeof (Elf32_External_Rel);
+           htab->srelgot->size += RELOC_SIZE (htab);
        }
     }
   else
@@ -6397,7 +6555,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   for (p = eh->relocs_copied; p != NULL; p = p->next)
     {
       asection *sreloc = elf_section_data (p->section)->sreloc;
-      sreloc->size += p->count * sizeof (Elf32_External_Rel);
+      sreloc->size += p->count * RELOC_SIZE (htab);
     }
 
   return TRUE;
@@ -6493,7 +6651,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
              else if (p->count != 0)
                {
                  srel = elf_section_data (p->section)->sreloc;
-                 srel->size += p->count * sizeof (Elf32_External_Rel);
+                 srel->size += p->count * RELOC_SIZE (htab);
                  if ((p->section->output_section->flags & SEC_READONLY) != 0)
                    info->flags |= DF_TEXTREL;
                }
@@ -6524,7 +6682,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
                s->size += 4;
 
              if (info->shared || *local_tls_type == GOT_TLS_GD)
-               srel->size += sizeof (Elf32_External_Rel);
+               srel->size += RELOC_SIZE (htab);
            }
          else
            *local_got = (bfd_vma) -1;
@@ -6538,7 +6696,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
       htab->tls_ldm_got.offset = htab->sgot->size;
       htab->sgot->size += 8;
       if (info->shared)
-       htab->srelgot->size += sizeof (Elf32_External_Rel);
+       htab->srelgot->size += RELOC_SIZE (htab);
     }
   else
     htab->tls_ldm_got.offset = -1;
@@ -6573,8 +6731,8 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
          if (s->size != 0)
            {
              /* Remember whether there are any reloc sections other
-                 than .rel.plt.  */
-             if (strcmp (name, ".rel.plt") != 0)
+                than .rel(a).plt and .rela.plt.unloaded.  */
+             if (s != htab->srelplt && s != htab->srelplt2)
                relocs = TRUE;
 
              /* We use the reloc_count field as a counter if we need
@@ -6592,8 +6750,8 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
       if (s->size == 0)
        {
          /* If we don't need this section, strip it from the
-            output file.  This is mostly to handle .rel.bss and
-            .rel.plt.  We must create both sections in
+            output file.  This is mostly to handle .rel(a).bss and
+            .rel(a).plt.  We must create both sections in
             create_dynamic_sections, because they must be created
             before the linker maps input sections to output
             sections.  The linker does that before
@@ -6633,17 +6791,28 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
        {
          if (   !add_dynamic_entry (DT_PLTGOT, 0)
              || !add_dynamic_entry (DT_PLTRELSZ, 0)
-             || !add_dynamic_entry (DT_PLTREL, DT_REL)
+             || !add_dynamic_entry (DT_PLTREL,
+                                    htab->use_rel ? DT_REL : DT_RELA)
              || !add_dynamic_entry (DT_JMPREL, 0))
            return FALSE;
        }
 
       if (relocs)
        {
-         if (   !add_dynamic_entry (DT_REL, 0)
-             || !add_dynamic_entry (DT_RELSZ, 0)
-             || !add_dynamic_entry (DT_RELENT, sizeof (Elf32_External_Rel)))
-           return FALSE;
+         if (htab->use_rel)
+           {
+             if (!add_dynamic_entry (DT_REL, 0)
+                 || !add_dynamic_entry (DT_RELSZ, 0)
+                 || !add_dynamic_entry (DT_RELENT, RELOC_SIZE (htab)))
+               return FALSE;
+           }
+         else
+           {
+             if (!add_dynamic_entry (DT_RELA, 0)
+                 || !add_dynamic_entry (DT_RELASZ, 0)
+                 || !add_dynamic_entry (DT_RELAENT, RELOC_SIZE (htab)))
+               return FALSE;
+           }
        }
 
       /* If any dynamic relocs apply to a read-only section,
@@ -6692,7 +6861,7 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
       BFD_ASSERT (h->dynindx != -1);
 
       splt = bfd_get_section_by_name (dynobj, ".plt");
-      srel = bfd_get_section_by_name (dynobj, ".rel.plt");
+      srel = bfd_get_section_by_name (dynobj, RELOC_SECTION (htab, ".plt"));
       BFD_ASSERT (splt != NULL && srel != NULL);
 
       /* Fill in the entry in the procedure linkage table.  */
@@ -6719,7 +6888,7 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
        }
       else
        {
-         bfd_vma got_offset;
+         bfd_vma got_offset, got_address, plt_address;
          bfd_vma got_displacement;
          asection * sgot;
          
@@ -6737,38 +6906,103 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
             symbols appear in the same order as in .plt.  */
          plt_index = (got_offset - 12) / 4;
 
-         /* Calculate the displacement between the PLT slot and the
-            entry in the GOT.  The eight-byte offset accounts for the
-            value produced by adding to pc in the first instruction
-            of the PLT stub.  */
-         got_displacement = (sgot->output_section->vma
-                             + sgot->output_offset
-                             + got_offset
-                             - splt->output_section->vma
-                             - splt->output_offset
-                             - h->plt.offset
-                             - 8);
+         /* Calculate the address of the GOT entry.  */
+         got_address = (sgot->output_section->vma
+                        + sgot->output_offset
+                        + got_offset);
 
-         BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
+         /* ...and the address of the PLT entry.  */
+         plt_address = (splt->output_section->vma
+                        + splt->output_offset
+                        + h->plt.offset);
 
-         if (!htab->use_blx && eh->plt_thumb_refcount > 0)
+         if (htab->vxworks_p && info->shared)
+           {
+             unsigned int i;
+             bfd_vma val;
+
+             for (i = 0; i != htab->plt_entry_size / 4; i++)
+               {
+                 val = elf32_arm_vxworks_shared_plt_entry[i];
+                 if (i == 2)
+                   val |= got_address - sgot->output_section->vma;
+                 if (i == 5)
+                   val |= plt_index * RELOC_SIZE (htab);
+                 bfd_put_32 (output_bfd, val,
+                             htab->splt->contents + h->plt.offset + i * 4);
+               }
+           }
+         else if (htab->vxworks_p)
            {
-             bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0],
-                         splt->contents + h->plt.offset - 4);
-             bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1],
-                         splt->contents + h->plt.offset - 2);
+             unsigned int i;
+             bfd_vma val;
+
+             for (i = 0; i != htab->plt_entry_size / 4; i++)
+               {
+                 val = elf32_arm_vxworks_exec_plt_entry[i];
+                 if (i == 2)
+                   val |= got_address;
+                 if (i == 4)
+                   val |= 0xffffff & -((h->plt.offset + i * 4 + 8) >> 2);
+                 if (i == 5)
+                   val |= plt_index * RELOC_SIZE (htab);
+                 bfd_put_32 (output_bfd, val,
+                             htab->splt->contents + h->plt.offset + i * 4);
+               }
+
+             loc = (htab->srelplt2->contents
+                    + (plt_index * 2 + 1) * RELOC_SIZE (htab));
+
+             /* Create the .rela.plt.unloaded R_ARM_ABS32 relocation
+                referencing the GOT for this PLT entry.  */
+             rel.r_offset = plt_address + 8;
+             rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
+             rel.r_addend = got_offset;
+             SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
+             loc += RELOC_SIZE (htab);
+
+             /* Create the R_ARM_ABS32 relocation referencing the
+                beginning of the PLT for this GOT entry.  */
+             rel.r_offset = got_address;
+             rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32);
+             rel.r_addend = 0;
+             SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
            }
+         else
+           {
+             /* Calculate the displacement between the PLT slot and the
+                entry in the GOT.  The eight-byte offset accounts for the
+                value produced by adding to pc in the first instruction
+                of the PLT stub.  */
+             got_displacement = got_address - (plt_address + 8);
 
-         bfd_put_32 (output_bfd, elf32_arm_plt_entry[0] | ((got_displacement & 0x0ff00000) >> 20),
-                     splt->contents + h->plt.offset + 0);
-         bfd_put_32 (output_bfd, elf32_arm_plt_entry[1] | ((got_displacement & 0x000ff000) >> 12),
-                     splt->contents + h->plt.offset + 4);
-         bfd_put_32 (output_bfd, elf32_arm_plt_entry[2] | (got_displacement & 0x00000fff),
-                     splt->contents + h->plt.offset + 8);
+             BFD_ASSERT ((got_displacement & 0xf0000000) == 0);
+
+             if (!htab->use_blx && eh->plt_thumb_refcount > 0)
+               {
+                 bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[0],
+                             splt->contents + h->plt.offset - 4);
+                 bfd_put_16 (output_bfd, elf32_arm_plt_thumb_stub[1],
+                             splt->contents + h->plt.offset - 2);
+               }
+
+             bfd_put_32 (output_bfd,
+                         elf32_arm_plt_entry[0]
+                         | ((got_displacement & 0x0ff00000) >> 20),
+                         splt->contents + h->plt.offset + 0);
+             bfd_put_32 (output_bfd,
+                         elf32_arm_plt_entry[1]
+                         | ((got_displacement & 0x000ff000) >> 12),
+                         splt->contents + h->plt.offset + 4);
+             bfd_put_32 (output_bfd,
+                         elf32_arm_plt_entry[2]
+                         | (got_displacement & 0x00000fff),
+                         splt->contents + h->plt.offset + 8);
 #ifdef FOUR_WORD_PLT
-         bfd_put_32 (output_bfd, elf32_arm_plt_entry[3],
-                     splt->contents + h->plt.offset + 12);
+             bfd_put_32 (output_bfd, elf32_arm_plt_entry[3],
+                         splt->contents + h->plt.offset + 12);
 #endif
+           }
 
          /* Fill in the entry in the global offset table.  */
          bfd_put_32 (output_bfd,
@@ -6776,15 +7010,14 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
                       + splt->output_offset),
                      sgot->contents + got_offset);
          
-         /* Fill in the entry in the .rel.plt section.  */
-         rel.r_offset = (sgot->output_section->vma
-                         + sgot->output_offset
-                         + got_offset);
+         /* Fill in the entry in the .rel(a).plt section.  */
+         rel.r_addend = 0;
+         rel.r_offset = got_address;
          rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_JUMP_SLOT);
        }
 
-      loc = srel->contents + plt_index * sizeof (Elf32_External_Rel);
-      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+      loc = srel->contents + plt_index * RELOC_SIZE (htab);
+      SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
 
       if (!h->def_regular)
        {
@@ -6808,16 +7041,19 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
       asection * srel;
       Elf_Internal_Rela rel;
       bfd_byte *loc;
+      bfd_vma offset;
 
       /* This symbol has an entry in the global offset table.  Set it
         up.  */
       sgot = bfd_get_section_by_name (dynobj, ".got");
-      srel = bfd_get_section_by_name (dynobj, ".rel.got");
+      srel = bfd_get_section_by_name (dynobj, RELOC_SECTION (htab, ".got"));
       BFD_ASSERT (sgot != NULL && srel != NULL);
 
+      offset = (h->got.offset & ~(bfd_vma) 1);
+      rel.r_addend = 0;
       rel.r_offset = (sgot->output_section->vma
                      + sgot->output_offset
-                     + (h->got.offset &~ (bfd_vma) 1));
+                     + offset);
 
       /* If this is a static link, or it is a -Bsymbolic link and the
         symbol is defined locally or was forced to be local because
@@ -6829,16 +7065,21 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
        {
          BFD_ASSERT((h->got.offset & 1) != 0);
          rel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
+         if (!htab->use_rel)
+           {
+             rel.r_addend = bfd_get_32 (output_bfd, sgot->contents + offset);
+             bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + offset);
+           }
        }
       else
        {
          BFD_ASSERT((h->got.offset & 1) == 0);
-         bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset);
+         bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + offset);
          rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_GLOB_DAT);
        }
 
-      loc = srel->contents + srel->reloc_count++ * sizeof (Elf32_External_Rel);
-      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+      loc = srel->contents + srel->reloc_count++ * RELOC_SIZE (htab);
+      SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
     }
 
   if (h->needs_copy)
@@ -6853,20 +7094,23 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd, struct bfd_link_info * info,
                      || h->root.type == bfd_link_hash_defweak));
 
       s = bfd_get_section_by_name (h->root.u.def.section->owner,
-                                  ".rel.bss");
+                                  RELOC_SECTION (htab, ".bss"));
       BFD_ASSERT (s != NULL);
 
+      rel.r_addend = 0;
       rel.r_offset = (h->root.u.def.value
                      + h->root.u.def.section->output_section->vma
                      + h->root.u.def.section->output_offset);
       rel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_COPY);
-      loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rel);
-      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+      loc = s->contents + s->reloc_count++ * RELOC_SIZE (htab);
+      SWAP_RELOC_OUT (htab) (output_bfd, &rel, loc);
     }
 
-  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
+  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  On VxWorks,
+     the _GLOBAL_OFFSET_TABLE_ symbol is not absolute: it is relative
+     to the ".got" section.  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || h == htab->root.hgot)
+      || (!htab->vxworks_p && h == htab->root.hgot))
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -6938,7 +7182,7 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
              name = ".got";
              goto get_vma;
            case DT_JMPREL:
-             name = ".rel.plt";
+             name = RELOC_SECTION (htab, ".plt");
            get_vma:
              s = bfd_get_section_by_name (output_bfd, name);
              BFD_ASSERT (s != NULL);
@@ -6958,13 +7202,15 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
              break;
 
            case DT_PLTRELSZ:
-             s = bfd_get_section_by_name (output_bfd, ".rel.plt");
+             s = bfd_get_section_by_name (output_bfd,
+                                          RELOC_SECTION (htab, ".plt"));
              BFD_ASSERT (s != NULL);
              dyn.d_un.d_val = s->size;
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
              
            case DT_RELSZ:
+           case DT_RELASZ:
              if (!htab->symbian_p)
                {
                  /* My reading of the SVR4 ABI indicates that the
@@ -6973,10 +7219,11 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
                     what Solaris does.  However, UnixWare can not handle
                     that case.  Therefore, we override the DT_RELSZ entry
                     here to make it not include the JMPREL relocs.  Since
-                    the linker script arranges for .rel.plt to follow all
+                    the linker script arranges for .rel(a).plt to follow all
                     other relocation sections, we don't have to worry
                     about changing the DT_REL entry.  */
-                 s = bfd_get_section_by_name (output_bfd, ".rel.plt");
+                 s = bfd_get_section_by_name (output_bfd,
+                                              RELOC_SECTION (htab, ".plt"));
                  if (s != NULL)
                    dyn.d_un.d_val -= s->size;
                  bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
@@ -6986,7 +7233,6 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
 
            case DT_REL:
            case DT_RELA:
-           case DT_RELASZ:
              /* In the BPABI, the DT_REL tag must point at the file
                 offset, not the VMA, of the first relocation
                 section.  So, we use code similar to that in
@@ -7049,31 +7295,83 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
       /* Fill in the first entry in the procedure linkage table.  */
       if (splt->size > 0 && elf32_arm_hash_table (info)->plt_header_size)
        {
-         bfd_vma got_displacement;
+         const bfd_vma *plt0_entry;
+         bfd_vma got_address, plt_address, got_displacement;
+
+         /* Calculate the addresses of the GOT and PLT.  */
+         got_address = sgot->output_section->vma + sgot->output_offset;
+         plt_address = splt->output_section->vma + splt->output_offset;
+
+         if (htab->vxworks_p)
+           {
+             /* The VxWorks GOT is relocated by the dynamic linker.
+                Therefore, we must emit relocations rather than simply
+                computing the values now.  */
+             Elf_Internal_Rela rel;
+
+             plt0_entry = elf32_arm_vxworks_exec_plt0_entry;
+             bfd_put_32 (output_bfd, plt0_entry[0], splt->contents + 0);
+             bfd_put_32 (output_bfd, plt0_entry[1], splt->contents + 4);
+             bfd_put_32 (output_bfd, plt0_entry[2], splt->contents + 8);
+             bfd_put_32 (output_bfd, got_address, splt->contents + 12);
+
+             /* Generate a relocation for _GLOBAL_OFFSET_TABLE_. */
+             rel.r_offset = plt_address + 12;
+             rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
+             rel.r_addend = 0;
+             SWAP_RELOC_OUT (htab) (output_bfd, &rel,
+                                    htab->srelplt2->contents);
+           }
+         else
+           {
+             got_displacement = got_address - (plt_address + 16);
+
+             plt0_entry = elf32_arm_plt0_entry;
+             bfd_put_32 (output_bfd, plt0_entry[0], splt->contents + 0);
+             bfd_put_32 (output_bfd, plt0_entry[1], splt->contents + 4);
+             bfd_put_32 (output_bfd, plt0_entry[2], splt->contents + 8);
+             bfd_put_32 (output_bfd, plt0_entry[3], splt->contents + 12);
 
-         /* Calculate the displacement between the PLT slot and &GOT[0].  */
-         got_displacement = (sgot->output_section->vma
-                             + sgot->output_offset
-                             - splt->output_section->vma
-                             - splt->output_offset
-                             - 16);
-
-         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[0], splt->contents +  0);
-         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[1], splt->contents +  4);
-         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[2], splt->contents +  8);
-         bfd_put_32 (output_bfd, elf32_arm_plt0_entry[3], splt->contents + 12);
 #ifdef FOUR_WORD_PLT
-         /* The displacement value goes in the otherwise-unused last word of
-            the second entry.  */
-         bfd_put_32 (output_bfd, got_displacement,        splt->contents + 28);
+             /* The displacement value goes in the otherwise-unused
+                last word of the second entry.  */
+             bfd_put_32 (output_bfd, got_displacement, splt->contents + 28);
 #else
-         bfd_put_32 (output_bfd, got_displacement,        splt->contents + 16);
+             bfd_put_32 (output_bfd, got_displacement, splt->contents + 16);
 #endif
+           }
        }
 
       /* UnixWare sets the entsize of .plt to 4, although that doesn't
         really seem like the right value.  */
       elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
+
+      if (htab->vxworks_p && !info->shared && htab->splt->size > 0)
+       {
+         /* Correct the .rel(a).plt.unloaded relocations.  They will have
+            incorrect symbol indexes.  */
+         int num_plts;
+         char *p;
+
+         num_plts = ((htab->splt->size - htab->plt_header_size)
+                     / htab->plt_entry_size);
+         p = htab->srelplt2->contents + RELOC_SIZE (htab);
+
+         for (; num_plts; num_plts--)
+           {
+             Elf_Internal_Rela rel;
+
+             SWAP_RELOC_IN (htab) (output_bfd, p, &rel);
+             rel.r_info = ELF32_R_INFO (htab->root.hgot->indx, R_ARM_ABS32);
+             SWAP_RELOC_OUT (htab) (output_bfd, &rel, p);
+             p += RELOC_SIZE (htab);
+
+             SWAP_RELOC_IN (htab) (output_bfd, p, &rel);
+             rel.r_info = ELF32_R_INFO (htab->root.hplt->indx, R_ARM_ABS32);
+             SWAP_RELOC_OUT (htab) (output_bfd, &rel, p);
+             p += RELOC_SIZE (htab);
+           }
+       }
     }
 
   /* Fill in the first three entries in the global offset table.  */
@@ -7443,7 +7741,7 @@ elf32_arm_output_symbol_hook (struct bfd_link_info *info,
                              const char *name,
                              Elf_Internal_Sym *elfsym,
                              asection *input_sec,
-                             struct elf_link_hash_entry *h ATTRIBUTE_UNUSED)
+                             struct elf_link_hash_entry *h)
 {
   int mapcount;
   elf32_arm_section_map *map;
@@ -7451,12 +7749,17 @@ elf32_arm_output_symbol_hook (struct bfd_link_info *info,
   _arm_elf_section_data *arm_data;
   struct elf32_arm_link_hash_table *globals;
 
+  globals = elf32_arm_hash_table (info);
+  if (globals->vxworks_p
+      && !elf_vxworks_link_output_symbol_hook (info, name, elfsym,
+                                              input_sec, h))
+    return FALSE;
+
   /* Only do this on final link.  */
   if (info->relocatable)
     return TRUE;
 
   /* Only build a map if we need to byteswap code.  */
-  globals = elf32_arm_hash_table (info);
   if (!globals->byteswap_code)
     return TRUE;
 
@@ -7837,27 +8140,48 @@ elf32_arm_vxworks_link_hash_table_create (bfd *abfd)
   if (ret)
     {
       struct elf32_arm_link_hash_table *htab
-       = (struct elf32_arm_link_hash_table *)ret;
+       = (struct elf32_arm_link_hash_table *) ret;
       htab->use_rel = 0;
+      htab->vxworks_p = 1;
     }
   return ret;
 }     
 
+static void
+elf32_arm_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
+{
+  elf32_arm_final_write_processing (abfd, linker);
+  elf_vxworks_final_write_processing (abfd, linker);
+}
+
 #undef elf32_bed
 #define elf32_bed elf32_arm_vxworks_bed
 
 #undef bfd_elf32_bfd_link_hash_table_create
 #define bfd_elf32_bfd_link_hash_table_create \
   elf32_arm_vxworks_link_hash_table_create
+#undef elf_backend_add_symbol_hook
+#define elf_backend_add_symbol_hook \
+  elf_vxworks_add_symbol_hook
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+  elf32_arm_vxworks_final_write_processing
+#undef elf_backend_emit_relocs
+#define elf_backend_emit_relocs \
+  elf_vxworks_emit_relocs
 
 #undef elf_backend_may_use_rel_p
-#define elf_backend_may_use_rel_p   0
+#define elf_backend_may_use_rel_p      0
 #undef elf_backend_may_use_rela_p
-#define elf_backend_may_use_rela_p  1
+#define elf_backend_may_use_rela_p     1
 #undef elf_backend_default_use_rela_p
-#define elf_backend_default_use_rela_p 1
+#define elf_backend_default_use_rela_p 1
 #undef elf_backend_rela_normal
-#define elf_backend_rela_normal     1
+#define elf_backend_rela_normal                1
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym       1
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE                        0x1000
 
 #include "elf32-target.h"
 
@@ -7969,6 +8293,7 @@ elf32_arm_symbian_modify_segment_map (bfd *abfd,
 #undef bfd_elf32_bfd_link_hash_table_create
 #define bfd_elf32_bfd_link_hash_table_create \
   elf32_arm_symbian_link_hash_table_create
+#undef elf_backend_add_symbol_hook
 
 #undef elf_backend_special_sections
 #define elf_backend_special_sections elf32_arm_symbian_special_sections
@@ -7976,6 +8301,10 @@ elf32_arm_symbian_modify_segment_map (bfd *abfd,
 #undef elf_backend_begin_write_processing
 #define elf_backend_begin_write_processing \
     elf32_arm_symbian_begin_write_processing
+#undef elf_backend_final_write_processing
+#define elf_backend_final_write_processing \
+  elf32_arm_final_write_processing
+#undef elf_backend_emit_relocs
 
 #undef elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map elf32_arm_symbian_modify_segment_map
@@ -7989,12 +8318,16 @@ elf32_arm_symbian_modify_segment_map (bfd *abfd,
 #define elf_backend_want_got_plt 0
 
 #undef elf_backend_may_use_rel_p
-#define elf_backend_may_use_rel_p   1
+#define elf_backend_may_use_rel_p      1
 #undef elf_backend_may_use_rela_p
-#define elf_backend_may_use_rela_p  0
+#define elf_backend_may_use_rela_p     0
 #undef elf_backend_default_use_rela_p
-#define elf_backend_default_use_rela_p 0
+#define elf_backend_default_use_rela_p 0
 #undef elf_backend_rela_normal
-#define elf_backend_rela_normal     0
+#define elf_backend_rela_normal                0
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym       0
+#undef ELF_MAXPAGESIZE
+#define ELF_MAXPAGESIZE                        0x8000
 
 #include "elf32-target.h"
index ca185b1d15cdc3bcd8bca4cec4d253eff6c8668e..5417f7e021fcea7e15f5b26b68d076d4f4eb939b 100644 (file)
@@ -1,3 +1,18 @@
+2006-03-07  Richard Sandiford  <richard@codesourcery.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+           Zack Weinberg  <zack@codesourcery.com>
+           Nathan Sidwell  <nathan@codesourcery.com>
+           Paul Brook  <paul@codesourcery.com>
+           Ricardo Anguiano  <anguiano@codesourcery.com>
+           Phil Edwards  <phil@codesourcery.com>
+
+       * config/tc-arm.c (md_apply_fix): Install a value of zero into a
+       BFD_RELOC_ARM_OFFSET_IMM field if we're going to generate a RELA
+       R_ARM_ABS12 reloc.
+       (tc_gen_reloc): Keep the original fx_offset for RELA pc-relative
+       relocs, but adjust by md_pcrel_from_section.  Create R_ARM_ABS12
+       relocations for BFD_RELOC_ARM_OFFSET_IMM on RELA targets.
+
 2006-03-06  Bob Wilson  <bob.wilson@acm.org>
 
        * config/tc-xtensa.c (xtensa_post_relax_hook): Generate literal tables
index 79da171f6f29fc3ac1d6d8b3d27be7aef3818c97..e98733d6dd09641fb3758f33dea9f378765a034e 100644 (file)
@@ -11535,6 +11535,9 @@ md_apply_fix (fixS *    fixP,
       break;
 
     case BFD_RELOC_ARM_OFFSET_IMM:
+      if (!fixP->fx_done && seg->use_rela_p)
+       value = 0;
+
     case BFD_RELOC_ARM_LITERAL:
       sign = value >= 0;
 
@@ -12256,8 +12259,7 @@ md_apply_fix (fixS *    fixP,
    format.  */
 
 arelent *
-tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
-             fixS *     fixp)
+tc_gen_reloc (asection *section, fixS *fixp)
 {
   arelent * reloc;
   bfd_reloc_code_real_type code;
@@ -12269,7 +12271,12 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
 
   if (fixp->fx_pcrel)
-    fixp->fx_offset = reloc->address;
+    {
+      if (section->use_rela_p)
+       fixp->fx_offset -= md_pcrel_from_section (fixp, section);
+      else
+       fixp->fx_offset = reloc->address;
+    }
   reloc->addend = fixp->fx_offset;
 
   switch (fixp->fx_r_type)
@@ -12357,6 +12364,12 @@ tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
       return NULL;
 
     case BFD_RELOC_ARM_OFFSET_IMM:
+      if (section->use_rela_p)
+       {
+         code = fixp->fx_r_type;
+         break;
+       }
+
       if (fixp->fx_addsy != NULL
          && !S_IS_DEFINED (fixp->fx_addsy)
          && S_IS_LOCAL (fixp->fx_addsy))
index 28adf506561e5af17507cd1e8870332521ed49f5..2eb5dbcd991d44a9142cb5767ccce3b9f3b5812c 100644 (file)
@@ -1,3 +1,10 @@
+2006-03-07  Richard Sandiford  <richard@codesourcery.com>
+
+       * gas/arm/abs12.s, gas/arm/abs12.d: New test.
+       * gas/arm/pic.d: Skip for *-*-vxworks*...
+       * gas/arm/pic_vxworks.d: ...use this version instead.
+       * gas/arm/unwind_vxworks.d: Fix expected output.
+
 2006-03-06  Nathan Sidwell  <nathan@codesourcery.com>
 
        * gas/m68k/arch-cpu-1.s: Tweak.
diff --git a/gas/testsuite/gas/arm/abs12.d b/gas/testsuite/gas/arm/abs12.d
new file mode 100644 (file)
index 0000000..5d4bb3b
--- /dev/null
@@ -0,0 +1,20 @@
+#objdump: -dr
+#not-skip: *-vxworks
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <\.text>:
+   0:  e5910000        ldr     r0, \[r1\]
+                       0: R_ARM_ABS12  global
+   4:  e5910000        ldr     r0, \[r1\]
+                       4: R_ARM_ABS12  global\+0xc
+   8:  e5910000        ldr     r0, \[r1\]
+                       8: R_ARM_ABS12  global\+0x100000
+   c:  e5910000        ldr     r0, \[r1\]
+                       c: R_ARM_ABS12  \.text\+0x18
+  10:  e5910000        ldr     r0, \[r1\]
+                       10: R_ARM_ABS12 \.text\+0x24
+  14:  e5910000        ldr     r0, \[r1\]
+                       14: R_ARM_ABS12 \.text\+0x100018
diff --git a/gas/testsuite/gas/arm/abs12.s b/gas/testsuite/gas/arm/abs12.s
new file mode 100644 (file)
index 0000000..9c2faa5
--- /dev/null
@@ -0,0 +1,7 @@
+       ldr     r0,[r1,#global]
+       ldr     r0,[r1,#global + 12]
+       ldr     r0,[r1,#global + 0x100000]
+       ldr     r0,[r1,#local]
+       ldr     r0,[r1,#local + 12]
+       ldr     r0,[r1,#local + 0x100000]
+local:
index 8eed71df4811a47c137b2be319841bae07b0a9f9..f5232a36992efbaa1477244706a83041897cbbcd 100644 (file)
@@ -2,6 +2,8 @@
 #name: PIC
 # This test is only valid on ELF based ports.
 #not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+# VxWorks needs a special variant of this file.
+#skip: *-*-vxworks*
 
 # Test generation of PIC
 
diff --git a/gas/testsuite/gas/arm/pic_vxworks.d b/gas/testsuite/gas/arm/pic_vxworks.d
new file mode 100644 (file)
index 0000000..f7db8aa
--- /dev/null
@@ -0,0 +1,22 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: PIC
+#source: pic.s
+#not-skip: *-*-vxworks*
+
+# Test generation of PIC
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+00+0 <[^>]*> eb000000  bl      .*
+                       0: R_ARM_PC24   foo\+0xfffffff8
+00+4 <[^>]*> eb000000  bl      .*
+                       4: R_ARM_PLT32  foo\+0xfffffff8
+       \.\.\.
+                       8: R_ARM_ABS32  sym
+                       c: R_ARM_GOT32  sym
+                       10: R_ARM_GOTOFF32      sym
+                       14: R_ARM_GOTPC _GLOBAL_OFFSET_TABLE_
+                       18: R_ARM_TARGET1       foo2
+                       1c: R_ARM_SBREL32       foo3
+                       20: R_ARM_TARGET2       foo4
index 333e6ce6a055bdfb79e595bc0182cf07bfc58527..ccd16a65cc9aae3770d32a2520b811474e543222 100644 (file)
@@ -1,7 +1,5 @@
 #objdump: -sr
 #name: Unwind table generation
-# This test is only valid on ELF based ports.
-#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
 # This is the VxWorks variant of this file.
 #source: unwind.s
 #not-skip: *-*-vxworks*
 
 RELOCATION RECORDS FOR \[.ARM.extab\]:
 OFFSET   TYPE              VALUE 
-0000000c R_ARM_PREL31      .text\+0x0+c
+0000000c R_ARM_PREL31      .text
 
 
 RELOCATION RECORDS FOR \[.ARM.exidx\]:
 OFFSET   TYPE              VALUE 
 00000000 R_ARM_PREL31      .text
 00000000 R_ARM_NONE        __aeabi_unwind_cpp_pr0
-00000008 R_ARM_PREL31      .text.*
-00000008 R_ARM_NONE        __aeabi_unwind_cpp_pr1\+0x0+8
-0000000c R_ARM_PREL31      .ARM.extab\+0x0+c
-00000010 R_ARM_PREL31      .text.*
-00000014 R_ARM_PREL31      .ARM.extab.*
-00000018 R_ARM_PREL31      .text.*
-0000001c R_ARM_PREL31      .ARM.extab.*
-00000020 R_ARM_PREL31      .text.*
-00000028 R_ARM_PREL31      .text.*
+00000008 R_ARM_PREL31      .text.*\+0x00000004
+00000008 R_ARM_NONE        __aeabi_unwind_cpp_pr1
+0000000c R_ARM_PREL31      .ARM.extab
+00000010 R_ARM_PREL31      .text.*\+0x00000008
+00000014 R_ARM_PREL31      .ARM.extab.*\+0x0000000c
+00000018 R_ARM_PREL31      .text.*\+0x0000000c
+0000001c R_ARM_PREL31      .ARM.extab.*\+0x0000001c
+00000020 R_ARM_PREL31      .text.*\+0x00000010
+00000028 R_ARM_PREL31      .text.*\+0x00000012
 
 
 Contents of section .text:
@@ -36,8 +34,8 @@ Contents of section .ARM.extab:
  0010 (8402b101 b0b0b005 2a000000 00c60181|01b10284 05b0b0b0 0000002a 8101c600)  .*
  0020 (b0b0c1c1|c1c1b0b0) 00000000                    .*
 Contents of section .ARM.exidx:
- 0000 00000000 (b0b0a880 00000000|80a8b0b0 00000000) 00000000  .*
+ 0000 00000000 (b0b0a880|80a8b0b0) 00000000 00000000  .*
  0010 00000000 00000000 00000000 00000000  .*
- 0020 (00000000 08849780 00000000 b00fb180|00000000 80978408 00000000 80b10fb0)  .*
+ 0020 00000000 (08849780|80978408) 00000000 (b00fb180|80b10fb0)  .*
 # Ignore .ARM.attributes section
 #...
index 9bdfcc4c2010b97684efa73eb5e9408f26419fb3..6f091b0bb95c585a34ddd1ff95eba619fdefdc6c 100644 (file)
@@ -1,3 +1,17 @@
+2006-03-07  Richard Sandiford  <richard@codesourcery.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+           Zack Weinberg  <zack@codesourcery.com>
+           Nathan Sidwell  <nathan@codesourcery.com>
+           Paul Brook  <paul@codesourcery.com>
+           Ricardo Anguiano  <anguiano@codesourcery.com>
+           Phil Edwards  <phil@codesourcery.com>
+
+       * emulparams/armelf_vxworks.sh: Include vxworks.sh.
+       (MAXPAGESIZE): Define.
+       * emulparams/vxworks.sh: Undefine EMBEDDED.
+       * Makefile.am (earmelf_vxworks.c): Depend on vxworks.sh and vxworks.em.
+       * Makefile.in: Regenerate.
+
 2006-03-03  Bjoern Haase  <bjoern.m.haase@web.de>
 
        * scripttempl/avr.sc:  Add *(.jumptables) *(.lowtext) sections.
index 9679af038bd41580a52f79c7b6abc3442172c4c6..db64da4d966a59635983beb557c514e24092c14c 100644 (file)
@@ -539,7 +539,8 @@ earmelfb_nbsd.c: $(srcdir)/emulparams/armelfb_nbsd.sh \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} armelfb_nbsd "$(tdir_armelfb_nbsd)"
 earmelf_vxworks.c: $(srcdir)/emulparams/armelf_vxworks.sh \
-  $(srcdir)/emulparams/armelf.sh $(srcdir)/emultempl/elf32.em \
+  $(srcdir)/emulparams/vxworks.sh $(srcdir)/emulparams/armelf.sh \
+  $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/vxworks.em \
   $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc \
   ${GEN_DEPENDS}
        ${GENSCRIPTS} armelf_vxworks "$(tdir_armelf)"
index 264f0360dabe3c9eac826e5872b720d502e6465a..dff417394dcabf454429a668d339a56b7cea3020 100644 (file)
@@ -1345,7 +1345,8 @@ earmelfb_nbsd.c: $(srcdir)/emulparams/armelfb_nbsd.sh \
   $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
        ${GENSCRIPTS} armelfb_nbsd "$(tdir_armelfb_nbsd)"
 earmelf_vxworks.c: $(srcdir)/emulparams/armelf_vxworks.sh \
-  $(srcdir)/emulparams/armelf.sh $(srcdir)/emultempl/elf32.em \
+  $(srcdir)/emulparams/vxworks.sh $(srcdir)/emulparams/armelf.sh \
+  $(srcdir)/emultempl/elf32.em $(srcdir)/emultempl/vxworks.em \
   $(srcdir)/emultempl/armelf.em $(srcdir)/scripttempl/elf.sc \
   ${GEN_DEPENDS}
        ${GENSCRIPTS} armelf_vxworks "$(tdir_armelf)"
index 5b0f3d82526ec6b01e021c9234144d0d58a71768..7b6445e8308288acdf573c941d90141f9423eecc 100644 (file)
@@ -2,3 +2,5 @@
 OUTPUT_FORMAT="elf32-littlearm-vxworks"
 BIG_OUTPUT_FORMAT="elf32-bigarm-vxworks"
 LITTLE_OUTPUT_FORMAT="$OUTPUT_FORMAT"
+MAXPAGESIZE=0x1000
+. ${srcdir}/emulparams/vxworks.sh
index e62673295b9674e4d0c54ce5750ae39c840d2051..4382859e645c432d7e838d86351972620cf0b9f2 100644 (file)
@@ -25,3 +25,4 @@ OTHER_SYMBOLS="PROVIDE (_ehdr = ${TEXT_START_ADDR});"
 DATA_END_SYMBOLS=".edata : { PROVIDE (_edata = .); }"
 VXWORKS_BASE_EM_FILE=$EXTRA_EM_FILE
 EXTRA_EM_FILE=vxworks
+unset EMBEDDED
index aacef8feda06fae892fe43a445e74b5fac8f0c4a..972581c4a504f5a2ee9a43bab1e3a88aab5e4b66 100644 (file)
@@ -1,3 +1,12 @@
+2006-03-07  Richard Sandiford  <richard@codesourcery.com>
+
+       * ld-arm/vxworks1.dd, ld-arm/vxworks1.ld, ld-arm/vxworks1-lib.dd,
+       * ld-arm/vxworks1-lib.nd, ld-arm/vxworks1-lib.rd,
+       * ld-arm/vxworks1-lib.s, ld-arm/vxworks1.rd, ld-arm/vxworks1.s,
+       * ld-arm/vxworks1-static.d, ld-arm/vxworks2.s, ld-arm/vxworks2.sd,
+       * ld-arm/vxworks2-static.sd: New tests.
+       * ld-arm/arm-elf.exp: Run them.
+
 2006-03-06  Nathan Sidwell  <nathan@codesourcery.com>
 
        * ld-m68k: New tests.
index 76a743e1f2e23c167569eba117f2dd31284e7380..1cb231faf1460cb9f18d4e1fade4127d359ae1ee 100644 (file)
 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 #
 
+if {[istarget "arm-*-vxworks"]} {
+    set armvxworkstests {
+       {"VxWorks shared library test 1" "-shared -Tvxworks1.ld"
+        "" {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 $armvxworkstests
+    run_dump_test "vxworks1-static"
+}
+
 # Exclude non-ARM-ELF targets.
 
 if { ![is_elf_format] || ![istarget "arm*-*-*"] } {
diff --git a/ld/testsuite/ld-arm/vxworks1-lib.dd b/ld/testsuite/ld-arm/vxworks1-lib.dd
new file mode 100644 (file)
index 0000000..e13254d
--- /dev/null
@@ -0,0 +1,41 @@
+
+.*:     file format .*
+
+Disassembly of section \.plt:
+
+00080800 <_PROCEDURE_LINKAGE_TABLE_>:
+   80800:      e59fc000        ldr     ip, \[pc, #0\]  ; 80808 <_PROCEDURE_LINKAGE_TABLE_\+0x8>
+   80804:      e79cf009        ldr     pc, \[ip, r9\]
+   80808:      0000000c        andeq   r0, r0, ip
+   8080c:      e59fc000        ldr     ip, \[pc, #0\]  ; 80814 <_PROCEDURE_LINKAGE_TABLE_\+0x14>
+   80810:      e599f008        ldr     pc, \[r9, #8\]
+   80814:      00000000        andeq   r0, r0, r0
+   80818:      e59fc000        ldr     ip, \[pc, #0\]  ; 80820 <_PROCEDURE_LINKAGE_TABLE_\+0x20>
+   8081c:      e79cf009        ldr     pc, \[ip, r9\]
+   80820:      00000010        andeq   r0, r0, r0, lsl r0
+   80824:      e59fc000        ldr     ip, \[pc, #0\]  ; 8082c <_PROCEDURE_LINKAGE_TABLE_\+0x2c>
+   80828:      e599f008        ldr     pc, \[r9, #8\]
+   8082c:      0000000c        andeq   r0, r0, ip
+Disassembly of section \.text:
+
+00080c00 <foo>:
+   80c00:      e92dc200        stmdb   sp!, {r9, lr, pc}
+   80c04:      e59f9024        ldr     r9, \[pc, #36\] ; 80c30 <\.text\+0x30>
+   80c08:      e5999000        ldr     r9, \[r9\]
+   80c0c:      e5999000        ldr     r9, \[r9\]
+   80c10:      e59f001c        ldr     r0, \[pc, #28\] ; 80c34 <\.text\+0x34>
+   80c14:      e7991000        ldr     r1, \[r9, r0\]
+   80c18:      e2811001        add     r1, r1, #1      ; 0x1
+   80c1c:      e7891000        str     r1, \[r9, r0\]
+   80c20:      eb000004        bl      80c38 <slocal>
+   80c24:      ebfffefb        bl      80818 <_PROCEDURE_LINKAGE_TABLE_\+0x18>
+   80c28:      ebfffef4        bl      80800 <_PROCEDURE_LINKAGE_TABLE_>
+   80c2c:      e8bd8200        ldmia   sp!, {r9, pc}
+   80c30:      00000000        andeq   r0, r0, r0
+   80c34:      00000014        andeq   r0, r0, r4, lsl r0
+
+00080c38 <slocal>:
+   80c38:      e1a0f00e        mov     pc, lr
+
+00080c3c <sglobal>:
+   80c3c:      e1a0f00e        mov     pc, lr
diff --git a/ld/testsuite/ld-arm/vxworks1-lib.nd b/ld/testsuite/ld-arm/vxworks1-lib.nd
new file mode 100644 (file)
index 0000000..edf3db3
--- /dev/null
@@ -0,0 +1,9 @@
+#...
+Symbol table '\.dynsym' .*:
+#...
+.*: 00081400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#...
+Symbol table '\.symtab' .*:
+#...
+.*: 00081400 * 0 * OBJECT * GLOBAL * DEFAULT * [0-9]+ _GLOBAL_OFFSET_TABLE_
+#pass
diff --git a/ld/testsuite/ld-arm/vxworks1-lib.rd b/ld/testsuite/ld-arm/vxworks1-lib.rd
new file mode 100644 (file)
index 0000000..c4c46f6
--- /dev/null
@@ -0,0 +1,12 @@
+
+Relocation section '\.rela\.plt' at offset .* contains 2 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+0008140c  .*16 R_ARM_JUMP_SLOT   00000000   sexternal \+ 0
+00081410  .*16 R_ARM_JUMP_SLOT   00080c3c   sglobal \+ 0
+
+Relocation section '\.rela\.dyn' at offset .* contains 4 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+00081c00  00000017 R_ARM_RELATIVE * 00080c38
+00080c0c  .*06 R_ARM_ABS12       00000000   __GOTT_INDEX__ \+ 0
+00080c30  .*02 R_ARM_ABS32       00000000   __GOTT_BASE__ \+ 0
+00081414  .*15 R_ARM_GLOB_DAT    00081800   x \+ 0
diff --git a/ld/testsuite/ld-arm/vxworks1-lib.s b/ld/testsuite/ld-arm/vxworks1-lib.s
new file mode 100644 (file)
index 0000000..66dfd1e
--- /dev/null
@@ -0,0 +1,36 @@
+       .text
+       .globl  foo
+       .type   foo, %function
+foo:
+       stmfd   sp!, {r9, lr, pc}
+       ldr     r9, 1f
+       ldr     r9, [r9]
+       ldr     r9, [r9, #__GOTT_INDEX__]
+       ldr     r0, 1f + 4
+       ldr     r1, [r9, r0]
+       add     r1, r1, #1
+       str     r1, [r9, r0]
+       bl      slocal(PLT)
+       bl      sglobal(PLT)
+       bl      sexternal(PLT)
+       ldmfd   sp!, {r9, pc}
+1:
+       .word   __GOTT_BASE__
+       .word   x(got)
+       .size   foo, .-foo
+
+       .type   slocal, %function
+slocal:
+       mov     pc,lr
+       .size   slocal, .-slocal
+
+       .globl  sglobal
+       .type   sglobal, %function
+sglobal:
+       mov     pc,lr
+       .size   sglobal, .-sglobal
+
+       .data
+       .4byte  slocal
+
+       .comm   x,4,4
diff --git a/ld/testsuite/ld-arm/vxworks1-static.d b/ld/testsuite/ld-arm/vxworks1-static.d
new file mode 100644 (file)
index 0000000..88c0baf
--- /dev/null
@@ -0,0 +1,4 @@
+#name: VxWorks executable test 1 (static)
+#source: vxworks1.s
+#ld: tmpdir/libvxworks1.so -Tvxworks1.ld
+#error: Dynamic sections created in non-dynamic link
diff --git a/ld/testsuite/ld-arm/vxworks1.dd b/ld/testsuite/ld-arm/vxworks1.dd
new file mode 100644 (file)
index 0000000..529e3a5
--- /dev/null
@@ -0,0 +1,37 @@
+
+.*:     file format .*
+
+Disassembly of section \.plt:
+
+00080800 <_PROCEDURE_LINKAGE_TABLE_>:
+   80800:      e52dc008        str     ip, \[sp, #-8\]!
+   80804:      e59fc000        ldr     ip, \[pc, #0\]  ; 8080c <_PROCEDURE_LINKAGE_TABLE_\+0xc>
+   80808:      e59cf008        ldr     pc, \[ip, #8\]
+   8080c:      00081400        andeq   r1, r8, r0, lsl #8
+                       8080c: R_ARM_ABS32      _GLOBAL_OFFSET_TABLE_
+   80810:      e59fc000        ldr     ip, \[pc, #0\]  ; 80818 <_PROCEDURE_LINKAGE_TABLE_\+0x18>
+   80814:      e59cf000        ldr     pc, \[ip\]
+   80818:      0008140c        andeq   r1, r8, ip, lsl #8
+                       80818: R_ARM_ABS32      _GLOBAL_OFFSET_TABLE_\+0xc
+   8081c:      e59fc000        ldr     ip, \[pc, #0\]  ; 80824 <_PROCEDURE_LINKAGE_TABLE_\+0x24>
+   80820:      eafffff6        b       80800 <_PROCEDURE_LINKAGE_TABLE_>
+   80824:      00000000        andeq   r0, r0, r0
+   80828:      e59fc000        ldr     ip, \[pc, #0\]  ; 80830 <_PROCEDURE_LINKAGE_TABLE_\+0x30>
+   8082c:      e59cf000        ldr     pc, \[ip\]
+   80830:      00081410        andeq   r1, r8, r0, lsl r4
+                       80830: R_ARM_ABS32      _GLOBAL_OFFSET_TABLE_\+0x10
+   80834:      e59fc000        ldr     ip, \[pc, #0\]  ; 8083c <_PROCEDURE_LINKAGE_TABLE_\+0x3c>
+   80838:      eafffff0        b       80800 <_PROCEDURE_LINKAGE_TABLE_>
+   8083c:      0000000c        andeq   r0, r0, ip
+Disassembly of section \.text:
+
+00080c00 <_start>:
+   80c00:      ebffff08        bl      80428 <_PROCEDURE_LINKAGE_TABLE_-0x3d8>
+                       80c00: R_ARM_PC24       \.plt\+0x20
+   80c04:      eb000000        bl      80c14 <sexternal\+0x8>
+                       80c04: R_ARM_PC24       sexternal\+0xfffffff8
+   80c08:      eaffff00        b       80408 <_PROCEDURE_LINKAGE_TABLE_-0x3f8>
+                       80c08: R_ARM_PC24       \.plt\+0x8
+
+00080c0c <sexternal>:
+   80c0c:      e1a0f00e        mov     pc, lr
diff --git a/ld/testsuite/ld-arm/vxworks1.ld b/ld/testsuite/ld-arm/vxworks1.ld
new file mode 100644 (file)
index 0000000..ec5039d
--- /dev/null
@@ -0,0 +1,30 @@
+SECTIONS
+{
+  . = 0x80000;
+  .interp : { *(.interp) }
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+
+  . = ALIGN (0x400);
+  .rela.dyn : { *(.rela.dyn) }
+  .rela.plt : { *(.rela.plt) }
+
+  . = ALIGN (0x400);
+  .plt : { *(.plt) }
+
+  . = ALIGN (0x400);
+  .text : { *(.text) }
+
+  . = ALIGN (0x1000);
+  .dynamic : { *(.dynamic) }
+
+  . = ALIGN (0x400);
+  .got : { *(.got.plt) *(.got) }
+
+  . = ALIGN (0x400);
+  .bss : { *(.bss) *(.dynbss) }
+
+  . = ALIGN (0x400);
+  .data : { *(.data) }
+}
diff --git a/ld/testsuite/ld-arm/vxworks1.rd b/ld/testsuite/ld-arm/vxworks1.rd
new file mode 100644 (file)
index 0000000..8d7d5cb
--- /dev/null
@@ -0,0 +1,19 @@
+
+Relocation section '\.rela\.plt' at offset .* contains 2 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+0008140c  .*16 R_ARM_JUMP_SLOT   00080810   sglobal \+ 0
+00081410  .*16 R_ARM_JUMP_SLOT   00080828   foo \+ 0
+
+Relocation section '\.rela\.text' at offset .* contains 3 entries:
+ Offset     Info    Type            Sym.Value  Sym. Name \+ Addend
+00080c00  .*01 R_ARM_PC24        00080800   \.plt \+ 20
+00080c04  .*01 R_ARM_PC24        00080c0c   sexternal \+ fffffff8
+00080c08  .*01 R_ARM_PC24        00080800   \.plt \+ 8
+
+Relocation section '\.rela\.plt\.unloaded' at offset .* contains 5 entries:
+ Offset     Info    Type            Sym\.Value  Sym\. Name \+ Addend
+0008080c  .*02 R_ARM_ABS32       00081400   _GLOBAL_OFFSET_TABLE_ \+ 0
+00080818  .*02 R_ARM_ABS32       00081400   _GLOBAL_OFFSET_TABLE_ \+ c
+0008140c  .*02 R_ARM_ABS32       00080800   _PROCEDURE_LINKAGE_TAB.* \+ 0
+00080830  .*02 R_ARM_ABS32       00081400   _GLOBAL_OFFSET_TABLE_ \+ 10
+00081410  .*02 R_ARM_ABS32       00080800   _PROCEDURE_LINKAGE_TAB.* \+ 0
diff --git a/ld/testsuite/ld-arm/vxworks1.s b/ld/testsuite/ld-arm/vxworks1.s
new file mode 100644 (file)
index 0000000..0139a11
--- /dev/null
@@ -0,0 +1,14 @@
+       .text
+       .globl  _start
+       .type   _start, %function
+_start:
+       bl      foo
+       bl      sexternal
+       b       sglobal
+       .size   _start, .-_start
+
+       .globl  sexternal
+       .type   sexternal, %function
+sexternal:
+       mov     pc, lr
+       .size   sexternal, .-sexternal
diff --git a/ld/testsuite/ld-arm/vxworks2-static.sd b/ld/testsuite/ld-arm/vxworks2-static.sd
new file mode 100644 (file)
index 0000000..912755b
--- /dev/null
@@ -0,0 +1,9 @@
+#...
+Elf file type is EXEC \(Executable file\)
+Entry point 0x80000
+#...
+Program Headers:
+  Type .*
+  LOAD .* 0x00080000 0x00080000 .* R E 0x1000
+
+#...
diff --git a/ld/testsuite/ld-arm/vxworks2.s b/ld/testsuite/ld-arm/vxworks2.s
new file mode 100644 (file)
index 0000000..1bd207b
--- /dev/null
@@ -0,0 +1,5 @@
+       .globl  _start
+       .type   _start, %function
+_start:
+       mov     pc, lr
+       .end    _start
diff --git a/ld/testsuite/ld-arm/vxworks2.sd b/ld/testsuite/ld-arm/vxworks2.sd
new file mode 100644 (file)
index 0000000..5ff87d3
--- /dev/null
@@ -0,0 +1,13 @@
+#...
+Elf file type is EXEC \(Executable file\)
+Entry point 0x80400
+#...
+Program Headers:
+  Type .*
+  PHDR .*
+#...
+  LOAD .* 0x00080000 0x00080000 .* R E 0x1000
+  LOAD .* 0x00081000 0x00081000 .* RW  0x1000
+  DYNAMIC .*
+
+#...