Fix a potential buffer overrun in the MMIX disassembler when processing a corrupt input file.
PR 24958 * mmix-dis.c (MAX_REG_NAME_LEN): Define. (MAX_SPEC_REG_NAME_LEN): Define. (struct mmix_dis_info): Use defined constants for array lengths. (get_reg_name): New function. (get_sprec_reg_name): New function. (print_insn_mmix): Use new functions.
This commit is contained in:
parent
6591bf0131
commit
1e4b5e7d35
|
@ -1,3 +1,13 @@
|
|||
2019-09-03 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 24958
|
||||
* mmix-dis.c (MAX_REG_NAME_LEN): Define.
|
||||
(MAX_SPEC_REG_NAME_LEN): Define.
|
||||
(struct mmix_dis_info): Use defined constants for array lengths.
|
||||
(get_reg_name): New function.
|
||||
(get_sprec_reg_name): New function.
|
||||
(print_insn_mmix): Use new functions.
|
||||
|
||||
2019-08-27 Srinath Parvathaneni <srinath.parvathaneni@arm.com>
|
||||
|
||||
* arm-dis.c (mve_opcodes): Add entry for MVE_VMOV_VEC_TO_VEC.
|
||||
|
|
|
@ -54,15 +54,17 @@
|
|||
#define INSN_IMMEDIATE_BIT (IMM_OFFSET_BIT << 24)
|
||||
#define INSN_BACKWARD_OFFSET_BIT (1 << 24)
|
||||
|
||||
#define MAX_REG_NAME_LEN 256
|
||||
#define MAX_SPEC_REG_NAME_LEN 32
|
||||
struct mmix_dis_info
|
||||
{
|
||||
const char *reg_name[256];
|
||||
const char *spec_reg_name[32];
|
||||
const char *reg_name[MAX_REG_NAME_LEN];
|
||||
const char *spec_reg_name[MAX_SPEC_REG_NAME_LEN];
|
||||
|
||||
/* Waste a little memory so we don't have to allocate each separately.
|
||||
We could have an array with static contents for these, but on the
|
||||
other hand, we don't have to. */
|
||||
char basic_reg_name[256][sizeof ("$255")];
|
||||
char basic_reg_name[MAX_REG_NAME_LEN][sizeof ("$255")];
|
||||
};
|
||||
|
||||
/* Initialize a target-specific array in INFO. */
|
||||
|
@ -111,7 +113,7 @@ initialize_mmix_dis_info (struct disassemble_info *info)
|
|||
for (i = 0; i < nsyms && syms[i] != NULL; i++)
|
||||
{
|
||||
if (syms[i]->section == reg_section
|
||||
&& syms[i]->value < 256
|
||||
&& syms[i]->value < MAX_REG_NAME_LEN
|
||||
&& minfop->reg_name[syms[i]->value] == NULL)
|
||||
minfop->reg_name[syms[i]->value] = syms[i]->name;
|
||||
}
|
||||
|
@ -119,7 +121,7 @@ initialize_mmix_dis_info (struct disassemble_info *info)
|
|||
}
|
||||
|
||||
/* Fill in the rest with the canonical names. */
|
||||
for (i = 0; i < 256; i++)
|
||||
for (i = 0; i < MAX_REG_NAME_LEN; i++)
|
||||
if (minfop->reg_name[i] == NULL)
|
||||
{
|
||||
sprintf (minfop->basic_reg_name[i], "$%ld", i);
|
||||
|
@ -238,6 +240,22 @@ get_opcode (unsigned long insn)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
get_reg_name (const struct mmix_dis_info * minfop, unsigned int x)
|
||||
{
|
||||
if (x >= MAX_REG_NAME_LEN)
|
||||
return _("*illegal*");
|
||||
return minfop->reg_name[x];
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
get_spec_reg_name (const struct mmix_dis_info * minfop, unsigned int x)
|
||||
{
|
||||
if (x >= MAX_SPEC_REG_NAME_LEN)
|
||||
return _("*illegal*");
|
||||
return minfop->spec_reg_name[x];
|
||||
}
|
||||
|
||||
/* The main disassembly function. */
|
||||
|
||||
int
|
||||
|
@ -333,15 +351,15 @@ print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
|
|||
case mmix_operands_regs:
|
||||
/* All registers: "$X,$Y,$Z". */
|
||||
(*info->fprintf_func) (info->stream, "%s,%s,%s",
|
||||
minfop->reg_name[x],
|
||||
minfop->reg_name[y],
|
||||
minfop->reg_name[z]);
|
||||
get_reg_name (minfop, x),
|
||||
get_reg_name (minfop, y),
|
||||
get_reg_name (minfop, z));
|
||||
break;
|
||||
|
||||
case mmix_operands_reg_yz:
|
||||
/* Like SETH - "$X,YZ". */
|
||||
(*info->fprintf_func) (info->stream, "%s,0x%x",
|
||||
minfop->reg_name[x], y * 256 + z);
|
||||
get_reg_name (minfop, x), y * 256 + z);
|
||||
break;
|
||||
|
||||
case mmix_operands_regs_z_opt:
|
||||
|
@ -350,12 +368,13 @@ print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
|
|||
/* The regular "$X,$Y,$Z|Z". */
|
||||
if (insn & INSN_IMMEDIATE_BIT)
|
||||
(*info->fprintf_func) (info->stream, "%s,%s,%d",
|
||||
minfop->reg_name[x], minfop->reg_name[y], z);
|
||||
get_reg_name (minfop, x),
|
||||
get_reg_name (minfop, y), z);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%s,%s,%s",
|
||||
minfop->reg_name[x],
|
||||
minfop->reg_name[y],
|
||||
minfop->reg_name[z]);
|
||||
get_reg_name (minfop, x),
|
||||
get_reg_name (minfop, y),
|
||||
get_reg_name (minfop, z));
|
||||
break;
|
||||
|
||||
case mmix_operands_jmp:
|
||||
|
@ -378,23 +397,23 @@ print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
|
|||
{
|
||||
if (insn & INSN_IMMEDIATE_BIT)
|
||||
(*info->fprintf_func) (info->stream, "%s,%s,%d",
|
||||
minfop->reg_name[x],
|
||||
get_reg_name (minfop, x),
|
||||
ROUND_MODE (y), z);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%s,%s,%s",
|
||||
minfop->reg_name[x],
|
||||
get_reg_name (minfop, x),
|
||||
ROUND_MODE (y),
|
||||
minfop->reg_name[z]);
|
||||
get_reg_name (minfop, z));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (insn & INSN_IMMEDIATE_BIT)
|
||||
(*info->fprintf_func) (info->stream, "%s,%d",
|
||||
minfop->reg_name[x], z);
|
||||
get_reg_name (minfop, x), z);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%s,%s",
|
||||
minfop->reg_name[x],
|
||||
minfop->reg_name[z]);
|
||||
get_reg_name (minfop, x),
|
||||
get_reg_name (minfop, z));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -408,13 +427,13 @@ print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
|
|||
"$X,ROUND_MODE,$Z". */
|
||||
if (y != 0)
|
||||
(*info->fprintf_func) (info->stream, "%s,%s,%s",
|
||||
minfop->reg_name[x],
|
||||
get_reg_name (minfop, x),
|
||||
ROUND_MODE (y),
|
||||
minfop->reg_name[z]);
|
||||
get_reg_name (minfop, z));
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%s,%s",
|
||||
minfop->reg_name[x],
|
||||
minfop->reg_name[z]);
|
||||
get_reg_name (minfop, x),
|
||||
get_reg_name (minfop, z));
|
||||
break;
|
||||
|
||||
case mmix_operands_sync:
|
||||
|
@ -427,22 +446,22 @@ print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
|
|||
/* Like SYNCD - "X,$Y,$Z|Z". */
|
||||
if (insn & INSN_IMMEDIATE_BIT)
|
||||
(*info->fprintf_func) (info->stream, "%d,%s,%d",
|
||||
x, minfop->reg_name[y], z);
|
||||
x, get_reg_name (minfop, y), z);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%d,%s,%s",
|
||||
x, minfop->reg_name[y],
|
||||
minfop->reg_name[z]);
|
||||
x, get_reg_name (minfop, y),
|
||||
get_reg_name (minfop, z));
|
||||
break;
|
||||
|
||||
case mmix_operands_neg:
|
||||
/* Like NEG and NEGU - "$X,Y,$Z|Z". */
|
||||
if (insn & INSN_IMMEDIATE_BIT)
|
||||
(*info->fprintf_func) (info->stream, "%s,%d,%d",
|
||||
minfop->reg_name[x], y, z);
|
||||
get_reg_name (minfop, x), y, z);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%s,%d,%s",
|
||||
minfop->reg_name[x], y,
|
||||
minfop->reg_name[z]);
|
||||
get_reg_name (minfop, x), y,
|
||||
get_reg_name (minfop, z));
|
||||
break;
|
||||
|
||||
case mmix_operands_pushj:
|
||||
|
@ -456,7 +475,7 @@ print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
|
|||
|
||||
info->target = memaddr + offset;
|
||||
|
||||
(*info->fprintf_func) (info->stream, "%s,", minfop->reg_name[x]);
|
||||
(*info->fprintf_func) (info->stream, "%s,", get_reg_name (minfop, x));
|
||||
(*info->print_address_func) (memaddr + offset, info);
|
||||
}
|
||||
break;
|
||||
|
@ -464,26 +483,26 @@ print_insn_mmix (bfd_vma memaddr, struct disassemble_info *info)
|
|||
case mmix_operands_get:
|
||||
/* GET - "X,spec_reg". */
|
||||
(*info->fprintf_func) (info->stream, "%s,%s",
|
||||
minfop->reg_name[x],
|
||||
minfop->spec_reg_name[z]);
|
||||
get_reg_name (minfop, x),
|
||||
get_spec_reg_name (minfop, z));
|
||||
break;
|
||||
|
||||
case mmix_operands_put:
|
||||
/* PUT - "spec_reg,$Z|Z". */
|
||||
if (insn & INSN_IMMEDIATE_BIT)
|
||||
(*info->fprintf_func) (info->stream, "%s,%d",
|
||||
minfop->spec_reg_name[x], z);
|
||||
get_spec_reg_name (minfop, x), z);
|
||||
else
|
||||
(*info->fprintf_func) (info->stream, "%s,%s",
|
||||
minfop->spec_reg_name[x],
|
||||
minfop->reg_name[z]);
|
||||
get_spec_reg_name (minfop, x),
|
||||
get_reg_name (minfop, z));
|
||||
break;
|
||||
|
||||
case mmix_operands_set:
|
||||
/* Two registers, "$X,$Y". */
|
||||
(*info->fprintf_func) (info->stream, "%s,%s",
|
||||
minfop->reg_name[x],
|
||||
minfop->reg_name[y]);
|
||||
get_reg_name (minfop, x),
|
||||
get_reg_name (minfop, y));
|
||||
break;
|
||||
|
||||
case mmix_operands_save:
|
||||
|
|
Loading…
Reference in New Issue