Test the auto importing direct from a dll functionality.
authorNick Clifton <nickc@redhat.com>
Wed, 18 Dec 2002 16:05:10 +0000 (16:05 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 18 Dec 2002 16:05:10 +0000 (16:05 +0000)
ld/testsuite/ChangeLog
ld/testsuite/ld-auto-import/auto-import.exp [new file with mode: 0644]
ld/testsuite/ld-auto-import/client.c [new file with mode: 0644]
ld/testsuite/ld-auto-import/dll.c [new file with mode: 0644]

index 5779c8b2288c3ccab28cc11d676335b8aba092da..a09864f37822dd518d3ef91a7b38cdf3dbfbb81b 100644 (file)
@@ -1,3 +1,11 @@
+2002-12-18  Ralf Habacker  <ralf.habacker@freenet.de>
+
+       * ld-auto-import: New directory.
+       * ld-auto-import/auto-import.exp: Test the auto importing direct
+       from a dll functionality.
+       * ld-auto-import/client.c: Source code for test.
+       * ld-auto-import/dll.c: Likewise.
+
 2002-12-12  Alexandre Oliva  <aoliva@redhat.com>
 
        * ld-mips-elf/mips-elf.exp: Remove branch-misc-2 test.
diff --git a/ld/testsuite/ld-auto-import/auto-import.exp b/ld/testsuite/ld-auto-import/auto-import.exp
new file mode 100644 (file)
index 0000000..659e702
--- /dev/null
@@ -0,0 +1,160 @@
+# Expect script for ld-auto-import tests
+#   Copyright 2002
+#   Free Software Foundation, Inc.
+#
+# This file 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Written by Ralf.Habacker@freenet.de
+# Based on ls-shared/shared.exp by Ian Lance Taylor (ian@cygnus.com)
+#
+# Note: 
+# 
+# This test checks the "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 4 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. 
+
+# 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 ELF platforms.
+# Square bracket expressions seem to confuse istarget.
+if { ![istarget *-pc-cygwin]    
+     && ![istarget *-pc-mingw*] } {
+    return
+}
+
+# No compiler, no test.
+if { [which $CC] == 0 } {
+    untested "Auto import test"
+    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
+    } else {
+       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"
+    } elseif ![ld_special_link "$ld -shared --out-implib=$tmpdir/libstandard.dll.a" $tmpdir/dll.dll "$tmpdir/dll.o $MYLIBS" ] {
+       fail "linking shared lib"
+    } else {
+       # 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"
+       } else {
+           # Check linking with import library.
+           set msg "linking auto-import client using a standard import library"
+           if [ld_special_link $ld $tmpdir/client.exe "--enable-auto-import /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.exe "--enable-auto-import /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/clientimport.exe "--enable-auto-import /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/clientimport.exe "--disable-auto-import /lib/crt0.o $tmpdir/client.o -L$tmpdir -ldll $MYLIBS" ] {
+               pass $msg
+           }   else {
+               fail $msg
+           }
+       }
+    }
+}
+
+if [istarget *-pc-mingw*] {
+    unsupported "mingw currently not supported"
+}
diff --git a/ld/testsuite/ld-auto-import/client.c b/ld/testsuite/ld-auto-import/client.c
new file mode 100644 (file)
index 0000000..9ed80c5
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>\r
+\r
+extern int var;\r
+extern void (*func_ptr)(void);\r
+extern void print_var (void);\r
+extern void print_foo (void);\r
+extern int foo;\r
+extern int var2[2];\r
+\r
+typedef struct\r
+{\r
+  int *   var;\r
+  void (* func_ptr)(void);\r
+}\r
+TEST;\r
+\r
+TEST xyz = { &var, print_var };\r
+\r
+int\r
+main (void)\r
+{\r
+  print_var ();\r
+\r
+  printf ("We see var = %d\n", var);\r
+  printf ("Setting var = 456\n");\r
+\r
+  var = 456;\r
+\r
+  print_var ();\r
+  printf ("We see var = %d\n\n", var);\r
+\r
+  var = 90;\r
+  print_var ();\r
+  printf ("We see var = %d\n\n", var);\r
+\r
+  print_foo ();\r
+  printf ("We see foo = %d\n", foo);\r
+  printf ("Setting foo = 19\n");\r
+  foo = 19;\r
+  print_foo ();\r
+  printf ("We see foo = %d\n\n", foo);\r
+  fflush (stdout);\r
+\r
+  printf ("Calling dllimported function pointer\n");\r
+  func_ptr ();\r
+\r
+  printf ("Calling functions using global structure\n"); \r
+  xyz.func_ptr ();\r
+  * xyz.var = 40;\r
+  xyz.func_ptr ();\r
+\r
+  printf ("We see var2[0] = %d\n\n", var2[0]);\r
+\r
+  return 0;\r
+}\r
diff --git a/ld/testsuite/ld-auto-import/dll.c b/ld/testsuite/ld-auto-import/dll.c
new file mode 100644 (file)
index 0000000..ccf85e4
--- /dev/null
@@ -0,0 +1,20 @@
+int var = 123;\r
+int foo = 121;\r
+\r
+int var2[2]= { 123, 456 };\r
+\r
+#include <stdio.h>\r
+\r
+void\r
+print_var (void)\r
+{\r
+  printf ("DLL sees var = %d\n", var);\r
+}\r
+\r
+void\r
+print_foo (void)\r
+{\r
+  printf ("DLL sees foo = %d\n", foo);\r
+}\r
+\r
+void (* func_ptr)(void) = print_foo;\r