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