From: Andrew Burgess Date: Sat, 6 Nov 2021 09:50:36 +0000 (+0000) Subject: gdb: fix disassembler regressions for 32-bit arm X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1527fe5f584c71dbf006c6646fe2ff729d7b2b48;p=binutils-gdb.git gdb: fix disassembler regressions for 32-bit arm After this commit: commit 76b43c9b5c2b275cbf4f927bfc25984410cb5dd5 Date: Tue Oct 5 15:10:12 2021 +0100 gdb: improve error reporting from the disassembler We started seeing FAILs in the gdb.base/all-architectures*.exp tests, when running on a 32-bit ARM target, though I suspect running on any target that compiles such that bfd_vma is 32-bits would also trigger the failures. The problem is that the test is expected GDB's disassembler to print an error like this: Cannot access memory at address 0x0 However, after the above commit we see an error like: unknown disassembler error (error = -1) The reason for this is this code in opcodes/i386-dis.c (in the print_insn function): if (address_mode == mode_64bit && sizeof (bfd_vma) < 8) { (*info->fprintf_func) (info->stream, _("64-bit address is disabled")); return -1; } This code effectively disallows us from ever disassembling 64-bit x86 code if we compiled GDB with a 32-bit bfd_vma. Notice we return -1 (indicating a failure to disassemble), but never call the memory_error_func callback. Prior to the above commit GDB, when it received the -1 return value would assume that a memory error had occurred and just print whatever value happened to be in the memory error address variable, the default value of 0 just happened to be fine because the test had asked GDB to do this 'disassemble 0x0,+4'. If we instead change the test to do 'disassemble 0x100,+4' then GDB would (previously) have still reported: Cannot access memory at address 0x0 which makes far less sense. In this commit I propose to fix this issue by changing the test to accept either the "Cannot access memory ..." string, or the newer "unknown disassembler error ..." string. With this change done the test now passes. However, there is one weakness with this strategy; if GDB broke such that we _always_ reported "unknown disassembler error ..." we would never notice. This clearly would be bad. To avoid this issue I have adjusted the all-architectures*.exp tests so that, when we disassemble for the default architecture (the one selected by "auto") we _only_ expect to get the "Cannot access memory ..." error string. [ Note: In an ideal world we should be able to disassemble any architecture at all times. There's no reason why the 64-bit x86 disassembler requires a 64-bit bfd_vma, other than the code happens to be written that way. We could rewrite the disassemble to not have this requirement, but, I don't plan to do that any time soon. ] Further, I have changed the all-architectures*.exp test so that we now disassemble at address 0x100, this should avoid us being able to pass by printing a default address of 0x0. I did originally change the address we disassembled at to 0x4, however, some architectures, e.g. ia64, have a default instruction alignment that is greater than 4, so would still round down to 0x0. I could have just picked 0x8 as an address, but I figured that 0x100 was likely to satisfy most architectures alignment requirements. --- diff --git a/gdb/testsuite/gdb.base/all-architectures.exp.tcl b/gdb/testsuite/gdb.base/all-architectures.exp.tcl index 967aa108665..c247d13e581 100644 --- a/gdb/testsuite/gdb.base/all-architectures.exp.tcl +++ b/gdb/testsuite/gdb.base/all-architectures.exp.tcl @@ -135,6 +135,8 @@ if {[lsearch $supported_archs "arm"] >= 0} { gdb_assert {[llength $supported_arm_abi] != 0} "at least one arm abi" } +set default_architecture "i386" + # Exercise printing float, double and long double. proc print_floats {} { @@ -148,15 +150,27 @@ proc print_floats {} { gdb_test_internal "print 1.0f" " = 1" "print, float" } -# Run tests on the current architecture. +# Run tests on the current architecture ARCH. -proc do_arch_tests {} { +proc do_arch_tests {arch} { print_floats + # When we disassemble using the default architecture then we + # expect that the only error we should get from the disassembler + # is a memory error. + # + # When we force the architecture to something other than the + # default then we might get the message about unknown errors, this + # happens if the libopcodes disassembler returns -1 without first + # registering a memory error. + set pattern "Cannot access memory at address 0x100" + if { $arch != $::default_architecture } { + set pattern "(($pattern)|(unknown disassembler error \\(error = -1\\)))" + } + # GDB can't access memory because there is no loaded executable # nor live inferior. - gdb_test_internal "disassemble 0x0,+4" \ - "Cannot access memory at address 0x0" + gdb_test_internal "disassemble 0x100,+4" "${pattern}" } # Given we can't change arch, osabi, endianness, etc. atomically, we @@ -303,9 +317,9 @@ with_test_prefix "tests" { # Run testing axis CUR_AXIS. This is a recursive # procedure that tries all combinations of options of # all the testing axes. - proc run_axis {all_axes cur_axis} { + proc run_axis {all_axes cur_axis arch} { if {$cur_axis == [llength $all_axes]} { - do_arch_tests + do_arch_tests $arch return } @@ -318,12 +332,12 @@ with_test_prefix "tests" { foreach v $options { with_test_prefix "$var=$v" { gdb_test_no_output_osabi "$cmd $v" "$cmd" - run_axis $all_axes [expr $cur_axis + 1] + run_axis $all_axes [expr $cur_axis + 1] $arch } } } - run_axis $all_axes 0 + run_axis $all_axes 0 $arch } } }