aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-i386.c57
-rw-r--r--gas/frags.c13
-rw-r--r--gas/frags.h3
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;