This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] i386 vxworks shared libraries - second try


On Thursday 05 May 2005 05:26, Alan Modra wrote:
> On Fri, Apr 29, 2005 at 12:43:51AM +0100, Paul Brook wrote:
> > Attached is a revised patch for i386 vxworks shared library support. The
>
> OK.  Except
>
> +	     createing a definition in the output file but it does not come
> +	     from any of out normal (.o) files. ie. a PLT stub.
>
> creating, our
>
> +	    {
> +	      memcpy (htab->splt->contents,
> +		      elf_i386_pic_plt0_entry, PLT_ENTRY_SIZE);
> +	      memset (htab->splt->contents + 12, htab->plt0_pad_byte, 4);
> +	    }
>
> I'd prefer if you change the size of elf_i386_pic_plt0_entry to 12 bytes
> and not use hardcoded numbers here.  The same goes for
> elf_i386_plt0_entry.

Applies as attached.

2005-05-05  Paul Brook  <paul@codesourcery.com>

bfd/
	* config.bfd: Use bfd_elf32_i386_vxworks_vec for i?86-*-vxworks.
	* configure.in: Add bfd_elf32_i386_vxworks_vec. i386 targets need
	elf-vxworks.lo.
	* configure: Regenerate.
	* Makefile.am (BFD32_BACKENDS): Add elf-vxworks.lo.
	(BFD32_BACKENDS_CFILES): Add elf-vxworks.c.
	(elf32-i386.lo): Depend on elf-vxworks.h.
	(elf-vxworks.lo): New rule.
	* Makefile.in: Regenerate.
	* elf-bfd.h (elf_backend_data): Update type of
	elf_backend_emit_relocs.
	(_bfd_elf_link_output_relocs): Update prototype.
	* elflink.c (_bfd_elf_link_output_relocs): Always use
	bed->elf_backend_emit_relocs when outputting relocations.
	* elfxx-target.h (elf_backend_emit_relocs): Default to
	_bfd_elf_link_output_relocs.
	* targets.c (bfd_elf32_i386_vxworks_vec): Declare.
	(_bfd_target_vector): Add bfd_elf32_i386_vxworks_vec.
	* elf32-i386.c: Add elf32-i386-vxworks target BFD.
	(elf_i386_plt0_entry): Remove padding.
	(elf_i386_pic_plt0_entry): Ditto.
	(PLTRESOLVE_RELOCS_SHLIB, PLTRESOLVE_RELOCS): Define.
	(PLT_NON_JUMP_SLOT_RELOCS): Define.
	(elf_i386_link_hash_table): Add srelplt2, hgot, hplt, is_vxworks and
	plt0_pad_byte fields.
	(elf_i386_link_hash_table_create): Zero them.
	(elf_i386_create_dynamic_sections): Create static relocation section.
	(allocate_dynrelocs): Allocate space for static PLT relocations.
	(elf_i386_size_dynamic_sections): Save shortcuts to PLT and GOT
	symbols.  Give PLT symbols function type.  Don't strip PLT sections
	if we have exported symbols from them. 
	(elf_i386_finish_dynamic_symbol): Fill in VxWorks PLT static
	relocation section.  Don't mark _GLOBAL_OFFSET_TABLE_ as absolute on
	VxWorks.
	(elf_i386_finish_dynamic_sections): Allow different pad bytes.
	Add relocation for GOT location.  Fill in PLT static relocations.
	(elf_i386_vxworks_link_hash_table_create): New function.
	(elf_i386_vxworks_link_output_symbol_hook): New function.
	* elf-vxworks.h: New file.
gas/
	* config/tc-i386.h (ELF_TARGET_FORMAT): Define for TE_VXWORKS.
gas/testsuite/
	* gas/i386/i386.exp: Don't run divide test on vxworks.
ld/
	* Makefile.am: Add eelf_i386_vxworks.
	* Makefile.in: Regenerate.
	* configure.tgt: Make i?86-*-vxworks use targ_emul=elf_i386_vxworks.
	* emulparams/elf_i386_vxworks.sh: New file.
	* emulparams/vxworks.sh: New file.
	* scripttempl/elf.sc: Add DATA_END_SYMBOLS and ETEXT_NAME.
Index: bfd/Makefile.am
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/Makefile.am,v
retrieving revision 1.154
diff -u -p -r1.154 Makefile.am
--- bfd/Makefile.am	5 May 2005 03:42:00 -0000	1.154
+++ bfd/Makefile.am	5 May 2005 13:52:05 -0000
@@ -271,6 +271,7 @@ BFD32_BACKENDS = \
 	elflink.lo \
 	elf-strtab.lo \
 	elf-eh-frame.lo \
+	elf-vxworks.lo \
 	epoc-pe-arm.lo \
 	epoc-pei-arm.lo \
 	hp300bsd.lo \
@@ -440,6 +441,7 @@ BFD32_BACKENDS_CFILES = \
 	elflink.c \
 	elf-strtab.c \
 	elf-eh-frame.c \
+	elf-vxworks.c \
 	epoc-pe-arm.c \
 	epoc-pei-arm.c \
 	hp300bsd.c \
@@ -1263,7 +1265,7 @@ elf32-i370.lo: elf32-i370.c $(INCDIR)/fi
 elf32-i386.lo: elf32-i386.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/i386.h \
-  $(INCDIR)/elf/reloc-macros.h elf32-target.h
+  $(INCDIR)/elf/reloc-macros.h elf32-target.h elf-vxworks.h
 elf32-i860.lo: elf32-i860.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/i860.h \
@@ -1422,6 +1424,10 @@ elf-eh-frame.lo: elf-eh-frame.c $(INCDIR
   $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
   $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
   $(INCDIR)/elf/dwarf2.h
+elf-vxworks.lo: elf-vxworks.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/reloc-macros.h elf-vxworks.h
 epoc-pe-arm.lo: epoc-pe-arm.c pe-arm.c $(INCDIR)/filenames.h \
   coff-arm.c $(INCDIR)/hashtab.h $(INCDIR)/coff/arm.h \
   $(INCDIR)/coff/external.h $(INCDIR)/coff/internal.h \
Index: bfd/config.bfd
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/config.bfd,v
retrieving revision 1.184
diff -u -p -r1.184 config.bfd
--- bfd/config.bfd	29 Apr 2005 18:41:45 -0000	1.184
+++ bfd/config.bfd	5 May 2005 13:52:05 -0000
@@ -606,7 +606,7 @@ case "${targ}" in
     targ_defvec=i386aout_vec
     ;;
   i[3-7]86-*-vxworks)
-    targ_defvec=bfd_elf32_i386_vec
+    targ_defvec=bfd_elf32_i386_vxworks_vec
     targ_underscore=yes
     ;;
   i[3-7]86-*-chaos)
Index: bfd/configure.in
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/configure.in,v
retrieving revision 1.180
diff -u -p -r1.180 configure.in
--- bfd/configure.in	5 May 2005 03:42:00 -0000	1.180
+++ bfd/configure.in	5 May 2005 13:52:05 -0000
@@ -591,8 +591,9 @@ do
     bfd_elf32_hppa_nbsd_vec)	tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
     bfd_elf32_hppa_vec)		tb="$tb elf32-hppa.lo elf32.lo $elf" ;;
     bfd_elf32_i370_vec)		tb="$tb elf32-i370.lo elf32.lo $elf" ;;
-    bfd_elf32_i386_freebsd_vec)	tb="$tb elf32-i386.lo elf32.lo $elf" ;;
-    bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_freebsd_vec)	tb="$tb elf32-i386.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i860_little_vec)	tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i860_vec)		tb="$tb elf32-i860.lo elf32.lo $elf" ;;
     bfd_elf32_i960_vec)		tb="$tb elf32-i960.lo elf32.lo $elf" ;;
Index: bfd/elf-bfd.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf-bfd.h,v
retrieving revision 1.182
diff -u -p -r1.182 elf-bfd.h
--- bfd/elf-bfd.h	4 May 2005 15:53:07 -0000	1.182
+++ bfd/elf-bfd.h	5 May 2005 13:52:06 -0000
@@ -873,7 +873,8 @@ struct elf_backend_data
   /* Emit relocations.  Overrides default routine for emitting relocs,
      except during a relocatable link, or if all relocs are being emitted.  */
   bfd_boolean (*elf_backend_emit_relocs)
-    (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *);
+    (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
+     struct elf_link_hash_entry **);
 
   /* Count relocations.  Not called for relocatable links
      or if all relocs are being preserved in the output.  */
@@ -1606,7 +1607,8 @@ extern bfd_boolean _bfd_elf_link_size_re
   (bfd *, Elf_Internal_Shdr *, asection *);
 
 extern bfd_boolean _bfd_elf_link_output_relocs
-  (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *);
+  (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
+   struct elf_link_hash_entry **);
 
 extern bfd_boolean _bfd_elf_fix_symbol_flags
   (struct elf_link_hash_entry *, struct elf_info_failed *);
Index: bfd/elf-vxworks.c
===================================================================
RCS file: bfd/elf-vxworks.c
diff -N bfd/elf-vxworks.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bfd/elf-vxworks.c	5 May 2005 13:55:10 -0000
@@ -0,0 +1,151 @@
+/* VxWorks support for ELF
+   Copyright 2005 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* This file provides routines used by all VxWorks targets.  */
+
+#include "bfd.h"
+#include "sysdep.h"
+#include "libbfd.h"
+#include "elf-bfd.h"
+#include "elf-vxworks.h"
+
+/* Tweak magic VxWorks symbols as they are loaded.  */
+bfd_boolean
+elf_vxworks_add_symbol_hook (bfd *abfd ATTRIBUTE_UNUSED,
+			     struct bfd_link_info *info,
+			     Elf_Internal_Sym *sym,
+			     const char **namep,
+			     flagword *flagsp,
+			     asection **secp ATTRIBUTE_UNUSED,
+			     bfd_vma *valp ATTRIBUTE_UNUSED)
+{
+  /* Ideally these "magic" symbols would be exported by libc.so.1
+     which would be found via a DT_NEEDED tag, and then handled
+     specially by the linker at runtime.  Except shared libraries
+     don't even link to libc.so.1 by default...
+     If the symbol is imported from, or will be put in a shared library,
+     give the symbol weak binding to get the desired samantics.
+     This transformation will be undone in
+     elf_i386_vxworks_link_output_symbol_hook. */
+  if ((info->shared || abfd->flags & DYNAMIC)
+      && (strcmp (*namep, "__GOTT_INDEX__") == 0
+	  || strcmp (*namep, "__GOTT_BASE__") == 0))
+    {
+      sym->st_info = ELF_ST_INFO (STB_WEAK, ELF_ST_TYPE (sym->st_info));
+      *flagsp |= BSF_WEAK;
+    }
+
+  return TRUE;
+}
+
+
+/* Tweak magic VxWorks symbols as they are written to the output file.  */
+bfd_boolean
+elf_vxworks_link_output_symbol_hook (const char *name,
+				     Elf_Internal_Sym *sym)
+{
+  /* Reverse the effects of the hack in elf_vxworks_add_symbol_hook.  */
+  if (strcmp (name, "__GOTT_INDEX__") == 0
+      || strcmp (name, "__GOTT_BASE__") == 0)
+    sym->st_info = ELF_ST_INFO (STB_GLOBAL, ELF_ST_TYPE (sym->st_info));
+
+  return TRUE;
+}
+
+
+/* Copy relocations into the output file.  Fixes up relocations againt PLT
+   entries, then calls the generic routine.  */
+
+bfd_boolean
+elf_vxworks_emit_relocs (bfd *output_bfd,
+			 asection *input_section,
+			 Elf_Internal_Shdr *input_rel_hdr,
+			 Elf_Internal_Rela *internal_relocs,
+			 struct elf_link_hash_entry **rel_hash)
+{
+  const struct elf_backend_data *bed;
+  Elf_Internal_Rela *irela;
+  Elf_Internal_Rela *irelaend;
+  int j;
+
+  bed = get_elf_backend_data (output_bfd);
+
+  irela = internal_relocs;
+  irelaend = irela + (NUM_SHDR_ENTRIES (input_rel_hdr)
+		      * bed->s->int_rels_per_ext_rel);
+  while (irela < irelaend)
+    {
+      if ((output_bfd->flags & (DYNAMIC|EXEC_P))
+	  && *rel_hash
+	  && (*rel_hash)->def_dynamic
+	  && !(*rel_hash)->def_regular
+	  && (*rel_hash)->root.type == bfd_link_hash_defined
+	  && (*rel_hash)->root.u.def.section->output_section != NULL)
+	{
+	  /* This is a relocation from an executable or shared library
+	     against a symbol in a different shared library.  We are
+	     creating a definition in the output file but it does not come
+	     from any of our normal (.o) files. ie. a PLT stub.
+	     Normally this would be a relocation against against SHN_UNDEF
+	     with the VMA of the PLT stub.  This upsets the VxWorks loader.
+	     Convert it to a section-relative relocation.
+	     This gets some other symbols (for instance .dynbss),
+	     but is conservatively correct.  */
+	  for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
+	    {
+	      asection *sec = (*rel_hash)->root.u.def.section;
+	      int this_idx =
+		elf_section_data (sec->output_section)->this_idx;
+
+	      irela[j].r_info = ELF32_R_INFO (this_idx,
+		  ELF32_R_TYPE (irela[j].r_info));
+	      irela[j].r_addend += (*rel_hash)->root.u.def.value;
+	      irela[j].r_addend += sec->output_offset;
+	    }
+	  /* Stop the generic routine adjusting this entry.  */
+	  *rel_hash = NULL;
+	}
+      irela += bed->s->int_rels_per_ext_rel;
+      rel_hash++;
+    }
+  return _bfd_elf_link_output_relocs (output_bfd, input_section,
+				      input_rel_hdr, internal_relocs,
+				      rel_hash);
+}
+
+
+/* Set the sh_link and sh_info fields on the static plt relocation secton.  */
+
+void
+elf_vxworks_final_write_processing (bfd *abfd,
+				    bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+  asection * sec;
+  struct bfd_elf_section_data *d;
+
+  sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded");
+  if (!sec)
+    return;
+  d = elf_section_data (sec);
+  d->this_hdr.sh_link = elf_tdata (abfd)->symtab_section;
+  sec = bfd_get_section_by_name (abfd, ".plt");
+  if (sec)
+    d->this_hdr.sh_info = elf_section_data (sec)->this_idx;
+}
Index: bfd/elf-vxworks.h
===================================================================
RCS file: bfd/elf-vxworks.h
diff -N bfd/elf-vxworks.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bfd/elf-vxworks.h	5 May 2005 13:51:56 -0000
@@ -0,0 +1,32 @@
+/* VxWorks support for ELF
+   Copyright 2005 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "elf/common.h"
+#include "elf/internal.h"
+
+bfd_boolean elf_vxworks_add_symbol_hook
+  (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
+   flagword *, asection **, bfd_vma *);
+bfd_boolean elf_vxworks_link_output_symbol_hook
+  (const char *, Elf_Internal_Sym *);
+bfd_boolean elf_vxworks_emit_relocs
+  (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
+   struct elf_link_hash_entry **);
+void elf_vxworks_final_write_processing (bfd *, bfd_boolean);
Index: bfd/elf32-i386.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf32-i386.c,v
retrieving revision 1.135
diff -u -p -r1.135 elf32-i386.c
--- bfd/elf32-i386.c	4 May 2005 15:53:14 -0000	1.135
+++ bfd/elf32-i386.c	5 May 2005 14:03:19 -0000
@@ -23,6 +23,7 @@
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
+#include "elf-vxworks.h"
 
 /* 386 uses REL relocations instead of RELA.  */
 #define USE_REL	1
@@ -471,15 +472,15 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Int
 #define PLT_ENTRY_SIZE 16
 
 /* The first entry in an absolute procedure linkage table looks like
-   this.  See the SVR4 ABI i386 supplement to see how this works.  */
+   this.  See the SVR4 ABI i386 supplement to see how this works.
+   Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte.  */
 
-static const bfd_byte elf_i386_plt0_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_i386_plt0_entry[12] =
 {
   0xff, 0x35,	/* pushl contents of address */
   0, 0, 0, 0,	/* replaced with address of .got + 4.  */
   0xff, 0x25,	/* jmp indirect */
-  0, 0, 0, 0,	/* replaced with address of .got + 8.  */
-  0, 0, 0, 0	/* pad out to 16 bytes.  */
+  0, 0, 0, 0	/* replaced with address of .got + 8.  */
 };
 
 /* Subsequent entries in an absolute procedure linkage table look like
@@ -495,13 +496,13 @@ static const bfd_byte elf_i386_plt_entry
   0, 0, 0, 0	/* replaced with offset to start of .plt.  */
 };
 
-/* The first entry in a PIC procedure linkage table look like this.  */
+/* The first entry in a PIC procedure linkage table look like this.
+   Will be padded to PLT_ENTRY_SIZE with htab->plt0_pad_byte.  */
 
-static const bfd_byte elf_i386_pic_plt0_entry[PLT_ENTRY_SIZE] =
+static const bfd_byte elf_i386_pic_plt0_entry[12] =
 {
   0xff, 0xb3, 4, 0, 0, 0,	/* pushl 4(%ebx) */
-  0xff, 0xa3, 8, 0, 0, 0,	/* jmp *8(%ebx) */
-  0, 0, 0, 0			/* pad out to 16 bytes.  */
+  0xff, 0xa3, 8, 0, 0, 0	/* jmp *8(%ebx) */
 };
 
 /* Subsequent entries in a PIC procedure linkage table look like this.  */
@@ -516,6 +517,12 @@ static const bfd_byte elf_i386_pic_plt_e
   0, 0, 0, 0	/* replaced with offset to start of .plt.  */
 };
 
+/* On VxWorks, the .rel.plt.unloaded section has absolute relocations
+   for the PLTResolve stub and then for each PLT entry.  */
+#define PLTRESOLVE_RELOCS_SHLIB 0
+#define PLTRESOLVE_RELOCS 2
+#define PLT_NON_JUMP_SLOT_RELOCS 2
+
 /* The i386 linker needs to keep track of the number of relocs that it
    decides to copy as dynamic relocs in check_relocs for each symbol.
    This is so that it can later discard them if they are found to be
@@ -595,7 +602,19 @@ struct elf_i386_link_hash_table
   asection *srelplt;
   asection *sdynbss;
   asection *srelbss;
-
+  
+  /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.  */
+  asection *srelplt2;
+
+  /* Short-cuts to frequently used symbols for VxWorks targets.  */
+  struct elf_link_hash_entry *hgot, *hplt;
+
+  /* True if the target system is VxWorks.  */
+  int is_vxworks;
+
+  /* Value used to fill the last word of the first plt entry.  */
+  bfd_byte plt0_pad_byte;
+  
   union {
     bfd_signed_vma refcount;
     bfd_vma offset;
@@ -668,6 +687,11 @@ elf_i386_link_hash_table_create (bfd *ab
   ret->srelbss = NULL;
   ret->tls_ldm_got.refcount = 0;
   ret->sym_sec.abfd = NULL;
+  ret->is_vxworks = 0;
+  ret->srelplt2 = NULL;
+  ret->hgot = NULL;
+  ret->hplt = NULL;
+  ret->plt0_pad_byte = 0;
 
   return &ret->elf.root;
 }
@@ -708,6 +732,9 @@ static bfd_boolean
 elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
 {
   struct elf_i386_link_hash_table *htab;
+  asection * s;
+  int flags;
+  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
 
   htab = elf_i386_hash_table (info);
   if (!htab->sgot && !create_got_section (dynobj, info))
@@ -726,6 +753,18 @@ elf_i386_create_dynamic_sections (bfd *d
       || (!info->shared && !htab->srelbss))
     abort ();
 
+  if (htab->is_vxworks && !info->shared)
+    {
+      s = bfd_make_section (dynobj, ".rel.plt.unloaded");
+      flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY
+	      | SEC_LINKER_CREATED);
+      if (s == NULL
+	 || ! bfd_set_section_flags (dynobj, s, flags)
+	 || ! bfd_set_section_alignment (dynobj, s, bed->s->log_file_align))
+       return FALSE;
+      htab->srelplt2 = s;
+    }
+
   return TRUE;
 }
 
@@ -1526,6 +1565,26 @@ allocate_dynrelocs (struct elf_link_hash
 
 	  /* We also need to make an entry in the .rel.plt section.  */
 	  htab->srelplt->size += sizeof (Elf32_External_Rel);
+
+	  if (htab->is_vxworks && !info->shared)
+	    {
+	      /* VxWorks has a second set of relocations for each PLT entry
+		 in executables.  They go in a separate relocation section,
+		 which is processed by the kernel loader.  */
+
+	      /* There are two relocations for the initial PLT entry: an
+		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
+		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
+
+	      if (h->plt.offset == PLT_ENTRY_SIZE)
+		htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
+
+	      /* There are two extra relocations for each subsequent PLT entry:
+		 an R_386_32 relocation for the GOT entry, and an R_386_32
+		 relocation for the PLT entry.  */
+
+	      htab->srelplt2->size += (sizeof (Elf32_External_Rel) * 2);
+	    }
 	}
       else
 	{
@@ -1816,6 +1875,27 @@ elf_i386_size_dynamic_sections (bfd *out
   else
     htab->tls_ldm_got.offset = -1;
 
+  if (htab->is_vxworks)
+    {
+      /* Save the GOT and PLT symbols in the hash table for easy access.
+	 Mark them as having relocations; they might not, but we won't
+	 know for sure until we build the GOT in finish_dynamic_symbol.  */
+
+      htab->hgot = elf_link_hash_lookup (elf_hash_table (info),
+					"_GLOBAL_OFFSET_TABLE_",
+					FALSE, FALSE, FALSE);
+      if (htab->hgot)
+	htab->hgot->indx = -2;
+      htab->hplt = elf_link_hash_lookup (elf_hash_table (info),
+					"_PROCEDURE_LINKAGE_TABLE_",
+					FALSE, FALSE, FALSE);
+      if (htab->hplt)
+	htab->hplt->indx = -2;
+
+      if (htab->is_vxworks && htab->hplt && htab->splt->flags & SEC_CODE)
+	htab->hplt->type = STT_FUNC;
+    }
+
   /* Allocate global sym .plt and .got entries, and space for global
      sym dynamic relocs.  */
   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
@@ -1825,6 +1905,8 @@ elf_i386_size_dynamic_sections (bfd *out
   relocs = FALSE;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
+      bfd_boolean strip_section = TRUE;
+
       if ((s->flags & SEC_LINKER_CREATED) == 0)
 	continue;
 
@@ -1834,10 +1916,16 @@ elf_i386_size_dynamic_sections (bfd *out
 	{
 	  /* Strip this section if we don't need it; see the
 	     comment below.  */
+	  /* We'd like to strip these sections if they aren't needed, but if
+	     we've exported dynamic symbols from them we must leave them.
+	     It's too late to tell BFD to get rid of the symbols.  */
+
+	  if (htab->hplt != NULL)
+	    strip_section = FALSE;
 	}
       else if (strncmp (bfd_get_section_name (dynobj, s), ".rel", 4) == 0)
 	{
-	  if (s->size != 0 && s != htab->srelplt)
+	  if (s->size != 0 && s != htab->srelplt && s != htab->srelplt2)
 	    relocs = TRUE;
 
 	  /* We use the reloc_count field as a counter if we need
@@ -1850,7 +1938,7 @@ elf_i386_size_dynamic_sections (bfd *out
 	  continue;
 	}
 
-      if (s->size == 0)
+      if (s->size == 0 && strip_section)
 	{
 	  /* If we don't need this section, strip it from the
 	     output file.  This is mostly to handle .rel.bss and
@@ -3029,6 +3117,43 @@ elf_i386_finish_dynamic_symbol (bfd *out
 		       + htab->sgotplt->output_offset
 		       + got_offset),
 		      htab->splt->contents + h->plt.offset + 2);
+
+	  if (htab->is_vxworks)
+	    {
+	      int s, k, reloc_index;
+
+	      /* Create the R_386_32 relocation referencing the GOT
+		 for this PLT entry.  */
+
+	      /* S: Current slot number (zero-based).  */
+	      s = (h->plt.offset - PLT_ENTRY_SIZE) / PLT_ENTRY_SIZE;
+	      /* K: Number of relocations for PLTResolve. */
+	      if (info->shared)
+		k = PLTRESOLVE_RELOCS_SHLIB;
+	      else
+		k = PLTRESOLVE_RELOCS;
+	      /* Skip the PLTresolve relocations, and the relocations for
+		 the other PLT slots. */
+	      reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS;
+	      loc = (htab->srelplt2->contents + reloc_index
+		     * sizeof (Elf32_External_Rel));
+
+	      rel.r_offset = (htab->splt->output_section->vma
+			      + htab->splt->output_offset
+			      + h->plt.offset + 2),
+	      rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_386_32);
+	      bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
+
+	      /* Create the R_386_32 relocation referencing the beginning of
+		 the PLT for this GOT entry.  */
+	      rel.r_offset = (htab->sgotplt->output_section->vma
+			      + htab->sgotplt->output_offset
+			      + got_offset);
+	      rel.r_info = ELF32_R_INFO (htab->hplt->indx, R_386_32);
+	      bfd_elf32_swap_reloc_out (output_bfd, &rel,
+	      loc + sizeof (Elf32_External_Rel));
+	    }
+
 	}
       else
 	{
@@ -3138,9 +3263,12 @@ elf_i386_finish_dynamic_symbol (bfd *out
       bfd_elf32_swap_reloc_out (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
-      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+      || (strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
+	  && !htab->is_vxworks))
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -3248,12 +3376,20 @@ elf_i386_finish_dynamic_sections (bfd *o
       if (htab->splt && htab->splt->size > 0)
 	{
 	  if (info->shared)
-	    memcpy (htab->splt->contents,
-		    elf_i386_pic_plt0_entry, PLT_ENTRY_SIZE);
+	    {
+	      memcpy (htab->splt->contents, elf_i386_pic_plt0_entry,
+		      sizeof (elf_i386_pic_plt0_entry));
+	      memset (htab->splt->contents + sizeof (elf_i386_pic_plt0_entry),
+		      htab->plt0_pad_byte,
+		      PLT_ENTRY_SIZE - sizeof (elf_i386_pic_plt0_entry));
+	    }
 	  else
 	    {
-	      memcpy (htab->splt->contents,
-		      elf_i386_plt0_entry, PLT_ENTRY_SIZE);
+	      memcpy (htab->splt->contents, elf_i386_plt0_entry,
+		      sizeof(elf_i386_plt0_entry));
+	      memset (htab->splt->contents + sizeof (elf_i386_plt0_entry),
+		      htab->plt0_pad_byte,
+		      PLT_ENTRY_SIZE - sizeof (elf_i386_plt0_entry));
 	      bfd_put_32 (output_bfd,
 			  (htab->sgotplt->output_section->vma
 			   + htab->sgotplt->output_offset
@@ -3264,12 +3400,69 @@ elf_i386_finish_dynamic_sections (bfd *o
 			   + htab->sgotplt->output_offset
 			   + 8),
 			  htab->splt->contents + 8);
+
+	      if (htab->is_vxworks)
+		{
+		  Elf_Internal_Rela rel;
+		  struct elf_link_hash_entry *hgot;
+
+		  /* The VxWorks GOT is relocated by the dynamic linker.
+		     Therefore, we must emit relocations rather than
+		     simply computing the values now.  */
+		  hgot = elf_link_hash_lookup (elf_hash_table (info),
+					       "_GLOBAL_OFFSET_TABLE_",
+					       FALSE, FALSE, FALSE);
+		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 4.
+		     On IA32 we use REL relocations so the addend goes in
+		     the PLT directly.  */
+		  rel.r_offset = (htab->splt->output_section->vma
+				  + htab->splt->output_offset
+				  + 2);
+		  rel.r_info = ELF32_R_INFO (hgot->indx, R_386_32);
+		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
+					    htab->srelplt2->contents);
+		  /* Generate a relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
+		  rel.r_offset = (htab->splt->output_section->vma
+				  + htab->splt->output_offset
+				  + 8);
+		  rel.r_info = ELF32_R_INFO (hgot->indx, R_386_32);
+		  bfd_elf32_swap_reloc_out (output_bfd, &rel,
+					    htab->srelplt2->contents +
+					    sizeof (Elf32_External_Rel));
+		}
 	    }
 
 	  /* UnixWare sets the entsize of .plt to 4, although that doesn't
 	     really seem like the right value.  */
 	  elf_section_data (htab->splt->output_section)
 	    ->this_hdr.sh_entsize = 4;
+
+	  /* Correct the .rel.plt.unloaded relocations.  */
+	  if (htab->is_vxworks && !info->shared)
+	    {
+	      int num_plts = (htab->splt->size / PLT_ENTRY_SIZE) - 1;
+	      char *p;
+
+	      p = htab->srelplt2->contents;
+	      if (info->shared)
+		p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
+	      else
+		p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel);
+
+	      for (; num_plts; num_plts--)
+		{
+		  Elf_Internal_Rela rel;
+		  bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
+		  rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_386_32);
+		  bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
+		  p += sizeof (Elf32_External_Rel);
+
+		  bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
+		  rel.r_info = ELF32_R_INFO (htab->hplt->indx, R_386_32);
+		  bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
+		  p += sizeof (Elf32_External_Rel);
+		}
+	    }
 	}
     }
 
@@ -3380,3 +3573,74 @@ elf_i386_post_process_headers (bfd *abfd
 #define	elf32_bed				elf32_i386_fbsd_bed
 
 #include "elf32-target.h"
+
+/* VxWorks support.  */
+
+#undef	TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		bfd_elf32_i386_vxworks_vec
+#undef	TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		"elf32-i386-vxworks"
+
+
+/* Like elf_i386_link_hash_table_create but with tweaks for VxWorks.  */
+
+static struct bfd_link_hash_table *
+elf_i386_vxworks_link_hash_table_create (bfd *abfd)
+{
+  struct bfd_link_hash_table *ret;
+  struct elf_i386_link_hash_table *htab;
+
+  ret = elf_i386_link_hash_table_create (abfd);
+  if (ret)
+    {
+      htab = (struct elf_i386_link_hash_table *) ret;
+      htab->is_vxworks = 1;
+      htab->plt0_pad_byte = 0x90;
+    }
+
+  return ret;
+}
+
+
+/* Tweak magic VxWorks symbols as they are written to the output file.  */
+static bfd_boolean
+elf_i386_vxworks_link_output_symbol_hook (struct bfd_link_info *info
+					    ATTRIBUTE_UNUSED,
+					  const char *name,
+					  Elf_Internal_Sym *sym,
+					  asection *input_sec ATTRIBUTE_UNUSED,
+					  struct elf_link_hash_entry *h
+					    ATTRIBUTE_UNUSED)
+{
+  /* Ignore the first dummy symbol.  */
+  if (!name)
+    return TRUE;
+
+  return elf_vxworks_link_output_symbol_hook (name, sym);
+}
+
+#undef	elf_backend_post_process_headers
+#undef bfd_elf32_bfd_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+  elf_i386_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_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook \
+  elf_i386_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 \
+  elf_vxworks_final_write_processing
+
+/* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
+   define it.  */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym	1
+
+#undef	elf32_bed
+#define elf32_bed				elf32_i386_vxworks_bed
+
+#include "elf32-target.h"
Index: bfd/elflink.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elflink.c,v
retrieving revision 1.157
diff -u -p -r1.157 elflink.c
--- bfd/elflink.c	4 May 2005 15:53:28 -0000	1.157
+++ bfd/elflink.c	5 May 2005 13:52:06 -0000
@@ -2138,7 +2138,9 @@ bfd_boolean
 _bfd_elf_link_output_relocs (bfd *output_bfd,
 			     asection *input_section,
 			     Elf_Internal_Shdr *input_rel_hdr,
-			     Elf_Internal_Rela *internal_relocs)
+			     Elf_Internal_Rela *internal_relocs,
+			     struct elf_link_hash_entry **rel_hash
+			       ATTRIBUTE_UNUSED)
 {
   Elf_Internal_Rela *irela;
   Elf_Internal_Rela *irelaend;
@@ -6782,8 +6784,7 @@ elf_link_input_bfd (struct elf_final_lin
     return TRUE;
 
   emit_relocs = (finfo->info->relocatable
-		 || finfo->info->emitrelocations
-		 || bed->elf_backend_emit_relocs);
+		 || finfo->info->emitrelocations);
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   if (elf_bad_symtab (input_bfd))
@@ -7163,10 +7164,9 @@ elf_link_input_bfd (struct elf_final_lin
 	      Elf_Internal_Rela *irelaend;
 	      bfd_vma last_offset;
 	      struct elf_link_hash_entry **rel_hash;
+	      struct elf_link_hash_entry **rel_hash_list;
 	      Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2;
 	      unsigned int next_erel;
-	      bfd_boolean (*reloc_emitter)
-		(bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *);
 	      bfd_boolean rela_normal;
 
 	      input_rel_hdr = &elf_section_data (o)->rel_hdr;
@@ -7181,6 +7181,7 @@ elf_link_input_bfd (struct elf_final_lin
 	      rel_hash = (elf_section_data (o->output_section)->rel_hashes
 			  + elf_section_data (o->output_section)->rel_count
 			  + elf_section_data (o->output_section)->rel_count2);
+	      rel_hash_list = rel_hash;
 	      last_offset = o->output_offset;
 	      if (!finfo->info->relocatable)
 		last_offset += o->output_section->vma;
@@ -7363,16 +7364,11 @@ elf_link_input_bfd (struct elf_final_lin
 		}
 
 	      /* Swap out the relocs.  */
-	      if (bed->elf_backend_emit_relocs
-		  && !(finfo->info->relocatable
-		       || finfo->info->emitrelocations))
-		reloc_emitter = bed->elf_backend_emit_relocs;
-	      else
-		reloc_emitter = _bfd_elf_link_output_relocs;
-
 	      if (input_rel_hdr->sh_size != 0
-		  && ! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
-					 internal_relocs))
+		  && !bed->elf_backend_emit_relocs (output_bfd, o,
+						    input_rel_hdr,
+						    internal_relocs,
+						    rel_hash_list))
 		return FALSE;
 
 	      input_rel_hdr2 = elf_section_data (o)->rel_hdr2;
@@ -7380,8 +7376,11 @@ elf_link_input_bfd (struct elf_final_lin
 		{
 		  internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
 				      * bed->s->int_rels_per_ext_rel);
-		  if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr2,
-					  internal_relocs))
+		  rel_hash_list += NUM_SHDR_ENTRIES (input_rel_hdr);
+		  if (!bed->elf_backend_emit_relocs (output_bfd, o,
+						     input_rel_hdr2,
+						     internal_relocs,
+						     rel_hash_list))
 		    return FALSE;
 		}
 	    }
Index: bfd/elfxx-target.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elfxx-target.h,v
retrieving revision 1.81
diff -u -p -r1.81 elfxx-target.h
--- bfd/elfxx-target.h	4 May 2005 15:53:31 -0000	1.81
+++ bfd/elfxx-target.h	5 May 2005 13:52:07 -0000
@@ -416,7 +416,7 @@
 #define elf_backend_merge_symbol_attribute	NULL
 #endif
 #ifndef elf_backend_emit_relocs
-#define elf_backend_emit_relocs			NULL
+#define elf_backend_emit_relocs			_bfd_elf_link_output_relocs
 #endif
 #ifndef elf_backend_count_relocs
 #define elf_backend_count_relocs		NULL
Index: bfd/targets.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/targets.c,v
retrieving revision 1.126
diff -u -p -r1.126 targets.c
--- bfd/targets.c	4 May 2005 15:53:40 -0000	1.126
+++ bfd/targets.c	5 May 2005 13:52:07 -0000
@@ -561,6 +561,7 @@ extern const bfd_target bfd_elf32_hppa_n
 extern const bfd_target bfd_elf32_hppa_vec;
 extern const bfd_target bfd_elf32_i370_vec;
 extern const bfd_target bfd_elf32_i386_freebsd_vec;
+extern const bfd_target bfd_elf32_i386_vxworks_vec;
 extern const bfd_target bfd_elf32_i386_vec;
 extern const bfd_target bfd_elf32_i860_little_vec;
 extern const bfd_target bfd_elf32_i860_vec;
@@ -860,6 +861,7 @@ static const bfd_target * const _bfd_tar
 	&bfd_elf32_hppa_vec,
 	&bfd_elf32_i370_vec,
 	&bfd_elf32_i386_freebsd_vec,
+	&bfd_elf32_i386_vxworks_vec,
 	&bfd_elf32_i386_vec,
 	&bfd_elf32_i860_little_vec,
 	&bfd_elf32_i860_vec,
Index: gas/config/tc-i386.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-i386.h,v
retrieving revision 1.52
diff -u -p -r1.52 tc-i386.h
--- gas/config/tc-i386.h	23 Nov 2004 07:55:11 -0000	1.52
+++ gas/config/tc-i386.h	5 May 2005 13:51:56 -0000
@@ -61,7 +61,10 @@ extern unsigned long i386_mach (void);
 
 #ifdef TE_FreeBSD
 #define ELF_TARGET_FORMAT	"elf32-i386-freebsd"
+#elif defined (TE_VXWORKS)
+#define ELF_TARGET_FORMAT	"elf32-i386-vxworks"
 #endif
+
 #ifndef ELF_TARGET_FORMAT
 #define ELF_TARGET_FORMAT	"elf32-i386"
 #endif
Index: gas/testsuite/gas/i386/i386.exp
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/testsuite/gas/i386/i386.exp,v
retrieving revision 1.33
diff -u -p -r1.33 i386.exp
--- gas/testsuite/gas/i386/i386.exp	1 Apr 2005 07:50:24 -0000	1.33
+++ gas/testsuite/gas/i386/i386.exp	5 May 2005 13:51:56 -0000
@@ -65,7 +65,8 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
 	&& (![is_elf_format] || [istarget "*-*-linux*"]
 	    || [istarget "*-*-netbsd*"]
 	    || [istarget "*-*-freebsd*"]
-	    || [istarget "*-*-netware*"])} {
+	    || [istarget "*-*-netware*"]
+	    || [istarget "*-*-vxworks*"])} {
 	# Don't run this test on targets where '/' starts comments.
 	run_dump_test "divide"
     }
Index: ld/Makefile.am
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/Makefile.am,v
retrieving revision 1.172
diff -u -p -r1.172 Makefile.am
--- ld/Makefile.am	14 Apr 2005 05:26:40 -0000	1.172
+++ ld/Makefile.am	5 May 2005 13:51:56 -0000
@@ -191,6 +191,7 @@ ALL_EMULATIONS = \
 	eelf_i386_chaos.o \
 	eelf_i386_fbsd.o \
 	eelf_i386_ldso.o \
+	eelf_i386_vxworks.o \
 	eelf_s390.o \
 	egld960.o \
 	egld960coff.o \
@@ -872,6 +873,10 @@ eelf_i386_fbsd.c: $(srcdir)/emulparams/e
 eelf_i386_ldso.c: $(srcdir)/emulparams/elf_i386_ldso.sh \
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_i386_ldso "$(tdir_elf_i386_ldso)"
+eelf_i386_vxworks.c: $(srcdir)/emulparams/elf_i386_vxworks.sh \
+  $(srcdir)/emulparams/vxworks.sh \
+  $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf_i386_vxworks "$(tdir_elf_i386_vxworks)"
 eelf_s390.c: $(srcdir)/emulparams/elf_s390.sh \
   $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_s390 "$(tdir_elf_s390)"
Index: ld/configure.tgt
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/configure.tgt,v
retrieving revision 1.168
diff -u -p -r1.168 configure.tgt
--- ld/configure.tgt	29 Apr 2005 18:43:35 -0000	1.168
+++ ld/configure.tgt	5 May 2005 13:52:09 -0000
@@ -237,7 +237,7 @@ i[3-7]86-*-interix*)	targ_emul=i386pe_po
  			targ_extra_ofiles="deffilep.o pe-dll.o" ;;
 i[3-7]86-*-beospe*)	targ_emul=i386beos ;;
 i[3-7]86-*-beos*)	targ_emul=elf_i386_be ;;
-i[3-7]86-*-vxworks*)	targ_emul=elf_i386 ;;
+i[3-7]86-*-vxworks*)	targ_emul=elf_i386_vxworks ;;
 i[3-7]86-*-chaos)	targ_emul=elf_i386_chaos ;;
 m8*-*-*)		targ_emul=m88kbcs ;;
 a29k-*-udi)		targ_emul=sa29200 ;;
Index: ld/emulparams/elf_i386_vxworks.sh
===================================================================
RCS file: ld/emulparams/elf_i386_vxworks.sh
diff -N ld/emulparams/elf_i386_vxworks.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/emulparams/elf_i386_vxworks.sh	5 May 2005 13:51:56 -0000
@@ -0,0 +1,14 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-i386-vxworks"
+TEXT_START_ADDR=0x08048000
+MAXPAGESIZE=0x1000
+COMMONPAGESIZE=0x1000
+NONPAGED_TEXT_START_ADDR=0x08048000
+ARCH=i386
+MACHINE=
+NOP=0x90909090
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_PIE_SCRIPT=yes
+NO_SMALL_DATA=yes
+. ${srcdir}/emulparams/vxworks.sh
Index: ld/emulparams/vxworks.sh
===================================================================
RCS file: ld/emulparams/vxworks.sh
diff -N ld/emulparams/vxworks.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/emulparams/vxworks.sh	5 May 2005 13:51:56 -0000
@@ -0,0 +1,25 @@
+# If you change this file, please also look at files which source this one:
+# elf_i386_vxworks.sh elf32ppcvxworks.sh elf32ebmipvxworks.sh
+
+# The Diab tools use a different init/fini convention.  Initialization code
+# is place in sections named ".init$NN".  These sections are then concatenated
+# into the .init section.  It is important that .init$00 be first and .init$99
+# be last. The other sections should be sorted, but the current linker script
+# parse does not seem to allow that with the SORT keyword in this context.
+INIT_START='_init = .;
+            KEEP (*(.init$00));
+            KEEP (*(.init$0[1-9]));
+            KEEP (*(.init$[1-8][0-9]));
+            KEEP (*(.init$9[0-8]));'
+INIT_END='KEEP (*(.init$99));'
+FINI_START='_fini = .;
+            KEEP (*(.fini$00));
+            KEEP (*(.fini$0[1-9]));
+            KEEP (*(.fini$[1-8][0-9]));
+            KEEP (*(.fini$9[0-8]));'
+FINI_END='KEEP (*(.fini$99));
+          PROVIDE (_etext = .);'
+
+ETEXT_NAME=etext_unrelocated
+OTHER_END_SYMBOLS="PROVIDE (_ehdr = ${TEXT_START_ADDR});"
+DATA_END_SYMBOLS=".edata : { PROVIDE (_edata = .); }"
Index: ld/scripttempl/elf.sc
===================================================================
RCS file: /var/cvsroot/src-cvs/src/ld/scripttempl/elf.sc,v
retrieving revision 1.53
diff -u -p -r1.53 elf.sc
--- ld/scripttempl/elf.sc	23 Mar 2005 04:14:46 -0000	1.53
+++ ld/scripttempl/elf.sc	5 May 2005 13:51:56 -0000
@@ -25,6 +25,8 @@
 #		.text section.
 #	DATA_START_SYMBOLS - symbols that appear at the start of the
 #		.data section.
+#	DATA_END_SYMBOLS - symbols that appear at the end of the
+#		writeable data sections.
 #	OTHER_GOT_SYMBOLS - symbols defined just before .got.
 #	OTHER_GOT_SECTIONS - sections just after .got.
 #	OTHER_SDATA_SECTIONS - sections just after .sdata.
@@ -45,6 +47,8 @@
 # 	combination of .fini sections.
 #	STACK_ADDR - start of a .stack section.
 #	OTHER_END_SYMBOLS - symbols to place right at the end of the script.
+#	ETEXT_NAME - name of a symbol for the end of the text section,
+#		normally etext.
 #	SEPARATE_GOTPLT - if set, .got.plt should be separate output section,
 #		so that .got can be in the RELRO area.  It should be set to
 #		the number of bytes in the beginning of .got.plt which can be
@@ -84,6 +88,7 @@ if [ -z "$MACHINE" ]; then OUTPUT_ARCH=$
 test -z "${ELFSIZE}" && ELFSIZE=32
 test -z "${ALIGNMENT}" && ALIGNMENT="${ELFSIZE} / 8"
 test "$LD_FLAG" = "N" && DATA_ADDR=.
+test -z "${ETEXT_NAME}" && ETEXT_NAME=etext
 test -n "$CREATE_SHLIB$CREATE_PIE" && test -n "$SHLIB_DATA_ADDR" && COMMONPAGESIZE=""
 test -z "$CREATE_SHLIB$CREATE_PIE" && test -n "$DATA_ADDR" && COMMONPAGESIZE=""
 test -n "$RELRO_NOW" && unset SEPARATE_GOTPLT
@@ -307,9 +312,9 @@ cat <<EOF
     KEEP (*(.fini))
     ${RELOCATING+${FINI_END}}
   } =${NOP-0}
-  ${RELOCATING+PROVIDE (__etext = .);}
-  ${RELOCATING+PROVIDE (_etext = .);}
-  ${RELOCATING+PROVIDE (etext = .);}
+  ${RELOCATING+PROVIDE (__${ETEXT_NAME} = .);}
+  ${RELOCATING+PROVIDE (_${ETEXT_NAME} = .);}
+  ${RELOCATING+PROVIDE (${ETEXT_NAME} = .);}
   ${WRITABLE_RODATA-${RODATA}}
   .rodata1      ${RELOCATING-0} : { *(.rodata1) }
   ${CREATE_SHLIB-${SDATA2}}
@@ -370,8 +375,7 @@ cat <<EOF
   ${OTHER_GOT_SECTIONS}
   ${SDATA}
   ${OTHER_SDATA_SECTIONS}
-  ${RELOCATING+_edata = .;}
-  ${RELOCATING+PROVIDE (edata = .);}
+  ${RELOCATING+${DATA_END_SYMBOLS-_edata = .; PROVIDE (edata = .);}}
   ${RELOCATING+__bss_start = .;}
   ${RELOCATING+${OTHER_BSS_SYMBOLS}}
   ${SBSS}

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