# Expect script for export table in executables tests
#   Copyright (C) 2003-2016 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"
}
