# Expect script for export table in executables tests
#   Copyright (C) 2003-2021 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 { ![check_compiler_available] } {
    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_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_FOR_TARGET $srcdir/$subdir/testexe.c $tmpdir/testexe.o] {
    fail "compiling executable"
    return
}

if ![ld_special_link "$CC_FOR_TARGET $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_FOR_TARGET $srcdir/$subdir/testdll.c $tmpdir/testdll.o] {
    fail "compiling shared lib"
    return
}

if ![ld_special_link "$CC_FOR_TARGET $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"
}
