From: Alan Modra Date: Fri, 20 Dec 2019 00:26:29 +0000 (+1030) Subject: ubsan: m68hc1x: left shift of negative value X-Git-Url: http://git.efficios.com/?a=commitdiff_plain;h=000fe1a756e707624d387eeacbaa959a01f0d040;p=deliverable%2Fbinutils-gdb.git ubsan: m68hc1x: left shift of negative value * m68hc11-dis.c (read_memory): Delete forward decls. (print_indexed_operand, print_insn): Likewise. (print_indexed_operand): Formatting. Don't rely on short being exactly 16 bits, make sign extension explicit. (print_insn): Likewise. Avoid signed overflow. --- diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 49b94e3a34..36667aea51 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,11 @@ +2019-12-20 Alan Modra + + * m68hc11-dis.c (read_memory): Delete forward decls. + (print_indexed_operand, print_insn): Likewise. + (print_indexed_operand): Formatting. Don't rely on short being + exactly 16 bits, make sign extension explicit. + (print_insn): Likewise. Avoid signed overflow. + 2019-12-19 Alan Modra * vax-dis.c (print_insn_mode): Stop index mode recursion. diff --git a/opcodes/m68hc11-dis.c b/opcodes/m68hc11-dis.c index 97647b4552..2a10481670 100644 --- a/opcodes/m68hc11-dis.c +++ b/opcodes/m68hc11-dis.c @@ -45,11 +45,6 @@ static const char *const reg_dst_table[] = #define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4) -/* Prototypes for local functions. */ -static int read_memory (bfd_vma, bfd_byte *, int, struct disassemble_info *); -static int print_indexed_operand (bfd_vma, struct disassemble_info *, - int*, int, int, bfd_vma, int); -static int print_insn (bfd_vma, struct disassemble_info *, int); static int read_memory (bfd_vma memaddr, bfd_byte* buffer, int size, @@ -73,13 +68,13 @@ read_memory (bfd_vma memaddr, bfd_byte* buffer, int size, Returns the number of bytes read or -1 if failure. */ static int print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info, - int* indirect, int mov_insn, int pc_offset, - bfd_vma endaddr, int arch) + int* indirect, int mov_insn, int pc_offset, + bfd_vma endaddr, int arch) { bfd_byte buffer[4]; int reg; int status; - short sval; + bfd_vma val; int pos = 1; if (indirect) @@ -95,23 +90,22 @@ print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info, if ((buffer[0] & 0x20) == 0) { reg = (buffer[0] >> 6) & 3; - sval = (buffer[0] & 0x1f); - if (sval & 0x10) - sval |= 0xfff0; + val = ((buffer[0] & 0x1f) ^ 0x10) - 0x10; /* 68HC12 requires an adjustment for movb/movw pc relative modes. */ if (reg == PC_REGNUM && info->mach == bfd_mach_m6812 && mov_insn) - sval += pc_offset; + val += pc_offset; (*info->fprintf_func) (info->stream, "0x%x,%s", - (unsigned short) sval, reg_name[reg]); + (unsigned) val & 0xffff, reg_name[reg]); if (reg == PC_REGNUM) - { - (* info->fprintf_func) (info->stream, " {"); - if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutils. */ - (*info->fprintf_func) (info->stream, "0x"); - (* info->print_address_func) (endaddr + sval, info); - (* info->fprintf_func) (info->stream, "}"); - } + { + (* info->fprintf_func) (info->stream, " {"); + /* Avoid duplicate 0x from core binutils. */ + if (info->symtab_size > 0) + (*info->fprintf_func) (info->stream, "0x"); + (* info->print_address_func) (endaddr + val, info); + (* info->fprintf_func) (info->stream, "}"); + } } /* Auto pre/post increment/decrement. */ @@ -120,88 +114,81 @@ print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info, const char *mode; reg = (buffer[0] >> 6) & 3; - sval = (buffer[0] & 0x0f); - if (sval & 0x8) + val = buffer[0] & 7; + if (buffer[0] & 8) { - sval |= 0xfff0; - sval = -sval; + val = 8 - val; mode = "-"; } else { - sval = sval + 1; + val = val + 1; mode = "+"; } (*info->fprintf_func) (info->stream, "%d,%s%s%s", - (unsigned short) sval, - (buffer[0] & 0x10 ? "" : mode), - reg_name[reg], (buffer[0] & 0x10 ? mode : "")); + (unsigned) val, + buffer[0] & 0x10 ? "" : mode, + reg_name[reg], buffer[0] & 0x10 ? mode : ""); } /* [n,r] 16-bits offset indexed indirect. */ else if ((buffer[0] & 0x07) == 3) { if ((mov_insn) && (!(arch & cpu9s12x))) - { - (*info->fprintf_func) (info->stream, "", - buffer[0] & 0x0ff); - return 0; - } + { + (*info->fprintf_func) (info->stream, "", + buffer[0] & 0x0ff); + return 0; + } reg = (buffer[0] >> 3) & 0x03; status = read_memory (memaddr + pos, &buffer[0], 2, info); if (status != 0) - { - return status; - } + return status; pos += 2; - sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); + val = (buffer[0] << 8) | buffer[1]; (*info->fprintf_func) (info->stream, "[0x%x,%s]", - sval & 0x0ffff, reg_name[reg]); + (unsigned) val & 0xffff, reg_name[reg]); if (indirect) - *indirect = 1; + *indirect = 1; } /* n,r with 9 and 16 bit signed constant. */ else if ((buffer[0] & 0x4) == 0) { if ((mov_insn) && (!(arch & cpu9s12x))) - { - (*info->fprintf_func) (info->stream, "", - buffer[0] & 0x0ff); - return 0; - } + { + (*info->fprintf_func) (info->stream, "", + buffer[0] & 0x0ff); + return 0; + } reg = (buffer[0] >> 3) & 0x03; status = read_memory (memaddr + pos, &buffer[1], (buffer[0] & 0x2 ? 2 : 1), info); if (status != 0) - { - return status; - } + return status; + if (buffer[0] & 2) { - sval = ((buffer[1] << 8) | (buffer[2] & 0x0FF)); - sval &= 0x0FFFF; + val = (((buffer[1] << 8) | buffer[2]) ^ 0x8000) - 0x8000; pos += 2; - endaddr += 2; + endaddr += 2; } else { - sval = buffer[1] & 0x00ff; - if (buffer[0] & 0x01) - sval |= 0xff00; + val = buffer[1] - ((buffer[0] & 1) << 8); pos++; - endaddr++; + endaddr++; } (*info->fprintf_func) (info->stream, "0x%x,%s", - (unsigned short) sval, reg_name[reg]); + (unsigned) val & 0xffff, reg_name[reg]); if (reg == PC_REGNUM) - { - (* info->fprintf_func) (info->stream, " {0x"); - (* info->print_address_func) (endaddr + sval, info); - (* info->fprintf_func) (info->stream, "}"); - } + { + (* info->fprintf_func) (info->stream, " {0x"); + (* info->print_address_func) (endaddr + val, info); + (* info->fprintf_func) (info->stream, "}"); + } } else { @@ -220,8 +207,8 @@ print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info, case 3: default: (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]); - if (indirect) - *indirect = 1; + if (indirect) + *indirect = 1; break; } } @@ -238,12 +225,11 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) bfd_byte buffer[4]; unsigned int code; long format, pos, i; - short sval; + bfd_vma val; const struct m68hc11_opcode *opcode; if (arch & cpuxgate) { - int val; /* Get two bytes as all XGATE instructions are 16bit. */ status = read_memory (memaddr, buffer, 2, info); if (status != 0) @@ -295,17 +281,14 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) else if (format & M68XG_OP_REL9) { (*info->fprintf_func) (info->stream, " 0x"); - val = (buffer[0] & 0x1) ? buffer[1] | 0xFFFFFF00 : buffer[1]; + val = buffer[1] - ((buffer[0] & 1) << 8); (*info->print_address_func) (memaddr + (val << 1) + 2, info); } else if (format & M68XG_OP_REL10) { (*info->fprintf_func) (info->stream, " 0x"); - val = (buffer[0] << 8) | (unsigned int) buffer[1]; - if (val & 0x200) - val |= 0xfffffc00; - else - val &= 0x000001ff; + val = (buffer[0] << 8) | buffer[1]; + val = ((val & 0x3ff) ^ 0x200) - 0x200; (*info->print_address_func) (memaddr + (val << 1) + 2, info); } else if ((code & 0x00ff) == 0x00f8) @@ -639,13 +622,11 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) (*info->fprintf_func) (info->stream, "%s,", reg_src_table[buffer[0] & 0x07]); - sval = buffer[1] & 0x0ff; - if (buffer[0] & 0x10) - sval |= 0xff00; + val = buffer[1] - ((buffer[0] & 0x10) << 4); pos += 2; (*info->fprintf_func) (info->stream, "0x"); - (*info->print_address_func) (memaddr + pos + sval, info); + (*info->print_address_func) (memaddr + pos + val, info); format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL); } else if (format & (M6812_OP_REG | M6812_OP_REG_2)) @@ -662,7 +643,6 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) if (format & (M6811_OP_IMM16 | M6811_OP_IND16)) { - int val; bfd_vma addr; unsigned page = 0; @@ -676,9 +656,7 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) offset = 0; pos += 2; - val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); - val &= 0x0FFFF; - addr = val; + addr = val = (buffer[0] << 8) | buffer[1]; pc_dst_offset = 2; if (format & M6812_OP_PAGE) { @@ -686,16 +664,15 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) if (status != 0) return status; - page = (unsigned) buffer[0]; + page = buffer[0]; if (addr >= M68HC12_BANK_BASE && addr < 0x0c000) - addr = ((val - M68HC12_BANK_BASE) - | (page << M68HC12_BANK_SHIFT)) - + M68HC12_BANK_VIRT; + addr = (val - M68HC12_BANK_BASE + (page << M68HC12_BANK_SHIFT) + + M68HC12_BANK_VIRT); } else if ((arch & cpu6812) && addr >= M68HC12_BANK_BASE && addr < 0x0c000) { - int cur_page; + unsigned cur_page; bfd_vma vaddr; if (memaddr >= M68HC12_BANK_VIRT) @@ -704,9 +681,8 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) else cur_page = 0; - vaddr = ((addr - M68HC12_BANK_BASE) - + (cur_page << M68HC12_BANK_SHIFT)) - + M68HC12_BANK_VIRT; + vaddr = (addr - M68HC12_BANK_BASE + + (cur_page << M68HC12_BANK_SHIFT)) + M68HC12_BANK_VIRT; if (!info->symbol_at_address_func (addr, info) && info->symbol_at_address_func (vaddr, info)) addr = vaddr; @@ -721,14 +697,16 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) format &= ~M6811_OP_IND16; } - if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutils. */ + /* Avoid duplicate 0x from core binutils. */ + if (info->symtab_size > 0) (*info->fprintf_func) (info->stream, "0x"); (*info->print_address_func) (addr, info); if (format & M6812_OP_PAGE) { (* info->fprintf_func) (info->stream, " {"); - if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutils. */ + /* Avoid duplicate 0x from core binutils. */ + if (info->symtab_size > 0) (*info->fprintf_func) (info->stream, "0x"); (* info->print_address_func) (val, info); (* info->fprintf_func) (info->stream, ", 0x%x}", page); @@ -750,8 +728,6 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) if (format & M6812_OP_IND16_P2) { - int val; - (*info->fprintf_func) (info->stream, ", "); status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); @@ -760,9 +736,9 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) pos += 2; - val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); - val &= 0x0FFFF; - if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutils. */ + val = (buffer[0] << 8) | buffer[1]; + /* Avoid duplicate 0x from core binutils. */ + if (info->symtab_size > 0) (*info->fprintf_func) (info->stream, "0x"); (*info->print_address_func) (val, info); } @@ -784,30 +760,24 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) } if (format & M6811_OP_JUMP_REL) { - int val; - status = read_memory (memaddr + pos, &buffer[0], 1, info); if (status != 0) return status; (*info->fprintf_func) (info->stream, "0x"); pos++; - val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0]; + val = (buffer[0] ^ 0x80) - 0x80; (*info->print_address_func) (memaddr + pos + val, info); format &= ~M6811_OP_JUMP_REL; } else if (format & M6812_OP_JUMP_REL16) { - int val; - status = read_memory (memaddr + pos, &buffer[0], 2, info); if (status != 0) return status; pos += 2; - val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); - if (val & 0x8000) - val |= 0xffff0000; + val = (((buffer[0] << 8) | buffer[1]) ^ 0x8000) - 0x8000; (*info->fprintf_func) (info->stream, "0x"); (*info->print_address_func) (memaddr + pos + val, info); @@ -816,16 +786,14 @@ print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) if (format & M6812_OP_PAGE) { - int val; - status = read_memory (memaddr + pos + offset, &buffer[0], 1, info); if (status != 0) return status; pos += 1; - val = buffer[0] & 0x0ff; - (*info->fprintf_func) (info->stream, ", 0x%x", val); + val = buffer[0]; + (*info->fprintf_func) (info->stream, ", 0x%x", (unsigned) val); } #ifdef DEBUG