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]

[patch] VxWorks x86 shared library support.


The attached patch implements support for x86 VxWorks shared libraries.

VxWorks shared libraries are somewhat different to sysv shared libraries, so I 
needed to make a couple of changes to common code:
- The __GOTT_BASE__ and __GOTT_INDEX__ symbols are supplied by the OS loader, 
so we need to allow undefined references to these symbols.
- The OS loader requires both the normal dynamic relocations and a copy of the 
original static relocations for the PLT.

Both these changes will also be used by other (not yet submitted) VxWorks 
targets.

To actually generate working executables an additional option to create 
dynamic sections in executables is needed. This will follow shortly.

Tested on i586-wrs-vxworks and i686-pc-linux-gnu.
Ok?

Paul

2004-01-19  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.
	* configure: Regenerate.
	* elf-bfd.h (struct elf_backend_data): Add is_vxworks.
	(RELOC_FOR_GLOBAL_SYMBOL): Ignore VxWorks magic GOT symbols.
	* elf.c (assign_section_numbers): Add special handling for VxWorks
	.plt.unloaded section.
	* elflink.c (_bfd_elf_create_dynamic_sections): Mark VxWorks PLT
	symbols as functions.
	(elf_link_adjust_relocs): Convert SHN_UNDEF relocs for PLT stubs
	into section relative relocs.
	(elf_link_output_extsym): Ignore undefined VxWorks GOTT symbols.
	* elfxx-target.h (elf_backend_is_vxworks): Define.
	(elfNN_bed): Use it.
	* 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.
	(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.  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.
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/config.bfd
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/config.bfd,v
retrieving revision 1.183
diff -u -p -r1.183 config.bfd
--- bfd/config.bfd	23 Mar 2005 15:35:43 -0000	1.183
+++ bfd/config.bfd	12 Apr 2005 15:00:30 -0000
@@ -601,7 +601,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.174
diff -u -p -r1.174 configure.in
--- bfd/configure.in	5 Apr 2005 07:58:38 -0000	1.174
+++ bfd/configure.in	12 Apr 2005 15:00:30 -0000
@@ -621,6 +621,7 @@ do
     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_vxworks_vec)	tb="$tb elf32-i386.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vec)		tb="$tb elf32-i386.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" ;;
Index: bfd/elf-bfd.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf-bfd.h,v
retrieving revision 1.179
diff -u -p -r1.179 elf-bfd.h
--- bfd/elf-bfd.h	4 Apr 2005 16:11:02 -0000	1.179
+++ bfd/elf-bfd.h	12 Apr 2005 15:19:33 -0000
@@ -1035,6 +1035,9 @@ struct elf_backend_data
        that the p_paddr field in the section header to be set to zero.
        This field indicates whether this behavior is required.  */
   unsigned want_p_paddr_set_to_zero : 1;
+
+  /* Set for VxWorks target to enable special shared library hamdling.  */
+  unsigned is_vxworks : 1;
 };
 
 /* Information stored for each BFD section in an ELF file.  This
@@ -1841,6 +1844,15 @@ extern bfd_boolean _sh_elf_set_mach_from
       else if (info->unresolved_syms_in_objects == RM_IGNORE		\
 	       && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)		\
 	;								\
+     else if (get_elf_backend_data (input_bfd)->is_vxworks		\
+	      && info->shared						\
+	      && (strcmp (h->root.root.string, "__GOTT_BASE__") == 0	\
+		  || strcmp (h->root.root.string, "__GOTT_INDEX__") == 0)) \
+	/* 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... */		\
+	;								\
       else								\
 	{								\
 	  bfd_boolean err;						\
Index: bfd/elf.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf.c,v
retrieving revision 1.277
diff -u -p -r1.277 elf.c
--- bfd/elf.c	5 Apr 2005 04:01:09 -0000	1.277
+++ bfd/elf.c	12 Apr 2005 15:20:26 -0000
@@ -2736,6 +2736,7 @@ assign_section_numbers (bfd *abfd, struc
   Elf_Internal_Shdr **i_shdrp;
   bfd_size_type amt;
   struct bfd_elf_section_data *d;
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   section_number = 1;
 
@@ -2931,8 +2932,6 @@ assign_section_numbers (bfd *abfd, struc
 		         where elfsec is 0.  */
 		      if (elfsec == 0)
 			{
-			  const struct elf_backend_data *bed
-			    = get_elf_backend_data (abfd);
 			  if (bed->link_order_error_handler)
 			    bed->link_order_error_handler
 			      (_("%B: warning: sh_link not set for section `%A'"),
@@ -2990,6 +2989,19 @@ assign_section_numbers (bfd *abfd, struc
 	  else
 	    name += 5;
 	  s = bfd_get_section_by_name (abfd, name);
+
+	  /* For VxWorks dynamic RTPs we have both dynamic and
+	     non-dynamic relocation sections which apply to the same place.
+	     The non-dynamic one has a different name and refers to the
+	     static symbol table.  The hack below makes this work.  */
+	  if (bed->is_vxworks && strcmp (name, ".plt.unloaded") == 0)
+	      {
+		d->this_hdr.sh_link = t->symtab_section;
+
+		if (s == NULL)
+		  s = bfd_get_section_by_name (abfd, ".plt");
+	      }
+
 	  if (s != NULL)
 	    d->this_hdr.sh_info = elf_section_data (s)->this_idx;
 	  break;
Index: bfd/elf32-i386.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elf32-i386.c,v
retrieving revision 1.132
diff -u -p -r1.132 elf32-i386.c
--- bfd/elf32-i386.c	6 Feb 2005 18:11:29 -0000	1.132
+++ bfd/elf32-i386.c	12 Apr 2005 15:20:08 -0000
@@ -516,6 +516,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 +601,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 +686,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 +731,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 +752,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 +1564,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 +1874,24 @@ 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;
+    }
+
   /* 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 +1901,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 +1912,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 +1934,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 +3113,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 +3259,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 +3372,16 @@ 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, PLT_ENTRY_SIZE);
+	      memset (htab->splt->contents + 12, htab->plt0_pad_byte, 4);
+	    }
 	  else
 	    {
 	      memcpy (htab->splt->contents,
 		      elf_i386_plt0_entry, PLT_ENTRY_SIZE);
+	      memset (htab->splt->contents + 12, htab->plt0_pad_byte, 4);
 	      bfd_put_32 (output_bfd,
 			  (htab->sgotplt->output_section->vma
 			   + htab->sgotplt->output_offset
@@ -3264,12 +3392,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 +3565,46 @@ 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;
+}
+
+#undef	elf_backend_post_process_headers
+#define	elf_backend_post_process_headers	elf_i386_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
+/* 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 elf_backend_is_vxworks
+#define elf_backend_is_vxworks 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.144
diff -u -p -r1.144 elflink.c
--- bfd/elflink.c	1 Apr 2005 03:49:46 -0000	1.144
+++ bfd/elflink.c	13 Apr 2005 17:13:03 -0000
@@ -299,7 +299,10 @@ _bfd_elf_create_dynamic_sections (bfd *a
 	return FALSE;
       h = (struct elf_link_hash_entry *) bh;
       h->def_regular = 1;
-      h->type = STT_OBJECT;
+      if (bed->is_vxworks && (pltflags & SEC_CODE) != 0)
+	h->type = STT_FUNC;
+      else
+	h->type = STT_OBJECT;
 
       if (! info->executable
 	  && ! bfd_elf_link_record_dynamic_symbol (info, h))
@@ -5846,9 +5849,40 @@ elf_link_adjust_relocs (bfd *abfd,
       BFD_ASSERT ((*rel_hash)->indx >= 0);
 
       (*swap_in) (abfd, erela, irela);
-      for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
-	irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift
-			   | (irela[j].r_info & r_type_mask));
+      if (bed->is_vxworks
+	  && (abfd->flags & (DYNAMIC|EXEC_P))
+	  && (*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
+	     createing a definition in the output file but it does not come
+	     from any of out 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 = ((bfd_vma) this_idx << r_sym_shift
+				| (irela[j].r_info & r_type_mask));
+	      irela[j].r_addend += (*rel_hash)->root.u.def.value;
+	      irela[j].r_addend += sec->output_offset;
+	    }
+	}
+      else
+	{
+	  for (j = 0; j < bed->s->int_rels_per_ext_rel; j++)
+	    irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift
+			      | (irela[j].r_info & r_type_mask));
+	}
       (*swap_out) (abfd, irela, erela);
     }
 }
@@ -6332,7 +6366,14 @@ elf_link_output_extsym (struct elf_link_
       && h->ref_dynamic
       && !h->ref_regular
       && ! elf_link_check_versioned_symbol (finfo->info, bed, h)
-      && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
+      && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE
+      /* On VxWorks, these two symbols are undefined in shared
+	 libaries.  The Diab compiler does not create undefined
+	 references in the main executable so using "-u __GOTT_BASE__"
+	 when invoking GNU ld would not be fully compatible.  */
+      && (!bed->is_vxworks
+	  || (strcmp (h->root.root.string, "__GOTT_BASE__") != 0
+	      && strcmp (h->root.root.string, "__GOTT_INDEX__") != 0)))
     {
       if (! ((*finfo->info->callbacks->undefined_symbol)
 	     (finfo->info, h->root.root.string, h->root.u.undef.abfd,
Index: bfd/elfxx-target.h
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/elfxx-target.h,v
retrieving revision 1.79
diff -u -p -r1.79 elfxx-target.h
--- bfd/elfxx-target.h	2 Mar 2005 04:47:25 -0000	1.79
+++ bfd/elfxx-target.h	12 Apr 2005 15:20:43 -0000
@@ -99,6 +99,9 @@
 #ifndef elf_backend_want_p_paddr_set_to_zero
 #define elf_backend_want_p_paddr_set_to_zero 0
 #endif
+#ifndef elf_backend_is_vxworks
+#define elf_backend_is_vxworks 0
+#endif
 
 #define bfd_elfNN_bfd_debug_info_start	bfd_void
 #define bfd_elfNN_bfd_debug_info_end	bfd_void
@@ -610,7 +613,8 @@ static const struct elf_backend_data elf
   elf_backend_can_refcount,
   elf_backend_want_got_sym,
   elf_backend_want_dynbss,
-  elf_backend_want_p_paddr_set_to_zero
+  elf_backend_want_p_paddr_set_to_zero,
+  elf_backend_is_vxworks
 };
 #endif
 
Index: bfd/targets.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/bfd/targets.c,v
retrieving revision 1.124
diff -u -p -r1.124 targets.c
--- bfd/targets.c	24 Mar 2005 21:02:19 -0000	1.124
+++ bfd/targets.c	12 Apr 2005 15:00:30 -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	12 Apr 2005 15:00:30 -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	13 Apr 2005 16:54:31 -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.171
diff -u -p -r1.171 Makefile.am
--- ld/Makefile.am	12 Apr 2005 02:50:28 -0000	1.171
+++ ld/Makefile.am	12 Apr 2005 15:00:30 -0000
@@ -190,6 +190,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 \
@@ -871,6 +872,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.167
diff -u -p -r1.167 configure.tgt
--- ld/configure.tgt	23 Mar 2005 15:35:50 -0000	1.167
+++ ld/configure.tgt	12 Apr 2005 15:00:30 -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	12 Apr 2005 15:00:30 -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	12 Apr 2005 15:00:30 -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	12 Apr 2005 15:00:30 -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]