mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2026-08-27 00:26:02 -04:00
PR 34036 looping in symbol_equated_p chains
This patch adds a new function for safely traversing a chain of equated symbols to find the defining symbol. PR 34036 * symbols.c (symbol_equated_to): New function. * symbols.h (symbol_equated_to): Declare. * expr.c (resolve_register): Use symbol_equated_to. * config/tc-i386.c (parse_register): Likewise. * config/tc-v850.c (reg_name_search): Likewise.
This commit is contained in:
parent
c9c059cbf3
commit
ea2b9ecdc8
5 changed files with 47 additions and 22 deletions
|
|
@ -17062,19 +17062,13 @@ parse_register (const char *reg_string, char **end_op)
|
|||
char *save = input_line_pointer;
|
||||
char *buf = xstrdup (reg_string), *name;
|
||||
symbolS *symbolP;
|
||||
offsetT off;
|
||||
|
||||
input_line_pointer = buf;
|
||||
get_symbol_name (&name);
|
||||
symbolP = symbol_find (name);
|
||||
while (symbolP && symbol_equated_p (symbolP))
|
||||
{
|
||||
const expressionS *e = symbol_get_value_expression(symbolP);
|
||||
|
||||
if (e->X_add_number)
|
||||
break;
|
||||
symbolP = e->X_add_symbol;
|
||||
}
|
||||
if (symbolP && S_GET_SEGMENT (symbolP) == reg_section)
|
||||
symbolP = symbol_equated_to (symbolP, &off);
|
||||
if (symbolP && off == 0 && S_GET_SEGMENT (symbolP) == reg_section)
|
||||
{
|
||||
const expressionS *e = symbol_get_value_expression (symbolP);
|
||||
|
||||
|
|
|
|||
|
|
@ -943,8 +943,13 @@ reg_name_search (const struct reg_name *regs,
|
|||
/* If the symbol is an alias for another name then use that.
|
||||
If the symbol is an alias for a number, then return the number. */
|
||||
if (symbol_equated_p (symbolP))
|
||||
name
|
||||
= S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol);
|
||||
{
|
||||
offsetT off;
|
||||
symbolP = symbol_equated_to (symbolP, &off);
|
||||
if (symbolP == NULL || off != 0)
|
||||
return -1;
|
||||
name = S_GET_NAME (symbolP);
|
||||
}
|
||||
else if (accept_numbers)
|
||||
{
|
||||
int reg = S_GET_VALUE (symbolP);
|
||||
|
|
|
|||
19
gas/expr.c
19
gas/expr.c
|
|
@ -2473,22 +2473,19 @@ resolve_expression (expressionS *expressionP)
|
|||
void resolve_register (expressionS *expP)
|
||||
{
|
||||
symbolS *sym;
|
||||
offsetT acc = 0;
|
||||
const expressionS *e = expP;
|
||||
offsetT acc;
|
||||
const expressionS *e;
|
||||
|
||||
if (expP->X_op != O_symbol)
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
if (!md_register_arithmetic && e->X_add_number)
|
||||
break;
|
||||
sym = e->X_add_symbol;
|
||||
acc += e->X_add_number;
|
||||
e = symbol_get_value_expression (sym);
|
||||
}
|
||||
while (symbol_equated_p (sym));
|
||||
sym = symbol_equated_to (expP->X_add_symbol, &acc);
|
||||
acc += expP->X_add_number;
|
||||
if (sym == NULL
|
||||
|| (!md_register_arithmetic && acc != 0))
|
||||
return;
|
||||
|
||||
e = symbol_get_value_expression (sym);
|
||||
if (e->X_op == O_register)
|
||||
{
|
||||
expr_copy (expP, e);
|
||||
|
|
|
|||
|
|
@ -3020,6 +3020,34 @@ symbol_equated_reloc_p (const symbolS *s)
|
|||
|| S_IS_COMMON (s)));
|
||||
}
|
||||
|
||||
/* Return the final symbol in a chain of equated symbols, and the offset
|
||||
from that symbol. If the chain has a loop, return NULL.
|
||||
For a non-equated SYM, return SYM. */
|
||||
|
||||
symbolS *
|
||||
symbol_equated_to (symbolS *sym, offsetT *off)
|
||||
{
|
||||
valueT add = 0;
|
||||
symbolS *ret = sym;
|
||||
while (ret && symbol_equated_p (ret))
|
||||
{
|
||||
const expressionS *e = symbol_get_value_expression (ret);
|
||||
add += e->X_add_number;
|
||||
ret->flags.resolving = 1;
|
||||
ret = e->X_add_symbol;
|
||||
if (ret->flags.resolving)
|
||||
ret = NULL;
|
||||
}
|
||||
while (sym && sym->flags.resolving)
|
||||
{
|
||||
const expressionS *e = symbol_get_value_expression (sym);
|
||||
sym->flags.resolving = 0;
|
||||
sym = e->X_add_symbol;
|
||||
}
|
||||
*off = add;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return whether a symbol has a constant value. */
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ extern int symbol_resolving_p (const symbolS *);
|
|||
extern int symbol_section_p (const symbolS *);
|
||||
extern int symbol_equated_p (const symbolS *);
|
||||
extern int symbol_equated_reloc_p (const symbolS *);
|
||||
extern symbolS *symbol_equated_to (symbolS *, offsetT *);
|
||||
extern int symbol_constant_p (const symbolS *);
|
||||
extern int symbol_shadow_p (const symbolS *);
|
||||
extern symbolS *symbol_symbolS (symbolS *);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue