diff options
-rw-r--r-- | gdb/testsuite/gdb.base/macro-source-path.c | 22 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/macro-source-path.exp | 87 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/macro-source-path.c | 20 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/macro-source-path.exp | 396 | ||||
-rw-r--r-- | gdb/testsuite/lib/dwarf.exp | 92 |
5 files changed, 617 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/macro-source-path.c b/gdb/testsuite/gdb.base/macro-source-path.c new file mode 100644 index 0000000..f4ede11 --- /dev/null +++ b/gdb/testsuite/gdb.base/macro-source-path.c @@ -0,0 +1,22 @@ +/* Copyright 2022 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#define TWO 2 + +int +main (void) +{ + return ONE + TWO; +} diff --git a/gdb/testsuite/gdb.base/macro-source-path.exp b/gdb/testsuite/gdb.base/macro-source-path.exp new file mode 100644 index 0000000..edbb4ae --- /dev/null +++ b/gdb/testsuite/gdb.base/macro-source-path.exp @@ -0,0 +1,87 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Compile a source file using different ways of passing the path to the +# compiler. Then, verify that we can print a macro defined in that file. + +standard_testfile + +# If the host is remote, source files are uploaded to the host and compiled +# there, but without the directory structure we expect, making the test +# pointless. Skip the test in that case. +if { [is_remote host] } { + return +} + +# Copy the source file at these locations in the output directory ($out): +# +# $out/cwd/macro-source-path.c +# $out/other/macro-source-path.c +# +# Set the current working directory to $out/cwd, so that we can test compiling +# using relative paths. + +set out_dir [standard_output_file ""] +file mkdir $out_dir/cwd +file mkdir $out_dir/other +file copy -force $srcdir/$subdir/$srcfile $out_dir/cwd +file copy -force $srcdir/$subdir/$srcfile $out_dir/other + +# Run one test. +# +# SRC is the path to the source file, to be passed to the compiler as-is. +# NAME is the name of the test. + +proc test { src name } { + with_test_prefix $name { + set binfile $::out_dir/$name + + if { [gdb_compile $src $binfile executable {debug macros additional_flags=-DONE=1}] != "" } { + fail "could not compile" + return + } + + clean_restart $binfile + + if { ![runto_main] } { + return + } + + # Print the macro that is defined on the command-line. + if { [test_compiler_info "clang-*"] } { + # This is really a clang bug, it puts the macros defined on the command + # line after the main source file, in the macro table. + setup_kfail "gdb/29034" "*-*-*" + } + gdb_test "print ONE" " = 1" + + # Print the macro that is defined in the main file. + gdb_test "print TWO" " = 2" + } +} + +# When adding a test here, please consider adding an equivalent case to the test +# of the same name in gdb.dwarf2. + +with_cwd "$out_dir/cwd" { + test $testfile.c filename + test ./$testfile.c dot-filename + test ../cwd/$testfile.c dot-dot-filename + test [file normalize $testfile.c] absolute-cwd + test ../other/$testfile.c dot-dot-other + test [file normalize ../other/$testfile.c] absolute-other +} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path.c b/gdb/testsuite/gdb.dwarf2/macro-source-path.c new file mode 100644 index 0000000..749bcc1 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path.c @@ -0,0 +1,20 @@ +/* Copyright 2022 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +int +main (void) +{ + asm ("main_label: .globl main_label"); +} diff --git a/gdb/testsuite/gdb.dwarf2/macro-source-path.exp b/gdb/testsuite/gdb.dwarf2/macro-source-path.exp new file mode 100644 index 0000000..8743edd --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/macro-source-path.exp @@ -0,0 +1,396 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2022 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Generate binaries imitating different ways source file paths can be passed to +# compilers. Test printing macros from those binaries. + +load_lib dwarf.exp + +if {![dwarf2_support]} { + return 0 +} + +standard_testfile .c + +lassign [function_range main $srcdir/$subdir/$srcfile] \ + main_start main_len + +# Run one test. +# +# - TEST_NAME is the name of the test, used to differentiate the binaries. +# - LINES_VERSION is the version of the version of the .debug_line section to +# generate. +# - DW_AT_NAME is the string to put in the compilation unit's DW_AT_name +# attribute. +# - MAIN_FILE_IDX is the file index the .debug_line and .debug_macro sections +# will use to refer to the main file. +# - DIRECTORIES is a list of directories to put in the .debug_line section +# header +# - FILE_NAMES is a list of {name, directory index} pairs describing the files +# names to put in the .debug_line section header. + +proc do_test { test_name lines_version DW_AT_name main_file_idx directories + file_names } { + with_test_prefix "test_name=$test_name" { + foreach_with_prefix is_64 {true false} { + # So we can access them in Dwarf::assemble... + set ::lines_version $lines_version + set ::DW_AT_name $DW_AT_name + set ::main_file_idx $main_file_idx + set ::directories $directories + set ::file_names $file_names + set ::is_64 $is_64 + set 32_or_64 [expr $is_64 ? 64 : 32] + + set asm_file [standard_output_file ${::testfile}-${test_name}-${32_or_64}.S] + Dwarf::assemble $asm_file { + declare_labels Llines cu_macros + + # DW_AT_comp_dir is always the current working directory + # from which the compiler was invoked. We pretend the compiler was + # always launched from /tmp/cwd. + set comp_dir "/tmp/cwd" + + cu {} { + DW_TAG_compile_unit { + {DW_AT_producer "My C Compiler"} + {DW_AT_language @DW_LANG_C11} + {DW_AT_name $::DW_AT_name} + {DW_AT_comp_dir $comp_dir} + {DW_AT_stmt_list $Llines DW_FORM_sec_offset} + {DW_AT_macros $cu_macros DW_FORM_sec_offset} + } { + declare_labels int_type + + int_type: DW_TAG_base_type { + {DW_AT_byte_size 4 DW_FORM_sdata} + {DW_AT_encoding @DW_ATE_signed} + {DW_AT_name int} + } + + DW_TAG_subprogram { + {MACRO_AT_func {main}} + {type :$int_type} + } + } + } + + # Define the .debug_line section. + lines [list version $::lines_version] "Llines" { + foreach directory $::directories { + include_dir $directory + } + + foreach file_name $::file_names { + lassign $file_name name dir_index + file_name $name $dir_index + } + + # A line number program just good enough so that GDB can + # figure out we are stopped in main. + program { + DW_LNS_set_file $::main_file_idx + DW_LNE_set_address $::main_start + line 10 + DW_LNS_copy + + DW_LNE_set_address "$::main_start + $::main_len" + DW_LNE_end_sequence + } + } + + # Define the .debug_macro section. + macro { + cu_macros: unit { + "debug-line-offset-label" $Llines + "is-64" $::is_64 + } { + # A macro defined outside the main file, as if it was defined + # on the command line with -D. + # + # Clang has this bug where it puts the macros defined on + # the command-line after the main file portion (see + # PR 29034). We're not trying to replicate that here, + # this is not in the scope of this test. + define 0 "ONE 1" + start_file 0 $::main_file_idx + # A macro defined at line 1 of the main file. + define 1 "TWO 2" + end_file + } + } + } + + if { [prepare_for_testing "failed to prepare" ${::testfile}-${test_name}-${32_or_64} \ + [list $::srcfile $asm_file] {nodebug}] } { + return + } + + if ![runto_main] { + return + } + + gdb_test "print ONE" " = 1" + gdb_test "print TWO" " = 2" + } + } +} + +# When adding a test here, please consider adding an equivalent case to the test +# of the same name in gdb.base. + +# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`, +# gcc 11 paired with gas from binutils 2.38. + +## test.c +do_test gcc11-ld238-dw5-filename 5 "test.c" 1 { + "/tmp/cwd" +} { + {"test.c" 0} + {"test.c" 0} +} + +## ./test.c +do_test gcc11-ld238-dw5-dot-filename 5 "./test.c" 1 { + "/tmp/cwd" + "." +} { + {"test.c" 1} + {"test.c" 1} +} + +## ../cwd/test.c +do_test gcc11-ld238-dw5-dot-dot-cwd 5 "../cwd/test.c" 1 { + "/tmp/cwd" + "../cwd" +} { + {"test.c" 1} + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test gcc11-ld238-dw5-absolute-cwd 5 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" + "/tmp/cwd" +} { + {"test.c" 1} + {"test.c" 0} +} + +## ../other/test.c +do_test gcc11-ld238-dw5-dot-dot-other 5 "../other/test.c" 1 { + "/tmp/cwd" + "../other" +} { + {"test.c" 1} + {"test.c" 1} +} + +## /tmp/other/test.c +do_test gcc11-ld238-dw5-absolute-other 5 "/tmp/other/test.c" 1 { + "/tmp/cwd" + "/tmp/other" +} { + {"test.c" 1} + {"test.c" 1} +} + +# The following tests are based on the output of `gcc -gdwarf-4 -g3 <file>`, +# gcc 11 paired with gas from binutils 2.38. With -gdwarf-4, gcc generates a +# v4 (pre-standard) .debug_macro section. + +## test.c +do_test gcc11-ld238-dw4-filename 4 "test.c" 1 { +} { + {"test.c" 0} +} + +## ./test.c +do_test gcc11-ld238-dw4-dot-filename 4 "./test.c" 1 { + "." +} { + {"test.c" 1} +} + +## ../cwd/test.c +do_test gcc11-ld238-dw4-dot-dot-cwd 4 "../cwd/test.c" 1 { + "../cwd" +} { + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test gcc11-ld238-dw4-absolute-cwd 4 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" +} { + {"test.c" 1} +} + +## ../other/test.c +do_test gcc11-ld238-dw4-dot-dot-other 4 "../other/test.c" 1 { + "../other" +} { + {"test.c" 1} +} + +## /tmp/other/test.c +do_test gcc11-ld238-dw4-absolute-other 4 "/tmp/other/test.c" 1 { + "/tmp/other" +} { + {"test.c" 1} +} + +# The following tests are based on the output of `clang-14 -gdwarf-5 +# -fdebug-macro -g3 <file>` (using its built-in assembler) + +## test.c +do_test clang14-dw5-filename 5 "test.c" 0 { + "/tmp/cwd" +} { + {"test.c" 0} +} + +## ./test.c +do_test clang14-dw5-dot-filename 5 "test.c" 1 { + "/tmp/cwd" + "." +} { + {"test.c" 0} + {"test.c" 1} +} + +## ../cwd/test.c +do_test clang14-dw5-dot-dot-cwd 5 "../cwd/test.c" 0 { + "/tmp/cwd" +} { + {"../cwd/test.c" 0} +} + +## /tmp/cwd/test.c +do_test clang14-dw5-absolute-cwd 5 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" +} { + {"/tmp/cwd/test.c" 0} + {"test.c" 0} +} + +## ../other/test.c +do_test clang14-dw5-dot-dot-other 5 "../other/test.c" 0 { + "/tmp/cwd" +} { + {"../other/test.c" 0} +} + +## /tmp/other/test.c +do_test clang14-dw5-absolute-other 5 "/tmp/other/test.c" 1 { + "/tmp/cwd" + "/tmp" +} { + {"/tmp/other/test.c" 0} + {"other/test.c" 1} +} + +# The following tests are based on the output of `clang-14 -gdwarf-4 +# -fdebug-macro -g3 <file>` (using its built-in assembler). With -gdwarf-4, +# clang produces a .debug_macinfo section, not a .debug_macro section. But +# this test still creates a .debug_macro section, that's good enough for what +# we want to test. + +## test.c +do_test clang14-dw4-filename 4 "test.c" 1 { +} { + {"test.c" 0} +} + +## ./test.c +do_test clang14-dw4-dot-filename 4 "test.c" 1 { + "." +} { + {"test.c" 1} +} + +## ../cwd/test.c +do_test clang14-dw4-dot-dot-cwd 4 "../cwd/test.c" 1 { + "../cwd" +} { + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test clang14-dw4-absolute-cwd 4 "/tmp/cwd/test.c" 1 { +} { + {"test.c" 0} +} + +## ../other/test.c +do_test clang14-dw4-dot-dot-other 4 "../other/test.c" 1 { + "../other" +} { + {"test.c" 1} +} + +## /tmp/other/test.c +do_test clang14-dw4-absolute-other 4 "/tmp/other/test.c" 1 { + "/tmp" +} { + {"other/test.c" 1} +} + +# The following tests are based on the output of `gcc -gdwarf-5 -g3 <file>`, +# gcc 11 paired with gas from binutils 2.34 (Ubuntu 20.04). It generates a v5 +# .debug_macro section, but a v3 .debug_line section. + +## test.c +do_test gcc11-ld234-dw5-filename 3 "test.c" 1 { +} { + {"test.c" 0} +} + +## ./test.c +do_test gcc11-ld234-dw5-dot-filename 3 "./test.c" 1 { + "." +} { + {"test.c" 1} +} + +## ../cwd/test.c +do_test gcc11-ld234-dw5-dot-dot-cwd 3 "../cwd/test.c" 1 { + "../cwd" +} { + {"test.c" 1} +} + +## /tmp/cwd/test.c +do_test gcc11-ld234-dw5-absolute-cwd 3 "/tmp/cwd/test.c" 1 { + "/tmp/cwd" +} { + {"test.c" 1} +} + +## ../other/test.c +do_test gcc11-ld234-dw5-dot-dot-other 3 "../other/test.c" 1 { + "../other" +} { + {"test.c" 1} +} + +## /tmp/other/test.c +do_test gcc11-ld234-dw5-absolute-other 3 "/tmp/other/test.c" 1 { + "/tmp/other" +} { + {"test.c" 1} +} diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 3d0ea83..356451b 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -2144,6 +2144,98 @@ namespace eval Dwarf { incr _debug_loclists_locdesc_count } + # Emit a DWARF .debug_macro section. + # + # BODY must be Tcl code that emits the content of the section. It is + # evaluated in the caller's context. The body can use the `unit` proc + # (see `_macro_unit`) to generate macro units. + + proc macro { body } { + _section ".debug_macro" + + with_override Dwarf::unit Dwarf::_macro_unit { + uplevel $body + } + } + + # Generate one macro unit. + # + # This proc is meant to be used within proc macro's body. It is made + # available as `unit` while inside proc macro's body. + # + # BODY must be Tcl code that emits the content of the unit. It may call + # procedures defined below, prefixed with `_macro_unit_`, to generate the + # unit's content. It is evaluated in the caller's context. + # + # The `is-64 true|false` options tells whether to use 64-bit DWARF instead + # of 32-bit DWARF. The default is 32-bit. + # + # If specified, the `debug-line-offset-label` option is the name of a label + # to use for the unit header's `debug_line_offset` field value. If + # omitted, the unit header will not contain the `debug_line_offset` field. + + proc _macro_unit { options body } { + parse_options { + {"is-64" "false"} + {"debug-line-offset-label" ""} + } + + _op .2byte 5 "version" + + # Flags: + # + # offset_size_flag = set if is-64 is true + # debug_line_offset_flag = set if debug-line-offset-label is set + # opcode_operands_table_flag = 0 + set flags 0 + + if { ${is-64} } { + set flags [expr $flags | 0x1] + } + + if { ${debug-line-offset-label} != "" } { + set flags [expr $flags | 0x2] + } + + _op .byte $flags "flags" + + if { ${debug-line-offset-label} != "" } { + if { ${is-64} } { + _op .8byte ${debug-line-offset-label} "debug_line offset" + } else { + _op .4byte ${debug-line-offset-label} "debug_line offset" + } + } + + with_override Dwarf::define Dwarf::_macro_unit_define { + with_override Dwarf::start_file Dwarf::_macro_unit_start_file { + with_override Dwarf::end_file Dwarf::_macro_unit_end_file { + uplevel $body + }}} + } + + # Emit a DW_MACRO_define entry. + + proc _macro_unit_define { lineno text } { + _op .byte 0x1 "DW_MACRO_define" + _op .uleb128 $lineno "Line number" + _op .asciz "\"$text\"" "Macro definition" + } + + # Emit a DW_MACRO_start_file entry. + + proc _macro_unit_start_file { lineno file_idx } { + _op .byte 0x3 "DW_MACRO_start_file" + _op .uleb128 $lineno + _op .uleb128 $file_idx + } + + # Emit a DW_MACRO_end_file entry. + + proc _macro_unit_end_file {} { + _op .byte 0x4 "DW_MACRO_end_file" + } + # Emit a DWARF .debug_line unit. # OPTIONS is a list with an even number of elements containing # option-name and option-value pairs. |