summaryrefslogtreecommitdiffstats
path: root/contrib/binutils/gas/config/tc-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/gas/config/tc-i386.c')
-rw-r--r--contrib/binutils/gas/config/tc-i386.c379
1 files changed, 233 insertions, 146 deletions
diff --git a/contrib/binutils/gas/config/tc-i386.c b/contrib/binutils/gas/config/tc-i386.c
index f681014..fc1bd13 100644
--- a/contrib/binutils/gas/config/tc-i386.c
+++ b/contrib/binutils/gas/config/tc-i386.c
@@ -104,8 +104,10 @@ static void output_insn PARAMS ((void));
static void output_branch PARAMS ((void));
static void output_jump PARAMS ((void));
static void output_interseg_jump PARAMS ((void));
-static void output_imm PARAMS ((void));
-static void output_disp PARAMS ((void));
+static void output_imm PARAMS ((fragS *insn_start_frag,
+ offsetT insn_start_off));
+static void output_disp PARAMS ((fragS *insn_start_frag,
+ offsetT insn_start_off));
#ifndef I386COFF
static void s_bss PARAMS ((int));
#endif
@@ -435,7 +437,7 @@ const pseudo_typeS md_pseudo_table[] =
{"code64", set_code_flag, CODE_64BIT},
{"intel_syntax", set_intel_syntax, 1},
{"att_syntax", set_intel_syntax, 0},
- {"file", dwarf2_directive_file, 0},
+ {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0},
{"loc", dwarf2_directive_loc, 0},
{0, 0, 0}
};
@@ -1130,21 +1132,6 @@ pt (t)
#endif /* DEBUG386 */
-int
-tc_i386_force_relocation (fixp)
- struct fix *fixp;
-{
-#ifdef BFD_ASSEMBLER
- if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
- || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
- return 1;
- return 0;
-#else
- /* For COFF. */
- return fixp->fx_r_type == 7;
-#endif
-}
-
#ifdef BFD_ASSEMBLER
static bfd_reloc_code_real_type reloc
PARAMS ((int, int, int, bfd_reloc_code_real_type));
@@ -1201,9 +1188,12 @@ reloc (size, pcrel, sign, other)
int
tc_i386_fix_adjustable (fixP)
- fixS *fixP;
+ fixS *fixP ATTRIBUTE_UNUSED;
{
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+ if (OUTPUT_FLAVOR != bfd_target_elf_flavour)
+ return 1;
+
/* Prevent all adjustments to global symbols, or else dynamic
linking will not work correctly. */
if (S_IS_EXTERNAL (fixP->fx_addsy)
@@ -1214,28 +1204,47 @@ tc_i386_fix_adjustable (fixP)
&& (S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0
&& fixP->fx_pcrel))
return 0;
-#endif
+
/* adjust_reloc_syms doesn't know about the GOT. */
if (fixP->fx_r_type == BFD_RELOC_386_GOTOFF
|| fixP->fx_r_type == BFD_RELOC_386_PLT32
|| fixP->fx_r_type == BFD_RELOC_386_GOT32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_GD
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LDM
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LDO_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_IE_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_IE
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_GOTIE
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LE_32
+ || fixP->fx_r_type == BFD_RELOC_386_TLS_LE
|| fixP->fx_r_type == BFD_RELOC_X86_64_PLT32
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOT32
|| fixP->fx_r_type == BFD_RELOC_X86_64_GOTPCREL
|| fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
return 0;
+#endif
return 1;
}
#else
#define reloc(SIZE,PCREL,SIGN,OTHER) 0
+#define BFD_RELOC_8 0
#define BFD_RELOC_16 0
#define BFD_RELOC_32 0
+#define BFD_RELOC_8_PCREL 0
#define BFD_RELOC_16_PCREL 0
#define BFD_RELOC_32_PCREL 0
#define BFD_RELOC_386_PLT32 0
#define BFD_RELOC_386_GOT32 0
#define BFD_RELOC_386_GOTOFF 0
+#define BFD_RELOC_386_TLS_GD 0
+#define BFD_RELOC_386_TLS_LDM 0
+#define BFD_RELOC_386_TLS_LDO_32 0
+#define BFD_RELOC_386_TLS_IE_32 0
+#define BFD_RELOC_386_TLS_IE 0
+#define BFD_RELOC_386_TLS_GOTIE 0
+#define BFD_RELOC_386_TLS_LE_32 0
+#define BFD_RELOC_386_TLS_LE 0
#define BFD_RELOC_X86_64_PLT32 0
#define BFD_RELOC_X86_64_GOT32 0
#define BFD_RELOC_X86_64_GOTPCREL 0
@@ -1314,11 +1323,19 @@ md_assemble (line)
if (!match_template ())
return;
- /* Undo SYSV386_COMPAT brokenness when in Intel mode. See i386.h */
- if (SYSV386_COMPAT
- && intel_syntax
- && (i.tm.base_opcode & 0xfffffde0) == 0xdce0)
- i.tm.base_opcode ^= FloatR;
+ if (intel_syntax)
+ {
+ /* Undo SYSV386_COMPAT brokenness when in Intel mode. See i386.h */
+ if (SYSV386_COMPAT
+ && (i.tm.base_opcode & 0xfffffde0) == 0xdce0)
+ i.tm.base_opcode ^= FloatR;
+
+ /* Zap movzx and movsx suffix. The suffix may have been set from
+ "word ptr" or "byte ptr" on the source operand, but we'll use
+ the suffix later to choose the destination register. */
+ if ((i.tm.base_opcode & ~9) == 0x0fb6)
+ i.suffix = 0;
+ }
if (i.tm.opcode_modifier & FWait)
if (!add_prefix (FWAIT_OPCODE))
@@ -2206,18 +2223,6 @@ process_suffix ()
return 0;
}
- /* For movzx and movsx, need to check the register type. */
- if (intel_syntax
- && (i.tm.base_opcode == 0xfb6 || i.tm.base_opcode == 0xfbe)
- && i.suffix == BYTE_MNEM_SUFFIX)
- {
- unsigned int prefix = DATA_PREFIX_OPCODE;
-
- if ((i.op[1].regs->reg_type & Reg16) != 0)
- if (!add_prefix (prefix))
- return 0;
- }
-
if (i.suffix && i.suffix != BYTE_MNEM_SUFFIX)
{
/* It's not a byte, select word/dword operation. */
@@ -2233,8 +2238,10 @@ process_suffix ()
size prefix, except for instructions that will ignore this
prefix anyway. */
if (i.suffix != QWORD_MNEM_SUFFIX
- && (i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
- && !(i.tm.opcode_modifier & IgnoreSize))
+ && !(i.tm.opcode_modifier & IgnoreSize)
+ && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT)
+ || (flag_code == CODE_64BIT
+ && (i.tm.opcode_modifier & JumpByte))))
{
unsigned int prefix = DATA_PREFIX_OPCODE;
if (i.tm.opcode_modifier & JumpByte) /* jcxz, loop */
@@ -2244,25 +2251,11 @@ process_suffix ()
return 0;
}
- if (i.suffix != QWORD_MNEM_SUFFIX && (flag_code == CODE_64BIT)
- && !(i.tm.opcode_modifier & IgnoreSize)
- && (i.tm.opcode_modifier & JumpByte))
- {
- if (!add_prefix (ADDR_PREFIX_OPCODE))
- return 0;
- }
-
/* Set mode64 for an operand. */
if (i.suffix == QWORD_MNEM_SUFFIX
+ && flag_code == CODE_64BIT
&& (i.tm.opcode_modifier & NoRex64) == 0)
- {
- i.rex |= REX_MODE64;
- if (flag_code < CODE_64BIT)
- {
- as_bad (_("64bit operations available only in 64bit modes."));
- return 0;
- }
- }
+ i.rex |= REX_MODE64;
/* Size floating point instruction. */
if (i.suffix == LONG_MNEM_SUFFIX)
@@ -2596,9 +2589,8 @@ process_operands ()
else if (i.tm.opcode_modifier & Modrm)
{
/* The opcode is completed (modulo i.tm.extension_opcode which
- must be put into the modrm byte).
- Now, we make the modrm & index base bytes based on all the
- info we've collected. */
+ must be put into the modrm byte). Now, we make the modrm and
+ index base bytes based on all the info we've collected. */
default_seg = build_modrm_byte ();
}
@@ -2625,12 +2617,14 @@ process_operands ()
default_seg = &ds;
}
- /* If a segment was explicitly specified,
- and the specified segment is not the default,
- use an opcode prefix to select it.
- If we never figured out what the default segment is,
- then default_seg will be zero at this point,
- and the specified segment prefix will always be used. */
+ if (i.tm.base_opcode == 0x8d /* lea */ && i.seg[0] && !quiet_warnings)
+ as_warn (_("segment override on `lea' is ineffectual"));
+
+ /* If a segment was explicitly specified, and the specified segment
+ is not the default, use an opcode prefix to select it. If we
+ never figured out what the default segment is, then default_seg
+ will be zero at this point, and the specified segment prefix will
+ always be used. */
if ((i.seg[0]) && (i.seg[0] != default_seg))
{
if (!add_prefix (i.seg[0]->seg_prefix))
@@ -2981,6 +2975,7 @@ output_jump ()
{
char *p;
int size;
+ fixS *fixP;
if (i.tm.opcode_modifier & JumpByte)
{
@@ -3031,8 +3026,14 @@ output_jump ()
p = frag_more (1 + size);
*p++ = i.tm.base_opcode;
- fix_new_exp (frag_now, p - frag_now->fr_literal, size,
- i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0]));
+ fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size,
+ i.op[0].disps, 1, reloc (size, 1, 1, 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
+ 4G and 64k respectively. */
+ if (size == 1)
+ fixP->fx_signed = 1;
}
static void
@@ -3099,14 +3100,21 @@ output_interseg_jump ()
md_number_to_chars (p + size, (valueT) i.op[0].imms->X_add_number, 2);
}
+
static void
output_insn ()
{
+ fragS *insn_start_frag;
+ offsetT insn_start_off;
+
/* Tie dwarf2 debug info to the address at the start of the insn.
We can't do this after the insn has been output as the current
frag may have been closed off. eg. by frag_var. */
dwarf2_emit_insn (0);
+ insn_start_frag = frag_now;
+ insn_start_off = frag_now_fix ();
+
/* Output jumps. */
if (i.tm.opcode_modifier & Jump)
output_branch ();
@@ -3177,10 +3185,10 @@ output_insn ()
}
if (i.disp_operands)
- output_disp ();
+ output_disp (insn_start_frag, insn_start_off);
if (i.imm_operands)
- output_imm ();
+ output_imm (insn_start_frag, insn_start_off);
}
#ifdef DEBUG386
@@ -3192,7 +3200,9 @@ output_insn ()
}
static void
-output_disp ()
+output_disp (insn_start_frag, insn_start_off)
+ fragS *insn_start_frag;
+ offsetT insn_start_off;
{
char *p;
unsigned int n;
@@ -3222,6 +3232,7 @@ output_disp ()
}
else
{
+ RELOC_ENUM reloc_type;
int size = 4;
int sign = 0;
int pcrel = (i.flags[n] & Operand_PCrel) != 0;
@@ -3264,16 +3275,50 @@ output_disp ()
}
p = frag_more (size);
+ reloc_type = reloc (size, pcrel, sign, i.reloc[n]);
+#ifdef BFD_ASSEMBLER
+ if (reloc_type == BFD_RELOC_32
+ && GOT_symbol
+ && GOT_symbol == i.op[n].disps->X_add_symbol
+ && (i.op[n].disps->X_op == O_symbol
+ || (i.op[n].disps->X_op == O_add
+ && ((symbol_get_value_expression
+ (i.op[n].disps->X_op_symbol)->X_op)
+ == O_subtract))))
+ {
+ offsetT add;
+
+ if (insn_start_frag == frag_now)
+ add = (p - frag_now->fr_literal) - insn_start_off;
+ else
+ {
+ fragS *fr;
+
+ add = insn_start_frag->fr_fix - insn_start_off;
+ for (fr = insn_start_frag->fr_next;
+ fr && fr != frag_now; fr = fr->fr_next)
+ add += fr->fr_fix;
+ add += p - frag_now->fr_literal;
+ }
+
+ /* We don't support dynamic linking on x86-64 yet. */
+ if (flag_code == CODE_64BIT)
+ abort ();
+ reloc_type = BFD_RELOC_386_GOTPC;
+ i.op[n].disps->X_add_number += add;
+ }
+#endif
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
- i.op[n].disps, pcrel,
- reloc (size, pcrel, sign, i.reloc[n]));
+ i.op[n].disps, pcrel, reloc_type);
}
}
}
}
static void
-output_imm ()
+output_imm (insn_start_frag, insn_start_off)
+ fragS *insn_start_frag;
+ offsetT insn_start_off;
{
char *p;
unsigned int n;
@@ -3326,6 +3371,48 @@ output_imm ()
p = frag_more (size);
reloc_type = reloc (size, 0, sign, i.reloc[n]);
#ifdef BFD_ASSEMBLER
+ /* This is tough to explain. We end up with this one if we
+ * have operands that look like
+ * "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal here is to
+ * obtain the absolute address of the GOT, and it is strongly
+ * preferable from a performance point of view to avoid using
+ * a runtime relocation for this. The actual sequence of
+ * instructions often look something like:
+ *
+ * call .L66
+ * .L66:
+ * popl %ebx
+ * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx
+ *
+ * The call and pop essentially return the absolute address
+ * of the label .L66 and store it in %ebx. The linker itself
+ * will ultimately change the first operand of the addl so
+ * that %ebx points to the GOT, but to keep things simple, the
+ * .o file must have this operand set so that it generates not
+ * the absolute address of .L66, but the absolute address of
+ * itself. This allows the linker itself simply treat a GOTPC
+ * relocation as asking for a pcrel offset to the GOT to be
+ * added in, and the addend of the relocation is stored in the
+ * operand field for the instruction itself.
+ *
+ * Our job here is to fix the operand so that it would add
+ * the correct offset so that %ebx would point to itself. The
+ * thing that is tricky is that .-.L66 will point to the
+ * beginning of the instruction, so we need to further modify
+ * the operand so that it will point to itself. There are
+ * other cases where you have something like:
+ *
+ * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66]
+ *
+ * and here no correction would be required. Internally in
+ * the assembler we treat operands of this form as not being
+ * pcrel since the '.' is explicitly mentioned, and I wonder
+ * whether it would simplify matters to do it this way. Who
+ * knows. In earlier versions of the PIC patches, the
+ * pcrel_adjust field was used to store the correction, but
+ * since the expression is not pcrel, I felt it would be
+ * confusing to do it this way. */
+
if (reloc_type == BFD_RELOC_32
&& GOT_symbol
&& GOT_symbol == i.op[n].imms->X_add_symbol
@@ -3335,11 +3422,26 @@ output_imm ()
(i.op[n].imms->X_op_symbol)->X_op)
== O_subtract))))
{
+ offsetT add;
+
+ if (insn_start_frag == frag_now)
+ add = (p - frag_now->fr_literal) - insn_start_off;
+ else
+ {
+ fragS *fr;
+
+ add = insn_start_frag->fr_fix - insn_start_off;
+ for (fr = insn_start_frag->fr_next;
+ fr && fr != frag_now; fr = fr->fr_next)
+ add += fr->fr_fix;
+ add += p - frag_now->fr_literal;
+ }
+
/* We don't support dynamic linking on x86-64 yet. */
if (flag_code == CODE_64BIT)
abort ();
reloc_type = BFD_RELOC_386_GOTPC;
- i.op[n].imms->X_add_number += 3;
+ i.op[n].imms->X_add_number += add;
}
#endif
fix_new_exp (frag_now, p - frag_now->fr_literal, size,
@@ -3371,10 +3473,18 @@ lex_got (reloc, adjust)
const char *str;
const RELOC_ENUM rel[NUM_FLAG_CODE];
} gotrel[] = {
- { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
- { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
- { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
- { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }
+ { "PLT", { BFD_RELOC_386_PLT32, 0, BFD_RELOC_X86_64_PLT32 } },
+ { "GOTOFF", { BFD_RELOC_386_GOTOFF, 0, 0 } },
+ { "GOTPCREL", { 0, 0, BFD_RELOC_X86_64_GOTPCREL } },
+ { "TLSGD", { BFD_RELOC_386_TLS_GD, 0, 0 } },
+ { "TLSLDM", { BFD_RELOC_386_TLS_LDM, 0, 0 } },
+ { "GOTTPOFF", { BFD_RELOC_386_TLS_IE_32, 0, 0 } },
+ { "TPOFF", { BFD_RELOC_386_TLS_LE_32, 0, 0 } },
+ { "NTPOFF", { BFD_RELOC_386_TLS_LE, 0, 0 } },
+ { "DTPOFF", { BFD_RELOC_386_TLS_LDO_32, 0, 0 } },
+ { "GOTNTPOFF",{ BFD_RELOC_386_TLS_GOTIE, 0, 0 } },
+ { "INDNTPOFF",{ BFD_RELOC_386_TLS_IE, 0, 0 } },
+ { "GOT", { BFD_RELOC_386_GOT32, 0, BFD_RELOC_X86_64_GOT32 } }
};
char *cp;
unsigned int j;
@@ -3557,6 +3667,7 @@ i386_immediate (imm_start)
#ifdef BFD_ASSEMBLER
&& OUTPUT_FLAVOR == bfd_target_aout_flavour
#endif
+ && exp_seg != absolute_section
&& exp_seg != text_section
&& exp_seg != data_section
&& exp_seg != bss_section
@@ -3771,10 +3882,15 @@ i386_displacement (disp_start, disp_end)
#ifdef BFD_ASSEMBLER
&& OUTPUT_FLAVOR == bfd_target_aout_flavour
#endif
+ && exp_seg != absolute_section
&& exp_seg != text_section
&& exp_seg != data_section
&& exp_seg != bss_section
- && exp_seg != undefined_section)
+ && exp_seg != undefined_section
+#ifdef BFD_ASSEMBLER
+ && !bfd_is_com_section (exp_seg)
+#endif
+ )
{
#ifdef BFD_ASSEMBLER
as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
@@ -4200,8 +4316,9 @@ md_estimate_size_before_relax (fragP, segment)
shared library. */
if (S_GET_SEGMENT (fragP->fr_symbol) != segment
#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
- || S_IS_EXTERNAL (fragP->fr_symbol)
- || S_IS_WEAK (fragP->fr_symbol)
+ || (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && (S_IS_EXTERNAL (fragP->fr_symbol)
+ || S_IS_WEAK (fragP->fr_symbol)))
#endif
)
{
@@ -4258,11 +4375,14 @@ md_estimate_size_before_relax (fragP, segment)
case COND_JUMP:
if (no_cond_jump_promotion && fragP->fr_var == NO_RELOC)
{
+ fixS *fixP;
+
fragP->fr_fix += 1;
- fix_new (fragP, old_fr_fix, 1,
- fragP->fr_symbol,
- fragP->fr_offset, 1,
- BFD_RELOC_8_PCREL);
+ fixP = fix_new (fragP, old_fr_fix, 1,
+ fragP->fr_symbol,
+ fragP->fr_offset, 1,
+ BFD_RELOC_8_PCREL);
+ fixP->fx_signed = 1;
break;
}
@@ -4448,12 +4568,12 @@ md_apply_fix3 (fixP, valP, seg)
/* The fix we're to put in. */
fixS *fixP;
/* Pointer to the value of the bits. */
- valueT * valP;
+ valueT *valP;
/* Segment fix is from. */
segT seg ATTRIBUTE_UNUSED;
{
char *p = fixP->fx_where + fixP->fx_frag->fr_literal;
- valueT value = * valP;
+ valueT value = *valP;
#if defined (BFD_ASSEMBLER) && !defined (TE_Mach)
if (fixP->fx_pcrel)
@@ -4475,15 +4595,16 @@ md_apply_fix3 (fixP, valP, seg)
}
}
- /* This is a hack. There should be a better way to handle this.
- This covers for the fact that bfd_install_relocation will
- subtract the current location (for partial_inplace, PC relative
- relocations); see more below. */
- if ((fixP->fx_r_type == BFD_RELOC_32_PCREL
- || fixP->fx_r_type == BFD_RELOC_16_PCREL
- || fixP->fx_r_type == BFD_RELOC_8_PCREL)
- && fixP->fx_addsy && !use_rela_relocations)
+ if (fixP->fx_pcrel
+ && (fixP->fx_r_type == BFD_RELOC_32_PCREL
+ || fixP->fx_r_type == BFD_RELOC_16_PCREL
+ || fixP->fx_r_type == BFD_RELOC_8_PCREL)
+ && !use_rela_relocations)
{
+ /* This is a hack. There should be a better way to handle this.
+ This covers for the fact that bfd_install_relocation will
+ subtract the current location (for partial_inplace, PC relative
+ relocations); see more below. */
#ifndef OBJ_AOUT
if (OUTPUT_FLAVOR == bfd_target_elf_flavour
#ifdef TE_PE
@@ -4534,55 +4655,16 @@ md_apply_fix3 (fixP, valP, seg)
runtime we merely add the offset to the actual PLT entry. */
value = -4;
break;
- case BFD_RELOC_386_GOTPC:
-
-/* This is tough to explain. We end up with this one if we have
- * operands that look like "_GLOBAL_OFFSET_TABLE_+[.-.L284]". The goal
- * here is to obtain the absolute address of the GOT, and it is strongly
- * preferable from a performance point of view to avoid using a runtime
- * relocation for this. The actual sequence of instructions often look
- * something like:
- *
- * call .L66
- * .L66:
- * popl %ebx
- * addl $_GLOBAL_OFFSET_TABLE_+[.-.L66],%ebx
- *
- * The call and pop essentially return the absolute address of
- * the label .L66 and store it in %ebx. The linker itself will
- * ultimately change the first operand of the addl so that %ebx points to
- * the GOT, but to keep things simple, the .o file must have this operand
- * set so that it generates not the absolute address of .L66, but the
- * absolute address of itself. This allows the linker itself simply
- * treat a GOTPC relocation as asking for a pcrel offset to the GOT to be
- * added in, and the addend of the relocation is stored in the operand
- * field for the instruction itself.
- *
- * Our job here is to fix the operand so that it would add the correct
- * offset so that %ebx would point to itself. The thing that is tricky is
- * that .-.L66 will point to the beginning of the instruction, so we need
- * to further modify the operand so that it will point to itself.
- * There are other cases where you have something like:
- *
- * .long $_GLOBAL_OFFSET_TABLE_+[.-.L66]
- *
- * and here no correction would be required. Internally in the assembler
- * we treat operands of this form as not being pcrel since the '.' is
- * explicitly mentioned, and I wonder whether it would simplify matters
- * to do it this way. Who knows. In earlier versions of the PIC patches,
- * the pcrel_adjust field was used to store the correction, but since the
- * expression is not pcrel, I felt it would be confusing to do it this
- * way. */
-
- value -= 1;
- break;
+
case BFD_RELOC_386_GOT32:
+ case BFD_RELOC_386_TLS_GD:
+ case BFD_RELOC_386_TLS_LDM:
+ case BFD_RELOC_386_TLS_IE_32:
+ case BFD_RELOC_386_TLS_IE:
+ case BFD_RELOC_386_TLS_GOTIE:
case BFD_RELOC_X86_64_GOT32:
value = 0; /* Fully resolved at runtime. No addend. */
break;
- case BFD_RELOC_386_GOTOFF:
- case BFD_RELOC_X86_64_GOTPCREL:
- break;
case BFD_RELOC_VTABLE_INHERIT:
case BFD_RELOC_VTABLE_ENTRY:
@@ -4593,11 +4675,11 @@ md_apply_fix3 (fixP, valP, seg)
break;
}
#endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) */
- * valP = value;
+ *valP = value;
#endif /* defined (BFD_ASSEMBLER) && !defined (TE_Mach) */
/* Are we finished with this relocation now? */
- if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
+ if (fixP->fx_addsy == NULL)
fixP->fx_done = 1;
#ifdef BFD_ASSEMBLER
else if (use_rela_relocations)
@@ -4875,7 +4957,7 @@ i386_target_format ()
{
if (flag_code == CODE_64BIT)
use_rela_relocations = 1;
- return flag_code == CODE_64BIT ? "elf64-x86-64" : "elf32-i386";
+ return flag_code == CODE_64BIT ? "elf64-x86-64" : ELF_TARGET_FORMAT;
}
#endif
default:
@@ -5045,6 +5127,14 @@ tc_gen_reloc (section, fixp)
case BFD_RELOC_386_GOT32:
case BFD_RELOC_386_GOTOFF:
case BFD_RELOC_386_GOTPC:
+ case BFD_RELOC_386_TLS_GD:
+ case BFD_RELOC_386_TLS_LDM:
+ case BFD_RELOC_386_TLS_LDO_32:
+ case BFD_RELOC_386_TLS_IE_32:
+ case BFD_RELOC_386_TLS_IE:
+ case BFD_RELOC_386_TLS_GOTIE:
+ case BFD_RELOC_386_TLS_LE_32:
+ case BFD_RELOC_386_TLS_LE:
case BFD_RELOC_X86_64_32S:
case BFD_RELOC_RVA:
case BFD_RELOC_VTABLE_ENTRY:
@@ -5110,10 +5200,7 @@ tc_gen_reloc (section, fixp)
if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
rel->address = fixp->fx_offset;
- if (fixp->fx_pcrel)
- rel->addend = fixp->fx_addnumber;
- else
- rel->addend = 0;
+ rel->addend = 0;
}
/* Use the rela in 64bit mode. */
else
OpenPOWER on IntegriCloud