From: Alan Modra Date: Tue, 23 May 2000 05:04:30 +0000 (+0000) Subject: Pass jump reloc in fr_var so it can be used in X-Git-Tag: binutils-2_10~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2980a402485e6c1f48b1fad826c3fda60c1bd2a5;p=thirdparty%2Fbinutils-gdb.git Pass jump reloc in fr_var so it can be used in md_estimate_size_before_relax, replacing old kludge. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index ced94542996..b896badb8c6 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2000-05-23 Alan Modra + + * 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-14 David O'Brien * config/te-freebsd.h: New file. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 079010a200c..17b1f79a9bc 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -937,12 +937,11 @@ int 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 */ @@ -2157,10 +2156,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), @@ -3647,54 +3647,56 @@ 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. */ - 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 */ @@ -3719,10 +3721,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 882cb12284f..d1846647148 100644 --- a/gas/frags.c +++ b/gas/frags.c @@ -1,5 +1,5 @@ /* 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. @@ -93,11 +93,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 b4c6e383dc0..dcd9a2f813a 100644 --- a/gas/frags.h +++ b/gas/frags.h @@ -1,5 +1,5 @@ /* 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. @@ -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;