From a27e437177412e5b52999723f3c5d5d0d37b9087 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 28 Jul 2011 22:35:15 +0000 Subject: [PATCH] BFD vector for elf32-i386-nacl: 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. --- bfd/ChangeLog | 15 +++++ bfd/config.bfd | 14 ++-- bfd/configure | 1 + bfd/configure.in | 1 + bfd/elf32-i386.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ bfd/targets.c | 4 +- 6 files changed, 195 insertions(+), 6 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f1885cb133..c3fac58ee4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,20 @@ 2011-07-28 Roland McGrath + * 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. + * elf32-i386.c (struct elf_i386_plt_layout): New type. (GET_PLT_ENTRY_SIZE): New macro. (elf_i386_plt): New variable. diff --git a/bfd/config.bfd b/bfd/config.bfd index 3f5b9a1abb..3b9872a2a4 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -566,6 +566,10 @@ 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" + ;; #ifdef BFD64 x86_64-*-darwin*) targ_defvec=mach_o_x86_64_vec @@ -714,12 +718,12 @@ case "${targ}" in targ_defvec=bfd_elf32_lm32_vec targ_selvecs=bfd_elf32_lm32fdpic_vec ;; - + lm32-*-*linux*) targ_defvec=bfd_elf32_lm32fdpic_vec targ_selvecs=bfd_elf32_lm32_vec ;; - + m32c-*-elf | m32c-*-rtems*) targ_defvec=bfd_elf32_m32c_vec ;; @@ -927,11 +931,11 @@ case "${targ}" in want64=true ;; #endif - mips*el-sde-elf*) + mips*el-sde-elf*) targ_defvec=bfd_elf32_tradlittlemips_vec targ_selvecs="bfd_elf32_tradbigmips_vec bfd_elf32_ntradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec" want64=true - ;; + ;; mips*-sde-elf*) targ_defvec=bfd_elf32_tradbigmips_vec targ_selvecs="bfd_elf32_tradlittlemips_vec bfd_elf32_ntradbigmips_vec bfd_elf32_ntradlittlemips_vec bfd_elf64_tradbigmips_vec bfd_elf64_tradlittlemips_vec" @@ -1541,7 +1545,7 @@ case "${targ}" in xc16x-*-elf) targ_defvec=bfd_elf32_xc16x_vec ;; - + z80-*-*) targ_defvec=z80coff_vec targ_underscore=no diff --git a/bfd/configure b/bfd/configure index 40c17db9ca..06f78398c7 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 e1ae5fc934..530d4eeab3 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 cb16fafafc..38c7c5a610 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 0bfc104dbb..c34ce69072 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,