gdb/riscv: Add command to switch between numeric & abi register names
[binutils-gdb.git] / gdb / testsuite / gdb.base / corefile-buildid.exp
blob377ae802239a7d28bd9d47bf840c03bc42b332da
1 # Copyright 2019-2024 Free Software Foundation, Inc.
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.
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.
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/>.
16 # Based on break.exp, written by Rob Savoye. (rob@cygnus.com)
17 # Modified to test gdb's handling of separate debug info files.
18 # Modified to test gdb's handling of a debug-id retrieval.
20 # Build-id-related tests for core files.
22 standard_testfile .c -shlib-shr.c -shlib.c
24 # Create a corefile from PROGNAME.  Return the name of the generated
25 # corefile, or the empty string if anything goes wrong.
27 # The generated corefile must contain a buildid for PROGNAME.  If it
28 # doesn't then an empty string will be returned.
29 proc create_core_file { progname } {
30     # Generate a corefile.
31     set corefile [core_find $progname]
32     if {$corefile == ""} {
33         untested "could not generate core file"
34         return ""
35     }
36     verbose -log "corefile is $corefile"
38     # Check the corefile has a build-id for the executable.
39     if { [catch "exec [gdb_find_eu-unstrip] -n --core $corefile" output] == 0 } {
40         set line [lindex [split $output "\n"] 0]
41         set binfile_re (?:[string_to_regexp $progname]|\\\[(?:exe|pie)\\\])
42         if { ![regexp "^${::hex}\\+${::hex} \[a-f0-9\]+@${::hex}.*$binfile_re$" $line] } {
43             unsupported "no build-id for executable in corefile"
44             return ""
45         }
46     } else {
47         unsupported "eu-unstrip tool failed"
48         return ""
49     }
51     return $corefile
55 # Build a non-shared executable.
57 proc build_corefile_buildid_exec { progname } {
58     return [expr {[build_executable "build non-shared exec" $progname $::srcfile] != -1}]
61 # Build a shared executable.
63 proc build_corefile_buildid_shared { progname } {
64     # Compile DSO.
65     set objdso [standard_output_file $::testfile-shlib-shr.so]
66     if {[build_executable "build dso" $objdso $::srcfile2 {debug shlib}] == -1} {
67         return false
68     }
71     # Compile shared library.
72     set srclib $::srcfile3
73     set libname lib$::testfile.so
74     set objlib [standard_output_file $libname]
75     set dlopen_lib [shlib_target_file $objdso]
76     set opts [list debug shlib_load shlib \
77                   additional_flags=-DSHLIB_NAME=\"$dlopen_lib\"]
78     if {[build_executable "build solib" $objlib $::srcfile3 $opts] == -1} {
79         return false
80     }
82     # Compile main program.
83     set opts [list debug shlib=$objlib additional_flags=-DTEST_SHARED]
84     if {[build_executable "build shared exec" $progname $::srcfile $opts] == -1} {
85         return false
86     }
88     return true
91 # Append DEBUGDIR to the debug-file-directory path.
93 proc append_debug_dir {debugdir} {
94     global gdb_prompt
96     set orig_debugdir {}
97     gdb_test_multiple "show debug-file-directory" \
98         "get debug-file-directory" {
99             -re "The directory where separate debug symbols are searched for is \"(.*)\"\.\[\r\n\]+$gdb_prompt $" {
100                 set orig_debugdir $expect_out(1,string)
101                 pass "get debug-file-directory"
102             }
103         }
104     gdb_test_no_output "set debug-file-directory $debugdir:$orig_debugdir" \
105         "append debug directory"
108 # A convenience procedure to check if "info files" mentions the exec file
109 # FILE.
111 proc check_exec_file {file} {
112     global gdb_prompt
113     send_log "expecting exec file \"$file\"\n"
115     # Get line with "Local exec file:".
116     set ok 0
117     gdb_test_multiple "info files" "" -lbl {
118         -re "\r\nLocal exec file:" {
119             set test_name $gdb_test_name
120             set ok 1
121         }
122     }
124     if { $ok == 0 } {
125         return
126     }
128     # Get subsequent line with $file.
129     set ok 0
130     gdb_test_multiple "" $test_name -lbl {
131         -re "\r\n\[\t\ \]+`[string_to_regexp $file]'\[^\r\n\]*" {
132             set ok 1
133         }
134     }
136     if { $ok == 0 } {
137         return
138     }
140     # Skip till prompt.
141     gdb_test_multiple "" $test_name -lbl {
142         -re "\r\n$gdb_prompt $" {
143             pass $gdb_test_name
144         }
145     }
148 # Test whether gdb can find an exec file from a core file's build-id.
149 # The executable (and separate debuginfo if SEPDEBUG is true) is
150 # copied to the .build-id directory.
152 # SUFFIX is appended to the .builid-id parent directory name to
153 # keep all tests separate.
154 # SYMLINK specifies whether build-id files should be copied or symlinked.
155 # SHARED is a boolean indicating whether we are testing the shared
156 # library core dump test case.
158 proc locate_exec_from_core_build_id {corefile buildid \
159                                          dirname progname \
160                                          sepdebug symlink shared} {
161     clean_restart
163     # Set up the build-id directory and symlink the binary there.
164     set d "debugdir"
165     if {$shared} {
166         set d "${d}_shared"
167     } else {
168         set d "${d}_not-shared"
169     }
170     if {$symlink} {
171         set d "${d}_symlink"
172     } else {
173         set d "${d}_copy"
174     }
175     if {$sepdebug} {
176         set d "${d}_stripped"
177     } else {
178         set d "${d}_not-stripped"
179     }
181     set debugdir [standard_output_file $d]
182     remote_exec build \
183         "mkdir -p [file join $debugdir [file dirname $buildid]]"
185     set files_list {}
186     lappend files_list [file join $dirname [file tail $progname]] \
187         $buildid
188     if {$sepdebug} {
189         lappend files_list [file join $dirname [file tail $progname]].debug \
190             "$buildid.debug"
191     }
193     foreach {target name} $files_list {
194         set t [file join $dirname [file tail $target]]
195         if {$symlink} {
196             remote_exec build "ln -s $t [file join $debugdir $name]"
197         } else {
198             remote_exec build "cp $t [file join $debugdir $name]"
199         }
200     }
202     # Append the debugdir to the separate debug directory search path.
203     append_debug_dir $debugdir
205     gdb_test "core-file $corefile" "Program terminated with .*" \
206         "load core file"
207     if {$symlink} {
208         set expected_file [file join $dirname [file tail $progname]]
209     } else {
210         set expected_file $buildid
211     }
212     check_exec_file [file join $debugdir $expected_file]
215 foreach_with_prefix mode { exec shared } {
216     # Build the executable.
217     set progname ${binfile}-$mode
218     set build_proc build_corefile_buildid_${mode}
219     if { ![$build_proc $progname] } {
220         return -1
221     }
223     # Generate a corefile.
224     set corefile [create_core_file $progname]
225     if { $corefile eq "" } {
226         return -1
227     }
229     # Get the build-id filename without ".debug" on the end.  This
230     # will have the format: '.build-id/xx/xxxxx'
231     set buildid [build_id_debug_filename_get $progname ""]
232     if {$buildid == ""} {
233         untested "binary has no build-id"
234         return
235     }
236     verbose -log "build-id is $buildid"
238     # Create a directory for the non-stripped test.
239     set combined_dirname [standard_output_file ${mode}_non-stripped]
240     remote_exec build "mkdir -p $combined_dirname"
241     remote_exec build "cp $progname $combined_dirname"
243     # Create a directory for the stripped test.
244     if {[gdb_gnu_strip_debug [standard_output_file $progname] no-debuglink] != 0} {
245         untested "could not strip executable  for [join $suffix \ ]"
246         return
247     }
248     set sepdebug_dirname [standard_output_file ${mode}_stripped]
249     remote_exec build "mkdir -p $sepdebug_dirname"
250     remote_exec build "mv $progname $sepdebug_dirname"
251     remote_exec build "mv ${progname}.debug $sepdebug_dirname"
253     # Now do the actual testing part.  Fill out a debug directory with
254     # build-id related files (copies or symlinks) and then load the
255     # corefile.  Check GDB finds the executable and debug information
256     # via the build-id related debug directory contents.
257     foreach_with_prefix sepdebug { false true } {
258         if { $sepdebug } {
259             set dirname $sepdebug_dirname
260         } else {
261             set dirname $combined_dirname
262         }
264         foreach_with_prefix symlink { false true } {
265             locate_exec_from_core_build_id $corefile $buildid \
266                 $dirname $progname \
267                 $sepdebug $symlink [expr {$mode eq "shared"}]
268         }
269     }