diff options
-rw-r--r-- | opcodes/ChangeLog | 4 | ||||
-rw-r--r-- | opcodes/m68k-dis.c | 416 |
2 files changed, 252 insertions, 168 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 36348b7..93b5397 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,7 @@ +2008-11-25 Nick Clifton <nickc@redhat.com> + + * m68k-dis.c: Rewrite to remove use of setjmp/longjmp. + 2008-09-29 Nick Clifton <nickc@redhat.com> * po/vi.po: Updated Vietnamese translation. diff --git a/opcodes/m68k-dis.c b/opcodes/m68k-dis.c index 77820ef..8836570 100644 --- a/opcodes/m68k-dis.c +++ b/opcodes/m68k-dis.c @@ -60,46 +60,103 @@ static char *const reg_half_names[] = #endif /* Get a 1 byte signed integer. */ -#define NEXTBYTE(p) (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1])) +#define NEXTBYTE(p, val) \ + do \ + { \ + p += 2; \ + if (FETCH_DATA (info, p) < 0) \ + return -3; \ + val = COERCE_SIGNED_CHAR (p[-1]); \ + } \ + while (0) /* Get a 2 byte signed integer. */ #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000)) -#define NEXTWORD(p) \ - (p += 2, FETCH_DATA (info, p), \ - COERCE16 ((p[-2] << 8) + p[-1])) + +#define NEXTWORD(p, val, ret_val) \ + do \ + { \ + p += 2; \ + if (FETCH_DATA (info, p) < 0) \ + return ret_val; \ + val = COERCE16 ((p[-2] << 8) + p[-1]); \ + } \ + while (0) /* Get a 4 byte signed integer. */ #define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000) -#define NEXTLONG(p) \ - (p += 4, FETCH_DATA (info, p), \ - (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))) + +#define NEXTLONG(p, val, ret_val) \ + do \ + { \ + p += 4; \ + if (FETCH_DATA (info, p) < 0) \ + return ret_val; \ + val = COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \ + } \ + while (0) /* Get a 4 byte unsigned integer. */ -#define NEXTULONG(p) \ - (p += 4, FETCH_DATA (info, p), \ - (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])) +#define NEXTULONG(p, val) \ + do \ + { \ + p += 4; \ + if (FETCH_DATA (info, p) < 0) \ + return -3; \ + val = (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \ + } \ + while (0) /* Get a single precision float. */ -#define NEXTSINGLE(val, p) \ - (p += 4, FETCH_DATA (info, p), \ - floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val)) +#define NEXTSINGLE(val, p) \ + do \ + { \ + p += 4; \ + if (FETCH_DATA (info, p) < 0) \ + return -3; \ + floatformat_to_double (& floatformat_ieee_single_big, \ + (char *) p - 4, & val); \ + } \ + while (0) /* Get a double precision float. */ -#define NEXTDOUBLE(val, p) \ - (p += 8, FETCH_DATA (info, p), \ - floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val)) +#define NEXTDOUBLE(val, p) \ + do \ + { \ + p += 8; \ + if (FETCH_DATA (info, p) , 0) \ + return -3; \ + floatformat_to_double (& floatformat_ieee_double_big, \ + (char *) p - 8, & val); \ + } \ + while (0) /* Get an extended precision float. */ -#define NEXTEXTEND(val, p) \ - (p += 12, FETCH_DATA (info, p), \ - floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val)) +#define NEXTEXTEND(val, p) \ + do \ + { \ + p += 12; \ + if (FETCH_DATA (info, p) < 0) \ + return -3; \ + floatformat_to_double (& floatformat_m68881_ext, \ + (char *) p - 12, & val); \ + } \ + while (0) /* Need a function to convert from packed to double precision. Actually, it's easier to print a packed number than a double anyway, so maybe there should be a special case to handle this... */ -#define NEXTPACKED(p) \ - (p += 12, FETCH_DATA (info, p), 0.0) +#define NEXTPACKED(p, val) \ + do \ + { \ + p += 12; \ + if (FETCH_DATA (info, p) < 0) \ + return -3; \ + val = 0.0; \ + } \ + while (0) + /* Maximum length of an instruction. */ #define MAXLEN 22 @@ -112,12 +169,13 @@ struct private bfd_byte *max_fetched; bfd_byte the_buffer[MAXLEN]; bfd_vma insn_start; - jmp_buf bailout; }; +static fprintf_ftype save_printer; +static void (* save_print_address) (bfd_vma, struct disassemble_info *); + /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) - to ADDR (exclusive) are valid. Returns 1 for success, longjmps - on error. */ + to ADDR (exclusive) are valid. Returns 1 for success, 0 on error. */ #define FETCH_DATA(info, addr) \ ((addr) <= ((struct private *) (info->private_data))->max_fetched \ ? 1 : fetch_data ((info), (addr))) @@ -136,7 +194,9 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) if (status != 0) { (*info->memory_error_func) (status, start, info); - longjmp (priv->bailout, 1); + info->fprintf_func = save_printer; + info->print_address_func = save_print_address; + return 0; } else priv->max_fetched = addr; @@ -161,7 +221,8 @@ dummy_print_address (bfd_vma vma ATTRIBUTE_UNUSED, /* Fetch BITS bits from a position in the instruction specified by CODE. CODE is a "place to put an argument", or 'x' for a destination that is a general address (mode and register). - BUFFER contains the instruction. */ + BUFFER contains the instruction. + Returns -1 on failure. */ static int fetch_arg (unsigned char *buffer, @@ -216,64 +277,75 @@ fetch_arg (unsigned char *buffer, break; case 'k': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[3] >> 4); break; case 'C': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = buffer[3]; break; case '1': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 12; break; case '2': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 6; break; case '3': case 'j': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; break; case '4': - FETCH_DATA (info, buffer + 5); + if (! FETCH_DATA (info, buffer + 5)) + return -1; val = (buffer[4] << 8) + buffer[5]; val >>= 12; break; case '5': - FETCH_DATA (info, buffer + 5); + if (! FETCH_DATA (info, buffer + 5)) + return -1; val = (buffer[4] << 8) + buffer[5]; val >>= 6; break; case '6': - FETCH_DATA (info, buffer + 5); + if (! FETCH_DATA (info, buffer + 5)) + return -1; val = (buffer[4] << 8) + buffer[5]; break; case '7': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 7; break; case '8': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 10; break; case '9': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] << 8) + buffer[3]; val >>= 5; break; @@ -283,7 +355,8 @@ fetch_arg (unsigned char *buffer, break; case 'E': - FETCH_DATA (info, buffer + 3); + if (! FETCH_DATA (info, buffer + 3)) + return -1; val = (buffer[2] >> 1); break; @@ -450,7 +523,8 @@ print_base (int regno, bfd_vma disp, disassemble_info *info) /* Print an indexed argument. The base register is BASEREG (-1 for pc). P points to extension word, in buffer. - ADDR is the nominal core address of that extension word. */ + ADDR is the nominal core address of that extension word. + Returns NULL upon error. */ static unsigned char * print_indexed (int basereg, @@ -465,7 +539,7 @@ print_indexed (int basereg, char buf[40]; char vmabuf[50]; - word = NEXTWORD (p); + NEXTWORD (p, word, NULL); /* Generate the text for the index register. Where this will be output is not yet determined. */ @@ -503,10 +577,10 @@ print_indexed (int basereg, switch ((word >> 4) & 3) { case 2: - base_disp = NEXTWORD (p); + NEXTWORD (p, base_disp, NULL); break; case 3: - base_disp = NEXTLONG (p); + NEXTLONG (p, base_disp, NULL); } if (basereg == -1) base_disp += addr; @@ -526,10 +600,10 @@ print_indexed (int basereg, switch (word & 3) { case 2: - outer_disp = NEXTWORD (p); + NEXTWORD (p, outer_disp, NULL); break; case 3: - outer_disp = NEXTLONG (p); + NEXTLONG (p, outer_disp, NULL); } print_base (basereg, base_disp, info); @@ -547,9 +621,18 @@ print_indexed (int basereg, return p; } +#define FETCH_ARG(size, val) \ + do \ + { \ + val = fetch_arg (buffer, place, size, info); \ + if (val < 0) \ + return -3; \ + } \ + while (0) + /* Returns number of bytes "eaten" by the operand, or return -1 if an invalid operand was found, or -2 if - an opcode tabe error was found. + an opcode tabe error was found or -3 to simply abort. ADDR is the pc for this arg to be relative to. */ static int @@ -575,23 +658,21 @@ print_insn_arg (const char *d, case 'c': /* Cache identifier. */ { static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" }; - val = fetch_arg (buffer, place, 2, info); - (*info->fprintf_func) (info->stream, cacheFieldName[val]); + FETCH_ARG (2, val); + (*info->fprintf_func) (info->stream, cacheFieldName[val]); break; } case 'a': /* Address register indirect only. Cf. case '+'. */ { - (*info->fprintf_func) - (info->stream, - "%s@", - reg_names[fetch_arg (buffer, place, 3, info) + 8]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s@", reg_names[val + 8]); break; } case '_': /* 32-bit absolute address for move16. */ { - uval = NEXTULONG (p); + NEXTULONG (p, uval); (*info->print_address_func) (uval, info); break; } @@ -643,7 +724,7 @@ print_insn_arg (const char *d, /* Fido added these. */ {"%cac", 0xffe}, {"%mbo", 0xfff}}; - val = fetch_arg (buffer, place, 12, info); + FETCH_ARG (12, val); for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--) if (names[regno].value == val) { @@ -656,7 +737,7 @@ print_insn_arg (const char *d, break; case 'Q': - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); /* 0 means 8, except for the bkpt instruction... */ if (val == 0 && d[1] != 's') val = 8; @@ -664,7 +745,7 @@ print_insn_arg (const char *d, break; case 'x': - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); /* 0 means -1. */ if (val == 0) val = -1; @@ -672,12 +753,12 @@ print_insn_arg (const char *d, break; case 'j': - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); (*info->fprintf_func) (info->stream, "#%d", val+1); break; case 'K': - val = fetch_arg (buffer, place, 9, info); + FETCH_ARG (9, val); (*info->fprintf_func) (info->stream, "#%d", val); break; @@ -685,12 +766,13 @@ print_insn_arg (const char *d, if (place == 'h') { static char *const scalefactor_name[] = { "<<", ">>" }; - val = fetch_arg (buffer, place, 1, info); + + FETCH_ARG (1, val); (*info->fprintf_func) (info->stream, scalefactor_name[val]); } else { - val = fetch_arg (buffer, place, 8, info); + FETCH_ARG (8, val); if (val & 0x80) val = val - 0x100; (*info->fprintf_func) (info->stream, "#%d", val); @@ -698,29 +780,27 @@ print_insn_arg (const char *d, break; case 'T': - val = fetch_arg (buffer, place, 4, info); + FETCH_ARG (4, val); (*info->fprintf_func) (info->stream, "#%d", val); break; case 'D': - (*info->fprintf_func) (info->stream, "%s", - reg_names[fetch_arg (buffer, place, 3, info)]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s", reg_names[val]); break; case 'A': - (*info->fprintf_func) - (info->stream, "%s", - reg_names[fetch_arg (buffer, place, 3, info) + 010]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s", reg_names[val + 010]); break; case 'R': - (*info->fprintf_func) - (info->stream, "%s", - reg_names[fetch_arg (buffer, place, 4, info)]); + FETCH_ARG (4, val); + (*info->fprintf_func) (info->stream, "%s", reg_names[val]); break; case 'r': - regno = fetch_arg (buffer, place, 4, info); + FETCH_ARG (4, regno); if (regno > 7) (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]); else @@ -728,13 +808,12 @@ print_insn_arg (const char *d, break; case 'F': - (*info->fprintf_func) - (info->stream, "%%fp%d", - fetch_arg (buffer, place, 3, info)); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%%fp%d", val); break; case 'O': - val = fetch_arg (buffer, place, 6, info); + FETCH_ARG (6, val); if (val & 0x20) (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]); else @@ -742,78 +821,78 @@ print_insn_arg (const char *d, break; case '+': - (*info->fprintf_func) - (info->stream, "%s@+", - reg_names[fetch_arg (buffer, place, 3, info) + 8]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s@+", reg_names[val + 8]); break; case '-': - (*info->fprintf_func) - (info->stream, "%s@-", - reg_names[fetch_arg (buffer, place, 3, info) + 8]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s@-", reg_names[val + 8]); break; case 'k': if (place == 'k') - (*info->fprintf_func) - (info->stream, "{%s}", - reg_names[fetch_arg (buffer, place, 3, info)]); + { + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "{%s}", reg_names[val]); + } else if (place == 'C') { - val = fetch_arg (buffer, place, 7, info); + FETCH_ARG (7, val); if (val > 63) /* This is a signed constant. */ val -= 128; (*info->fprintf_func) (info->stream, "{#%d}", val); } else - return -2; + return -1; break; case '#': case '^': p1 = buffer + (*d == '#' ? 2 : 4); if (place == 's') - val = fetch_arg (buffer, place, 4, info); + FETCH_ARG (4, val); else if (place == 'C') - val = fetch_arg (buffer, place, 7, info); + FETCH_ARG (7, val); else if (place == '8') - val = fetch_arg (buffer, place, 3, info); + FETCH_ARG (3, val); else if (place == '3') - val = fetch_arg (buffer, place, 8, info); + FETCH_ARG (8, val); else if (place == 'b') - val = NEXTBYTE (p1); + NEXTBYTE (p1, val); else if (place == 'w' || place == 'W') - val = NEXTWORD (p1); + NEXTWORD (p1, val, -3); else if (place == 'l') - val = NEXTLONG (p1); + NEXTLONG (p1, val, -3); else return -2; + (*info->fprintf_func) (info->stream, "#%d", val); break; case 'B': if (place == 'b') - disp = NEXTBYTE (p); + NEXTBYTE (p, disp); else if (place == 'B') disp = COERCE_SIGNED_CHAR (buffer[1]); else if (place == 'w' || place == 'W') - disp = NEXTWORD (p); + NEXTWORD (p, disp, -3); else if (place == 'l' || place == 'L' || place == 'C') - disp = NEXTLONG (p); + NEXTLONG (p, disp, -3); else if (place == 'g') { - disp = NEXTBYTE (buffer); + NEXTBYTE (buffer, disp); if (disp == 0) - disp = NEXTWORD (p); + NEXTWORD (p, disp, -3); else if (disp == -1) - disp = NEXTLONG (p); + NEXTLONG (p, disp, -3); } else if (place == 'c') { if (buffer[1] & 0x40) /* If bit six is one, long offset. */ - disp = NEXTLONG (p); + NEXTLONG (p, disp, -3); else - disp = NEXTWORD (p); + NEXTWORD (p, disp, -3); } else return -2; @@ -822,29 +901,32 @@ print_insn_arg (const char *d, break; case 'd': - val = NEXTWORD (p); - (*info->fprintf_func) - (info->stream, "%s@(%d)", - reg_names[fetch_arg (buffer, place, 3, info) + 8], val); - break; + { + int val1; + + NEXTWORD (p, val, -3); + FETCH_ARG (3, val1); + (*info->fprintf_func) (info->stream, "%s@(%d)", reg_names[val1 + 8], val); + break; + } case 's': - (*info->fprintf_func) (info->stream, "%s", - fpcr_names[fetch_arg (buffer, place, 3, info)]); + FETCH_ARG (3, val); + (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]); break; case 'e': - val = fetch_arg(buffer, place, 2, info); + FETCH_ARG (2, val); (*info->fprintf_func) (info->stream, "%%acc%d", val); break; case 'g': - val = fetch_arg(buffer, place, 1, info); - (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23"); + FETCH_ARG (1, val); + (*info->fprintf_func) (info->stream, "%%accext%s", val == 0 ? "01" : "23"); break; case 'i': - val = fetch_arg(buffer, place, 2, info); + FETCH_ARG (2, val); if (val == 1) (*info->fprintf_func) (info->stream, "<<"); else if (val == 3) @@ -856,7 +938,8 @@ print_insn_arg (const char *d, case 'I': /* Get coprocessor ID... */ val = fetch_arg (buffer, 'd', 3, info); - + if (val < 0) + return -3; if (val != 1) /* Unusual coprocessor ID? */ (*info->fprintf_func) (info->stream, "(cpid=%d) ", val); break; @@ -888,10 +971,16 @@ print_insn_arg (const char *d, if (place == 'd') { val = fetch_arg (buffer, 'x', 6, info); + if (val < 0) + return -3; val = ((val & 7) << 3) + ((val >> 3) & 7); } else - val = fetch_arg (buffer, 's', 6, info); + { + val = fetch_arg (buffer, 's', 6, info); + if (val < 0) + return -3; + } /* If the <ea> is invalid for *d, then reject this match. */ if (!m68k_valid_ea (*d, val)) @@ -923,29 +1012,31 @@ print_insn_arg (const char *d, break; case 5: - val = NEXTWORD (p); + NEXTWORD (p, val, -3); (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val); break; case 6: p = print_indexed (regno, p, addr, info); + if (p == NULL) + return -3; break; case 7: switch (val & 7) { case 0: - val = NEXTWORD (p); + NEXTWORD (p, val, -3); (*info->print_address_func) (val, info); break; case 1: - uval = NEXTULONG (p); + NEXTULONG (p, uval); (*info->print_address_func) (uval, info); break; case 2: - val = NEXTWORD (p); + NEXTWORD (p, val, -3); (*info->fprintf_func) (info->stream, "%%pc@("); (*info->print_address_func) (addr + val, info); (*info->fprintf_func) (info->stream, ")"); @@ -953,6 +1044,8 @@ print_insn_arg (const char *d, case 3: p = print_indexed (-1, p, addr, info); + if (p == NULL) + return -3; break; case 4: @@ -960,17 +1053,17 @@ print_insn_arg (const char *d, switch (place) { case 'b': - val = NEXTBYTE (p); + NEXTBYTE (p, val); flt_p = 0; break; case 'w': - val = NEXTWORD (p); + NEXTWORD (p, val, -3); flt_p = 0; break; case 'l': - val = NEXTLONG (p); + NEXTLONG (p, val, -3); flt_p = 0; break; @@ -987,7 +1080,7 @@ print_insn_arg (const char *d, break; case 'p': - flval = NEXTPACKED (p); + NEXTPACKED (p, flval); break; default: @@ -1009,7 +1102,7 @@ print_insn_arg (const char *d, mask bit and if set, add a '&' to the arg. */ if (place == '/') { - val = fetch_arg (buffer, place, 1, info); + FETCH_ARG (1, val); if (val) info->fprintf_func (info->stream, "&"); } @@ -1021,7 +1114,7 @@ print_insn_arg (const char *d, { char doneany; p1 = buffer + 2; - val = NEXTWORD (p1); + NEXTWORD (p1, val, -3); /* Move the pointer ahead if this point is farther ahead than the last. */ p = p1 > p ? p1 : p; @@ -1062,7 +1155,8 @@ print_insn_arg (const char *d, { /* `fmovem' insn. */ char doneany; - val = fetch_arg (buffer, place, 8, info); + + FETCH_ARG (8, val); if (val == 0) { (*info->fprintf_func) (info->stream, "#0"); @@ -1096,10 +1190,9 @@ print_insn_arg (const char *d, } else if (place == '8') { + FETCH_ARG (3, val); /* fmoveml for FP status registers. */ - (*info->fprintf_func) (info->stream, "%s", - fpcr_names[fetch_arg (buffer, place, 3, - info)]); + (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]); } else return -2; @@ -1115,9 +1208,10 @@ print_insn_arg (const char *d, case '2': case '3': { - int val = fetch_arg (buffer, place, 5, info); + int val; char *name = 0; + FETCH_ARG (5, val); switch (val) { case 2: name = "%tt0"; break; @@ -1152,8 +1246,9 @@ print_insn_arg (const char *d, case 'f': { - int fc = fetch_arg (buffer, place, 5, info); + int fc; + FETCH_ARG (5, fc); if (fc == 1) (*info->fprintf_func) (info->stream, "%%dfc"); else if (fc == 0) @@ -1170,8 +1265,9 @@ print_insn_arg (const char *d, case 't': { - int level = fetch_arg (buffer, place, 3, info); + int level; + FETCH_ARG (3, level); (*info->fprintf_func) (info->stream, "%d", level); } break; @@ -1179,8 +1275,9 @@ print_insn_arg (const char *d, case 'u': { short is_upper = 0; - int reg = fetch_arg (buffer, place, 5, info); + int reg; + FETCH_ARG (5, reg); if (reg & 0x10) { is_upper = 1; @@ -1309,6 +1406,8 @@ match_insn_m68k (bfd_vma memaddr, info->print_address_func = save_print_address; return 0; } + else if (eaten == -3) + return 0; else { /* We must restore the print functions before trying to print the @@ -1318,7 +1417,7 @@ match_insn_m68k (bfd_vma memaddr, info->fprintf_func (info->stream, /* xgettext:c-format */ _("<internal error in opcode table: %s %s>\n"), - best->name, best->args); + best->name, best->args); return 2; } } @@ -1439,6 +1538,8 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info, if (d[0] == 's' && d[1] == '8') { val = fetch_arg (buffer, d[1], 3, info); + if (val < 0) + return 0; if ((val & (val - 1)) != 0) break; } @@ -1473,6 +1574,8 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info, int print_insn_m68k (bfd_vma memaddr, disassemble_info *info) { + fprintf_ftype save_printer; + void (* save_print_address) (bfd_vma, struct disassemble_info *); unsigned int arch_mask; struct private priv; int val; @@ -1481,11 +1584,10 @@ print_insn_m68k (bfd_vma memaddr, disassemble_info *info) /* Save these printing functions in case we need to restore them later. */ - fprintf_ftype save_printer = info->fprintf_func; - void (* save_print_address) (bfd_vma, struct disassemble_info *) - = info->print_address_func; + save_printer = info->fprintf_func; + save_print_address = info->print_address_func; - info->private_data = (PTR) &priv; + info->private_data = & priv; /* Tell objdump to use two bytes per chunk and six bytes per line for displaying raw data. */ info->bytes_per_chunk = 2; @@ -1494,49 +1596,27 @@ print_insn_m68k (bfd_vma memaddr, disassemble_info *info) priv.max_fetched = priv.the_buffer; priv.insn_start = memaddr; - if (setjmp (priv.bailout) != 0) - { - /* longjmp may be called while these printing functions are - temporarily replaced with dummy functions. Restore them - before we leave. - - Admittedly, this save-and-restore operation is somewhat ugly - in that we are exposing the fact that match_insn_m68k - temporarily replaces insn->fprintf_func and - insn->print_address_func. Perhaps, a real fix is to report a - FETCH_DATA failure with a return value of some sort, without - using setjmp/longjmp. A better fix may be to teach the m68k - disassembler do its job without temporarily replacing - insn->fprintf_func and insn->print_address_func, but that's a - task for another day. */ - info->fprintf_func = save_printer; - info->print_address_func = save_print_address; - - /* Error return. */ - return -1; - } - arch_mask = bfd_m68k_mach_to_features (info->mach); if (!arch_mask) { /* First try printing an m680x0 instruction. Try printing a Coldfire one if that fails. */ val = m68k_scan_mask (memaddr, info, m68k_mask); - if (val) - return val; - - val = m68k_scan_mask (memaddr, info, mcf_mask); - if (val) - return val; + if (val == 0) + val = m68k_scan_mask (memaddr, info, mcf_mask); } else { val = m68k_scan_mask (memaddr, info, arch_mask); - if (val) - return val; } - /* Handle undefined instructions. */ - info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]); - return 2; + if (val == 0) + /* Handle undefined instructions. */ + info->fprintf_func (info->stream, "0%o", (buffer[0] << 8) + buffer[1]); + + /* Restore print functions. */ + info->fprintf_func = save_printer; + info->print_address_func = save_print_address; + + return val ? val : 2; } |