diff options
author | Andrew Burgess <aburgess@redhat.com> | 2022-10-20 11:14:33 +0100 |
---|---|---|
committer | Andrew Burgess <aburgess@redhat.com> | 2023-04-03 14:46:32 +0100 |
commit | 3812b38d8de5804ad3eadd6c7a5d532402ddabab (patch) | |
tree | 24567807fc8f29e4b8eaab45db57fcf4e9f494d6 | |
parent | 0576dff20f052ab6d1ddba861235c7dc2584a145 (diff) | |
download | binutils-3812b38d8de5804ad3eadd6c7a5d532402ddabab.zip binutils-3812b38d8de5804ad3eadd6c7a5d532402ddabab.tar.gz binutils-3812b38d8de5804ad3eadd6c7a5d532402ddabab.tar.bz2 |
gdbserver: allow agent expressions to fail with invalid memory access
This commit extends gdbserver to take account of a failed memory
access from agent_mem_read, and to return a new eval_result_type
expr_eval_invalid_memory_access.
I have only updated the agent_mem_read calls related directly to
reading memory, I have not updated any of the calls related to
tracepoint data collection. This is just because I'm not familiar
with that area of gdb/gdbserver, and I don't want to break anything,
so leaving the existing behaviour untouched seems like the safest
approach.
I've then updated gdb.base/bp-cond-failure.exp to test evaluating the
breakpoints on the target, and have also extended the test so that it
checks for different sizes of memory access.
-rw-r--r-- | gdb/testsuite/gdb.base/bp-cond-failure.exp | 22 | ||||
-rw-r--r-- | gdbserver/ax.cc | 12 | ||||
-rw-r--r-- | gdbserver/ax.h | 3 |
3 files changed, 17 insertions, 20 deletions
diff --git a/gdb/testsuite/gdb.base/bp-cond-failure.exp b/gdb/testsuite/gdb.base/bp-cond-failure.exp index b528ccc..cb57220 100644 --- a/gdb/testsuite/gdb.base/bp-cond-failure.exp +++ b/gdb/testsuite/gdb.base/bp-cond-failure.exp @@ -47,7 +47,7 @@ if { [is_address_zero_readable] } { # Where the breakpoint will be placed. set bp_line [gdb_get_line_number "Breakpoint here"] -proc run_test { cond_eval } { +proc run_test { cond_eval access_type } { clean_restart ${::binfile} if { ![runto_main] } { @@ -59,7 +59,7 @@ proc run_test { cond_eval } { } # Setup the conditional breakpoint and record its number. - gdb_breakpoint "${::srcfile}:${::bp_line} if (*(int *) 0) == 0" + gdb_breakpoint "${::srcfile}:${::bp_line} if (*(${access_type} *) 0) == 0" set bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"] gdb_test "continue" \ @@ -88,17 +88,7 @@ set cond_eval_modes { "auto" } gdb_test_multiple "show breakpoint condition-evaluation" "" { -re -wrap "Breakpoint condition evaluation mode is auto \\(currently target\\)\\." { - - ## NOTE: Instead of testing with "auto" and "host" in this - ## case we only test with "host". This is because a GDB bug - ## prevents the "auto" (a.k.a. target) mode from working. - ## - ## Don't worry, this will be fixed in a later commit, and this - ## comment will be removed at that time. - ## - ## lappend cond_eval_modes "host" - - set cond_eval_modes { "host" } + lappend cond_eval_modes "host" pass $gdb_test_name } @@ -107,6 +97,8 @@ gdb_test_multiple "show breakpoint condition-evaluation" "" { } } -foreach_with_prefix cond_eval $cond_eval_modes { - run_test $cond_eval +foreach_with_prefix access_type { "char" "short" "int" "long long" } { + foreach_with_prefix cond_eval $cond_eval_modes { + run_test $cond_eval $access_type + } } diff --git a/gdbserver/ax.cc b/gdbserver/ax.cc index 38ebfbb..fba5b4a 100644 --- a/gdbserver/ax.cc +++ b/gdbserver/ax.cc @@ -1112,22 +1112,26 @@ gdb_eval_agent_expr (struct eval_agent_expr_context *ctx, break; case gdb_agent_op_ref8: - agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1); + if (agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1) != 0) + return expr_eval_invalid_memory_access; top = cnv.u8.val; break; case gdb_agent_op_ref16: - agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2); + if (agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2) != 0) + return expr_eval_invalid_memory_access; top = cnv.u16.val; break; case gdb_agent_op_ref32: - agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4); + if (agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4) != 0) + return expr_eval_invalid_memory_access; top = cnv.u32.val; break; case gdb_agent_op_ref64: - agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8); + if (agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8) != 0) + return expr_eval_invalid_memory_access; top = cnv.u64.val; break; diff --git a/gdbserver/ax.h b/gdbserver/ax.h index 8e64a7a..c98e36a 100644 --- a/gdbserver/ax.h +++ b/gdbserver/ax.h @@ -41,7 +41,8 @@ enum eval_result_type expr_eval_unhandled_opcode, expr_eval_unrecognized_opcode, expr_eval_divide_by_zero, - expr_eval_invalid_goto + expr_eval_invalid_goto, + expr_eval_invalid_memory_access }; struct agent_expr |