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 launch_id [dap_launch $testfile] 33 34 set obj [dap_check_request_and_response "set breakpoint" \ 35 setFunctionBreakpoints \ 36 {o breakpoints [a [o name [s main]]]}] 37 set fn_bpno [dap_get_breakpoint_number $obj] 38 39 dap_check_request_and_response "configurationDone" configurationDone 40 41 dap_check_response "launch response" launch $launch_id 42 43 dap_wait_for_event_and_check "inferior started" thread "body reason" started 44 45 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \ 46 "body reason" breakpoint \ 47 "body hitBreakpointIds" $fn_bpno 48 49 # Find out how many lines of disassembly we should request. This is 50 # kind of lame but DAP doesn't really provide tools to do this, and 51 # gdb's DAP implementation doesn't try to figure out what memory might 52 # not really be part of a function. 53 set obj [dap_check_request_and_response "disassemble using CLI" \ 54 evaluate {o expression [s {disassemble &return_value}] \ 55 context [s repl]}] 56 set output [dict get [lindex $obj 0] body result] 57 # The result will have literal "\" "n" sequences, turn these into 58 # newlines. 59 set with_nl [string map [list "\\n" "\n"] $output] 60 # The value we want is the number of lines starting with an address. 61 set insn_count 0 62 foreach line [split $with_nl "\n"] { 63 if {[regexp "^ *0x" $line]} { 64 incr insn_count 65 } 66 } 67 68 set obj [dap_check_request_and_response "find function address" \ 69 evaluate {o expression [s "&return_value"]}] 70 set pc [dict get [lindex $obj 0] body memoryReference] 71 72 set obj [dap_check_request_and_response "disassemble the function" \ 73 disassemble \ 74 [format {o memoryReference [s %s] instructionCount [i %d]} \ 75 $pc $insn_count]] 76 set response [lindex $obj 0] 77 78 set seen_labels(_) _ 79 set insn_no 1 80 foreach insn [dict get $response body instructions] { 81 with_test_prefix $insn_no { 82 gdb_assert {[dict exists $insn line]} \ 83 "line in disassemble output" 84 gdb_assert {[dict exists $insn location]} \ 85 "location in disassemble output" 86 if {[dict exists $insn symbol]} { 87 set seen_labels([dict get $insn symbol]) 1 88 } 89 } 90 incr insn_no 91 } 92 93 proc require_label {name} { 94 global seen_labels 95 if {[info exists seen_labels($name)]} { 96 pass "saw label $name" 97 } else { 98 fail "saw label $name" 99 } 100 } 101 102 require_label return_value 103 require_label compute 104 require_label out_label 105 106 dap_shutdown 107