X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Fs12z-opc.c;h=b68a4b815c42c69c4e4e6f6e25d6086f84147ad0;hb=50d036364fb2a71b3ac9a0b0cdbe58296832a1b2;hp=36509b58dcd8bb52278d3d5755c6ef47c41c79ec;hpb=ef1ad42b8b5f2c43d74582d2e629841c39962c18;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/s12z-opc.c b/opcodes/s12z-opc.c index 36509b58dc..b68a4b815c 100644 --- a/opcodes/s12z-opc.c +++ b/opcodes/s12z-opc.c @@ -1,5 +1,5 @@ /* s12z-decode.c -- Freescale S12Z disassembly - Copyright (C) 2018 Free Software Foundation, Inc. + Copyright (C) 2018-2020 Free Software Foundation, Inc. This file is part of the GNU opcodes library. @@ -31,13 +31,13 @@ #include "s12z-opc.h" -typedef int (* insn_bytes_f) (struct mem_read_abstraction_base *); +typedef int (*insn_bytes_f) (struct mem_read_abstraction_base *); -typedef void (*operands_f) (struct mem_read_abstraction_base *, - int *n_operands, struct operand **operand); +typedef int (*operands_f) (struct mem_read_abstraction_base *, + int *n_operands, struct operand **operand); -typedef enum operator (*discriminator_f) (struct mem_read_abstraction_base *, - enum operator hint); +typedef enum optr (*discriminator_f) (struct mem_read_abstraction_base *, + enum optr hint); enum OPR_MODE { @@ -127,15 +127,22 @@ x_opr_n_bytes (struct mem_read_abstraction_base *mra, int offset) static int opr_n_bytes_p1 (struct mem_read_abstraction_base *mra) { - return 1 + x_opr_n_bytes (mra, 0); + int n = x_opr_n_bytes (mra, 0); + if (n < 0) + return n; + return 1 + n; } static int opr_n_bytes2 (struct mem_read_abstraction_base *mra) { int s = x_opr_n_bytes (mra, 0); - s += x_opr_n_bytes (mra, s); - return s + 1; + if (s < 0) + return s; + int n = x_opr_n_bytes (mra, s); + if (n < 0) + return n; + return s + n + 1; } enum BB_MODE @@ -188,7 +195,12 @@ bfextins_n_bytes (struct mem_read_abstraction_base *mra) int n = bbs->n_operands; if (bbs->opr) - n += x_opr_n_bytes (mra, n - 1); + { + int x = x_opr_n_bytes (mra, n - 1); + if (x < 0) + return x; + n += x; + } return n; } @@ -256,26 +268,32 @@ xysp_reg_from_postbyte (uint8_t postbyte) return reg; } -static struct operand * create_immediate_operand (int value) +static struct operand * +create_immediate_operand (int value) { struct immediate_operand *op = malloc (sizeof (*op)); - ((struct operand *)op)->cl = OPND_CL_IMMEDIATE; - op->value = value; - ((struct operand *)op)->osize = -1; - + if (op != NULL) + { + op->parent.cl = OPND_CL_IMMEDIATE; + op->parent.osize = -1; + op->value = value; + } return (struct operand *) op; } -static struct operand * create_bitfield_operand (int width, int offset) +static struct operand * +create_bitfield_operand (int width, int offset) { struct bitfield_operand *op = malloc (sizeof (*op)); - ((struct operand *)op)->cl = OPND_CL_BIT_FIELD; - op->width = width; - op->offset = offset; - ((struct operand *)op)->osize = -1; - + if (op != NULL) + { + op->parent.cl = OPND_CL_BIT_FIELD; + op->parent.osize = -1; + op->width = width; + op->offset = offset; + } return (struct operand *) op; } @@ -284,10 +302,12 @@ create_register_operand_with_size (int reg, short osize) { struct register_operand *op = malloc (sizeof (*op)); - ((struct operand *)op)->cl = OPND_CL_REGISTER; - op->reg = reg; - ((struct operand *)op)->osize = osize; - + if (op != NULL) + { + op->parent.cl = OPND_CL_REGISTER; + op->parent.osize = osize; + op->reg = reg; + } return (struct operand *) op; } @@ -297,23 +317,29 @@ create_register_operand (int reg) return create_register_operand_with_size (reg, -1); } -static struct operand * create_register_all_operand (void) +static struct operand * +create_register_all_operand (void) { struct register_operand *op = malloc (sizeof (*op)); - ((struct operand *)op)->cl = OPND_CL_REGISTER_ALL; - ((struct operand *)op)->osize = -1; - + if (op != NULL) + { + op->parent.cl = OPND_CL_REGISTER_ALL; + op->parent.osize = -1; + } return (struct operand *) op; } -static struct operand * create_register_all16_operand (void) +static struct operand * +create_register_all16_operand (void) { struct register_operand *op = malloc (sizeof (*op)); - ((struct operand *)op)->cl = OPND_CL_REGISTER_ALL16; - ((struct operand *)op)->osize = -1; - + if (op != NULL) + { + op->parent.cl = OPND_CL_REGISTER_ALL16; + op->parent.osize = -1; + } return (struct operand *) op; } @@ -321,16 +347,18 @@ static struct operand * create_register_all16_operand (void) static struct operand * create_simple_memory_operand (bfd_vma addr, bfd_vma base, bool relative) { - struct simple_memory_operand *op = malloc (sizeof (*op)); - - ((struct operand *)op)->cl = OPND_CL_SIMPLE_MEMORY; - op->addr = addr; - op->base = base; - op->relative = relative; - ((struct operand *)op)->osize = -1; + struct simple_memory_operand *op; assert (relative || base == 0); - + op = malloc (sizeof (*op)); + if (op != NULL) + { + op->parent.cl = OPND_CL_SIMPLE_MEMORY; + op->parent.osize = -1; + op->addr = addr; + op->base = base; + op->relative = relative; + } return (struct operand *) op; } @@ -339,15 +367,17 @@ create_memory_operand (bool indirect, int base, int n_regs, int reg0, int reg1) { struct memory_operand *op = malloc (sizeof (*op)); - ((struct operand *)op)->cl = OPND_CL_MEMORY; - op->indirect = indirect; - op->base_offset = base; - op->mutation = OPND_RM_NONE; - op->n_regs = n_regs; - op->regs[0] = reg0; - op->regs[1] = reg1; - ((struct operand *)op)->osize = -1; - + if (op != NULL) + { + op->parent.cl = OPND_CL_MEMORY; + op->parent.osize = -1; + op->indirect = indirect; + op->base_offset = base; + op->mutation = OPND_RM_NONE; + op->n_regs = n_regs; + op->regs[0] = reg0; + op->regs[1] = reg1; + } return (struct operand *) op; } @@ -356,27 +386,31 @@ create_memory_auto_operand (enum op_reg_mutation mutation, int reg) { struct memory_operand *op = malloc (sizeof (*op)); - ((struct operand *)op)->cl = OPND_CL_MEMORY; - op->indirect = false; - op->base_offset = 0; - op->mutation = mutation; - op->n_regs = 1; - op->regs[0] = reg; - op->regs[1] = -1; - ((struct operand *)op)->osize = -1; - + if (op != NULL) + { + op->parent.cl = OPND_CL_MEMORY; + op->parent.osize = -1; + op->indirect = false; + op->base_offset = 0; + op->mutation = mutation; + op->n_regs = 1; + op->regs[0] = reg; + op->regs[1] = -1; + } return (struct operand *) op; } -static void -z_ext24_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) +static int +z_ext24_decode (struct mem_read_abstraction_base *mra, int *n_operands, + struct operand **operand) { + struct operand *op; uint8_t buffer[3]; int status = mra->read (mra, 0, 3, buffer); if (status < 0) - return; + return status; int i; uint32_t addr = 0; @@ -386,68 +420,77 @@ z_ext24_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct o addr |= buffer[i]; } - operand[(*n_operands)++] = create_simple_memory_operand (addr, 0, false); + op = create_simple_memory_operand (addr, 0, false); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static uint32_t -z_decode_signed_value (struct mem_read_abstraction_base *mra, int offset, short size) +static int +z_decode_signed_value (struct mem_read_abstraction_base *mra, int offset, + short size, uint32_t *result) { assert (size >0); assert (size <= 4); bfd_byte buffer[4]; - if (0 > mra->read (mra, offset, size, buffer)) - { - return 0; - } + int status = mra->read (mra, offset, size, buffer); + if (status < 0) + return status; int i; uint32_t value = 0; for (i = 0; i < size; ++i) - { - value |= buffer[i] << (8 * (size - i - 1)); - } + value = (value << 8) | buffer[i]; if (buffer[0] & 0x80) { /* Deal with negative values */ - value -= 0x1UL << (size * 8); + value -= 1u << (size * 4) << (size * 4); } - return value; + *result = value; + return 0; } -static uint32_t -decode_signed_value (struct mem_read_abstraction_base *mra, short size) +static int +decode_signed_value (struct mem_read_abstraction_base *mra, short size, + uint32_t *result) { - return z_decode_signed_value (mra, 0, size); + return z_decode_signed_value (mra, 0, size, result); } -static void +static int x_imm1 (struct mem_read_abstraction_base *mra, int offset, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte byte; int status = mra->read (mra, offset, 1, &byte); if (status < 0) - return; + return status; - operand[(*n_operands)++] = create_immediate_operand (byte); + op = create_immediate_operand (byte); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } /* An eight bit immediate operand. */ -static void +static int imm1_decode (struct mem_read_abstraction_base *mra, - int *n_operands, struct operand **operand) + int *n_operands, struct operand **operand) { - x_imm1 (mra, 0, n_operands, operand); + return x_imm1 (mra, 0, n_operands, operand); } -static void +static int trap_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { - x_imm1 (mra, -1, n_operands, operand); + return x_imm1 (mra, -1, n_operands, operand); } @@ -485,30 +528,30 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, else n = x; - operand = create_immediate_operand (n); + operand = create_immediate_operand (n); break; } case OPR_REG: { uint8_t x = (postbyte & 0x07); - operand = create_register_operand (x); + operand = create_register_operand (x); break; } case OPR_OFXYS: { - operand = create_memory_operand (false, postbyte & 0x0F, 1, + operand = create_memory_operand (false, postbyte & 0x0F, 1, xysp_reg_from_postbyte (postbyte), -1); break; } case OPR_REG_DIRECT: { - operand = create_memory_operand (false, 0, 2, postbyte & 0x07, + operand = create_memory_operand (false, 0, 2, postbyte & 0x07, xysp_reg_from_postbyte (postbyte)); break; } case OPR_REG_INDIRECT: { - operand = create_memory_operand (true, 0, 2, postbyte & 0x07, + operand = create_memory_operand (true, 0, 2, postbyte & 0x07, (postbyte & 0x10) ? REG_Y : REG_X); break; } @@ -516,7 +559,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, case OPR_IDX_INDIRECT: { uint8_t x1; - mra->read (mra, offset, 1, &x1); + status = mra->read (mra, offset, 1, &x1); + if (status < 0) + return NULL; int idx = x1; if (postbyte & 0x01) @@ -525,7 +570,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, idx -= 0x1UL << 8; } - operand = create_memory_operand (true, idx, 1, + operand = create_memory_operand (true, idx, 1, xysp_reg_from_postbyte (postbyte), -1); break; } @@ -533,7 +578,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, case OPR_IDX3_DIRECT: { uint8_t x[3]; - mra->read (mra, offset, 3, x); + status = mra->read (mra, offset, 3, x); + if (status < 0) + return NULL; int idx = x[0] << 16 | x[1] << 8 | x[2]; if (x[0] & 0x80) @@ -542,7 +589,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, idx -= 0x1UL << 24; } - operand = create_memory_operand (false, idx, 1, + operand = create_memory_operand (false, idx, 1, xysp_reg_from_postbyte (postbyte), -1); break; } @@ -550,7 +597,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, case OPR_IDX3_DIRECT_REG: { uint8_t x[3]; - mra->read (mra, offset, 3, x); + status = mra->read (mra, offset, 3, x); + if (status < 0) + return NULL; int idx = x[0] << 16 | x[1] << 8 | x[2]; if (x[0] & 0x80) @@ -559,14 +608,16 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, idx -= 0x1UL << 24; } - operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1); + operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1); break; } case OPR_IDX3_INDIRECT: { uint8_t x[3]; - mra->read (mra, offset, 3, x); + status = mra->read (mra, offset, 3, x); + if (status < 0) + return NULL; int idx = x[0] << 16 | x[1] << 8 | x[2]; if (x[0] & 0x80) @@ -583,7 +634,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, case OPR_IDX_DIRECT: { uint8_t x1; - mra->read (mra, offset, 1, &x1); + status = mra->read (mra, offset, 1, &x1); + if (status < 0) + return NULL; int idx = x1; if (postbyte & 0x01) @@ -592,7 +645,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, idx -= 0x1UL << 8; } - operand = create_memory_operand (false, idx, 1, + operand = create_memory_operand (false, idx, 1, xysp_reg_from_postbyte (postbyte), -1); break; } @@ -600,11 +653,13 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, case OPR_IDX2_REG: { uint8_t x[2]; - mra->read (mra, offset, 2, x); + status = mra->read (mra, offset, 2, x); + if (status < 0) + return NULL; uint32_t idx = x[1] | x[0] << 8 ; idx |= (postbyte & 0x30) << 12; - operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1); + operand = create_memory_operand (false, idx, 1, postbyte & 0x07, -1); break; } @@ -649,7 +704,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, bfd_byte buffer[4]; status = mra->read (mra, offset, size, buffer); if (status < 0) - operand = NULL; + return NULL; uint32_t ext18 = 0; for (i = 0; i < size; ++i) @@ -668,7 +723,9 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, case OPR_EXT1: { uint8_t x1 = 0; - mra->read (mra, offset, 1, &x1); + status = mra->read (mra, offset, 1, &x1); + if (status < 0) + return NULL; int16_t addr; addr = x1; addr |= (postbyte & 0x3f) << 8; @@ -683,7 +740,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, bfd_byte buffer[4]; status = mra->read (mra, offset, size, buffer); if (status < 0) - operand = NULL; + return NULL; uint32_t ext24 = 0; for (i = 0; i < size; ++i) @@ -701,7 +758,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, bfd_byte buffer[4]; status = mra->read (mra, offset, size, buffer); if (status < 0) - operand = NULL; + return NULL; uint32_t ext24 = 0; for (i = 0; i < size; ++i) @@ -709,7 +766,7 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, ext24 |= buffer[i] << (8 * (size - i - 1)); } - operand = create_memory_operand (true, ext24, 0, -1, -1); + operand = create_memory_operand (true, ext24, 0, -1, -1); break; } @@ -718,7 +775,8 @@ x_opr_decode_with_size (struct mem_read_abstraction_base *mra, int offset, abort (); } - operand->osize = osize; + if (operand != NULL) + operand->osize = osize; return operand; } @@ -729,124 +787,181 @@ x_opr_decode (struct mem_read_abstraction_base *mra, int offset) return x_opr_decode_with_size (mra, offset, -1); } -static void +static int z_opr_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { - operand[(*n_operands)++] = x_opr_decode (mra, 0); + struct operand *op = x_opr_decode (mra, 0); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int z_opr_decode2 (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { int n = x_opr_n_bytes (mra, 0); - - operand[(*n_operands)++] = x_opr_decode (mra, 0); - operand[(*n_operands)++] = x_opr_decode (mra, n); + if (n < 0) + return n; + struct operand *op = x_opr_decode (mra, 0); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = x_opr_decode (mra, n); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int imm1234 (struct mem_read_abstraction_base *mra, int base, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte opcode; int status = mra->read (mra, -1, 1, &opcode); if (status < 0) - return; + return status; opcode -= base; int size = registers[opcode & 0xF].bytes; - uint32_t imm = decode_signed_value (mra, size); + uint32_t imm; + if (decode_signed_value (mra, size, &imm) < 0) + return -1; - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } /* Special case of LD and CMP with register S and IMM operand */ -static void +static int reg_s_imm (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { - operand[(*n_operands)++] = create_register_operand (REG_S); + struct operand *op; - uint32_t imm = decode_signed_value (mra, 3); - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_register_operand (REG_S); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + + uint32_t imm; + if (decode_signed_value (mra, 3, &imm) < 0) + return -1; + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } /* Special case of LD, CMP and ST with register S and OPR operand */ -static void +static int reg_s_opr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { - operand[(*n_operands)++] = create_register_operand (REG_S); - operand[(*n_operands)++] = x_opr_decode (mra, 0); + struct operand *op; + + op = create_register_operand (REG_S); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = x_opr_decode (mra, 0); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int z_imm1234_8base (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { - imm1234 (mra, 8, n_operands, operand); + return imm1234 (mra, 8, n_operands, operand); } -static void +static int z_imm1234_0base (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { - imm1234 (mra, 0, n_operands, operand); + return imm1234 (mra, 0, n_operands, operand); } -static void +static int z_tfr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte byte; int status = mra->read (mra, 0, 1, &byte); if (status < 0) - return; + return status; - operand[(*n_operands)++] = create_register_operand (byte >> 4); - operand[(*n_operands)++] = create_register_operand (byte & 0x0F); + op = create_register_operand (byte >> 4); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_register_operand (byte & 0x0F); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int z_reg (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte byte; int status = mra->read (mra, -1, 1, &byte); if (status < 0) - return; + return status; - operand[(*n_operands)++] = create_register_operand (byte & 0x07); + op = create_register_operand (byte & 0x07); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int reg_xy (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte byte; int status = mra->read (mra, -1, 1, &byte); if (status < 0) - return; + return status; - operand[(*n_operands)++] = - create_register_operand ((byte & 0x01) ? REG_Y : REG_X); + op = create_register_operand ((byte & 0x01) ? REG_Y : REG_X); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int lea_reg_xys_opr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte byte; int status = mra->read (mra, -1, 1, &byte); if (status < 0) - return; + return status; int reg_xys = -1; switch (byte & 0x03) @@ -862,18 +977,26 @@ lea_reg_xys_opr (struct mem_read_abstraction_base *mra, break; } - operand[(*n_operands)++] = create_register_operand (reg_xys); - operand[(*n_operands)++] = x_opr_decode (mra, 0); + op = create_register_operand (reg_xys); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = x_opr_decode (mra, 0); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int lea_reg_xys (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte byte; int status = mra->read (mra, -1, 1, &byte); if (status < 0) - return; + return status; int reg_n = -1; switch (byte & 0x03) @@ -891,23 +1014,30 @@ lea_reg_xys (struct mem_read_abstraction_base *mra, status = mra->read (mra, 0, 1, &byte); if (status < 0) - return; + return status; - operand[(*n_operands)++] = create_register_operand (reg_n); - operand[(*n_operands)++] = create_memory_operand (false, (int8_t) byte, - 1, reg_n, -1); + op = create_register_operand (reg_n); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_memory_operand (false, (int8_t) byte, 1, reg_n, -1); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } /* PC Relative offsets of size 15 or 7 bits */ -static void +static int rel_15_7 (struct mem_read_abstraction_base *mra, int offset, int *n_operands, struct operand **operands) { + struct operand *op; bfd_byte upper; int status = mra->read (mra, offset - 1, 1, &upper); if (status < 0) - return; + return status; bool rel_size = (upper & 0x80); @@ -918,7 +1048,7 @@ rel_15_7 (struct mem_read_abstraction_base *mra, int offset, bfd_byte lower; status = mra->read (mra, offset, 1, &lower); if (status < 0) - return; + return status; addr <<= 8; addr |= lower; @@ -938,17 +1068,20 @@ rel_15_7 (struct mem_read_abstraction_base *mra, int offset, addr = addr - 0x40; } - operands[(*n_operands)++] = - create_simple_memory_operand (addr, mra->posn (mra) - 1, true); + op = create_simple_memory_operand (addr, mra->posn (mra) - 1, true); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; + return 0; } /* PC Relative offsets of size 15 or 7 bits */ -static void +static int decode_rel_15_7 (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { - rel_15_7 (mra, 1, n_operands, operand); + return rel_15_7 (mra, 1, n_operands, operand); } static int shift_n_bytes (struct mem_read_abstraction_base *); @@ -958,55 +1091,90 @@ static int bm_rel_n_bytes (struct mem_read_abstraction_base *); static int mul_n_bytes (struct mem_read_abstraction_base *); static int bm_n_bytes (struct mem_read_abstraction_base *); -static void psh_pul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); -static void shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); -static void mul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); -static void bm_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); -static void bm_rel_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); -static void mov_imm_opr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); -static void loop_primitive_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands); -static void bit_field_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands); -static void exg_sex_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands); +static int psh_pul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); +static int shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); +static int mul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); +static int bm_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); +static int bm_rel_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); +static int mov_imm_opr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); +static int loop_primitive_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands); +static int bit_field_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands); +static int exg_sex_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands); -static enum operator shift_discrim (struct mem_read_abstraction_base *mra, enum operator hint); -static enum operator psh_pul_discrim (struct mem_read_abstraction_base *mra, enum operator hint); -static enum operator mul_discrim (struct mem_read_abstraction_base *mra, enum operator hint); -static enum operator loop_primitive_discrim (struct mem_read_abstraction_base *mra, enum operator hint); -static enum operator bit_field_discrim (struct mem_read_abstraction_base *mra, enum operator hint); -static enum operator exg_sex_discrim (struct mem_read_abstraction_base *mra, enum operator hint); +static enum optr shift_discrim (struct mem_read_abstraction_base *mra, enum optr hint); +static enum optr psh_pul_discrim (struct mem_read_abstraction_base *mra, enum optr hint); +static enum optr mul_discrim (struct mem_read_abstraction_base *mra, enum optr hint); +static enum optr loop_primitive_discrim (struct mem_read_abstraction_base *mra, enum optr hint); +static enum optr bit_field_discrim (struct mem_read_abstraction_base *mra, enum optr hint); +static enum optr exg_sex_discrim (struct mem_read_abstraction_base *mra, enum optr hint); -static void +static int cmp_xy (struct mem_read_abstraction_base *mra ATTRIBUTE_UNUSED, int *n_operands, struct operand **operand) { - operand[(*n_operands)++] = create_register_operand (REG_X); - operand[(*n_operands)++] = create_register_operand (REG_Y); + struct operand *op; + + op = create_register_operand (REG_X); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_register_operand (REG_Y); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int sub_d6_x_y (struct mem_read_abstraction_base *mra ATTRIBUTE_UNUSED, int *n_operands, struct operand **operand) { - operand[(*n_operands)++] = create_register_operand (REG_D6); - operand[(*n_operands)++] = create_register_operand (REG_X); - operand[(*n_operands)++] = create_register_operand (REG_Y); + struct operand *op; + + op = create_register_operand (REG_D6); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_register_operand (REG_X); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_register_operand (REG_Y); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int sub_d6_y_x (struct mem_read_abstraction_base *mra ATTRIBUTE_UNUSED, int *n_operands, struct operand **operand) { - operand[(*n_operands)++] = create_register_operand (REG_D6); - operand[(*n_operands)++] = create_register_operand (REG_Y); - operand[(*n_operands)++] = create_register_operand (REG_X); + struct operand *op; + + op = create_register_operand (REG_D6); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_register_operand (REG_Y); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_register_operand (REG_X); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void ld_18bit_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand); +static int +ld_18bit_decode (struct mem_read_abstraction_base *mra, int *n_operands, + struct operand **operand); -static enum operator -mul_discrim (struct mem_read_abstraction_base *mra, enum operator hint) +static enum optr +mul_discrim (struct mem_read_abstraction_base *mra, enum optr hint) { uint8_t mb; int status = mra->read (mra, 0, 1, &mb); @@ -1042,7 +1210,7 @@ mul_discrim (struct mem_read_abstraction_base *mra, enum operator hint) struct opcode { /* The operation that this opcode performs. */ - enum operator operator; + enum optr operator; /* The size of this operation. May be -1 if it is implied in the operands or if size is not applicable. */ @@ -1622,19 +1790,20 @@ static const struct mb mul_table[] = { }; -static void +static int mul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { uint8_t mb; + struct operand *op; int status = mra->read (mra, 0, 1, &mb); if (status < 0) - return; + return status; uint8_t byte; status = mra->read (mra, -1, 1, &byte); if (status < 0) - return; + return status; enum MUL_MODE mode = -1; size_t i; @@ -1647,37 +1816,67 @@ mul_decode (struct mem_read_abstraction_base *mra, break; } } - operand[(*n_operands)++] = create_register_operand (byte & 0x07); + op = create_register_operand (byte & 0x07); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; switch (mode) { case MUL_REG_IMM: { int size = (mb & 0x3); - operand[(*n_operands)++] = - create_register_operand_with_size ((mb & 0x38) >> 3, size); - uint32_t imm = z_decode_signed_value (mra, 1, size + 1); - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_register_operand_with_size ((mb & 0x38) >> 3, size); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + + uint32_t imm; + if (z_decode_signed_value (mra, 1, size + 1, &imm) < 0) + return -1; + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; } break; case MUL_REG_REG: - operand[(*n_operands)++] = create_register_operand ((mb & 0x38) >> 3); - operand[(*n_operands)++] = create_register_operand (mb & 0x07); + op = create_register_operand ((mb & 0x38) >> 3); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = create_register_operand (mb & 0x07); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case MUL_REG_OPR: - operand[(*n_operands)++] = create_register_operand ((mb & 0x38) >> 3); - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, mb & 0x3); + op = create_register_operand ((mb & 0x38) >> 3); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = x_opr_decode_with_size (mra, 1, mb & 0x3); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case MUL_OPR_OPR: { int first = x_opr_n_bytes (mra, 1); - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, - (mb & 0x30) >> 4); - operand[(*n_operands)++] = x_opr_decode_with_size (mra, first + 1, - (mb & 0x0c) >> 2); + if (first < 0) + return first; + op = x_opr_decode_with_size (mra, 1, (mb & 0x30) >> 4); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = x_opr_decode_with_size (mra, first + 1, (mb & 0x0c) >> 2); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; } } + return 0; } @@ -1685,10 +1884,11 @@ static int mul_n_bytes (struct mem_read_abstraction_base *mra) { int nx = 2; + int first, second; uint8_t mb; int status = mra->read (mra, 0, 1, &mb); if (status < 0) - return 0; + return status; enum MUL_MODE mode = -1; size_t i; @@ -1712,15 +1912,20 @@ mul_n_bytes (struct mem_read_abstraction_base *mra) case MUL_REG_REG: break; case MUL_REG_OPR: - nx += x_opr_n_bytes (mra, 1); + first = x_opr_n_bytes (mra, 1); + if (first < 0) + return first; + nx += first; break; case MUL_OPR_OPR: - { - int first = x_opr_n_bytes (mra, nx - 1); - nx += first; - int second = x_opr_n_bytes (mra, nx - 1); - nx += second; - } + first = x_opr_n_bytes (mra, nx - 1); + if (first < 0) + return first; + nx += first; + second = x_opr_n_bytes (mra, nx - 1); + if (second < 0) + return second; + nx += second; break; } @@ -1766,14 +1971,15 @@ static const struct bm bm_table[] = { { 0x87, 0x84, BM_RESERVED1}, }; -static void +static int bm_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; uint8_t bm; int status = mra->read (mra, 0, 1, &bm); if (status < 0) - return; + return status; size_t i; enum BM_MODE mode = -1; @@ -1791,28 +1997,44 @@ bm_decode (struct mem_read_abstraction_base *mra, { case BM_REG_IMM: case BM_RESERVED0: - operand[(*n_operands)++] = create_register_operand (bm & 0x07); + op = create_register_operand (bm & 0x07); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_B: - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 0); + op = x_opr_decode_with_size (mra, 1, 0); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_W: - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 1); + op = x_opr_decode_with_size (mra, 1, 1); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_L: - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 3); + op = x_opr_decode_with_size (mra, 1, 3); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_REG: case BM_RESERVED1: { uint8_t xb; - mra->read (mra, 1, 1, &xb); + status = mra->read (mra, 1, 1, &xb); + if (status < 0) + return status; /* Don't emit a size suffix for register operands */ if ((xb & 0xF8) != 0xB8) - operand[(*n_operands)++] = - x_opr_decode_with_size (mra, 1, (bm & 0x0c) >> 2); + op = x_opr_decode_with_size (mra, 1, (bm & 0x0c) >> 2); else - operand[(*n_operands)++] = x_opr_decode (mra, 1); + op = x_opr_decode (mra, 1); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; } break; } @@ -1821,8 +2043,12 @@ bm_decode (struct mem_read_abstraction_base *mra, switch (mode) { case BM_REG_IMM: + case BM_RESERVED0: imm = (bm & 0x38) >> 3; - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_L: imm |= (bm & 0x03) << 3; @@ -1832,27 +2058,32 @@ bm_decode (struct mem_read_abstraction_base *mra, /* fallthrough */ case BM_OPR_B: imm |= (bm & 0x70) >> 4; - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_REG: case BM_RESERVED1: - operand[(*n_operands)++] = create_register_operand ((bm & 0x70) >> 4); - break; - case BM_RESERVED0: - assert (0); + op = create_register_operand ((bm & 0x70) >> 4); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; } + return 0; } -static void +static int bm_rel_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; uint8_t bm; int status = mra->read (mra, 0, 1, &bm); if (status < 0) - return; + return status; size_t i; enum BM_MODE mode = -1; @@ -1871,39 +2102,64 @@ bm_rel_decode (struct mem_read_abstraction_base *mra, { case BM_REG_IMM: case BM_RESERVED0: - operand[(*n_operands)++] = create_register_operand (bm & 0x07); + op = create_register_operand (bm & 0x07); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_B: - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 0); - n = 1 + x_opr_n_bytes (mra, 1); + op = x_opr_decode_with_size (mra, 1, 0); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + n = x_opr_n_bytes (mra, 1); + if (n < 0) + return n; + n += 1; break; case BM_OPR_W: - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 1); - n = 1 + x_opr_n_bytes (mra, 1); + op = x_opr_decode_with_size (mra, 1, 1); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + n = x_opr_n_bytes (mra, 1); + if (n < 0) + return n; + n += 1; break; case BM_OPR_L: - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, 3); - n = 1 + x_opr_n_bytes (mra, 1); + op = x_opr_decode_with_size (mra, 1, 3); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + n = x_opr_n_bytes (mra, 1); + if (n < 0) + return n; + n += 1; break; case BM_OPR_REG: case BM_RESERVED1: { uint8_t xb; - mra->read (mra, +1, 1, &xb); + status = mra->read (mra, +1, 1, &xb); + if (status < 0) + return status; /* Don't emit a size suffix for register operands */ if ((xb & 0xF8) != 0xB8) { short os = (bm & 0x0c) >> 2; - operand[(*n_operands)++] = x_opr_decode_with_size (mra, 1, os); + op = x_opr_decode_with_size (mra, 1, os); } else - operand[(*n_operands)++] = x_opr_decode (mra, 1); - + op = x_opr_decode (mra, 1); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; } break; } - int imm = 0; + int x, imm = 0; switch (mode) { case BM_OPR_L: @@ -1914,24 +2170,39 @@ bm_rel_decode (struct mem_read_abstraction_base *mra, /* fall through */ case BM_OPR_B: imm |= (bm & 0x70) >> 4; - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_RESERVED0: imm = (bm & 0x38) >> 3; - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_REG_IMM: imm = (bm & 0xF8) >> 3; - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; break; case BM_OPR_REG: case BM_RESERVED1: - operand[(*n_operands)++] = create_register_operand ((bm & 0x70) >> 4); - n += x_opr_n_bytes (mra, 1); + op = create_register_operand ((bm & 0x70) >> 4); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + x = x_opr_n_bytes (mra, 1); + if (x < 0) + return x; + n += x; break; } - rel_15_7 (mra, n + 1, n_operands, operand); + return rel_15_7 (mra, n + 1, n_operands, operand); } static int @@ -1954,7 +2225,7 @@ bm_n_bytes (struct mem_read_abstraction_base *mra) } } - int n = 2; + int n = 0; switch (mode) { case BM_REG_IMM: @@ -1964,15 +2235,15 @@ bm_n_bytes (struct mem_read_abstraction_base *mra) case BM_OPR_B: case BM_OPR_W: case BM_OPR_L: - n += x_opr_n_bytes (mra, 1); - break; case BM_OPR_REG: case BM_RESERVED1: - n += x_opr_n_bytes (mra, 1); + n = x_opr_n_bytes (mra, 1); + if (n < 0) + return n; break; } - return n; + return n + 2; } static int @@ -2039,6 +2310,7 @@ static int shift_n_bytes (struct mem_read_abstraction_base *mra) { bfd_byte sb; + int opr1, opr2; int status = mra->read (mra, 0, 1, &sb); if (status != 0) return status; @@ -2056,20 +2328,24 @@ shift_n_bytes (struct mem_read_abstraction_base *mra) { case SB_REG_REG_N_EFF: return 2; - break; case SB_REG_OPR_EFF: case SB_ROT: - return 2 + x_opr_n_bytes (mra, 1); - break; + opr1 = x_opr_n_bytes (mra, 1); + if (opr1 < 0) + return opr1; + return 2 + opr1; case SB_REG_OPR_OPR: - { - int opr1 = x_opr_n_bytes (mra, 1); - int opr2 = 0; - if ((sb & 0x30) != 0x20) + opr1 = x_opr_n_bytes (mra, 1); + if (opr1 < 0) + return opr1; + opr2 = 0; + if ((sb & 0x30) != 0x20) + { opr2 = x_opr_n_bytes (mra, opr1 + 1); - return 2 + opr1 + opr2; - } - break; + if (opr2 < 0) + return opr2; + } + return 2 + opr1 + opr2; default: return 3; } @@ -2080,50 +2356,63 @@ shift_n_bytes (struct mem_read_abstraction_base *mra) static int - mov_imm_opr_n_bytes (struct mem_read_abstraction_base *mra) { bfd_byte byte; - int status = mra->read (mra, -1, 1, &byte); + int status = mra->read (mra, -1, 1, &byte); if (status < 0) return status; int size = byte - 0x0c + 1; + int n = x_opr_n_bytes (mra, size); + if (n < 0) + return n; - return size + x_opr_n_bytes (mra, size) + 1; + return size + n + 1; } -static void +static int mov_imm_opr (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; bfd_byte byte; int status = mra->read (mra, -1, 1, &byte); if (status < 0) - return ; + return status; int size = byte - 0x0c + 1; - uint32_t imm = decode_signed_value (mra, size); + uint32_t imm; + if (decode_signed_value (mra, size, &imm)) + return -1; - operand[(*n_operands)++] = create_immediate_operand (imm); - operand[(*n_operands)++] = x_opr_decode (mra, size); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + op = x_opr_decode (mra, size); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } -static void +static int ld_18bit_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; size_t size = 3; bfd_byte buffer[3]; int status = mra->read (mra, 0, 2, buffer + 1); if (status < 0) - return ; + return status; status = mra->read (mra, -1, 1, buffer); if (status < 0) - return ; + return status; buffer[0] = (buffer[0] & 0x30) >> 4; @@ -2134,7 +2423,11 @@ ld_18bit_decode (struct mem_read_abstraction_base *mra, imm |= buffer[i] << (8 * (size - i - 1)); } - operand[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + return 0; } @@ -2166,7 +2459,9 @@ loop_prim_n_bytes (struct mem_read_abstraction_base *mra) { int mx = 0; uint8_t lb; - mra->read (mra, mx++, 1, &lb); + int status = mra->read (mra, mx++, 1, &lb); + if (status < 0) + return status; enum LP_MODE mode = -1; size_t i; @@ -2182,11 +2477,16 @@ loop_prim_n_bytes (struct mem_read_abstraction_base *mra) if (mode == LP_OPR) { - mx += x_opr_n_bytes (mra, mx) ; + int n = x_opr_n_bytes (mra, mx); + if (n < 0) + return n; + mx += n; } uint8_t rb; - mra->read (mra, mx++, 1, &rb); + status = mra->read (mra, mx++, 1, &rb); + if (status < 0) + return status; if (rb & 0x80) mx++; @@ -2196,65 +2496,86 @@ loop_prim_n_bytes (struct mem_read_abstraction_base *mra) -static enum operator -exg_sex_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATTRIBUTE_UNUSED) +static enum optr +exg_sex_discrim (struct mem_read_abstraction_base *mra, + enum optr hint ATTRIBUTE_UNUSED) { uint8_t eb; int status = mra->read (mra, 0, 1, &eb); + enum optr operator = OP_INVALID; if (status < 0) - return OP_INVALID; + return operator; struct operand *op0 = create_register_operand ((eb & 0xf0) >> 4); + if (op0 == NULL) + return -1; struct operand *op1 = create_register_operand (eb & 0xf); + if (op1 == NULL) + return -1; - 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; + int reg1 = ((struct register_operand *) op1)->reg; + if (reg0 >= 0 && reg0 < S12Z_N_REGISTERS + && reg1 >= 0 && reg1 < S12Z_N_REGISTERS) + { + const struct reg *r0 = registers + reg0; + const struct reg *r1 = registers + reg1; - enum operator operator = (r0->bytes < r1->bytes) ? OP_sex : OP_exg; + operator = r0->bytes < r1->bytes ? OP_sex : OP_exg; + } free (op0); free (op1); - + return operator; } -static void +static int exg_sex_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands) { + struct operand *op; uint8_t eb; int status = mra->read (mra, 0, 1, &eb); if (status < 0) - return; + return status; /* Ship out the operands. */ - operands[(*n_operands)++] = create_register_operand ((eb & 0xf0) >> 4); - operands[(*n_operands)++] = create_register_operand (eb & 0xf); -} - -static enum operator + op = create_register_operand ((eb & 0xf0) >> 4); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; + op = create_register_operand (eb & 0xf); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; + return 0; +} + +static enum optr loop_primitive_discrim (struct mem_read_abstraction_base *mra, - enum operator hint ATTRIBUTE_UNUSED) + enum optr hint ATTRIBUTE_UNUSED) { uint8_t lb; int status = mra->read (mra, 0, 1, &lb); if (status < 0) return OP_INVALID; - enum operator opbase = (lb & 0x80) ? OP_dbNE : OP_tbNE; + enum optr opbase = (lb & 0x80) ? OP_dbNE : OP_tbNE; return opbase + ((lb & 0x70) >> 4); } -static void +static int loop_primitive_decode (struct mem_read_abstraction_base *mra, - int *n_operands, struct operand **operands) + int *n_operands, struct operand **operands) { - int offs = 1; + struct operand *op; + int n, offs = 1; uint8_t lb; int status = mra->read (mra, 0, 1, &lb); if (status < 0) - return ; + return status; enum LP_MODE mode = -1; size_t i; @@ -2271,30 +2592,42 @@ loop_primitive_decode (struct mem_read_abstraction_base *mra, switch (mode) { case LP_REG: - operands[(*n_operands)++] = create_register_operand (lb & 0x07); + op = create_register_operand (lb & 0x07); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case LP_XY: - operands[(*n_operands)++] = - create_register_operand ((lb & 0x01) + REG_X); + op = create_register_operand ((lb & 0x01) + REG_X); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case LP_OPR: - offs += x_opr_n_bytes (mra, 1); - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, lb & 0x03); + n = x_opr_n_bytes (mra, 1); + if (n < 0) + return n; + offs += n; + op = x_opr_decode_with_size (mra, 1, lb & 0x03); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; } - rel_15_7 (mra, offs + 1, n_operands, operands); + return rel_15_7 (mra, offs + 1, n_operands, operands); } -static enum operator -shift_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATTRIBUTE_UNUSED) +static enum optr +shift_discrim (struct mem_read_abstraction_base *mra, + enum optr hint ATTRIBUTE_UNUSED) { size_t i; uint8_t sb; int status = mra->read (mra, 0, 1, &sb); if (status < 0) - return status; + return OP_INVALID; enum SB_DIR dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT; enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL; @@ -2316,20 +2649,21 @@ shift_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATTRIB } -static void -shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands) +static int +shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, + struct operand **operands) { + struct operand *op; size_t i; - uint8_t byte; int status = mra->read (mra, -1, 1, &byte); if (status < 0) - return ; + return status; uint8_t sb; status = mra->read (mra, 0, 1, &sb); if (status < 0) - return ; + return status; enum SB_MODE mode = -1; for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i) @@ -2350,7 +2684,9 @@ shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct op case SB_OPR_N: { uint8_t xb; - mra->read (mra, 1, 1, &xb); + status = mra->read (mra, 1, 1, &xb); + if (status < 0) + return status; /* The size suffix is not printed if the OPR operand refers directly to a register, because the size is implied by the size of that register. */ @@ -2367,15 +2703,24 @@ shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct op { case SB_REG_REG_N_EFF: case SB_REG_REG_N: - operands[(*n_operands)++] = create_register_operand (byte & 0x07); + op = create_register_operand (byte & 0x07); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case SB_REG_OPR_EFF: case SB_REG_OPR_OPR: - operands[(*n_operands)++] = create_register_operand (byte & 0x07); + op = create_register_operand (byte & 0x07); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case SB_ROT: - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, osize); + op = x_opr_decode_with_size (mra, 1, osize); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; default: @@ -2387,12 +2732,17 @@ shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct op { case SB_REG_REG_N_EFF: case SB_REG_REG_N: - operands[(*n_operands)++] = - create_register_operand_with_size (sb & 0x07, osize); + op = create_register_operand_with_size (sb & 0x07, osize); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case SB_REG_OPR_OPR: - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, osize); + op = x_opr_decode_with_size (mra, 1, osize); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; default: @@ -2404,53 +2754,74 @@ shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct op { case SB_REG_OPR_EFF: case SB_OPR_N: - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, osize); + op = x_opr_decode_with_size (mra, 1, osize); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case SB_REG_REG_N: { - uint8_t xb; - mra->read (mra, 1, 1, &xb); - - /* This case is slightly unusual. - If XB matches the binary pattern 0111XXXX, then instead of - interpreting this as a general OPR postbyte in the IMMe4 mode, - the XB byte is interpreted in s special way. */ - if ((xb & 0xF0) == 0x70) - { - if (byte & 0x10) - { - int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1); - operands[(*n_operands)++] = create_immediate_operand (shift); - } - else - { - /* This should not happen. */ - abort (); - } - } - else - { - operands[(*n_operands)++] = x_opr_decode (mra, 1); - } + uint8_t xb; + status = mra->read (mra, 1, 1, &xb); + if (status < 0) + return status; + + /* This case is slightly unusual. + If XB matches the binary pattern 0111XXXX, then instead of + interpreting this as a general OPR postbyte in the IMMe4 mode, + the XB byte is interpreted in s special way. */ + if ((xb & 0xF0) == 0x70) + { + if (byte & 0x10) + { + int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1); + op = create_immediate_operand (shift); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; + } + else + { + /* This should not happen. */ + abort (); + } + } + else + { + op = x_opr_decode (mra, 1); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; + } } break; case SB_REG_OPR_OPR: { uint8_t xb; int n = x_opr_n_bytes (mra, 1); - mra->read (mra, 1 + n, 1, &xb); + if (n < 0) + return n; + status = mra->read (mra, 1 + n, 1, &xb); + if (status < 0) + return status; if ((xb & 0xF0) == 0x70) { int imm = xb & 0x0F; imm <<= 1; imm |= (sb & 0x08) >> 3; - operands[(*n_operands)++] = create_immediate_operand (imm); + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; } else { - operands[(*n_operands)++] = x_opr_decode (mra, 1 + n); + op = x_opr_decode (mra, 1 + n); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; } } break; @@ -2464,19 +2835,23 @@ shift_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct op case SB_REG_OPR_EFF: case SB_OPR_N: { - int imm = (sb & 0x08) ? 2 : 1; - operands[(*n_operands)++] = create_immediate_operand (imm); + int imm = (sb & 0x08) ? 2 : 1; + op = create_immediate_operand (imm); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; } break; default: break; } + return 0; } -static enum operator +static enum optr psh_pul_discrim (struct mem_read_abstraction_base *mra, - enum operator hint ATTRIBUTE_UNUSED) + enum optr hint ATTRIBUTE_UNUSED) { uint8_t byte; int status = mra->read (mra, 0, 1, &byte); @@ -2487,49 +2862,64 @@ psh_pul_discrim (struct mem_read_abstraction_base *mra, } -static void +static int psh_pul_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operand) { + struct operand *op; uint8_t byte; int status = mra->read (mra, 0, 1, &byte); if (status != 0) - return; + return status; int bit; if (byte & 0x40) { if ((byte & 0x3F) == 0) - { - operand[(*n_operands)++] = create_register_all16_operand (); - } + { + op = create_register_all16_operand (); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + } else for (bit = 5; bit >= 0; --bit) { if (byte & (0x1 << bit)) { - operand[(*n_operands)++] = create_register_operand (oprregs2[bit]); + op = create_register_operand (oprregs2[bit]); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; } } } else { if ((byte & 0x3F) == 0) - { - operand[(*n_operands)++] = create_register_all_operand (); - } + { + op = create_register_all_operand (); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; + } else for (bit = 5; bit >= 0; --bit) { if (byte & (0x1 << bit)) { - operand[(*n_operands)++] = create_register_operand (oprregs1[bit]); + op = create_register_operand (oprregs1[bit]); + if (op == NULL) + return -1; + operand[(*n_operands)++] = op; } } } + return 0; } -static enum operator -bit_field_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATTRIBUTE_UNUSED) +static enum optr +bit_field_discrim (struct mem_read_abstraction_base *mra, + enum optr hint ATTRIBUTE_UNUSED) { int status; bfd_byte bb; @@ -2537,24 +2927,25 @@ bit_field_discrim (struct mem_read_abstraction_base *mra, enum operator hint ATT if (status != 0) return OP_INVALID; - return (bb & 0x80) ? OP_bfins : OP_bfext; + return (bb & 0x80) ? OP_bfins : OP_bfext; } -static void +static int bit_field_decode (struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands) { + struct operand *op; int status; bfd_byte byte2; status = mra->read (mra, -1, 1, &byte2); if (status != 0) - return; + return status; bfd_byte bb; status = mra->read (mra, 0, 1, &bb); if (status != 0) - return; + return status; enum BB_MODE mode = -1; size_t i; @@ -2563,10 +2954,10 @@ bit_field_decode (struct mem_read_abstraction_base *mra, { bbs = bb_modes + i; if ((bb & bbs->mask) == bbs->value) - { - mode = bbs->mode; - break; - } + { + mode = bbs->mode; + break; + } } int reg1 = byte2 & 0x07; /* First operand */ @@ -2576,15 +2967,22 @@ bit_field_decode (struct mem_read_abstraction_base *mra, case BB_REG_REG_IMM: case BB_REG_OPR_REG: case BB_REG_OPR_IMM: - operands[(*n_operands)++] = create_register_operand (reg1); + op = create_register_operand (reg1); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case BB_OPR_REG_REG: - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, - (bb >> 2) & 0x03); + op = x_opr_decode_with_size (mra, 1, (bb >> 2) & 0x03); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case BB_OPR_REG_IMM: - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 2, - (bb >> 2) & 0x03); + op = x_opr_decode_with_size (mra, 2, (bb >> 2) & 0x03); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; } @@ -2594,24 +2992,34 @@ bit_field_decode (struct mem_read_abstraction_base *mra, case BB_REG_REG_REG: case BB_REG_REG_IMM: { - int reg_src = (bb >> 2) & 0x07; - operands[(*n_operands)++] = create_register_operand (reg_src); + int reg_src = (bb >> 2) & 0x07; + op = create_register_operand (reg_src); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; } break; case BB_OPR_REG_REG: case BB_OPR_REG_IMM: { - int reg_src = (byte2 & 0x07); - operands[(*n_operands)++] = create_register_operand (reg_src); + int reg_src = (byte2 & 0x07); + op = create_register_operand (reg_src); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; } break; case BB_REG_OPR_REG: - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 1, - (bb >> 2) & 0x03); + op = x_opr_decode_with_size (mra, 1, (bb >> 2) & 0x03); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; case BB_REG_OPR_IMM: - operands[(*n_operands)++] = x_opr_decode_with_size (mra, 2, - (bb >> 2) & 0x03); + op = x_opr_decode_with_size (mra, 2, (bb >> 2) & 0x03); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; break; } @@ -2622,24 +3030,33 @@ bit_field_decode (struct mem_read_abstraction_base *mra, case BB_OPR_REG_REG: case BB_REG_OPR_REG: { - int reg_parm = bb & 0x03; - operands[(*n_operands)++] = create_register_operand (reg_parm); + int reg_parm = bb & 0x03; + op = create_register_operand (reg_parm); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; } break; case BB_REG_REG_IMM: case BB_OPR_REG_IMM: case BB_REG_OPR_IMM: { - bfd_byte i1; - mra->read (mra, 1, 1, &i1); - int offset = i1 & 0x1f; - int width = bb & 0x03; - width <<= 3; - width |= i1 >> 5; - operands[(*n_operands)++] = create_bitfield_operand (width, offset); + bfd_byte i1; + status = mra->read (mra, 1, 1, &i1); + if (status < 0) + return status; + int offset = i1 & 0x1f; + int width = bb & 0x03; + width <<= 3; + width |= i1 >> 5; + op = create_bitfield_operand (width, offset); + if (op == NULL) + return -1; + operands[(*n_operands)++] = op; } break; } + return 0; } @@ -2647,26 +3064,32 @@ bit_field_decode (struct mem_read_abstraction_base *mra, The operation to be performed is returned. The number of operands, will be placed in N_OPERANDS. The operands themselved into OPERANDS. */ -static enum operator +static enum optr decode_operation (const struct opcode *opc, struct mem_read_abstraction_base *mra, int *n_operands, struct operand **operands) { - enum operator op = opc->operator; + enum optr op = opc->operator; if (opc->discriminator) - op = opc->discriminator (mra, opc->operator); + { + op = opc->discriminator (mra, opc->operator); + if (op == OP_INVALID) + return op; + } if (opc->operands) - opc->operands (mra, n_operands, operands); + if (opc->operands (mra, n_operands, operands) < 0) + return OP_INVALID; if (opc->operands2) - opc->operands2 (mra, n_operands, operands); + if (opc->operands2 (mra, n_operands, operands) < 0) + return OP_INVALID; return op; } int -decode_s12z (enum operator *myoperator, short *osize, +decode_s12z (enum optr *myoperator, short *osize, int *n_operands, struct operand **operands, struct mem_read_abstraction_base *mra) { @@ -2674,7 +3097,7 @@ decode_s12z (enum operator *myoperator, short *osize, bfd_byte byte; int status = mra->read (mra, 0, 1, &byte); - if (status != 0) + if (status < 0) return status; mra->advance (mra); @@ -2686,7 +3109,9 @@ decode_s12z (enum operator *myoperator, short *osize, n_bytes++; bfd_byte byte2; - mra->read (mra, 0, 1, &byte2); + status = mra->read (mra, 0, 1, &byte2); + if (status < 0) + return status; mra->advance (mra); opc = page2 + byte2; } @@ -2694,7 +3119,15 @@ decode_s12z (enum operator *myoperator, short *osize, *osize = opc->osize; /* Return the number of bytes in the instruction. */ - n_bytes += (opc && opc->insn_bytes) ? opc->insn_bytes (mra) : 0; + if (*myoperator != OP_INVALID && opc->insn_bytes) + { + int n = opc->insn_bytes (mra); + if (n < 0) + return n; + n_bytes += n; + } + else + n_bytes += 1; return n_bytes; }