1# Copyright 2020-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# Create an example function that contains both addresses marked as 17# statements and addresses marked as non-statements, and then 18# disassemble the function. 19# 20# Of particular interest is how 'disassemble /m' handles the 21# non-statement addresses, we want to ensure that these addresses are 22# included in the disassembly output. For completeness we test both 23# 'disassemble /m' and 'disassemble /s'. 24 25load_lib dwarf.exp 26 27# This test can only be run on targets which support DWARF-2 and use gas. 28require dwarf2_support 29 30# The .c files use __attribute__. 31require is_c_compiler_gcc 32 33# Reuse many of the test source files from dw2-inline-header-1.exp. 34standard_testfile dw2-inline-header-lbls.c dw2-inline-header.S \ 35 dw2-inline-header.c 36 37set asm_file [standard_output_file $srcfile2] 38Dwarf::assemble $asm_file { 39 global srcdir subdir srcfile srcfile3 40 declare_labels lines_label 41 42 get_func_info main 43 44 cu {} { 45 compile_unit { 46 {producer "gcc" } 47 {language @DW_LANG_C} 48 {name ${srcfile3}} 49 {low_pc 0 addr} 50 {stmt_list ${lines_label} DW_FORM_sec_offset} 51 } { 52 subprogram { 53 {external 1 flag} 54 {MACRO_AT_func {main}} 55 } 56 } 57 } 58 59 lines {version 2 default_is_stmt 1} lines_label { 60 include_dir "${srcdir}/${subdir}" 61 file_name "$srcfile3" 1 62 63 program { 64 DW_LNE_set_address $main_start 65 DW_LNS_advance_line 15 66 DW_LNS_copy 67 68 DW_LNE_set_address line_label_2 69 DW_LNS_negate_stmt 70 DW_LNS_copy 71 72 DW_LNE_set_address line_label_3 73 DW_LNS_advance_line 1 74 DW_LNS_copy 75 76 DW_LNE_set_address line_label_4 77 DW_LNS_negate_stmt 78 DW_LNS_copy 79 80 DW_LNE_set_address line_label_5 81 DW_LNS_negate_stmt 82 DW_LNS_copy 83 84 DW_LNE_set_address line_label_6 85 DW_LNS_advance_line 1 86 DW_LNS_negate_stmt 87 DW_LNS_copy 88 89 DW_LNE_set_address $main_end 90 DW_LNE_end_sequence 91 } 92 } 93} 94 95if { [prepare_for_testing "failed to prepare" ${testfile} \ 96 [list $srcfile $asm_file] {nodebug} ] } { 97 return -1 98} 99 100if ![runto_main] { 101 return -1 102} 103 104# Global lines array, maps lines numbers to the list of addresses 105# associated with that line in the debug output. 106array set lines {} 107 108# Look in the global LINES array and check that the disassembly for 109# line LINENUM includes the address of LABEL. 110proc check_disassembly_results { linenum label } { 111 global lines 112 113 set address [get_hexadecimal_valueof "&${label}" "__unknown__"] 114 set testname "check_disassembly_results $linenum $label" 115 if {![info exists lines($linenum)]} { 116 fail "$testname (no disassembly for $linenum)" 117 return 118 } 119 120 # Use a loop to compare the addresses as the addresses extracted 121 # from the disassembly output can be padded with zeros, while the 122 # address of the label will not be padded. 123 set addrs $lines($linenum) 124 foreach a $addrs { 125 if { $a == $address } { 126 pass $testname 127 return 128 } 129 } 130 fail $testname 131} 132 133foreach_with_prefix opt { m s } { 134 # Disassemble 'main' and split up the disassembly output. We 135 # build an associative array, for each line number store the list 136 # of addresses that were part of its disassembly output. 137 # 138 # LINENUM is the line we are currently collecting the disassembly 139 # addresses for, and ADDRS is the list of addresses collected for 140 # this line. 141 set linenum -1 142 set addrs {} 143 144 # Clear the global associative array used to hold the results. 145 unset lines 146 array set lines {} 147 148 gdb_test_multiple "disassemble /${opt} main" "" { 149 -re "Dump of assembler code for function main:\r\n" { 150 exp_continue 151 } 152 153 -re "^\[^\r\n\]+${srcfile3}:" { 154 exp_continue 155 } 156 157 -re "^(\\d+)\\s+\[^\r\n\]+\r\n" { 158 if { $linenum != -1 } { 159 set lines($linenum) $addrs 160 set addrs {} 161 } 162 set linenum $expect_out(1,string) 163 exp_continue 164 } 165 166 -re "^(?:=>)?\\s*($hex)\\s*\[^\r\n\]+\r\n" { 167 set address $expect_out(1,string) 168 lappend addrs $address 169 exp_continue 170 } 171 172 -re "^\\s*\r\n" { 173 exp_continue 174 } 175 176 -re "^End of assembler dump\\.\r\n" { 177 if { $linenum != -1 } { 178 set lines($linenum) $addrs 179 set linenum -1 180 set addrs {} 181 } 182 exp_continue 183 } 184 185 -re "^$gdb_prompt $" { 186 # All done. 187 } 188 } 189 190 # Now check that each label we expect to be associated with each line 191 # shows up in the disassembly output. 192 check_disassembly_results 16 "line_label_1" 193 check_disassembly_results 16 "line_label_2" 194 check_disassembly_results 17 "line_label_3" 195 check_disassembly_results 17 "line_label_4" 196 check_disassembly_results 17 "line_label_5" 197 check_disassembly_results 18 "line_label_6" 198} 199