1# Copyright 2013-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
16load_lib dwarf.exp
17
18# This test can only be run on targets which support DWARF-2 and use gas.
19if {![dwarf2_support]} {
20    return 0
21}
22
23# No remote host testing either.
24if {[is_remote host]} {
25    return 0
26}
27
28
29# Lots of source files since we test a few cases and make new files
30# for each.
31# The tests are:
32#     ok - the main file refers to a dwz and the buildids match
33#     mismatch - the buildids do not match
34#     fallback - the buildids do not match but a match is found via buildid
35standard_testfile main.c \
36    dwzbuildid-ok-base.S dwzbuildid-ok-sep.S \
37    dwzbuildid-mismatch-base.S dwzbuildid-mismatch-sep.S \
38    dwzbuildid-fallback-base.S dwzbuildid-fallback-sep.S \
39    dwzbuildid-fallback-ok.S
40
41# Write some assembly that just has a .gnu_debugaltlink section.
42proc write_just_debugaltlink {filename dwzname buildid} {
43    set asm_file [standard_output_file $filename]
44
45    Dwarf::assemble $asm_file {
46	upvar dwzname dwzname
47	upvar buildid buildid
48
49	gnu_debugaltlink $dwzname $buildid
50
51	# Only the DWARF reader checks .gnu_debugaltlink, so make sure
52	# there is a bit of DWARF in here.
53	cu {} {
54	    compile_unit {{language @DW_LANG_C}} {
55	    }
56	}
57    }
58}
59
60# Write some DWARF that also sets the buildid.
61proc write_dwarf_file {filename buildid {value 99}} {
62    set asm_file [standard_output_file $filename]
63
64    Dwarf::assemble $asm_file {
65	declare_labels int_label int_label2
66
67	upvar buildid buildid
68	upvar value value
69
70	build_id $buildid
71
72	cu {} {
73	    compile_unit {{language @DW_LANG_C}} {
74		int_label2: base_type {
75		    {name int}
76		    {byte_size 4 sdata}
77		    {encoding @DW_ATE_signed}
78		}
79
80		constant {
81		    {name the_int}
82		    {type :$int_label2}
83		    {const_value $value data1}
84		}
85	    }
86	}
87    }
88}
89
90if  { [gdb_compile ${srcdir}/${subdir}/${srcfile} ${binfile}1.o \
91	   object {nodebug}] != "" } {
92    return -1
93}
94
95# The values don't really matter, just whether they are equal.
96set ok_prefix 01
97set ok_suffix 0203040506
98set ok_suffix2 02030405ff
99set ok_buildid ${ok_prefix}${ok_suffix}
100set ok_buildid2 ${ok_prefix}${ok_suffix2}
101set bad_buildid ffffffffffff
102
103set debugdir [standard_output_file {}]
104set basedir $debugdir/.build-id
105file mkdir $basedir $basedir/$ok_prefix
106
107# Test where the separate debuginfo's buildid matches.
108write_just_debugaltlink $srcfile2 ${binfile}3.o $ok_buildid
109write_dwarf_file $srcfile3 $ok_buildid
110
111# Test where the separate debuginfo's buildid does not match.
112write_just_debugaltlink $srcfile4 ${binfile}5.o $ok_buildid
113write_dwarf_file $srcfile5 $bad_buildid
114
115# Test where the separate debuginfo's buildid does not match, but then
116# we find a match in the .build-id directory.
117write_just_debugaltlink $srcfile6 ${binfile}7.o $ok_buildid2
118# Use 77 as the value so that if we load the bad debuginfo, we will
119# see the wrong result.
120write_dwarf_file $srcfile7 $bad_buildid 77
121write_dwarf_file $srcfile8 $ok_buildid2
122
123# Compile everything.
124for {set i 2} {$i <= 8} {incr i} {
125    if {[gdb_compile [standard_output_file [set srcfile$i]] \
126	     ${binfile}$i.o object nodebug] != ""} {
127	return -1
128    }
129}
130
131# Copy a file into the .build-id place for the "fallback" test.
132file copy -force -- ${binfile}8.o $basedir/$ok_prefix/$ok_suffix2.debug
133
134# Link the executables.
135if {[gdb_compile [list ${binfile}1.o ${binfile}2.o] ${binfile}-ok \
136	 executable {}] != ""} {
137    return -1
138}
139
140if {[gdb_compile [list ${binfile}1.o ${binfile}4.o] ${binfile}-mismatch \
141	 executable {quiet}] != ""} {
142    return -1
143}
144
145if {[gdb_compile [list ${binfile}1.o ${binfile}6.o] ${binfile}-fallback \
146	 executable {}] != ""} {
147    return -1
148}
149
150
151foreach testname {ok mismatch fallback} {
152    with_test_prefix $testname {
153	gdb_exit
154	gdb_start
155	gdb_reinitialize_dir $srcdir/$subdir
156
157	gdb_test_no_output "set debug-file-directory $debugdir" \
158	    "set debug-file-directory"
159
160	gdb_load ${binfile}-${testname}
161
162	if {[runto_main]} {
163	    if {$testname == "mismatch"} {
164		gdb_test "print the_int" \
165		    "(No symbol table is loaded|No symbol \"the_int\" in current context).*"
166	    } else {
167		gdb_test "print the_int" " = 99"
168	    }
169	}
170    }
171}
172