summaryrefslogtreecommitdiff
path: root/ld/testsuite/ld-cygwin/exe-export.exp
blob: 1dfee1ab81b86fb5344f44b79facc36b8a56956d (plain)
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
# Expect script for export table in executables tests
#   Copyright (C) 2003-2015 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 Fabrizio Gennari <fabrizio.ge@tiscalinet.it>
# Based on auto-import.exp  by Ralf.Habacker@freenet.de
#
 
# This test can only be run on a cygwin platforms.
if {![istarget *-pc-cygwin]} {
    verbose "Not a cygwin target."
    return
}

# No compiler, no test.
if { [which $CC] == 0 } {
    untested "Exe export test (no compiler available)"
    return
}

proc run_dlltool { lib_file def_file } {
    global dlltool
    global base_dir
    global as
    
    if ![info exists dlltool] then {
	set dlltool [findfile $base_dir/../binutils/dlltool]
    }

    if { [which $dlltool] == 0 } then {
	verbose "$dlltool does not exist"
	return 0
    }

    verbose "$dlltool --as $as -l $lib_file -d $def_file"
    catch "exec $dlltool --as $as -l $lib_file -d $def_file" dlltool_output

    #remove empty lines
    regsub -all "\n+" $dlltool_output "" dlltool_output

    if [string match "" $dlltool_output] then {
        return 1
    }

    verbose -log "$dlltool_output"
    return 0
}

# ld_special_link
#       A copy of ld_simple_link (from ld-lib.exp) with extra
#       code to strip warnings about creating libraries.
#
proc ld_special_link { ld target objects } {
    global host_triplet
    global link_output

    if { [which $ld] == 0 } then {
	verbose "$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 some libs needed for cygwin.
set MYLDFLAGS "-Wl,--out-implib,$tmpdir/testexe.lib -nostartfiles -nostdlib"

# Build an export library for testdll
if ![run_dlltool $tmpdir/testdll.lib $srcdir/$subdir/testdll.def] {
    fail "building an export library for the shared lib"
    return
} 

# Compile the executable.
if ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/testexe.c $tmpdir/testexe.o] {
    fail "compiling executable"
    return
}

if ![ld_special_link "$CC $LDFLAGS $MYLDFLAGS -e _testexe_main@16" $tmpdir/testexe.exe "$tmpdir/testexe.o $srcdir/$subdir/testexe.def $tmpdir/testdll.lib -lkernel32"] {
    fail "linking executable"
    return
} 

# Compile the dll.
if ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/testdll.c $tmpdir/testdll.o] {
    fail "compiling shared lib"
    return
}

if ![ld_special_link "$CC $LDFLAGS -nostartfiles -nostdlib -e _testdll_main@12" $tmpdir/testdll.dll "$tmpdir/testdll.o $srcdir/$subdir/testdll.def $tmpdir/testexe.lib"] {
    fail "linking shared lib"
    return
} 

# This is as far as we can go with a cross-compiler
if ![isnative] then {
    verbose "Not running natively, so cannot execute binary"
    pass "Compile and link and executable with an export table"
    return
}

verbose -log "executing $tmpdir/testexe.exe"
catch "exec $tmpdir/testexe.exe" prog_output

set expected ""
if [string match $expected $prog_output] then {
    pass "export table in executable"
} else {
    verbose $prog_output
    fail "Output does not match expected string $expected"
}