1 # Copyright 2024 Free Software Foundation, Inc. 2 3 # This program is free software; you can redistribute it and/or modify 4 # it under the terms of the GNU General Public License as published by 5 # the Free Software Foundation; either version 3 of the License, or 6 # (at your option) any later version. 7 # 8 # This program is distributed in the hope that it will be useful, 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 # GNU General Public License for more details. 12 # 13 # You should have received a copy of the GNU General Public License 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 # Test DAP disassembly. 17 18 require allow_dap_tests 19 20 load_lib dap-support.exp 21 22 standard_testfile 23 24 if {[build_executable ${testfile}.exp $testfile] == -1} { 25 return 26 } 27 28 if {[dap_initialize] == ""} { 29 return 30 } 31 32 set obj [dap_check_request_and_response "set breakpoint" \ 33 setFunctionBreakpoints \ 34 {o breakpoints [a [o name [s main]]]}] 35 set fn_bpno [dap_get_breakpoint_number $obj] 36 37 dap_check_request_and_response "configurationDone" configurationDone 38 39 if {[dap_launch $testfile] == ""} { 40 return 41 } 42 dap_wait_for_event_and_check "inferior started" thread "body reason" started 43 44 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \ 45 "body reason" breakpoint \ 46 "body hitBreakpointIds" $fn_bpno 47 48 # Find out how many lines of disassembly we should request. This is 49 # kind of lame but DAP doesn't really provide tools to do this, and 50 # gdb's DAP implementation doesn't try to figure out what memory might 51 # not really be part of a function. 52 set obj [dap_check_request_and_response "disassemble using CLI" \ 53 evaluate {o expression [s {disassemble &return_value}] \ 54 context [s repl]}] 55 set output [dict get [lindex $obj 0] body result] 56 # The result will have literal "\" "n" sequences, turn these into 57 # newlines. 58 set with_nl [string map [list "\\n" "\n"] $output] 59 # The value we want is the number of lines starting with an address. 60 set insn_count 0 61 foreach line [split $with_nl "\n"] { 62 if {[regexp "^ *0x" $line]} { 63 incr insn_count 64 } 65 } 66 67 set obj [dap_check_request_and_response "find function address" \ 68 evaluate {o expression [s "&return_value"]}] 69 set pc [dict get [lindex $obj 0] body memoryReference] 70 71 set obj [dap_check_request_and_response "disassemble the function" \ 72 disassemble \ 73 [format {o memoryReference [s %s] instructionCount [i %d]} \ 74 $pc $insn_count]] 75 set response [lindex $obj 0] 76 77 set seen_labels(_) _ 78 set insn_no 1 79 foreach insn [dict get $response body instructions] { 80 with_test_prefix $insn_no { 81 gdb_assert {[dict exists $insn line]} \ 82 "line in disassemble output" 83 gdb_assert {[dict exists $insn location]} \ 84 "location in disassemble output" 85 if {[dict exists $insn symbol]} { 86 set seen_labels([dict get $insn symbol]) 1 87 } 88 } 89 incr insn_no 90 } 91 92 proc require_label {name} { 93 global seen_labels 94 if {[info exists seen_labels($name)]} { 95 pass "saw label $name" 96 } else { 97 fail "saw label $name" 98 } 99 } 100 101 require_label return_value 102 require_label compute 103 require_label out_label 104 105 dap_shutdown 106