diff options
author | Sergey Belyashov <sergey.belyashov@gmail.com> | 2020-03-03 13:09:19 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2020-03-03 13:09:19 +0000 |
commit | 8326546ebb46bba75a01e441960f408dd7ccdf2c (patch) | |
tree | aac8145ec911372273633cbc84f602177c787139 /gas/config/tc-z80.c | |
parent | d8e4137b5efc2dd5e99c45534cdccbdfcc814f1a (diff) | |
download | gdb-8326546ebb46bba75a01e441960f408dd7ccdf2c.zip gdb-8326546ebb46bba75a01e441960f408dd7ccdf2c.tar.gz gdb-8326546ebb46bba75a01e441960f408dd7ccdf2c.tar.bz2 |
Fix a potential illegal memory access in the Z80 assembler.
PR 25604
* config/tc-z80.c (contains_register): Prevent an illegal memory
access when checking an expression for a register name.
Diffstat (limited to 'gas/config/tc-z80.c')
-rw-r--r-- | gas/config/tc-z80.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/gas/config/tc-z80.c b/gas/config/tc-z80.c index 8f92d9f..312a0fc 100644 --- a/gas/config/tc-z80.c +++ b/gas/config/tc-z80.c @@ -825,19 +825,35 @@ is_indir (const char *s) } /* Check whether a symbol involves a register. */ -static int +static bfd_boolean contains_register (symbolS *sym) { if (sym) { - expressionS * ex = symbol_get_value_expression(sym); + expressionS * ex = symbol_get_value_expression (sym); + + switch (ex->X_op) + { + case O_register: + return TRUE; + + case O_add: + case O_subtract: + if (ex->X_op_symbol && contains_register (ex->X_op_symbol)) + return TRUE; + /* Fall through. */ + case O_uminus: + case O_symbol: + if (ex->X_add_symbol && contains_register (ex->X_add_symbol)) + return TRUE; + break; - return (O_register == ex->X_op) - || (ex->X_add_symbol && contains_register(ex->X_add_symbol)) - || (ex->X_op_symbol && contains_register(ex->X_op_symbol)); + default: + break; + } } - return 0; + return FALSE; } /* Parse general expression, not looking for indexed addressing. */ @@ -1168,7 +1184,7 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type) } p = frag_more (1); *p = val->X_add_number; - if ( contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol) ) + if (contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol)) { ill_op (); } @@ -1188,7 +1204,7 @@ emit_byte (expressionS * val, bfd_reloc_code_real_type r_type) } else { - /* For symbols only, constants are stored at begin of function */ + /* For symbols only, constants are stored at begin of function. */ fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val, (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type); } |