1# Expect script for LD selective linking tests
2#   Copyright (C) 1998-2014 Free Software Foundation, Inc.
3#
4# This file is part of the GNU Binutils.
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19# MA 02110-1301, USA.
20#
21# Written by Catherine Moore (clm@cygnus.com)
22# Make sure that constructors are handled correctly.
23
24# Only ELF based ports support selective linking
25if { ![is_elf_format] || ![check_gc_sections_available] } {
26    return
27}
28
29# List contains test-items with three items followed by four lists:
30# 1:name 2:test-type (CC or C++; add as needed) 3:filename 4:ld-flags
31# 5:must-have-symbols 6:must-not-have-symbols 7:xfail-targets.
32#
33# If a must(-not)-have symbol is a list, then that list must have two
34# items; the symbol name and a value the symbol must (not) have.
35#
36# Note: ld_nm trims leading `_' from _start
37#
38# FIXME: Instead of table, read settings from each source-file.
39set seltests {
40  {selective1 C   1.c  {}       {}    {dropme1 dropme2} {}}
41  {selective2 C   2.c  {}       {}    {foo} {}}
42  {selective3 C   2.c  {-u foo} {foo} {{foo 0}} {}}
43  {selective4 C++ 3.cc {}       {start a A::foo() B::foo()} {A::bar()} {mips*-*}}
44  {selective5 C++ 4.cc {}       {start a A::bar()} {A::foo() B::foo()} {mips*-*}}
45  {selective6 C++ 5.cc {}       {start a A::bar()}
46    {A::foo() B::foo() dropme1() dropme2()} {*-*-*}}
47}
48
49set cflags "-w -O -ffunction-sections -fdata-sections"
50set cxxflags "-fno-exceptions -fno-rtti"
51set ldflags "--gc-sections -Bstatic"
52
53if [istarget mips*-*] {
54    # MIPS16 doesn't support PIC code.
55    set cflags "-mno-abicalls $cflags"
56    # MIPS ELF uses __start by default, we override it.
57    set ldflags "-e _start $ldflags"
58}
59
60if [istarget sh64*-*-elf] {
61    # This is what gcc passes to ld by default, plus switch to the
62    # "usual" ELF _start (shelf32 normally uses just `start' for COFF
63    # compatibility)
64    set ldflags "-e _start -mshelf32 $ldflags"
65}
66
67# If we don't have g++ for the target, mark all tests as untested.
68if { ![is_remote host] && [which $CXX] == 0 } {
69    foreach testitem $seltests {
70	untested "[lindex $testitem 0]"
71    }
72    return
73}
74
75foreach testitem $seltests {
76    set testname [lindex $testitem 0]
77    set testtype [lindex $testitem 1]
78    set testfile [lindex $testitem 2]
79    set objfile "tmpdir/[file rootname $testfile].o"
80    set ldfile "tmpdir/[file rootname $testfile].x"
81    set failed 0
82
83    set ldargs [lindex $testitem 3]
84    set mustsyms [lindex $testitem 4]
85    set mustnotsyms [lindex $testitem 5]
86    set xfails [lindex $testitem 6]
87
88    foreach xfail_target $xfails {
89	setup_xfail $xfail_target
90    }
91
92    # It's either C or C++ at the moment.
93    if { $testtype == "C++" } {
94	set compiler "$CXX"
95	# Starting with 3.4.0, -fvtable-gc is no longer supported and thus
96	# the functionality we try to test for cannot be expected to work.
97	set version [remote_exec host "$CXX -dumpversion"]
98	set version [lindex $version 1]
99	if [regexp "^(\[1-9\]\[0-9\]+|\[4-9\]|3.(\[1-9\]\[0-9\]+|\[4-9\]))\\." $version] {
100	    set testflags "$cflags $cxxflags"
101	    setup_xfail {*-*-*}
102	} else {
103	    set testflags "$cflags $cxxflags -fvtable-gc"
104	}
105    } else {
106	set testflags "$cflags"
107	set compiler "$CC"
108    }
109
110    # Note that we do not actually *use* CXX; we just add cxxflags for C++
111    # tests.  It might have been a buglet originally; now I think better
112    # leave as is.
113    if { ![ld_compile "$compiler $testflags" $srcdir/$subdir/$testfile $objfile] } {
114	unresolved $testname
115	continue
116    }
117
118    # V850 targets need libgcc.a
119    if [istarget v850*-*-elf] {
120	set libgcc [remote_exec host "$compiler -print-libgcc-file-name"]
121	set libgcc [lindex $libgcc 1]
122	regsub -all "\[\r\n\]" $libgcc "" libgcc
123	set objfile "$objfile $libgcc"
124    }
125
126    # ARM targets need libgcc.a in THUMB mode so that __call_via_r3 is provided
127    if {[istarget arm-*-*]} {
128	set libgcc [remote_exec host "$compiler -print-libgcc-file-name"]
129	set libgcc [lindex $libgcc 1]
130	regsub -all "\[\r\n\]" $libgcc "" libgcc
131	set objfile "$objfile $libgcc"
132    }
133
134    # HPPA linux targets need libgcc.a for millicode routines ($$dyncall).
135    if [istarget hppa*-*-linux*] {
136	set libgcc [remote_exec host "$compiler -print-libgcc-file-name"]
137	set libgcc [lindex $libgcc 1]
138	regsub -all "\[\r\n\]" $libgcc "" libgcc
139	set objfile "$objfile $libgcc"
140    }
141
142    # m6811/m6812 code has references to soft registers.
143    if {[istarget m6811-*-*] || [istarget m6812-*-*] || [istarget m68hc1*-*-*]} {
144	set objfile "$objfile --defsym _.frame=0 --defsym _.d1=0"
145	set objfile "$objfile --defsym _.d2=0"
146    }
147
148    if ![ld_simple_link $ld $ldfile "$ldflags [join $ldargs] $objfile"] {
149	fail $testname
150	continue
151    }
152
153    if ![ld_nm $nm --demangle $ldfile] {
154	unresolved $testname
155	continue
156    }
157
158    # Must make V2 demangled names look like V3
159    foreach nm_output_key [array names nm_output] {
160	if [regsub \\(void\\) $nm_output_key () new_nm_output_key] {
161	    set nm_output($new_nm_output_key) nm_output($nm_output_key)
162	}
163    }
164
165    # Check each mandated symbol and optionally mandated values.
166    foreach mustsym $mustsyms {
167	if { [llength [concat $mustsym]] == 1 } {
168	    if { ![info exists nm_output($mustsym)] } {
169		verbose -log "$testname: missing $mustsym"
170		fail $testname
171		set failed 1
172		break
173	    }
174	} {
175	    set mustsymname [lindex $mustsym 0]
176	    set mustsymvalue [lindex $mustsym 1]
177	    if { ![info exists nm_output($mustsymname)] } {
178		verbose -log "$testname: missing $mustsymname"
179		fail $testname
180		set failed 1
181		break
182	    } {
183		if { $nm_output($mustsymname) != $mustsymvalue } {
184		    verbose -log "$testname: $mustsymname != $mustsymvalue"
185		    verbose -log "is instead $nm_output($mustsymname)"
186		    fail $testname
187		    set failed 1
188		    break
189		}
190	    }
191	}
192    }
193
194    if { $failed != 0 } {
195	continue
196    }
197
198    # Check each unwanted symbol, or that symbols do not have specific
199    # values.
200    foreach mustnotsym $mustnotsyms {
201	if { [llength [concat $mustnotsym]] == 1 } {
202	    if { [info exists nm_output($mustnotsym)] } {
203		verbose -log "$testname: $mustnotsym == $nm_output($mustnotsym)"
204		fail $testname
205		set failed 1
206		break
207	    }
208	} {
209	    set mustnotsymname [lindex $mustnotsym 0]
210	    set mustnotsymvalue [lindex $mustnotsym 1]
211	    if { [info exists nm_output($mustnotsymname)] \
212		    && $nm_output($mustnotsymname) == $mustnotsymvalue} {
213		verbose -log "$testname: $mustnotsymname == $mustnotsymvalue"
214		fail $testname
215		set failed 1
216		break
217	    }
218	}
219    }
220
221    if { $failed == 0 } {
222	pass $testname
223    }
224}
225