]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Pass jump reloc in fr_var so it can be used in
authorAlan Modra <amodra@gmail.com>
Tue, 23 May 2000 05:04:30 +0000 (05:04 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 23 May 2000 05:04:30 +0000 (05:04 +0000)
md_estimate_size_before_relax, replacing old kludge.

gas/ChangeLog
gas/config/tc-i386.c
gas/frags.c
gas/frags.h

index ced94542996f754e9b68eeb4e0739d13d3f3a84f..b896badb8c605c47b5d37df864b8dc80fb26ca2b 100644 (file)
@@ -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-14  David O'Brien  <obrien@FreeBSD.org>
 
        * config/te-freebsd.h: New file.
index 079010a200c3e0c0860a2a3fbc7084dbd82d93c7..17b1f79a9bc9bc61e48a882a3c507c7bbc9ac075 100644 (file)
@@ -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 */
 }
 \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 */
@@ -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() */
-\f
+  return 1; /* Guess a short jump.  */
+}
+
 /*
  *                     md_convert_frag();
  *
index 882cb12284f77ba3a6db1c1d4b8ea7e25064ce3a..d1846647148e0629fade4cbe96409c7d883257ab 100644 (file)
@@ -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.
index b4c6e383dc00f043140bb2f6430789c56fb13b6d..dcd9a2f813ae8fb47427d80eb75900b4173c72bf 100644 (file)
@@ -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;