Add R_X86_64_PC32_BND and R_X86_64_PLT32_BND
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 12 Nov 2013 23:46:55 +0000 (15:46 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 17 Nov 2013 16:57:56 +0000 (08:57 -0800)
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.

24 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf64-x86-64.c
bfd/libbfd.h
bfd/reloc.c
gas/ChangeLog
gas/config/tc-i386-intel.c
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/x86-64-mpx-branch-1.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-mpx-branch-1.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-mpx-branch-2.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-mpx-branch-2.s [new file with mode: 0644]
include/elf/ChangeLog
include/elf/x86-64.h
ld/testsuite/ChangeLog
ld/testsuite/ld-x86-64/mpx.exp [new file with mode: 0644]
ld/testsuite/ld-x86-64/mpx1.out [new file with mode: 0644]
ld/testsuite/ld-x86-64/mpx1a.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/mpx1a.rd [new file with mode: 0644]
ld/testsuite/ld-x86-64/mpx1b.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/mpx1c.c [new file with mode: 0644]
ld/testsuite/ld-x86-64/mpx1c.rd [new file with mode: 0644]

index 94b89a0..b5869d5 100644 (file)
@@ -1,3 +1,21 @@
+2013-11-17  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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  <hongjiu.lu@intel.com>
 
        * elf32-i386.c (elf_i386_allocate_dynrelocs): Make room for
index 79f2130..846116b 100644 (file)
@@ -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,
index 6ff5f36..8eac635 100644 (file)
@@ -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))
index 4f98108..4aaecbf 100644 (file)
@@ -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",
index 8778e1d..77a04f8 100644 (file)
@@ -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
 
index c72d37a..8127a9b 100644 (file)
@@ -1,3 +1,27 @@
+2013-11-17  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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  <yufeng.zhang@arm.com>
 
        * config/tc-aarch64.c (set_other_error): New function.
index e534110..8a2224a 100644 (file)
@@ -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;
index 4ce772c..7c26bca 100644 (file)
@@ -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:
index 6850f17..33afa04 100644 (file)
@@ -1,3 +1,12 @@
+2013-11-17  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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  <yufeng.zhang@arm.com>
 
        * gas/aarch64/diagnostic.s: Add tests.
index ce77fef..1fb2795 100644 (file)
@@ -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 (file)
index 0000000..5edb1c7
--- /dev/null
@@ -0,0 +1,28 @@
+#as: -J
+#objdump: -dwr
+#name: x86-64 MPX branch
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <foo1-0xc>:
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 6 <foo1-0x6>  2: R_X86_64_PC32_BND    \*ABS\*\+0x10003c
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq c <foo1>       8: R_X86_64_PC32_BND    \*ABS\*\+0x10003c
+
+0+c <foo1>:
+[      ]*[a-f0-9]+:    f2 eb fd                bnd jmp c <foo1>
+[      ]*[a-f0-9]+:    f2 72 fa                bnd jb c <foo1>
+[      ]*[a-f0-9]+:    f2 e8 f4 ff ff ff       bnd callq c <foo1>
+[      ]*[a-f0-9]+:    f2 eb 09                bnd jmp 24 <foo2>
+[      ]*[a-f0-9]+:    f2 72 06                bnd jb 24 <foo2>
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 24 <foo2>
+
+0+24 <foo2>:
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PC32_BND   foo-0x4
+[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 31 <foo2\+0xd>   2d: R_X86_64_PC32_BND   foo-0x4
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 37 <foo2\+0x13>       33: R_X86_64_PC32_BND   foo-0x4
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 3d <foo2\+0x19>        39: R_X86_64_PLT32_BND  foo-0x4
+[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 44 <foo2\+0x20>  40: R_X86_64_PLT32_BND  foo-0x4
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 4a <foo2\+0x26>       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 (file)
index 0000000..3cdb109
--- /dev/null
@@ -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 (file)
index 0000000..86fb360
--- /dev/null
@@ -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+ <foo1-0xc>:
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 6 <foo1-0x6>  2: R_X86_64_PC32_BND    \*ABS\*\+0x10003c
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq c <foo1>       8: R_X86_64_PC32_BND    \*ABS\*\+0x10003c
+
+0+c <foo1>:
+[      ]*[a-f0-9]+:    f2 eb fd                bnd jmp c <foo1>
+[      ]*[a-f0-9]+:    f2 72 fa                bnd jb c <foo1>
+[      ]*[a-f0-9]+:    f2 e8 f4 ff ff ff       bnd callq c <foo1>
+[      ]*[a-f0-9]+:    f2 eb 09                bnd jmp 24 <foo2>
+[      ]*[a-f0-9]+:    f2 72 06                bnd jb 24 <foo2>
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 24 <foo2>
+
+0+24 <foo2>:
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 2a <foo2\+0x6> 26: R_X86_64_PC32_BND   foo-0x4
+[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 31 <foo2\+0xd>   2d: R_X86_64_PC32_BND   foo-0x4
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 37 <foo2\+0x13>       33: R_X86_64_PC32_BND   foo-0x4
+[      ]*[a-f0-9]+:    f2 e9 00 00 00 00       bnd jmpq 3d <foo2\+0x19>        39: R_X86_64_PLT32_BND  foo-0x4
+[      ]*[a-f0-9]+:    f2 0f 82 00 00 00 00    bnd jb 44 <foo2\+0x20>  40: R_X86_64_PLT32_BND  foo-0x4
+[      ]*[a-f0-9]+:    f2 e8 00 00 00 00       bnd callq 4a <foo2\+0x26>       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 (file)
index 0000000..5fe9088
--- /dev/null
@@ -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
index dc22619..1dcb9f9 100644 (file)
@@ -1,3 +1,7 @@
+2013-11-17  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * x86-64.h: Add R_X86_64_PC32_BND and R_X86_64_PLT32_BND.
+
 2013-11-13  Yufeng Zhang  <yufeng.zhang@arm.com>
 
        * aarch64.h: Define R_AARCH64_TLS_DTPMOD64,
index 0ce92cd..ec59dbd 100644 (file)
@@ -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)
index 63db4e3..2462cd3 100644 (file)
@@ -1,3 +1,13 @@
+2013-11-17  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * 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  <will.newton@linaro.org>
 
        * 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 (file)
index 0000000..a2f5996
--- /dev/null
@@ -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 (file)
index 0000000..4630211
--- /dev/null
@@ -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 (file)
index 0000000..e1185b5
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+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 (file)
index 0000000..9bebc82
--- /dev/null
@@ -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 (file)
index 0000000..389ac10
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+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 (file)
index 0000000..12c7806
--- /dev/null
@@ -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 (file)
index 0000000..2b050bd
--- /dev/null
@@ -0,0 +1,3 @@
+#...
+[0-9a-f ]+R_X86_64_PC32_BND +0+ +.*
+#...