diff options
-rw-r--r-- | opcodes/ChangeLog | 5 | ||||
-rw-r--r-- | opcodes/m68k-dis.c | 28 |
2 files changed, 31 insertions, 2 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index f51cc25..71b2eb7 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2007-04-09 Kazu Hirata <kazu@codesourcery.com> + + * m68k-dis.c (print_insn_m68k): Restore info->fprintf_func and + info->print_address_func if longjmp is called. + 2007-03-29 DJ Delorie <dj@redhat.com> * m32c-desc.c: Regenerate. diff --git a/opcodes/m68k-dis.c b/opcodes/m68k-dis.c index 08a2838..16ad7e4 100644 --- a/opcodes/m68k-dis.c +++ b/opcodes/m68k-dis.c @@ -1475,6 +1475,12 @@ print_insn_m68k (bfd_vma memaddr, disassemble_info *info) bfd_byte *buffer = priv.the_buffer; + /* 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; + info->private_data = (PTR) &priv; /* Tell objdump to use two bytes per chunk and six bytes per line for displaying raw data. */ @@ -1485,8 +1491,26 @@ print_insn_m68k (bfd_vma memaddr, disassemble_info *info) priv.insn_start = memaddr; if (setjmp (priv.bailout) != 0) - /* Error return. */ - return -1; + { + /* 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) |