PR 30308 more unbounded recursion

Alan Modra <[email protected]> Thu, 23 Jul 2026 10:26:39 +0930
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
oss-fuzz found another case where i386_intel_simplify and
i386_intel_simplify_symbol recurse until stack overflow.  This time
recursion happened on an expression with both X_add_symbol and
X_op_symbol, the call stack alternating on the two symbols.  Fix
that case too.

	* config/tc-i386-intel.c (i386_intel_simplify): Mark X_add_symbol
	whenever calling i386_intel_simplify_symbol for X_op_symbol.
	* testsuite/gas/i386/intel-equ-loop.s,
	* testsuite/gas/i386/intel-equ-loop.l: Extend testcase.

diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c
index 21d3a333182..aafaaba0c9a 100644
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -443,10 +443,13 @@ i386_intel_simplify (expressionS *e)
 				   intel_state.index))
 	    return 0;
 	  e->X_add_symbol = newsym;
+	  symbol_mark_resolving (e->X_add_symbol);
 	}
       if (!intel_state.in_offset)
 	++intel_state.in_bracket;
       newsym = i386_intel_simplify_symbol (e->X_op_symbol);
+      if (e->X_add_symbol)
+	symbol_clear_resolving (e->X_add_symbol);
       if (!intel_state.in_offset)
 	--intel_state.in_bracket;
       if (!newsym)
@@ -560,7 +563,9 @@ i386_intel_simplify (expressionS *e)
 		}
 	    }
 
+	  symbol_mark_resolving (e->X_add_symbol);
 	  newsym = i386_intel_simplify_symbol (e->X_op_symbol);
+	  symbol_clear_resolving (e->X_add_symbol);
 	  if (newsym)
 	    {
 	      e->X_op_symbol = newsym;
@@ -617,7 +622,9 @@ i386_intel_simplify (expressionS *e)
 		  other = symbol_get_value_expression (e->X_add_symbol);
 		}
 
+	      symbol_mark_resolving (e->X_add_symbol);
 	      newsym = i386_intel_simplify_symbol (e->X_op_symbol);
+	      symbol_clear_resolving (e->X_add_symbol);
 	    }
 
 	  if (newsym)
@@ -719,7 +726,11 @@ i386_intel_simplify (expressionS *e)
 	return 0;
       if (e->X_op_symbol)
 	{
+	  if (e->X_add_symbol)
+	    symbol_mark_resolving (e->X_add_symbol);
 	  newsym = i386_intel_simplify_symbol (e->X_op_symbol);
+	  if (e->X_add_symbol)
+	    symbol_clear_resolving (e->X_add_symbol);
 	  if (!newsym)
 	    return 0;
 	  e->X_op_symbol = newsym;
diff --git a/gas/testsuite/gas/i386/intel-equ-loop.l b/gas/testsuite/gas/i386/intel-equ-loop.l
index 90dfa9623db..03f21082c3f 100644
--- a/gas/testsuite/gas/i386/intel-equ-loop.l
+++ b/gas/testsuite/gas/i386/intel-equ-loop.l
@@ -7,4 +7,6 @@
 .*: Error: can't resolve .*
 .*: Error: symbol definition loop .*
 .*: Error: can't resolve .*
+.*: Error: symbol definition loop .*
+.*: Error: can't resolve .*
 #pass
diff --git a/gas/testsuite/gas/i386/intel-equ-loop.s b/gas/testsuite/gas/i386/intel-equ-loop.s
index 02b2d3f44ff..f7d1d63395b 100644
--- a/gas/testsuite/gas/i386/intel-equ-loop.s
+++ b/gas/testsuite/gas/i386/intel-equ-loop.s
@@ -18,3 +18,8 @@
 	f = g + 1
 	g = f - 1
 	mov eax, [f]
+
+	h=i
+	j=h
+	i=j+h
+	.int i

-- 
Alan Modra