aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2019-10-29 09:17:39 +0000
committerNick Clifton <nickc@redhat.com>2019-10-29 09:17:39 +0000
commit66a66a17f489a4ffc614a31855e8d6f516e24640 (patch)
tree05d7f8980ceded5a6c341b4bee01813e86c02e7d /opcodes
parent2f1575ea6f93a3f0c2b439ac6bf5fe34ef42a1ad (diff)
downloadgdb-66a66a17f489a4ffc614a31855e8d6f516e24640.zip
gdb-66a66a17f489a4ffc614a31855e8d6f516e24640.tar.gz
gdb-66a66a17f489a4ffc614a31855e8d6f516e24640.tar.bz2
Fix array overruns in the S12Z disassembler.
* s12z-dis.c (opr_emit_disassembly): Check for illegal register values. (shift_size_table): Use a fixed size defined as S12Z_N_SIZES. (print_insn_s12z): Check for illegal size values.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog7
-rw-r--r--opcodes/s12z-dis.c53
-rw-r--r--opcodes/s12z-opc.c12
3 files changed, 56 insertions, 16 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 5f5a6c8..d83b5ba 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,10 @@
+2019-10-29 Nick Clifton <nickc@redhat.com>
+
+ * s12z-dis.c (opr_emit_disassembly): Check for illegal register
+ values.
+ (shift_size_table): Use a fixed size defined as S12Z_N_SIZES.
+ (print_insn_s12z): Check for illegal size values.
+
2019-10-28 Nick Clifton <nickc@redhat.com>
* csky-dis.c (csky_chars_to_number): Check for a negative
diff --git a/opcodes/s12z-dis.c b/opcodes/s12z-dis.c
index 6086f16..5930ab4 100644
--- a/opcodes/s12z-dis.c
+++ b/opcodes/s12z-dis.c
@@ -25,13 +25,11 @@
#include <assert.h>
#include "opcode/s12z.h"
-
#include "bfd.h"
#include "dis-asm.h"
-
#include "disassemble.h"
-
#include "s12z-opc.h"
+#include "opintl.h"
struct mem_read_abstraction
{
@@ -255,7 +253,11 @@ opr_emit_disassembly (const struct operand *opr,
case OPND_CL_REGISTER:
{
int r = ((struct register_operand*) opr)->reg;
- (*info->fprintf_func) (info->stream, "%s", registers[r].name);
+
+ if (r < 0 || r >= S12Z_N_REGISTERS)
+ (*info->fprintf_func) (info->stream, _("<illegal reg num>"));
+ else
+ (*info->fprintf_func) (info->stream, "%s", registers[r].name);
}
break;
case OPND_CL_REGISTER_ALL16:
@@ -306,14 +308,25 @@ opr_emit_disassembly (const struct operand *opr,
break;
}
if (mo->n_regs > 0)
- (*info->fprintf_func) (info->stream, fmt,
- registers[mo->regs[0]].name);
+ {
+ int r = mo->regs[0];
+
+ if (r < 0 || r >= S12Z_N_REGISTERS)
+ (*info->fprintf_func) (info->stream, fmt, _("<illegal reg num>"));
+ else
+ (*info->fprintf_func) (info->stream, fmt, registers[r].name);
+ }
used_reg = 1;
if (mo->n_regs > used_reg)
{
- (*info->fprintf_func) (info->stream, ",%s",
- registers[mo->regs[used_reg]].name);
+ int r = mo->regs[used_reg];
+
+ if (r < 0 || r >= S12Z_N_REGISTERS)
+ (*info->fprintf_func) (info->stream, _("<illegal reg num>"));
+ else
+ (*info->fprintf_func) (info->stream, ",%s",
+ registers[r].name);
}
(*info->fprintf_func) (info->stream, "%c",
@@ -323,7 +336,9 @@ opr_emit_disassembly (const struct operand *opr,
};
}
-static const char shift_size_table[] = {
+#define S12Z_N_SIZES 4
+static const char shift_size_table[S12Z_N_SIZES] =
+{
'b', 'w', 'p', 'l'
};
@@ -357,6 +372,7 @@ print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
if (osize == -1)
{
bool suffix = false;
+
for (o = 0; o < n_operands; ++o)
{
if (operands[o] && operands[o]->osize != -1)
@@ -366,18 +382,27 @@ print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
(*mra.info->fprintf_func) (mra.info->stream, "%c", '.');
suffix = true;
}
- (*mra.info->fprintf_func) (mra.info->stream, "%c",
- shift_size_table[operands[o]->osize]);
+
+ osize = operands[o]->osize;
+
+ if (osize < 0 || osize >= S12Z_N_SIZES)
+ (*mra.info->fprintf_func) (mra.info->stream, _("<bad>"));
+ else
+ (*mra.info->fprintf_func) (mra.info->stream, "%c",
+ shift_size_table[osize]);
+
}
}
}
else
{
- (*mra.info->fprintf_func) (mra.info->stream, ".%c",
- shift_size_table[osize]);
+ if (osize < 0 || osize >= S12Z_N_SIZES)
+ (*mra.info->fprintf_func) (mra.info->stream, _(".<bad>"));
+ else
+ (*mra.info->fprintf_func) (mra.info->stream, ".%c",
+ shift_size_table[osize]);
}
-
/* Ship out the operands. */
for (o = 0; o < n_operands; ++o)
{
diff --git a/opcodes/s12z-opc.c b/opcodes/s12z-opc.c
index eef097d..e7a3577 100644
--- a/opcodes/s12z-opc.c
+++ b/opcodes/s12z-opc.c
@@ -2205,8 +2205,16 @@ exg_sex_discrim (struct mem_read_abstraction_base *mra, enum optr hint ATTRIBUTE
struct operand *op0 = create_register_operand ((eb & 0xf0) >> 4);
struct operand *op1 = create_register_operand (eb & 0xf);
- const struct reg *r0 = registers + ((struct register_operand *) op0)->reg;
- const struct reg *r1 = registers + ((struct register_operand *) op1)->reg;
+ int reg0 = ((struct register_operand *) op0)->reg;
+ if (reg0 < 0 || reg0 >= S12Z_N_REGISTERS)
+ return OP_INVALID;
+
+ int reg1 = ((struct register_operand *) op1)->reg;
+ if (reg1 < 0 || reg1 >= S12Z_N_REGISTERS)
+ return OP_INVALID;
+
+ const struct reg *r0 = registers + reg0;
+ const struct reg *r1 = registers + reg1;
enum optr operator = (r0->bytes < r1->bytes) ? OP_sex : OP_exg;