[PATCH v2] x86/Intel: avoid infinite recursion in i386_intel_simplify_symbol() (again)

Jan Beulich jbeulich@suse.com
Wed May 20 06:50:39 GMT 2026


On 20.05.2026 01:44, Alan Modra wrote:
> I poked at this problem a little yesterday, and came up with the
> following patch that passes for all the testcases I threw at it.
> 
> ===
> Commit 22f8905d9f38 reintroduced pr30308.  This fix resolves equates
> safely in the presence of symbol loops by using symbol_equated_to.
> Symbols aren't prematurely modified by copying their value
> expressions before i386_intel_simplify does its work.  I figure that
> it is safer to do this for all symbols rather than just the particular
> case of equates, so the in_equate parameter can disappear.

This of course is a very nice (side-)effect of the change. I was worried
of copying too many symbols, but ...

> --- a/gas/config/tc-i386-intel.c
> +++ b/gas/config/tc-i386-intel.c
> @@ -381,49 +381,38 @@ i386_intel_simplify_register (expressionS *e)
>  }
>  
>  static symbolS *
> -i386_intel_simplify_symbol (symbolS *sym, bool in_equate)
> +i386_intel_simplify_symbol (symbolS *sym)
>  {
> -  if (symbol_resolving_p (sym))
> -    return sym;
> +  symbolS *orig = sym;
> +  offsetT off;
> +  sym = symbol_equated_to (sym, &off);
> +  if (sym == NULL || off != 0)
> +    return orig;
>  
>    segT seg = S_GET_SEGMENT (sym);
> -  if (seg != expr_section && seg != reg_section && !symbol_equated_p(sym))
> +  if (seg == undefined_section
> +      || (seg != expr_section && seg != reg_section && sym == orig))
>      return sym;
>  
> -  for (;;)
> -    {
> -      /* While we're after equates, symbol_equated_p() isn't suitable here.  */
> -      if (symbol_on_chain(sym, symbol_rootP, symbol_lastP))
> -	{
> -	  in_equate = true;
> -	  sym = symbol_clone (sym, 0);
> -	}
> -      else if (in_equate)
> -	{
> -	  expressionS *e = symbol_get_value_expression (sym);
> -
> -	  if (e->X_op == O_symbol && !e->X_add_number)
> -	    {
> -	      sym = e->X_add_symbol;
> -	      continue;
> -	    }
> -	  sym = make_expr_symbol (e);
> -	}
> -
> -      break;
> -    }
> -
> -  symbol_mark_resolving (sym);
> -  int ret = i386_intel_simplify (symbol_get_value_expression (sym), in_equate);
> -  if (ret == 2)
> -    S_SET_SEGMENT (sym, absolute_section);
> -  symbol_clear_resolving (sym);
> +  /* i386_intel_simplify modifies its arg.  We don't want to make
> +     premature changes to symbols here, particularly for a symbol
> +     equate.  Changing a symbol may affect future uses of that
> +     symbol.  So copy the symbol value and make a new symbol after
> +     i386_intel_simplify has done its work.  */
> +  expressionS *e = symbol_get_value_expression (sym);
> +  expressionS exp;
> +  memcpy (&exp, e, sizeof exp);
> +  int ret = i386_intel_simplify (&exp);
> +  if (ret == 0)
> +    return NULL;
>  
> -  return ret ? sym : NULL;
> +  if (memcmp (&exp, e, sizeof exp))
> +    sym = make_expr_symbol (&exp);

... this way you limit things as well. Let's go with your patch, and thank
you very much to looking into this.

One further remark lightly related to H-P's: I was first tempted to suggest
to replace the memcpy() by structure assignment. Yet then I realized that
this would be at risk of breaking the use of memcmp(). Perhaps the comment
could be extended to briefly mention this, to reduce the risk of someone
trying to replace the memcpy()?

Jan


More information about the Binutils mailing list