Pass jump reloc in fr_var so it can be used in
md_estimate_size_before_relax, replacing old kludge.
This commit is contained in:
parent
b08dff7bbe
commit
ee7fcc42b1
4 changed files with 46 additions and 36 deletions
|
@ -1,3 +1,12 @@
|
|||
2000-05-23 Alan Modra <alan@linuxcare.com.au>
|
||||
|
||||
* config/tc-i386.c (md_assemble): Pass jump reloc in fr_var...
|
||||
(md_estimate_size_before_relax): so we can use it here instead of
|
||||
old kludges. Localise vars to blocks. Comment.
|
||||
|
||||
* frags.c (frag_new): Update fr_var comments.
|
||||
* frags.h (struct frag): Ditto.
|
||||
|
||||
2000-05-22 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* config/tc-ia64.c (FUNC_PC_RELATIVE): New.
|
||||
|
|
|
@ -2264,10 +2264,11 @@ md_assemble (line)
|
|||
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),
|
||||
|
@ -3741,28 +3742,24 @@ i386_operand (operand_string)
|
|||
return 1; /* normal return */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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. On an ELF system, we can't relax
|
||||
an externally visible symbol, because it may be overridden by a
|
||||
|
@ -3782,20 +3779,19 @@ md_estimate_size_before_relax (fragP, segment)
|
|||
#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;
|
||||
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 */
|
||||
|
@ -3820,10 +3816,11 @@ md_estimate_size_before_relax (fragP, segment)
|
|||
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() */
|
||||
|
||||
return 1; /* Guess a short jump. */
|
||||
}
|
||||
|
||||
/*
|
||||
* md_convert_frag();
|
||||
*
|
||||
|
|
13
gas/frags.c
13
gas/frags.c
|
@ -95,11 +95,14 @@ frag_grow (nchars)
|
|||
* [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.
|
||||
|
|
|
@ -51,7 +51,8 @@ struct frag
|
|||
|
||||
/* (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;
|
||||
|
|
Loading…
Reference in a new issue