Home | History | Annotate | Line # | Download | only in gdb.dwarf2
      1 # This testcase is part of GDB, the GNU debugger.
      2 
      3 # Copyright 2022-2025 Free Software Foundation, Inc.
      4 
      5 # This program is free software; you can redistribute it and/or modify
      6 # it under the terms of the GNU General Public License as published by
      7 # the Free Software Foundation; either version 3 of the License, or
      8 # (at your option) any later version.
      9 #
     10 # This program is distributed in the hope that it will be useful,
     11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 # GNU General Public License for more details.
     14 #
     15 # You should have received a copy of the GNU General Public License
     16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 # Generate binaries imitating different ways source file paths can be passed to
     19 # compilers.  Test printing macros from those binaries.
     20 #
     21 # The entry points for this test are in the various
     22 # gdb.dwarf2/macro-source-path-*.exp files.
     23 
     24 standard_testfile macro-source-path.c
     25 
     26 lassign [function_range main $srcdir/$subdir/$srcfile] \
     27     main_start main_len
     28 
     29 # Run one test.
     30 #
     31 #  - TEST_NAME is the name of the test, used to differentiate the binaries.
     32 #  - LINES_VERSION is the version of the version of the .debug_line section to
     33 #    generate.
     34 #  - DW_AT_NAME is the string to put in the compilation unit's DW_AT_name
     35 #    attribute.
     36 #  - MAIN_FILE_IDX is the file index the .debug_line and .debug_macro sections
     37 #    will use to refer to the main file.
     38 #  - DIRECTORIES is a list of directories to put in the .debug_line section
     39 #    header
     40 #  - FILE_NAMES is a list of {name, directory index} pairs describing the files
     41 #    names to put in the .debug_line section header.
     42 
     43 proc do_test { test_name lines_version DW_AT_name main_file_idx directories
     44 	       file_names } {
     45     with_test_prefix "test_name=$test_name" {
     46 	foreach_with_prefix is_64 {true false} {
     47 	    # So we can access them in Dwarf::assemble...
     48 	    set ::lines_version $lines_version
     49 	    set ::DW_AT_name $DW_AT_name
     50 	    set ::main_file_idx $main_file_idx
     51 	    set ::directories $directories
     52 	    set ::file_names $file_names
     53 	    set ::is_64 $is_64
     54 	    set 32_or_64 [expr $is_64 ? 64 : 32]
     55 
     56 	    set asm_file [standard_output_file ${::testfile}-${test_name}-${32_or_64}.S]
     57 	    Dwarf::assemble $asm_file {
     58 		declare_labels Llines cu_macros
     59 
     60 		# DW_AT_comp_dir is always the current working directory
     61 		# from which the compiler was invoked.  We pretend the compiler was
     62 		# always launched from /tmp/cwd.
     63 		set comp_dir "/tmp/cwd"
     64 
     65 		cu {} {
     66 		    DW_TAG_compile_unit {
     67 			    {DW_AT_producer "My C Compiler"}
     68 			    {DW_AT_language @DW_LANG_C11}
     69 			    {DW_AT_name $::DW_AT_name}
     70 			    {DW_AT_comp_dir $comp_dir}
     71 			    {DW_AT_stmt_list $Llines DW_FORM_sec_offset}
     72 			    {DW_AT_macros $cu_macros DW_FORM_sec_offset}
     73 		    } {
     74 			declare_labels int_type
     75 
     76 			int_type: DW_TAG_base_type {
     77 			    {DW_AT_byte_size 4 DW_FORM_sdata}
     78 			    {DW_AT_encoding  @DW_ATE_signed}
     79 			    {DW_AT_name int}
     80 			}
     81 
     82 			DW_TAG_subprogram {
     83 			    {MACRO_AT_func {main}}
     84 			    {type :$int_type}
     85 			}
     86 		    }
     87 		}
     88 
     89 		# Define the .debug_line section.
     90 		lines [list version $::lines_version] "Llines" {
     91 		    foreach directory $::directories {
     92 			include_dir $directory
     93 		    }
     94 
     95 		    foreach file_name $::file_names {
     96 			lassign $file_name name dir_index
     97 			file_name $name $dir_index
     98 		    }
     99 
    100 		    # A line number program just good enough so that GDB can
    101 		    # figure out we are stopped in main.
    102 		    program {
    103 			DW_LNS_set_file $::main_file_idx
    104 			DW_LNE_set_address $::main_start
    105 			line 10
    106 			DW_LNS_copy
    107 
    108 			DW_LNE_set_address "$::main_start + $::main_len"
    109 			DW_LNE_end_sequence
    110 		    }
    111 		}
    112 
    113 		# Define the .debug_macro section.
    114 		macro {
    115 		    cu_macros: unit {
    116 			"debug-line-offset-label" $Llines
    117 			"is-64" $::is_64
    118 		    } {
    119 			# A macro defined outside the main file, as if it was defined
    120 			# on the command line with -D.
    121 			#
    122 			# Clang has this bug where it puts the macros defined on
    123 			# the command-line after the main file portion (see
    124 			# PR 29034).  We're not trying to replicate that here,
    125 			# this is not in the scope of this test.
    126 			define 0 "ONE 1"
    127 			define_strp 0 "THREE 3"
    128 			start_file 0 $::main_file_idx
    129 			    # A macro defined at line 1 of the main file.
    130 			    define 1 "TWO 2"
    131 			end_file
    132 		    }
    133 		}
    134 	    }
    135 
    136 	    if { [prepare_for_testing "failed to prepare" ${::testfile}-${test_name}-${32_or_64} \
    137 		      [list $::srcfile $asm_file] {nodebug}] } {
    138 		return
    139 	    }
    140 
    141 	    with_complaints 5 {
    142 		gdb_test_multiple "print main" "no complaints" {
    143 		    -wrap -re "During symbol reading: .*" {
    144 			fail $gdb_test_name
    145 		    }
    146 		    -wrap -re "" {
    147 			pass $gdb_test_name
    148 		    }
    149 		}
    150 	    }
    151 
    152 	    if ![runto_main] {
    153 		return
    154 	    }
    155 
    156 	    gdb_test "print ONE" " = 1"
    157 	    gdb_test "print TWO" " = 2"
    158 	    gdb_test "print THREE" " = 3"
    159 	}
    160     }
    161 }
    162