diff options
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r-- | gas/config/tc-i386.c | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 4ce772c..7c26bca 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: |