[binutils-gdb] PR 30308 more unbounded recursion

Alan Modra via Binutils-cvs <[email protected]> Thu, 23 Jul 2026 00:57:09 +0000 (GMT)
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D85fb82cc8c96=
0e97c5a51f51b87b19a3e6263c50

commit 85fb82cc8c960e97c5a51f51b87b19a3e6263c50
Author: Alan Modra <[email protected]>
Date:   Thu Jul 23 09:23:52 2026 +0930

    PR 30308 more unbounded recursion
   =20
    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.
   =20
            * config/tc-i386-intel.c (i386_intel_simplify): Mark X_add_symb=
ol
            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:
---
 gas/config/tc-i386-intel.c              | 11 +++++++++++
 gas/testsuite/gas/i386/intel-equ-loop.l |  2 ++
 gas/testsuite/gas/i386/intel-equ-loop.s |  5 +++++
 3 files changed, 18 insertions(+)

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 =3D newsym;
+	  symbol_mark_resolving (e->X_add_symbol);
 	}
       if (!intel_state.in_offset)
 	++intel_state.in_bracket;
       newsym =3D 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)
 		}
 	    }
=20
+	  symbol_mark_resolving (e->X_add_symbol);
 	  newsym =3D i386_intel_simplify_symbol (e->X_op_symbol);
+	  symbol_clear_resolving (e->X_add_symbol);
 	  if (newsym)
 	    {
 	      e->X_op_symbol =3D newsym;
@@ -617,7 +622,9 @@ i386_intel_simplify (expressionS *e)
 		  other =3D symbol_get_value_expression (e->X_add_symbol);
 		}
=20
+	      symbol_mark_resolving (e->X_add_symbol);
 	      newsym =3D i386_intel_simplify_symbol (e->X_op_symbol);
+	      symbol_clear_resolving (e->X_add_symbol);
 	    }
=20
 	  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 =3D 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 =3D newsym;
diff --git a/gas/testsuite/gas/i386/intel-equ-loop.l b/gas/testsuite/gas/i3=
86/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/i3=
86/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 =3D g + 1
 	g =3D f - 1
 	mov eax, [f]
+
+	h=3Di
+	j=3Dh
+	i=3Dj+h
+	.int i