From: Alan Modra Date: Thu, 15 Feb 2024 00:42:01 +0000 (+1030) Subject: PR30308, infinite recursion in i386_intel_simplify X-Git-Tag: gdb-15-branchpoint~971 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2fbbadc2c336cad228be998a118e3bab3be30757;p=thirdparty%2Fbinutils-gdb.git PR30308, infinite recursion in i386_intel_simplify This patch exposes the symbol "resolving" flag for use in i386_intel_simplify, not only preventing infinite recursion on the testcase in the PR but also more complicated cases like: .intel_syntax b = a a = b mov eax, [a] PR 30308 * symbols.c (symbol_mark_resolving, symbol_clear_resolving), (symbol_resolving_p): New functions. * symbols.h: Declare them. * config/tc-i386-intel.c (i386_intel_simplify): Delete forward declaration. Formatting. (i386_intel_simplify_symbol): Use resolving flag to prevent infinite recursion. --- diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c index c95af419cf7..3011606d574 100644 --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -369,21 +369,25 @@ i386_intel_simplify_register (expressionS *e) return 2; } -static int i386_intel_simplify (expressionS *); - -static INLINE int i386_intel_simplify_symbol(symbolS *sym) +static int +i386_intel_simplify_symbol (symbolS *sym) { - int ret = i386_intel_simplify (symbol_get_value_expression (sym)); + if (symbol_resolving_p (sym)) + return 1; + symbol_mark_resolving (sym); + int ret = i386_intel_simplify (symbol_get_value_expression (sym)); if (ret == 2) - { - S_SET_SEGMENT(sym, absolute_section); - ret = 1; - } + { + S_SET_SEGMENT (sym, absolute_section); + ret = 1; + } + symbol_clear_resolving (sym); return ret; } -static int i386_intel_simplify (expressionS *e) +static int +i386_intel_simplify (expressionS *e) { const reg_entry *the_reg = (this_operand >= 0 ? i.op[this_operand].regs : NULL); diff --git a/gas/symbols.c b/gas/symbols.c index 41f273c85ff..4df83bab0e9 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -2936,7 +2936,7 @@ symbol_removed_p (symbolS *s) return s->flags.removed; } -/* Mark a symbol has having been resolved. */ +/* Mark a symbol as having been resolved. */ void symbol_mark_resolved (symbolS *s) @@ -2952,6 +2952,28 @@ symbol_resolved_p (symbolS *s) return s->flags.resolved; } +/* Mark a symbol as being resolved. */ + +void +symbol_mark_resolving (symbolS *s) +{ + s->flags.resolving = 1; +} + +void +symbol_clear_resolving (symbolS *s) +{ + s->flags.resolving = 0; +} + +/* Return whether a symbol is being resolved. */ + +int +symbol_resolving_p (symbolS *s) +{ + return s->flags.resolving; +} + /* Return whether a symbol is a section symbol. */ int diff --git a/gas/symbols.h b/gas/symbols.h index 3232f1b2a33..c61fabcbe0a 100644 --- a/gas/symbols.h +++ b/gas/symbols.h @@ -206,6 +206,9 @@ extern void symbol_mark_removed (symbolS *); extern int symbol_removed_p (symbolS *); extern void symbol_mark_resolved (symbolS *); extern int symbol_resolved_p (symbolS *); +extern void symbol_mark_resolving (symbolS *); +extern void symbol_clear_resolving (symbolS *); +extern int symbol_resolving_p (symbolS *); extern int symbol_section_p (symbolS *); extern int symbol_equated_p (symbolS *); extern int symbol_equated_reloc_p (symbolS *);