aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Belyashov <sergey.belyashov@gmail.com>2020-03-03 13:09:19 +0000
committerNick Clifton <nickc@redhat.com>2020-03-03 13:09:19 +0000
commit8326546ebb46bba75a01e441960f408dd7ccdf2c (patch)
treeaac8145ec911372273633cbc84f602177c787139
parentd8e4137b5efc2dd5e99c45534cdccbdfcc814f1a (diff)
downloadbinutils-8326546ebb46bba75a01e441960f408dd7ccdf2c.zip
binutils-8326546ebb46bba75a01e441960f408dd7ccdf2c.tar.gz
binutils-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.
-rw-r--r--gas/ChangeLog6
-rw-r--r--gas/config/tc-z80.c32
2 files changed, 30 insertions, 8 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 932acdc..00c5623 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,9 @@
+2020-03-03 Sergey Belyashov <sergey.belyashov@gmail.com>
+
+ PR 25604
+ * config/tc-z80.c (contains_register): Prevent an illegal memory
+ access when checking an expression for a register name.
+
2020-03-03 Alan Modra <amodra@gmail.com>
* config/obj-coff.h: Remove vestiges of coff-m68k and pe-mips
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);
}