diff options
-rw-r--r-- | gas/ChangeLog | 9 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 57 | ||||
-rw-r--r-- | gas/frags.c | 13 | ||||
-rw-r--r-- | gas/frags.h | 3 |
4 files changed, 46 insertions, 36 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ddcb37a..3e9aad7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 64a2797..bd7f5c2 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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(); * diff --git a/gas/frags.c b/gas/frags.c index 6518f37..ddafda7 100644 --- a/gas/frags.c +++ b/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. diff --git a/gas/frags.h b/gas/frags.h index b4c6e38..a27ee91 100644 --- a/gas/frags.h +++ b/gas/frags.h @@ -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; |