[PATCH 0/8] Handle memory error on disassemble

Yao Qi
2017-01-10T12:26:38Z

Hi,
Nowadays, we can set function pointer
disassemble_info.memory_error_func to throw error or exception when
disassembler gets an error, and the caller can/may catch the exception.
Both gdb and objdump use this interface for many years. After GDB is
switched to C++, this stops working due to the "foreign frame" from
opcodes. That is to say, a C++ program calls a C function
(print_insn_XXX from opcodes) and this function calls a C++ code which
throws exception. DW2 C++ exception unwinder can unwind across the C
function frame, unless the C code is compiled with -fexceptions. As
a result, GDB aborts on memory error during disassembly on some hosts.
See PR 20939 and patch #8 for more details.

This patch series fix this problem by stopping throwing exception
in disassemble_info.memory_error_func from gdb, but record the failed
memory address. Exception is thrown when it is returned from opcodes
function and return value is -1. Fortunately, most of disassemblers
in opcodes follow this convention except msp430 and m68k. Patch 4,
5 and 6 fix these disassmblers in opcodes. (Note that during the work
in opcodes, I find include/dis-asm.h exposes print_ins_$ARCH for each
arch, which is not necessary, because they can be got via
disassemble.c:disassembler by objdump and gdb. This will be done
in a follow-up series.)

Patch 1 is a refactor patch, to rewrite GDB disassemble in C++, so that
1) we can record the failed memory address during disassebly, 2) easier
to do unit tests. Patch 8 does the change in GDB to stop throwing
exception in disassemble_info.memory_error_func. In order to make sure
such change doesn't cause any regression, patch 3 and 7 are the unit
test to GDB disassembler on normal case and error case.

Note that PR 20939 needs to be fixed on GDB 7.12 branch, which still
can be built as a C program, so I probably need to rewrite the patch
using C for 7.12 branch.

Tested binutils with all targets enabled on x86_64-linux. Tested
gdb for {x86_64, aarch64}-linux and arm-linux (on aarch64-linux).

*** BLURB HERE ***

Yao Qi (8):
Refactor disassembly code
Call print_insn_mep in mep_gdb_print_insn
Disassembly unit test: disassemble one instruction
Return -1 on memory error in print_insn_msp430
Remove magic numbers in m68k-dis.c:print_insn_arg
Return -1 on memory error in print_insn_m68k
Disassembly unit test: memory error
Don't throw exception in dis_asm_memory_error

gdb/arm-tdep.c | 5 +-
gdb/disasm.c | 365 +++++++++++++++++++-----
gdb/disasm.h | 56 +++-
gdb/guile/scm-disasm.c | 77 ++---
gdb/mep-tdep.c | 8 +-
gdb/mips-tdep.c | 5 +-
gdb/record-btrace.c | 5 +-
gdb/selftest.c | 55 ++++
gdb/selftest.h | 3 +
gdb/spu-tdep.c | 20 +-
gdb/testsuite/gdb.base/all-architectures.exp.in | 3 +
opcodes/m68k-dis.c | 114 +++++---
opcodes/msp430-dis.c | 85 +++++-
13 files changed, 580 insertions(+), 221 deletions(-)

--
1.9.1