tc_i386_fix_adjustable (fixP)
fixS *fixP;
{
-#if defined (OBJ_ELF) || defined (TE_PE)
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (TE_PE)
/* Prevent all adjustments to global symbols, or else dynamic
linking will not work correctly. */
- if (S_IS_EXTERN (fixP->fx_addsy))
- return 0;
- if (S_IS_WEAK (fixP->fx_addsy))
+ if (S_IS_EXTERNAL (fixP->fx_addsy)
+ || S_IS_WEAK (fixP->fx_addsy))
return 0;
#endif
/* adjust_reloc_syms doesn't know about the GOT */
if (prefix)
*p++ = DATA_PREFIX_OPCODE;
*p = i.tm.base_opcode;
- /* 1 possible extra opcode + displacement go in fr_var. */
+ /* 1 possible extra opcode + displacement go in var part.
+ Pass reloc in fr_var. */
frag_var (rs_machine_dependent,
1 + size,
- 1,
+ i.disp_reloc[0],
((unsigned char) *p == JUMP_PC_RELATIVE
? ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL) | code16
: ENCODE_RELAX_STATE (COND_JUMP, SMALL) | code16),
return 1; /* normal return */
}
\f
-/*
- * md_estimate_size_before_relax()
- *
- * Called just before relax().
- * Any symbol that is now undefined will not become defined.
- * Return the correct fr_subtype in the frag.
- * Return the initial "guess for fr_var" to caller.
- * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
- * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
- * Although it may not be explicit in the frag, pretend fr_var starts with a
- * 0 value.
- */
+/* md_estimate_size_before_relax()
+
+ Called just before relax() for rs_machine_dependent frags. The x86
+ assembler uses these frags to handle variable size jump
+ instructions.
+
+ Any symbol that is now undefined will not become defined.
+ Return the correct fr_subtype in the frag.
+ Return the initial "guess for variable size of frag" to caller.
+ The guess is actually the growth beyond the fixed part. Whatever
+ we do to grow the fixed or variable part contributes to our
+ returned value. */
+
int
md_estimate_size_before_relax (fragP, segment)
register fragS *fragP;
register segT segment;
{
- register unsigned char *opcode;
- register int old_fr_fix;
-
- old_fr_fix = fragP->fr_fix;
- opcode = (unsigned char *) fragP->fr_opcode;
/* We've already got fragP->fr_subtype right; all we have to do is
- check for un-relaxable symbols. */
- if (S_GET_SEGMENT (fragP->fr_symbol) != segment)
+ check for un-relaxable symbols. On an ELF system, we can't relax
+ an externally visible symbol, because it may be overridden by a
+ shared library. */
+ if (S_GET_SEGMENT (fragP->fr_symbol) != segment
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (TE_PE)
+ || S_IS_EXTERNAL (fragP->fr_symbol)
+ || S_IS_WEAK (fragP->fr_symbol)
+#endif
+ )
{
- /* symbol is undefined in this segment */
- int code16 = fragP->fr_subtype & CODE16;
- int size = code16 ? 2 : 4;
+ /* Symbol is undefined in this segment, or we need to keep a
+ reloc so that weak symbols can be overridden. */
+ int size = (fragP->fr_subtype & CODE16) ? 2 : 4;
#ifdef BFD_ASSEMBLER
enum bfd_reloc_code_real reloc_type;
#else
int reloc_type;
#endif
+ unsigned char *opcode;
+ int old_fr_fix;
- if (GOT_symbol /* Not quite right - we should switch on presence of
- @PLT, but I cannot see how to get to that from
- here. We should have done this in md_assemble to
- really get it right all of the time, but I think it
- does not matter that much, as this will be right
- most of the time. ERY */
- && S_GET_SEGMENT(fragP->fr_symbol) == undefined_section)
- reloc_type = BFD_RELOC_386_PLT32;
- else if (code16)
+ if (fragP->fr_var != NO_RELOC)
+ reloc_type = fragP->fr_var;
+ else if (size == 2)
reloc_type = BFD_RELOC_16_PCREL;
else
reloc_type = BFD_RELOC_32_PCREL;
+ old_fr_fix = fragP->fr_fix;
+ opcode = (unsigned char *) fragP->fr_opcode;
+
switch (opcode[0])
{
case JUMP_PC_RELATIVE: /* make jmp (0xeb) a dword displacement jump */
break;
}
frag_wane (fragP);
+ return fragP->fr_fix - old_fr_fix;
}
- return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
-} /* md_estimate_size_before_relax() */
-\f
+ return 1; /* Guess a short jump. */
+}
+
/*
* md_convert_frag();
*
/* frags.c - manage frags -
- Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
* [frchain_now remains the same but frag_now is updated.]
* Because this calculates the correct value of fr_fix by
* looking at the obstack 'frags', it needs to know how many
- * characters at the end of the old frag belong to (the maximal)
- * fr_var: the rest must belong to fr_fix.
- * It doesn't actually set up the old frag's fr_var: you may have
- * set fr_var == 1, but allocated 10 chars to the end of the frag:
- * in this case you pass old_frags_var_max_size == 10.
+ * characters at the end of the old frag belong to the maximal
+ * variable part; The rest must belong to fr_fix.
+ * It doesn't actually set up the old frag's fr_var. You may have
+ * set fr_var == 1, but allocated 10 chars to the end of the frag;
+ * In this case you pass old_frags_var_max_size == 10.
+ * In fact, you may use fr_var for something totally unrelated to the
+ * size of the variable part of the frag; None of the generic frag
+ * handling code makes use of fr_var.
*
* Make a new frag, initialising some components. Link new frag at end
* of frchain_now.
/* frags.h - Header file for the frag concept.
- Copyright (C) 1987, 92, 93, 94, 95, 97, 98, 1999
+ Copyright (C) 1987, 92, 93, 94, 95, 97, 98, 99, 2000
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
/* (Fixed) number of octets we know we have. May be 0. */
offsetT fr_fix;
- /* (Variable) number of octets after above. May be 0. */
+ /* May be used for (Variable) number of octets after above.
+ The generic frag handling code no longer makes any use of fr_var. */
offsetT fr_var;
/* For variable-length tail. */
symbolS *fr_symbol;