1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# Expect script for ld-auto-import tests
# Copyright (C) 2002-2019 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# Written by Ralf.Habacker@freenet.de
# Based on ls-shared/shared.exp by Ian Lance Taylor (ian@cygnus.com)
#
# Note:
#
# This script tests some auto-import functionality:
#
# A. "auto importing direct from a dll" functionality, which dramatically reduces the
# linking time for big libraries and applications by skipping creating/using
# import libraries. Instead it links directly to the related dll or to a symlinked
# dll for replacing regular import libraries. The test has 6 stages:
#
# 1. compile and link a test dll exporting some text and data symbols and a
# standard import library
#
# 2. create a symbolic link to this dll to simulate a replaced import library.
#
# 3. compile and link a client application with the standard import library.
# This should produce no errors.
#
# 4. compile and link a client application with the created dll.
# This should also produce no errors.
#
# 5. compile and link a client application using the "import library".
# This should also produce no errors.
#
# 6. compile and link a client application with auto-import disabled.
# This should produce a linking error.
#
# B. runtime check if there are no segfaults when importing const data variables
#
# This test can only be run if ld generates native executables.
if ![isnative] then {return}
# This test can only be run on a couple of platforms.
# Square bracket expressions seem to confuse istarget.
if { ![istarget *-pc-cygwin]
&& ![istarget *-pc-mingw*] } {
return
}
if [istarget *-pc-mingw*] {
# FIXME: Add support for this target.
unsupported "mingw currently not supported"
}
# No compiler, no test.
if { ![check_compiler_available] } {
untested "Auto import test (compiler not found)"
return
}
# ld_special_link
# link a program using ld, without including any libraries
#
proc ld_special_link { ld target objects } {
global host_triplet
global link_output
if { [which $ld] == 0 } then {
perror "$ld does not exist"
return 0
}
if [is_endian_output_format $objects] then {
set flags [big_or_little_endian]
} else {
set flags ""
}
verbose -log "$ld $flags -o $target $objects"
catch "exec $ld $flags -o $target $objects" link_output
set exec_output [prune_warnings $link_output]
# We don't care if we get a warning about a non-existent start
# symbol, since the default linker script might use ENTRY.
regsub -all "(^|\n)(\[^\n\]*: warning: cannot find entry symbol\[^\n\]*\n?)" $exec_output "\\1" exec_output
# We don't care if we get a message about creating a library file.
regsub -all "(^|\n)(Creating library file\[^\n\]*\n?)" $exec_output "\\1" exec_output
if [string match "" $exec_output] then {
return 1
}
verbose -log "$exec_output"
return 0
}
set tmpdir tmpdir
set SHCFLAG ""
if [istarget *-pc-cygwin] {
# Set some libs needed for cygwin.
set MYLIBS "-L/usr/lib -lcygwin -L/usr/lib/w32api -lkernel32"
# Compile the dll.
if ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/dll.c $tmpdir/dll.o] {
fail "compiling shared lib"
}
if ![ld_special_link "$ld -shared --enable-auto-import -e __cygwin_dll_entry@12 --out-implib=$tmpdir/libstandard.dll.a" $tmpdir/dll.dll "$tmpdir/dll.o $MYLIBS"] {
fail "linking shared lib"
}
# Create symbolic link.
catch "exec ln -fs dll.dll $tmpdir/libsymlinked_dll.dll.a" ln_catch
# Compile and link the client program.
if ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/client.c $tmpdir/client.o] {
fail "compiling client"
}
# Check linking with import library.
set msg "linking auto-import client using a standard import library"
if [ld_special_link $ld $tmpdir/client-linklib.exe "--enable-auto-import --enable-runtime-pseudo-reloc /lib/crt0.o $tmpdir/client.o -L$tmpdir -lstandard $MYLIBS"] {
pass $msg
} else {
fail $msg
}
# Check linking directly with dll.
set msg "linking auto-import client using the dll"
if [ld_special_link $ld $tmpdir/client-linkdll.exe "--enable-auto-import --enable-runtime-pseudo-reloc /lib/crt0.o $tmpdir/client.o -L$tmpdir -ldll $MYLIBS"] {
pass $msg
} else {
fail $msg
}
# Check linking with symlinked dll.
set msg "linking auto-import client using symbolic linked dll"
if [ld_special_link $ld $tmpdir/client-symlinkeddll.exe "--enable-auto-import --enable-runtime-pseudo-reloc /lib/crt0.o $tmpdir/client.o -L$tmpdir -lsymlinked_dll $MYLIBS"] {
pass $msg
} else {
fail $msg
}
# Check linking with disabled auto-import, this must produce linking error.
set msg "linking with disabled auto-import"
if ![ld_special_link $ld $tmpdir/client-failed.exe "--disable-auto-import --enable-runtime-pseudo-reloc /lib/crt0.o $tmpdir/client.o -L$tmpdir -ldll $MYLIBS"] {
pass $msg
} else {
fail $msg
}
# Check that the app works - ie that there is output when the applications runs.
set msg "application runtime segfault check"
catch "exec $tmpdir/client-linklib.exe" exec_output
if ![string match "" $exec_output] then {
pass $msg
} else {
fail $msg
}
}
|