This is the mail archive of the binutils@sourceware.org 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 v2] BFD vector for elf32-i386-nacl


[Reworked on top of cleanups and parameterization already committed.]

This patch adds the BFD target vector for the new target elf32-i386-nacl.
This is to support Native Client (http://code.google.com/p/nativeclient/),
which is a new pseudo-operating system that uses vanilla ELF but has a
significantly nonstandard ABI.  (It is already known to config.sub as 'nacl'.)

This is far from being complete support for this target, but it should
be everything that will be needed in BFD proper.  It's gotten only the
lightest testing, and of course the target-specific details are subject
to potential fixes or changes later.

I have tested that the i686-linux target still passes check-binutils and
check-ld.  I'm not sure that tests much about correct PLT generation,
which is the only area of the shared code really touched here.  If there
are other good ways to test that (short of rebuilding a whole OS with
this linker), please let me know.

Ok for trunk?


Thanks,
Roland


bfd/
	* elf32-i386.c (NACL_PLT_ENTRY_SIZE, NACLMASK): New macros.
	(elf_i386_nacl_plt0_entry): New variable.
	(elf_i386_plt_entry): New variable.
	(elf_i386_nacl_pic_plt0_entry): New variable.
	(elf_i386_nacl_pic_plt_entry): New variable.
	(elf_i386_nacl_plt, elf_i386_nacl_arch_bed): New variables.
	(elf_backend_arch_data): New macro setting for elf_i386_nacl_vec stanza.
	(elf_backend_plt_alignment): Likewise.

	* config.bfd: Handle i[3-7]86-*-nacl*.
	* elf32-i386.c (bfd_elf32_i386_nacl_vec): New backend vector stanza.
	* targets.c: Support bfd_elf32_i386_nacl_vec.
	* configure.in: Likewise.
	* configure: Regenerated.

diff --git a/bfd/config.bfd b/bfd/config.bfd
index 3f5b9a1..4cb689d 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -566,6 +566,11 @@ case "${targ}" in
     targ_selvecs="i386linux_vec i386pei_vec"
     targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf32_x86_64_vec bfd_elf64_l1om_vec bfd_elf64_k1om_vec"
     ;;
+  i[3-7]86-*-nacl*)
+    targ_defvec=bfd_elf32_i386_nacl_vec
+    targ_selvecs="bfd_elf32_i386_vec"
+    #XXX targ64_selvecs="bfd_elf64_x86_64_nacl_vec bfd_elf32_x86_64_nacl_vec bfd_elf64_x86_64_vec bfd_elf32_x86_64_vec"
+    ;;
 #ifdef BFD64
   x86_64-*-darwin*)
     targ_defvec=mach_o_x86_64_vec
diff --git a/bfd/configure b/bfd/configure
index 40c17db..06f7839 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -15210,6 +15210,7 @@ do
     bfd_elf32_i370_vec)		tb="$tb elf32-i370.lo elf32.lo $elf" ;;
     bfd_elf32_i386_sol2_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_freebsd_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_nacl_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i860_little_vec)	tb="$tb elf32-i860.lo elf32.lo $elf" ;;
diff --git a/bfd/configure.in b/bfd/configure.in
index e1ae5fc..530d4ee 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -709,6 +709,7 @@ do
     bfd_elf32_i370_vec)		tb="$tb elf32-i370.lo elf32.lo $elf" ;;
     bfd_elf32_i386_sol2_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_freebsd_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_nacl_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i860_little_vec)	tb="$tb elf32-i860.lo elf32.lo $elf" ;;
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index cb16faf..38c7c5a 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -5030,6 +5030,170 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
 
 #include "elf32-target.h"
 
+/* Native Client support.  */
+
+#undef	TARGET_LITTLE_SYM
+#define	TARGET_LITTLE_SYM		bfd_elf32_i386_nacl_vec
+#undef	TARGET_LITTLE_NAME
+#define	TARGET_LITTLE_NAME		"elf32-i386-nacl"
+#undef	elf32_bed
+#define	elf32_bed			elf32_i386_nacl_bed
+
+#undef	ELF_MAXPAGESIZE
+#define	ELF_MAXPAGESIZE			0x10000
+
+/* Restore defaults.  */
+#undef	ELF_OSABI
+#undef	elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym	0
+#undef	elf_backend_post_process_headers
+#define	elf_backend_post_process_headers	_bfd_elf_set_osabi
+#undef	elf_backend_static_tls_alignment
+
+/* NaCl uses substantially different PLT entries for the same effects.  */
+
+#undef	elf_backend_plt_alignment
+#define elf_backend_plt_alignment	5
+#define NACL_PLT_ENTRY_SIZE		64
+#define	NACLMASK			0xe0 /* 32-byte alignment mask.  */
+
+static const bfd_byte elf_i386_nacl_plt0_entry[] =
+  {
+    0xff, 0x35,			  /* pushl contents of address */
+    0, 0, 0, 0,			  /* replaced with address of .got + 4.	 */
+    0x8b, 0x0d,                   /* movl contents of address, %ecx */
+    0, 0, 0, 0,			  /* replaced with address of .got + 8.	 */
+    0x83, 0xe1, NACLMASK,	  /* andl $NACLMASK, %ecx */
+    0xff, 0xe1			  /* jmp *%ecx */
+  };
+
+static const bfd_byte elf_i386_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
+  {
+    0x8b, 0x0d,				/* movl contents of address, %ecx */
+    0, 0, 0, 0,				/* replaced with GOT slot address.  */
+    0x83, 0xe1, NACLMASK,		/* andl $NACLMASK, %ecx */
+    0xff, 0xe1,				/* jmp *%ecx */
+
+    /* Pad to the next 32-byte boundary with nop instructions.	*/
+    0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+
+    /* Lazy GOT entries point here (32-byte aligned).  */
+    0x68,			       /* pushl immediate */
+    0, 0, 0, 0,			       /* replaced with reloc offset.  */
+    0xe9,			       /* jmp relative */
+    0, 0, 0, 0,			       /* replaced with offset to .plt.	 */
+
+    /* Pad to the next 32-byte boundary with nop instructions.	*/
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90
+  };
+
+static const bfd_byte
+elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] =
+  {
+    0xff, 0x73, 0x04,		/* pushl 4(%ebx) */
+    0x8b, 0x4b, 0x08,		/* mov 0x8(%ebx), %ecx */
+    0x83, 0xe1, 0xe0,		/* and $NACLMASK, %ecx */
+    0xff, 0xe1,			/* jmp *%ecx */
+    0x90                        /* nop */
+  };
+
+static const bfd_byte elf_i386_nacl_pic_plt_entry[NACL_PLT_ENTRY_SIZE] =
+  {
+    0x8b, 0x8b,          /* movl offset(%ebx), %ecx */
+    0, 0, 0, 0,          /* replaced with offset of this symbol in .got.  */
+    0x83, 0xe1, 0xe0,    /* andl $NACLMASK, %ecx */
+    0xff, 0xe1,          /* jmp *%ecx */
+
+    /* Pad to the next 32-byte boundary with nop instructions.	*/
+    0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+
+    /* Lazy GOT entries point here (32-byte aligned).  */
+    0x68,                /* pushl immediate */
+    0, 0, 0, 0,          /* replaced with offset into relocation table.  */
+    0xe9,                /* jmp relative */
+    0, 0, 0, 0,          /* replaced with offset to start of .plt.  */
+
+    /* Pad to the next 32-byte boundary with nop instructions.	*/
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
+    0x90, 0x90
+  };
+
+static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
+  {
+#if (PLT_CIE_LENGTH != 20                               \
+     || PLT_FDE_LENGTH != 36                            \
+     || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8  \
+     || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
+# error "Need elf_i386_backend_data parameters for eh_frame_plt offsets!"
+#endif
+    PLT_CIE_LENGTH, 0, 0, 0,		/* CIE length */
+    0, 0, 0, 0,                         /* CIE ID */
+    1,                                  /* CIE version */
+    'z', 'R', 0,                        /* Augmentation string */
+    1,                                  /* Code alignment factor */
+    0x7c,                               /* Data alignment factor: -4 */
+    8,                                  /* Return address column */
+    1,					/* Augmentation size */
+    DW_EH_PE_pcrel | DW_EH_PE_sdata4,	/* FDE encoding */
+    DW_CFA_def_cfa, 4, 4,		/* DW_CFA_def_cfa: r4 (esp) ofs 4 */
+    DW_CFA_offset + 8, 1,		/* DW_CFA_offset: r8 (eip) at cfa-4 */
+    DW_CFA_nop, DW_CFA_nop,
+
+    PLT_FDE_LENGTH, 0, 0, 0,     /* FDE length */
+    PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
+    0, 0, 0, 0,                  /* R_386_PC32 .plt goes here */
+    0, 0, 0, 0,                  /* .plt size goes here */
+    0,                           /* Augmentation size */
+    DW_CFA_def_cfa_offset, 8,    /* DW_CFA_def_cfa_offset: 8 */
+    DW_CFA_advance_loc + 6,      /* DW_CFA_advance_loc: 6 to __PLT__+6 */
+    DW_CFA_def_cfa_offset, 12,   /* DW_CFA_def_cfa_offset: 12 */
+    DW_CFA_advance_loc + 58,     /* DW_CFA_advance_loc: 58 to __PLT__+64 */
+    DW_CFA_def_cfa_expression,   /* DW_CFA_def_cfa_expression */
+    13,                          /* Block length */
+    DW_OP_breg4, 4,              /* DW_OP_breg4 (esp): 4 */
+    DW_OP_breg8, 0,              /* DW_OP_breg8 (eip): 0 */
+    DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
+    DW_OP_lit2, DW_OP_shl, DW_OP_plus,
+    DW_CFA_nop, DW_CFA_nop
+  };
+
+static const struct elf_i386_plt_layout elf_i386_nacl_plt =
+  {
+    elf_i386_nacl_plt0_entry,		/* plt0_entry */
+    sizeof (elf_i386_nacl_plt0_entry),	/* plt0_entry_size */
+    2,					/* plt0_got1_offset */
+    8,					/* plt0_got2_offset */
+    elf_i386_nacl_plt_entry,		/* plt_entry */
+    NACL_PLT_ENTRY_SIZE,		/* plt_entry_size */
+    2,					/* plt_got_offset */
+    33,					/* plt_reloc_offset */
+    38,					/* plt_plt_offset */
+    32,					/* plt_lazy_offset */
+    elf_i386_nacl_pic_plt0_entry,	/* pic_plt0_entry */
+    elf_i386_nacl_pic_plt_entry,	/* pic_plt_entry */
+    elf_i386_nacl_eh_frame_plt,		/* eh_frame_plt */
+    sizeof (elf_i386_nacl_eh_frame_plt),/* eh_frame_plt_size */
+  };
+
+static const struct elf_i386_backend_data elf_i386_nacl_arch_bed =
+  {
+    &elf_i386_nacl_plt,                      /* plt */
+    0x90,				/* plt0_pad_byte: nop insn */
+    0,                                  /* is_vxworks */
+  };
+
+#undef	elf_backend_arch_data
+#define elf_backend_arch_data	&elf_i386_nacl_arch_bed
+
+#include "elf32-target.h"
+
 /* VxWorks support.  */
 
 #undef	TARGET_LITTLE_SYM
@@ -5037,6 +5201,8 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
 #undef	TARGET_LITTLE_NAME
 #define TARGET_LITTLE_NAME		"elf32-i386-vxworks"
 #undef	ELF_OSABI
+#undef	elf_backend_plt_alignment
+#define elf_backend_plt_alignment	4
 
 static const struct elf_i386_backend_data elf_i386_vxworks_arch_bed =
   {
diff --git a/bfd/targets.c b/bfd/targets.c
index 0bfc104..c34ce69 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -1,6 +1,6 @@
 /* Generic target-file-type support for the BFD library.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -618,6 +618,7 @@ extern const bfd_target bfd_elf32_hppa_nbsd_vec;
 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_nacl_vec;
 extern const bfd_target bfd_elf32_i386_sol2_vec;
 extern const bfd_target bfd_elf32_i386_vxworks_vec;
 extern const bfd_target bfd_elf32_i386_vec;
@@ -978,6 +979,7 @@ static const bfd_target * const _bfd_target_vector[] =
 	&bfd_elf32_hppa_vec,
 	&bfd_elf32_i370_vec,
 	&bfd_elf32_i386_freebsd_vec,
+	&bfd_elf32_i386_nacl_vec,
 	&bfd_elf32_i386_sol2_vec,
 	&bfd_elf32_i386_vxworks_vec,
 	&bfd_elf32_i386_vec,


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