From: H.J. Lu Date: Tue, 12 Nov 2013 23:46:55 +0000 (-0800) Subject: Add R_X86_64_PC32_BND and R_X86_64_PLT32_BND X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c33205431ae179ed500f2840759a7624af1a23d4;p=binutils-gdb.git Add R_X86_64_PC32_BND and R_X86_64_PLT32_BND bfd/ * elf64-x86-64.c (x86_64_elf_howto_table): Add R_X86_64_PC32_BND and R_X86_64_PLT32_BND. (R_X86_64_standard): Replace R_X86_64_RELATIVE64 with R_X86_64_PLT32_BND. (IS_X86_64_PCREL_TYPE): Add R_X86_64_PLT32_BND. (x86_64_reloc_map): Add BFD_RELOC_X86_64_PC32_BND and BFD_RELOC_X86_64_PLT32_BND. (elf_x86_64_check_relocs): Handle R_X86_64_PC32_BND and R_X86_64_PLT32_BND. (elf_x86_64_gc_sweep_hook): Likewise. (elf_x86_64_relocate_section): Likewise. * reloc.c (bfd_reloc_code_real): Add BFD_RELOC_X86_64_PC32_BND and BFD_RELOC_X86_64_PLT32_BND. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. gas/ * config/tc-i386.c (reloc): Add an argument, bnd_prefix, to indicate if instruction has the BND prefix. Return BFD_RELOC_X86_64_PC32_BND instead of BFD_RELOC_32_PCREL if bnd_prefix isn't zero. (output_branch): Pass BFD_RELOC_X86_64_PC32_BND to frag_var if needed. (output_jump): Update reloc call. (output_interseg_jump): Likewise. (output_disp): Likewise. (output_imm): Likewise. (x86_cons_fix_new): Likewise. (lex_got): Add an argument, bnd_prefix, to indicate if instruction has the BND prefix. Use BFD_RELOC_X86_64_PLT32_BND if needed. (x86_cons): Update lex_got call. (i386_immediate): Likewise. (i386_displacement): Likewise. (md_apply_fix): Handle BFD_RELOC_X86_64_PC32_BND and BFD_RELOC_X86_64_PLT32_BND. (tc_gen_reloc): Likewise. * config/tc-i386-intel.c (i386_operator): Update lex_got call. gas/testsuite/ * gas/i386/i386.exp: Run x86-64-mpx-branch-1 and x86-64-mpx-branch-2 on 64-bit ELF targets. * gas/i386/x86-64-mpx-branch-1.d: New file. * gas/i386/x86-64-mpx-branch-1.s: Likewise. * gas/i386/x86-64-mpx-branch-2.d: Likewise. * gas/i386/x86-64-mpx-branch-2.s: Likewise. include/elf/ * x86-64.h: Add R_X86_64_PC32_BND and R_X86_64_PLT32_BND. ld/testsuite/ * ld-x86-64/mpx.exp: New file. * ld-x86-64/mpx1.out: Likewise. * ld-x86-64/mpx1a.c: Likewise. * ld-x86-64/mpx1a.rd: Likewise. * ld-x86-64/mpx1b.c: Likewise. * ld-x86-64/mpx1c.c: Likewise. * ld-x86-64/mpx1c.rd: Likewise. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 94b89a05c3e..b5869d59676 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,21 @@ +2013-11-17 H.J. Lu + + * elf64-x86-64.c (x86_64_elf_howto_table): Add R_X86_64_PC32_BND + and R_X86_64_PLT32_BND. + (R_X86_64_standard): Replace R_X86_64_RELATIVE64 with + R_X86_64_PLT32_BND. + (IS_X86_64_PCREL_TYPE): Add R_X86_64_PLT32_BND. + (x86_64_reloc_map): Add BFD_RELOC_X86_64_PC32_BND and + BFD_RELOC_X86_64_PLT32_BND. + (elf_x86_64_check_relocs): Handle R_X86_64_PC32_BND and + R_X86_64_PLT32_BND. + (elf_x86_64_gc_sweep_hook): Likewise. + (elf_x86_64_relocate_section): Likewise. + * reloc.c (bfd_reloc_code_real): Add BFD_RELOC_X86_64_PC32_BND + and BFD_RELOC_X86_64_PLT32_BND. + * bfd-in2.h: Regenerated. + * libbfd.h: Likewise. + 2013-11-15 H.J. Lu * elf32-i386.c (elf_i386_allocate_dynrelocs): Make room for diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 79f213074a6..846116b58a9 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -3125,6 +3125,8 @@ instruction. */ BFD_RELOC_X86_64_TLSDESC_CALL, BFD_RELOC_X86_64_TLSDESC, BFD_RELOC_X86_64_IRELATIVE, + BFD_RELOC_X86_64_PC32_BND, + BFD_RELOC_X86_64_PLT32_BND, /* ns32k relocations */ BFD_RELOC_NS32K_IMM_8, diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 6ff5f36d040..8eac635dfdf 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -172,12 +172,18 @@ static reloc_howto_type x86_64_elf_howto_table[] = HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", FALSE, MINUS_ONE, MINUS_ONE, FALSE), + HOWTO(R_X86_64_PC32_BND, 0, 2, 32, TRUE, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_PC32_BND", FALSE, 0xffffffff, 0xffffffff, + TRUE), + HOWTO(R_X86_64_PLT32_BND, 0, 2, 32, TRUE, 0, complain_overflow_signed, + bfd_elf_generic_reloc, "R_X86_64_PLT32_BND", FALSE, 0xffffffff, 0xffffffff, + TRUE), /* We have a gap in the reloc numbers here. R_X86_64_standard counts the number up to this point, and R_X86_64_vt_offset is the value to subtract from a reloc type of R_X86_64_GNU_VT* to form an index into this table. */ -#define R_X86_64_standard (R_X86_64_RELATIVE64 + 1) +#define R_X86_64_standard (R_X86_64_PLT32_BND + 1) #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard) /* GNU extension to record C++ vtable hierarchy. */ @@ -199,6 +205,7 @@ static reloc_howto_type x86_64_elf_howto_table[] = ( ((TYPE) == R_X86_64_PC8) \ || ((TYPE) == R_X86_64_PC16) \ || ((TYPE) == R_X86_64_PC32) \ + || ((TYPE) == R_X86_64_PC32_BND) \ || ((TYPE) == R_X86_64_PC64)) /* Map BFD relocs to the x86_64 elf relocs. */ @@ -248,6 +255,8 @@ static const struct elf_reloc_map x86_64_reloc_map[] = { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, }, { BFD_RELOC_X86_64_TLSDESC, R_X86_64_TLSDESC, }, { BFD_RELOC_X86_64_IRELATIVE, R_X86_64_IRELATIVE, }, + { BFD_RELOC_X86_64_PC32_BND, R_X86_64_PC32_BND,}, + { BFD_RELOC_X86_64_PLT32_BND, R_X86_64_PLT32_BND,}, { BFD_RELOC_VTABLE_INHERIT, R_X86_64_GNU_VTINHERIT, }, { BFD_RELOC_VTABLE_ENTRY, R_X86_64_GNU_VTENTRY, }, }; @@ -1542,8 +1551,10 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_X86_64_32: case R_X86_64_64: case R_X86_64_PC32: + case R_X86_64_PC32_BND: case R_X86_64_PC64: case R_X86_64_PLT32: + case R_X86_64_PLT32_BND: case R_X86_64_GOTPCREL: case R_X86_64_GOTPCREL64: if (htab->elf.dynobj == NULL) @@ -1706,6 +1717,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, break; case R_X86_64_PLT32: + case R_X86_64_PLT32_BND: /* This symbol requires a procedure linkage table entry. We actually build the entry in adjust_dynamic_symbol, because this might be a case of linking PIC code which is @@ -1766,6 +1778,7 @@ elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_X86_64_PC8: case R_X86_64_PC16: case R_X86_64_PC32: + case R_X86_64_PC32_BND: case R_X86_64_PC64: case R_X86_64_64: pointer: @@ -1782,7 +1795,9 @@ pointer: /* We may need a .plt entry if the function this reloc refers to is in a shared lib. */ h->plt.refcount += 1; - if (r_type != R_X86_64_PC32 && r_type != R_X86_64_PC64) + if (r_type != R_X86_64_PC32 + && r_type != R_X86_64_PC32_BND + && r_type != R_X86_64_PC64) h->pointer_equality_needed = 1; } @@ -2066,6 +2081,7 @@ elf_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, case R_X86_64_PC8: case R_X86_64_PC16: case R_X86_64_PC32: + case R_X86_64_PC32_BND: case R_X86_64_PC64: case R_X86_64_SIZE32: case R_X86_64_SIZE64: @@ -2075,6 +2091,7 @@ elf_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, /* Fall thru */ case R_X86_64_PLT32: + case R_X86_64_PLT32_BND: case R_X86_64_PLTOFF64: if (h != NULL) { @@ -3441,8 +3458,10 @@ elf_x86_64_relocate_section (bfd *output_bfd, } /* FALLTHROUGH */ case R_X86_64_PC32: + case R_X86_64_PC32_BND: case R_X86_64_PC64: case R_X86_64_PLT32: + case R_X86_64_PLT32_BND: goto do_relocation; case R_X86_64_GOTPCREL: @@ -3687,6 +3706,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, break; case R_X86_64_PLT32: + case R_X86_64_PLT32_BND: /* Relocation is to the entry for this symbol in the procedure linkage table. */ @@ -3719,6 +3739,7 @@ elf_x86_64_relocate_section (bfd *output_bfd, case R_X86_64_PC8: case R_X86_64_PC16: case R_X86_64_PC32: + case R_X86_64_PC32_BND: if (info->shared && (input_section->flags & SEC_ALLOC) != 0 && (input_section->flags & SEC_READONLY) != 0 @@ -3726,7 +3747,8 @@ elf_x86_64_relocate_section (bfd *output_bfd, { bfd_boolean fail = FALSE; bfd_boolean branch - = (r_type == R_X86_64_PC32 + = ((r_type == R_X86_64_PC32 + || r_type == R_X86_64_PC32_BND) && is_32bit_relative_branch (contents, rel->r_offset)); if (SYMBOL_REFERENCES_LOCAL (info, h)) diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 4f98108afd5..4aaecbffa0e 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1307,6 +1307,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_X86_64_TLSDESC_CALL", "BFD_RELOC_X86_64_TLSDESC", "BFD_RELOC_X86_64_IRELATIVE", + "BFD_RELOC_X86_64_PC32_BND", + "BFD_RELOC_X86_64_PLT32_BND", "BFD_RELOC_NS32K_IMM_8", "BFD_RELOC_NS32K_IMM_16", "BFD_RELOC_NS32K_IMM_32", diff --git a/bfd/reloc.c b/bfd/reloc.c index 8778e1d4657..77a04f8c0ca 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2699,6 +2699,10 @@ ENUMX BFD_RELOC_X86_64_TLSDESC ENUMX BFD_RELOC_X86_64_IRELATIVE +ENUMX + BFD_RELOC_X86_64_PC32_BND +ENUMX + BFD_RELOC_X86_64_PLT32_BND ENUMDOC x86-64/elf relocations diff --git a/gas/ChangeLog b/gas/ChangeLog index c72d37afda6..8127a9b1c50 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,27 @@ +2013-11-17 H.J. Lu + + * config/tc-i386.c (reloc): Add an argument, bnd_prefix, to + indicate if instruction has the BND prefix. Return + BFD_RELOC_X86_64_PC32_BND instead of BFD_RELOC_32_PCREL if + bnd_prefix isn't zero. + (output_branch): Pass BFD_RELOC_X86_64_PC32_BND to frag_var + if needed. + (output_jump): Update reloc call. + (output_interseg_jump): Likewise. + (output_disp): Likewise. + (output_imm): Likewise. + (x86_cons_fix_new): Likewise. + (lex_got): Add an argument, bnd_prefix, to indicate if + instruction has the BND prefix. Use BFD_RELOC_X86_64_PLT32_BND + if needed. + (x86_cons): Update lex_got call. + (i386_immediate): Likewise. + (i386_displacement): Likewise. + (md_apply_fix): Handle BFD_RELOC_X86_64_PC32_BND and + BFD_RELOC_X86_64_PLT32_BND. + (tc_gen_reloc): Likewise. + * config/tc-i386-intel.c (i386_operator): Update lex_got call. + 2013-11-15 Yufeng Zhang * config/tc-aarch64.c (set_other_error): New function. diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c index e534110f4cd..8a2224ad7f8 100644 --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -142,7 +142,9 @@ operatorT i386_operator (const char *name, unsigned int operands, char *pc) int adjust = 0; char *gotfree_input_line = lex_got (&i.reloc[this_operand], &adjust, - &intel_state.reloc_types); + &intel_state.reloc_types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); if (!gotfree_input_line) break; diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 4ce772ca298..7c26bca05be 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2800,6 +2800,7 @@ static bfd_reloc_code_real_type reloc (unsigned int size, int pcrel, int sign, + int bnd_prefix, bfd_reloc_code_real_type other) { if (other != NO_RELOC) @@ -2872,7 +2873,9 @@ reloc (unsigned int size, { case 1: return BFD_RELOC_8_PCREL; case 2: return BFD_RELOC_16_PCREL; - case 4: return BFD_RELOC_32_PCREL; + case 4: return (bnd_prefix && object_64bit + ? BFD_RELOC_X86_64_PC32_BND + : BFD_RELOC_32_PCREL); case 8: return BFD_RELOC_64_PCREL; } as_bad (_("cannot do %u byte pc-relative relocation"), size); @@ -6716,7 +6719,13 @@ output_branch (void) /* 1 possible extra opcode + 4 byte displacement go in var part. Pass reloc in fr_var. */ - frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p); + frag_var (rs_machine_dependent, 5, + ((!object_64bit + || i.reloc[0] != NO_RELOC + || (i.bnd_prefix == NULL && !add_bnd_prefix)) + ? i.reloc[0] + : BFD_RELOC_X86_64_PC32_BND), + subtype, sym, off, p); } static void @@ -6792,7 +6801,10 @@ output_jump (void) } fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0])); + i.op[0].disps, 1, reloc (size, 1, 1, + (i.bnd_prefix != NULL + || add_bnd_prefix), + i.reloc[0])); /* All jumps handled here are signed, but don't use a signed limit check for 32 and 16 bit jumps as we want to allow wrap around at @@ -6858,7 +6870,7 @@ output_interseg_jump (void) } else fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1])); + i.op[1].imms, 0, reloc (size, 0, 0, 0, i.reloc[1])); if (i.op[0].imms->X_op != O_constant) as_bad (_("can't handle non absolute segment in `%s'"), i.tm.name); @@ -7117,7 +7129,10 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off) } p = frag_more (size); - reloc_type = reloc (size, pcrel, sign, i.reloc[n]); + reloc_type = reloc (size, pcrel, sign, + (i.bnd_prefix != NULL + || add_bnd_prefix), + i.reloc[n]); if (GOT_symbol && GOT_symbol == i.op[n].disps->X_add_symbol && (((reloc_type == BFD_RELOC_32 @@ -7208,7 +7223,7 @@ output_imm (fragS *insn_start_frag, offsetT insn_start_off) sign = 0; p = frag_more (size); - reloc_type = reloc (size, 0, sign, i.reloc[n]); + reloc_type = reloc (size, 0, sign, 0, i.reloc[n]); /* This is tough to explain. We end up with this one if we * have operands that look like @@ -7302,7 +7317,7 @@ void x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len, expressionS *exp) { - enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, got_reloc); + enum bfd_reloc_code_real r = reloc (len, 0, cons_sign, 0, got_reloc); got_reloc = NO_RELOC; @@ -7344,7 +7359,8 @@ x86_address_bytes (void) static char * lex_got (enum bfd_reloc_code_real *rel, int *adjust, - i386_operand_type *types) + i386_operand_type *types, + int bnd_prefix) { /* Some of the relocations depend on the size of what field is to be relocated. But in our callers i386_immediate and i386_displacement @@ -7479,6 +7495,8 @@ lex_got (enum bfd_reloc_code_real *rel, *adjust = len; memcpy (tmpbuf + first, past_reloc, second); tmpbuf[first + second] = '\0'; + if (bnd_prefix && *rel == BFD_RELOC_X86_64_PLT32) + *rel = BFD_RELOC_X86_64_PLT32_BND; return tmpbuf; } @@ -7610,7 +7628,7 @@ x86_cons (expressionS *exp, int size) int adjust = 0; save = input_line_pointer; - gotfree_input_line = lex_got (&got_reloc, &adjust, NULL); + gotfree_input_line = lex_got (&got_reloc, &adjust, NULL, 0); if (gotfree_input_line) input_line_pointer = gotfree_input_line; @@ -7838,7 +7856,9 @@ i386_immediate (char *imm_start) save_input_line_pointer = input_line_pointer; input_line_pointer = imm_start; - gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types); + gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); if (gotfree_input_line) input_line_pointer = gotfree_input_line; @@ -8095,7 +8115,9 @@ i386_displacement (char *disp_start, char *disp_end) *displacement_string_end = '0'; } #endif - gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types); + gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); if (gotfree_input_line) input_line_pointer = gotfree_input_line; @@ -9055,7 +9077,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) && (fixP->fx_r_type == BFD_RELOC_32_PCREL || fixP->fx_r_type == BFD_RELOC_64_PCREL || fixP->fx_r_type == BFD_RELOC_16_PCREL - || fixP->fx_r_type == BFD_RELOC_8_PCREL) + || fixP->fx_r_type == BFD_RELOC_8_PCREL + || fixP->fx_r_type == BFD_RELOC_X86_64_PC32_BND) && !use_rela_relocations) { /* This is a hack. There should be a better way to handle this. @@ -9111,6 +9134,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) { case BFD_RELOC_386_PLT32: case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: /* Make the jump instruction point to the address of the operand. At runtime we merely add the offset to the actual PLT entry. */ value = -4; @@ -10182,6 +10206,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) #endif case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: case BFD_RELOC_X86_64_GOT32: case BFD_RELOC_X86_64_GOTPCREL: case BFD_RELOC_386_PLT32: @@ -10242,7 +10267,10 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) break; case 1: code = BFD_RELOC_8_PCREL; break; case 2: code = BFD_RELOC_16_PCREL; break; - case 4: code = BFD_RELOC_32_PCREL; break; + case 4: + code = (fixp->fx_r_type == BFD_RELOC_X86_64_PC32_BND + ? fixp-> fx_r_type : BFD_RELOC_32_PCREL); + break; #ifdef BFD64 case 8: code = BFD_RELOC_64_PCREL; break; #endif @@ -10335,6 +10363,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) switch (code) { case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: case BFD_RELOC_X86_64_GOT32: case BFD_RELOC_X86_64_GOTPCREL: case BFD_RELOC_X86_64_TLSGD: diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 6850f17d47a..33afa040b43 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2013-11-17 H.J. Lu + + * gas/i386/i386.exp: Run x86-64-mpx-branch-1 and + x86-64-mpx-branch-2 on 64-bit ELF targets. + * gas/i386/x86-64-mpx-branch-1.d: New file. + * gas/i386/x86-64-mpx-branch-1.s: Likewise. + * gas/i386/x86-64-mpx-branch-2.d: Likewise. + * gas/i386/x86-64-mpx-branch-2.s: Likewise. + 2013-11-15 Yufeng Zhang * gas/aarch64/diagnostic.s: Add tests. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index ce77fef80eb..1fb27959b09 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -589,6 +589,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "k1om" run_dump_test "x86-64-localpic" run_dump_test "debug1" + run_dump_test "x86-64-mpx-branch-1" + run_dump_test "x86-64-mpx-branch-2" run_dump_test "x86-64-dw2-compress-2" diff --git a/gas/testsuite/gas/i386/x86-64-mpx-branch-1.d b/gas/testsuite/gas/i386/x86-64-mpx-branch-1.d new file mode 100644 index 00000000000..5edb1c76ebd --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-1.d @@ -0,0 +1,28 @@ +#as: -J +#objdump: -dwr +#name: x86-64 MPX branch + +.*: +file format .* + + +Disassembly of section .text: + +0+ : +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 6 2: R_X86_64_PC32_BND \*ABS\*\+0x10003c +[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq c 8: R_X86_64_PC32_BND \*ABS\*\+0x10003c + +0+c : +[ ]*[a-f0-9]+: f2 eb fd bnd jmp c +[ ]*[a-f0-9]+: f2 72 fa bnd jb c +[ ]*[a-f0-9]+: f2 e8 f4 ff ff ff bnd callq c +[ ]*[a-f0-9]+: f2 eb 09 bnd jmp 24 +[ ]*[a-f0-9]+: f2 72 06 bnd jb 24 +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 24 + +0+24 : +[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 2a 26: R_X86_64_PC32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 31 2d: R_X86_64_PC32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 37 33: R_X86_64_PC32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 3d 39: R_X86_64_PLT32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 44 40: R_X86_64_PLT32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 4a 46: R_X86_64_PLT32_BND foo-0x4 diff --git a/gas/testsuite/gas/i386/x86-64-mpx-branch-1.s b/gas/testsuite/gas/i386/x86-64-mpx-branch-1.s new file mode 100644 index 00000000000..3cdb1091724 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-1.s @@ -0,0 +1,18 @@ + .text + bnd call 0x100040 + bnd jmp 0x100040 + +foo1: + bnd jmp foo1 + bnd jb foo1 + bnd call foo1 + bnd jmp foo2 + bnd jb foo2 + bnd call foo2 +foo2: + bnd jmp foo + bnd jb foo + bnd call foo + bnd jmp foo@PLT + bnd jb foo@PLT + bnd call foo@plt diff --git a/gas/testsuite/gas/i386/x86-64-mpx-branch-2.d b/gas/testsuite/gas/i386/x86-64-mpx-branch-2.d new file mode 100644 index 00000000000..86fb360a2bf --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-2.d @@ -0,0 +1,28 @@ +#as: -J -madd-bnd-prefix +#objdump: -dwr +#name: x86-64 branch with BND prefix + +.*: +file format .* + + +Disassembly of section .text: + +0+ : +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 6 2: R_X86_64_PC32_BND \*ABS\*\+0x10003c +[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq c 8: R_X86_64_PC32_BND \*ABS\*\+0x10003c + +0+c : +[ ]*[a-f0-9]+: f2 eb fd bnd jmp c +[ ]*[a-f0-9]+: f2 72 fa bnd jb c +[ ]*[a-f0-9]+: f2 e8 f4 ff ff ff bnd callq c +[ ]*[a-f0-9]+: f2 eb 09 bnd jmp 24 +[ ]*[a-f0-9]+: f2 72 06 bnd jb 24 +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 24 + +0+24 : +[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 2a 26: R_X86_64_PC32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 31 2d: R_X86_64_PC32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 37 33: R_X86_64_PC32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 e9 00 00 00 00 bnd jmpq 3d 39: R_X86_64_PLT32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 0f 82 00 00 00 00 bnd jb 44 40: R_X86_64_PLT32_BND foo-0x4 +[ ]*[a-f0-9]+: f2 e8 00 00 00 00 bnd callq 4a 46: R_X86_64_PLT32_BND foo-0x4 diff --git a/gas/testsuite/gas/i386/x86-64-mpx-branch-2.s b/gas/testsuite/gas/i386/x86-64-mpx-branch-2.s new file mode 100644 index 00000000000..5fe90883a6e --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-mpx-branch-2.s @@ -0,0 +1,18 @@ + .text + call 0x100040 + jmp 0x100040 + +foo1: + jmp foo1 + jb foo1 + call foo1 + jmp foo2 + jb foo2 + call foo2 +foo2: + jmp foo + jb foo + call foo + jmp foo@PLT + jb foo@PLT + call foo@plt diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index dc226198f7b..1dcb9f95cc7 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,7 @@ +2013-11-17 H.J. Lu + + * x86-64.h: Add R_X86_64_PC32_BND and R_X86_64_PLT32_BND. + 2013-11-13 Yufeng Zhang * aarch64.h: Define R_AARCH64_TLS_DTPMOD64, diff --git a/include/elf/x86-64.h b/include/elf/x86-64.h index 0ce92cd54f6..ec59dbd868d 100644 --- a/include/elf/x86-64.h +++ b/include/elf/x86-64.h @@ -74,6 +74,10 @@ START_RELOC_NUMBERS (elf_x86_64_reloc_type) RELOC_NUMBER (R_X86_64_TLSDESC, 36) /* 2x64-bit TLS descriptor. */ RELOC_NUMBER (R_X86_64_IRELATIVE, 37) /* Adjust indirectly by program base */ RELOC_NUMBER (R_X86_64_RELATIVE64, 38) /* 64bit adjust by program base */ + RELOC_NUMBER (R_X86_64_PC32_BND, 39) /* PC relative 32 bit + signed with BND prefix */ + RELOC_NUMBER (R_X86_64_PLT32_BND, 40) /* 32 bit PLT address with + BND prefix */ RELOC_NUMBER (R_X86_64_GNU_VTINHERIT, 250) /* GNU C++ hack */ RELOC_NUMBER (R_X86_64_GNU_VTENTRY, 251) /* GNU C++ hack */ END_RELOC_NUMBERS (R_X86_64_max) diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 63db4e3aa71..2462cd3560a 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2013-11-17 H.J. Lu + + * ld-x86-64/mpx.exp: New file. + * ld-x86-64/mpx1.out: Likewise. + * ld-x86-64/mpx1a.c: Likewise. + * ld-x86-64/mpx1a.rd: Likewise. + * ld-x86-64/mpx1b.c: Likewise. + * ld-x86-64/mpx1c.c: Likewise. + * ld-x86-64/mpx1c.rd: Likewise. + 2013-11-14 Will Newton * ld-arm/script-type.sym: Remove redundant STT_FILE symbol. diff --git a/ld/testsuite/ld-x86-64/mpx.exp b/ld/testsuite/ld-x86-64/mpx.exp new file mode 100644 index 00000000000..a2f5996ffa9 --- /dev/null +++ b/ld/testsuite/ld-x86-64/mpx.exp @@ -0,0 +1,60 @@ +# Expect script for ELF MPX tests. +# Copyright 2013 +# Free Software Foundation, Inc. +# +# This file is part of the GNU Binutils. +# +# 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 3 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., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +# The following tests require running the executable generated by ld, +# or enough of a build environment to create a fully linked executable. +# This is not commonly available when testing a cross-built linker. +if ![isnative] { + return +} + +# Only on Linux for now. +if ![istarget "x86_64-*-linux*"] { + return +} + +# Check to see if the C compiler works +if { [which $CC] == 0 } { + return +} + +set build_tests { + {"Build libmpx1a.a" + "" "-Wa,-madd-bnd-prefix -fPIC" + {mpx1a.c} {{readelf {-r --wide} mpx1a.rd}} "libmpx1a.a"} + {"Build libmpx1b.a" + "" "" + {mpx1b.c} {} "libmpx1b.a"} + {"Build libmpx1c.a" + "" "-Wa,-madd-bnd-prefix" + {mpx1c.c} {{readelf {-r --wide} mpx1c.rd}} "libmpx1c.a"} +} + +run_cc_link_tests $build_tests + +set run_tests { + {"Run mpx1" + "tmpdir/mpx1a.o tmpdir/mpx1b.o tmpdir/mpx1c.o" "" + {dummy.s} "mpx1" "mpx1.out"} +} + +run_ld_link_exec_tests [] $run_tests diff --git a/ld/testsuite/ld-x86-64/mpx1.out b/ld/testsuite/ld-x86-64/mpx1.out new file mode 100644 index 00000000000..463021151d2 --- /dev/null +++ b/ld/testsuite/ld-x86-64/mpx1.out @@ -0,0 +1,2 @@ +foo1 +foo2 diff --git a/ld/testsuite/ld-x86-64/mpx1a.c b/ld/testsuite/ld-x86-64/mpx1a.c new file mode 100644 index 00000000000..e1185b5fe6f --- /dev/null +++ b/ld/testsuite/ld-x86-64/mpx1a.c @@ -0,0 +1,7 @@ +#include + +void +foo1 (void) +{ + printf ("foo1\n"); +} diff --git a/ld/testsuite/ld-x86-64/mpx1a.rd b/ld/testsuite/ld-x86-64/mpx1a.rd new file mode 100644 index 00000000000..9bebc8294fa --- /dev/null +++ b/ld/testsuite/ld-x86-64/mpx1a.rd @@ -0,0 +1,3 @@ +#... +[0-9a-f ]+R_X86_64_PLT32_BND +0+ +.* +#... diff --git a/ld/testsuite/ld-x86-64/mpx1b.c b/ld/testsuite/ld-x86-64/mpx1b.c new file mode 100644 index 00000000000..389ac101344 --- /dev/null +++ b/ld/testsuite/ld-x86-64/mpx1b.c @@ -0,0 +1,7 @@ +#include + +void +foo2 (void) +{ + printf ("foo2\n"); +} diff --git a/ld/testsuite/ld-x86-64/mpx1c.c b/ld/testsuite/ld-x86-64/mpx1c.c new file mode 100644 index 00000000000..12c7806ff0c --- /dev/null +++ b/ld/testsuite/ld-x86-64/mpx1c.c @@ -0,0 +1,10 @@ +extern void foo1 (void); +extern void foo2 (void); + +int +main (void) +{ + foo1 (); + foo2 (); + return 0; +} diff --git a/ld/testsuite/ld-x86-64/mpx1c.rd b/ld/testsuite/ld-x86-64/mpx1c.rd new file mode 100644 index 00000000000..2b050bd8e75 --- /dev/null +++ b/ld/testsuite/ld-x86-64/mpx1c.rd @@ -0,0 +1,3 @@ +#... +[0-9a-f ]+R_X86_64_PC32_BND +0+ +.* +#...