19990502 sourceware import
[external/binutils.git] / ld / testsuite / ld-shared / shared.exp
1 # Expect script for ld-shared tests
2 #   Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation
3 #
4 # This file is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
8
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 #
18 # Written by Ian Lance Taylor (ian@cygnus.com)
19 #
20
21 # Make sure that ld can generate ELF shared libraries.
22 # Note that linking against ELF shared libraries is tested by the
23 # bootstrap test.
24
25 # This test can only be run if ld generates native executables.
26 if ![isnative] then {return}
27
28 # This test can only be run on a couple of ELF platforms.
29 # Square bracket expressions seem to confuse istarget.
30 if { ![istarget i386-*-sysv4*] \
31      && ![istarget i486-*-sysv4*] \
32      && ![istarget i586-*-sysv4*] \
33      && ![istarget i386-*-unixware] \
34      && ![istarget i486-*-unixware] \
35      && ![istarget i586-*-unixware] \
36      && ![istarget i386-*-elf*] \
37      && ![istarget i486-*-elf*] \
38      && ![istarget i586-*-elf*] \
39      && ![istarget i386-*-linux*] \
40      && ![istarget i486-*-linux*] \
41      && ![istarget i586-*-linux*] \
42      && ![istarget m68k-*-linux*] \
43      && ![istarget mips*-*-irix5*] \
44      && ![istarget powerpc-*-elf*] \
45      && ![istarget powerpc-*-linux*] \
46      && ![istarget powerpc-*-sysv4*] \
47      && ![istarget sparc*-*-elf] \
48      && ![istarget sparc*-*-solaris2*] \
49      && ![istarget sparc*-*-sunos4*] \
50      && ![istarget rs6000*-*-aix*] \
51      && ![istarget powerpc*-*-aix*] } {
52     return
53 }
54
55 if { [istarget i386-*-linuxaout*] \
56      || [istarget i486-*-linuxaout*] \
57      || [istarget i586-*-linuxaout*] \
58      || [istarget i386-*-linuxoldld*] \
59      || [istarget i486-*-linuxoldld*] \
60      || [istarget i586-*-linuxoldld*] \
61      || [istarget m68k-*-linuxaout*] } {
62     return
63 }
64
65 set tmpdir tmpdir
66 set SHCFLAG ""
67
68 if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
69
70     # AIX shared libraries do not seem to support useful features,
71     # like overriding the shared library function or letting the
72     # shared library refer to objects defined in the main program.  We
73     # avoid testing those features.
74     set SHCFLAG "-DXCOFF_TEST"
75
76     # The AIX 3.2.5 loader appears to randomly fail when loading
77     # shared libraries from NSF mounted partitions, so we avoid any
78     # potential problems by using a local directory.
79     catch {exec /bin/sh -c "echo $$"} pid
80     set tmpdir /usr/tmp/ld.$pid
81     catch "exec mkdir $tmpdir" exec_status
82
83     # On AIX, we need to explicitly export the symbols the shared
84     # library is going to provide, and need.
85     set file [open $tmpdir/xcoff.exp w]
86     puts $file shlibvar1
87     puts $file shlibvar2
88     puts $file shlib_shlibvar1
89     puts $file shlib_shlibvar2
90     puts $file shlib_shlibcall
91     puts $file shlib_shlibcalled
92     puts $file shlib_checkfunptr1
93     puts $file shlib_getfunptr1
94     puts $file shlib_check
95     close $file
96 }
97
98 # The test procedure.
99 proc shared_test { progname testname main sh1 sh2 dat args } {
100     global ld
101     global srcdir
102     global subdir
103     global exec_output
104     global host_triplet
105     global tmpdir
106
107     if [llength $args] { set shldflags [lindex $args 0] } else { set shldflags "" }
108
109     # Build the shared library.
110     # On AIX, we need to use an export file.
111     set shared -shared
112     if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
113         set shared "-bM:SRE -bE:$tmpdir/xcoff.exp"
114     }
115     if {![ld_simple_link $ld $tmpdir/$progname.so "$shared $shldflags $tmpdir/$sh1 $tmpdir/$sh2"]} {
116         fail "$testname"
117         return
118     }
119
120     # Link against the shared library.  Use -rpath so that the
121     # dynamic linker can locate the shared library at runtime.
122     # On AIX, we must include /lib in -rpath, as otherwise the loader
123     # can not find -lc.
124     set rpath $tmpdir
125     if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
126         set rpath /lib:$tmpdir
127     }
128     if ![ld_link $ld $tmpdir/$progname "-rpath $rpath $tmpdir/$main $tmpdir/$progname.so"] {
129         fail "$testname"
130         return
131     }
132
133     # Run the resulting program
134     send_log "$tmpdir/$progname >$tmpdir/$progname.out\n"
135     verbose "$tmpdir/$progname >$tmpdir/$progname.out"
136     catch "exec $tmpdir/$progname >$tmpdir/$progname.out" exec_output
137     if ![string match "" $exec_output] then {
138         send_log "$exec_output\n"
139         verbose "$exec_output"
140         fail "$testname"
141         return
142     }
143
144     send_log "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat\n"
145     verbose "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat"
146     catch "exec diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat" exec_output
147     set exec_output [prune_warnings $exec_output]
148
149     if {![string match "" $exec_output]} then {
150         send_log "$exec_output\n"
151         verbose "$exec_output"
152         fail "$testname"
153         return
154     }
155
156     pass "$testname"
157 }
158
159 if [istarget mips*-*-*] {
160     set picflag ""
161 } else {
162     # Unfortunately, the gcc argument is -fpic and the cc argument is
163     # -KPIC.  We have to try both.
164     set picflag "-fpic"
165     send_log "$CC $picflag\n"
166     verbose "$CC $picflag"
167     catch "exec $CC $picflag" exec_output
168     send_log "$exec_output\n"
169     verbose "--" "$exec_output"
170     if { [string match "*illegal option*" $exec_output] \
171          || [string match "*option ignored*" $exec_output] \
172          || [string match "*unrecognized option*" $exec_output] \
173          || [string match "*passed to ld*" $exec_output] } {
174         if [istarget *-*-sunos4*] {
175             set picflag "-pic"
176         } else {
177             set picflag "-KPIC"
178         }
179     }
180 }
181 verbose "Using $picflag to compile PIC code"
182
183 # Compile the main program.
184 if ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] {
185     unresolved "shared (non PIC)"
186     unresolved "shared"
187 } else {
188     # The shared library is composed of two files.  First compile them
189     # without using -fpic.  That should work on an ELF system,
190     # although it will be less efficient because the dynamic linker
191     # will need to do more relocation work.  However, note that not
192     # using -fpic will cause some of the tests to return different
193     # results.
194     if { ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/sh1.c $tmpdir/sh1np.o]
195          || ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/sh2.c $tmpdir/sh2np.o] } {
196         unresolved "shared (non PIC)"
197     } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
198         shared_test shnp "shared (nonPIC)" mainnp.o sh1np.o sh2np.o xcoff
199     } else {
200         # SunOS non PIC shared libraries don't permit some cases of
201         # overriding.
202         setup_xfail "*-*-sunos4*"
203         shared_test shnp "shared (non PIC)" mainnp.o sh1np.o sh2np.o shared
204
205         # Test ELF shared library relocations with a non-zero load
206         # address for the library.  Near as I can tell, the R_*_RELATIVE
207         # relocations for various targets are broken in the case where
208         # the load address is not zero (which is the default).
209         setup_xfail "*-*-sunos4*"
210         shared_test shnp "shared (non PIC, load offset)" \
211                 mainnp.o sh1np.o sh2np.o shared \
212                 "-T $srcdir/$subdir/elf-offset.ld"
213     } }
214
215     # Now compile the code using -fpic.
216
217     if { ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh1.c $tmpdir/sh1p.o] 
218          || ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh2.c $tmpdir/sh2p.o] } {
219         unresolved "shared"
220     } else {
221         # SunOS can not compare function pointers correctly
222         if [istarget "*-*-sunos4*"] {
223             shared_test shp "shared" mainnp.o sh1p.o sh2p.o sun4
224         } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
225             shared_test shp "shared" mainnp.o sh1p.o sh2p.o xcoff
226         } else {
227             shared_test shp "shared" mainnp.o sh1p.o sh2p.o shared
228         } }
229     }
230 }
231
232 # Now do the same tests again, but this time compile main.c PIC.
233 if ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] {
234     unresolved "shared (PIC main, non PIC so)"
235     unresolved "shared (PIC main)"
236 } else {
237     if { [file exists $tmpdir/sh1np.o ] && [ file exists $tmpdir/sh2np.o ] } {
238         if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
239             shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o xcoff
240         } else {
241             # SunOS non PIC shared libraries don't permit some cases of
242             # overriding.
243             setup_xfail "*-*-sunos4*"
244             shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o shared
245         }
246     } else {
247         unresolved "shared (PIC main, non PIC so)"
248     }
249
250     if { [file exists $tmpdir/sh1p.o ] && [ file exists $tmpdir/sh2p.o ] } {
251         if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
252             shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o xcoff
253         } else {
254             shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o shared
255         }
256     } else {
257         unresolved "shared (PIC main)"
258     }
259 }
260
261 if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
262     # Remove the temporary directory.
263     catch "exec rm -rf $tmpdir" exec_status
264 }