This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [PATCH] GAS relaxing bug


On Mon, 19 Mar 2001, Alan Modra wrote:

> --- write.c	2001/03/08 23:24:22	1.27
> +++ write.c	2001/03/19 00:49:33
> @@ -2069,9 +2069,9 @@ relax_frag (segment, fragP, stretch)
>  	 Beware zero-length frags.  */
>  
>        if (stretch != 0
> +	  && sym_frag->fr_address >= was_address
>  	  && S_GET_SEGMENT (symbolP) == segment
> -	  && (sym_frag->fr_address > was_address
> -	      || (sym_frag->fr_address == was_address
> -		  && is_dnrange (fragP, sym_frag))))
> +	  && is_dnrange (fragP, sym_frag))
>  	{
>  	  target += stretch;
>  	}

Even this isn't sufficient, I'm afraid, as is_dnrange can exit
prematurely.  Consider

before stretch          after really big stretch (or tiny frags)

--------

sym1_frag

--------

fragP                   --------

--------                sym1_frag

sym2_frag               --------

--------                fragP

                        --------

At the point where relax_frag is operating on fragP, sym2_frag has not yet
had it's address adjusted, so the address test in is_dnrange is
wrong.  The following, in addition to the above patch should handle things
properly.  Note that all this nonsense could go away if we kept a last
address value in frags, which is something I need for
http://sources.redhat.com/ml/binutils/2001-03/msg00131.html

--- write.c	2001/03/08 23:24:22	1.27
+++ write.c	2001/03/19 00:49:33
@@ -2007,6 +2007,9 @@ is_dnrange (f1, f2)
 {
   addressT f2addr;
 
+  f1 = f1->fr_next;
+  if (f1 == f2)
+    return 1;
   f2addr = f2->fr_address;
   for (; f1; f1 = f1->fr_next)
     {

Alan
-- 
Linuxcare



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]