* ld-shared: New directory, with new files to test generating ELF
authorIan Lance Taylor <ian@airs.com>
Thu, 27 Oct 1994 21:33:10 +0000 (21:33 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 27 Oct 1994 21:33:10 +0000 (21:33 +0000)
shared libraries.

ld/testsuite/ChangeLog
ld/testsuite/ld-shared/.Sanitize [new file with mode: 0644]
ld/testsuite/ld-shared/main.c [new file with mode: 0644]
ld/testsuite/ld-shared/sh1.c [new file with mode: 0644]
ld/testsuite/ld-shared/sh2.c [new file with mode: 0644]
ld/testsuite/ld-shared/shared.dat [new file with mode: 0644]
ld/testsuite/ld-shared/shared.exp [new file with mode: 0644]

index cee77f47b4af46764146f36262ef9dfb67cb6605..565620840744bfab70f71b56f83f08b2119a0ca2 100644 (file)
@@ -1,3 +1,19 @@
+Thu Oct 27 17:30:12 1994  Ian Lance Taylor  <ian@sanguine.cygnus.com>
+
+       * ld-shared: New directory, with new files to test generating ELF
+       shared libraries.
+
+       * lib/ld.exp (default_ld_compile): If the compilation worked, but
+       no object file was created, check to see if the compiler foolishly
+       ignored the -o switch when compiling, and move the resulting
+       object if it did.
+
+Thu Sep 29 12:36:51 1994  Ian Lance Taylor  (ian@sanguine.cygnus.com)
+
+       * VMS does not permits `.' in directory names.  Renamed
+       ld.bootstrap to ld-bootstrap, ld.cdtest to ld-cdtest, and
+       ld.scripts to ld-scripts.
+
 Wed Sep 28 12:18:54 1994  Ian Lance Taylor  (ian@sanguine.cygnus.com)
 
        * config/default.exp: Set variables as and nm.  Create tmpdir if
diff --git a/ld/testsuite/ld-shared/.Sanitize b/ld/testsuite/ld-shared/.Sanitize
new file mode 100644 (file)
index 0000000..46b301b
--- /dev/null
@@ -0,0 +1,40 @@
+# .Sanitize for ld dejagnu testsuites
+
+# Each directory to survive it's way into a release will need a file
+# like this one called "./.Sanitize".  All keyword lines must exist,
+# and must exist in the order specified by this file.  Each directory
+# in the tree will be processed, top down, in the following order..
+
+# Hash started lines like this one are comments and will be deleted
+# before anything else is done.  Blank lines will also be squashed
+# out.
+
+# The lines between the "Do-first:" line and the "Things-to-keep:"
+# line are executed as a /bin/sh shell script before anything else is
+# done in this directory.
+
+Do-first:
+
+# All files listed between the "Things-to-keep:" line and the
+# "Do-last:" line will be kept.  All other files will be removed.
+# Directories listed in this section will have their own Sanitize
+# called.  Directories not listed will be removed in their entirety
+# with rm -rf.
+
+Things-to-keep:
+
+main.c
+sh1.c
+sh2.c
+shared.dat
+shared.exp
+
+Things-to-lose:
+
+# The lines between the "Do-last:" line and the end of the file
+# are executed as a /bin/sh shell script after everything else is
+# done.
+
+Do-last:
+
+#eof
diff --git a/ld/testsuite/ld-shared/main.c b/ld/testsuite/ld-shared/main.c
new file mode 100644 (file)
index 0000000..7003c62
--- /dev/null
@@ -0,0 +1,63 @@
+/* This is the main program for the shared library test.  */
+
+#include <stdio.h>
+
+int mainvar = 1;
+int overriddenvar = 2;
+extern int shlibvar1;
+
+extern int shlib_mainvar ();
+extern int shlib_overriddenvar ();
+extern int shlib_shlibvar1 ();
+extern int shlib_shlibvar2 ();
+extern int shlib_shlibcall ();
+extern int shlib_maincall ();
+extern int shlib_checkfunptr1 ();
+extern int shlib_checkfunptr2 ();
+extern int (*shlib_getfunptr1 ()) ();
+extern int (*shlib_getfunptr2 ()) ();
+extern int shlib_check ();
+
+/* This function is called by the shared library.  */
+
+int
+main_called ()
+{
+  return 6;
+}
+
+int
+main ()
+{
+  int (*p) ();
+
+  printf ("mainvar == %d\n", mainvar);
+  printf ("overriddenvar == %d\n", overriddenvar);
+  printf ("shlibvar1 == %d\n", shlibvar1);
+  printf ("shlib_mainvar () == %d\n", shlib_mainvar ());
+  printf ("shlib_overriddenvar () == %d\n", shlib_overriddenvar ());
+  printf ("shlib_shlibvar1 () == %d\n", shlib_shlibvar1 ());
+  printf ("shlib_shlibvar2 () == %d\n", shlib_shlibvar2 ());
+  printf ("shlib_shlibcall () == %d\n", shlib_shlibcall ());
+  printf ("shlib_maincall () == %d\n", shlib_maincall ());
+  printf ("shlib_checkfunptr1 (shlib_mainvar) == %d\n",
+         shlib_checkfunptr1 (shlib_mainvar));
+  printf ("shlib_checkfunptr2 (main_called) == %d\n",
+         shlib_checkfunptr2 (main_called));
+  p = shlib_getfunptr1 ();
+  printf ("shlib_getfunptr1 () ");
+  if (p == shlib_mainvar)
+    printf ("==");
+  else
+    printf ("!=");
+  printf (" shlib_mainvar\n");
+  p = shlib_getfunptr2 ();
+  printf ("shlib_getfunptr2 () ");
+  if (p == main_called)
+    printf ("==");
+  else
+    printf ("!=");
+  printf (" main_called\n");
+  printf ("shlib_check () == %d\n", shlib_check ());
+  return 0;
+}
diff --git a/ld/testsuite/ld-shared/sh1.c b/ld/testsuite/ld-shared/sh1.c
new file mode 100644 (file)
index 0000000..6d5b669
--- /dev/null
@@ -0,0 +1,133 @@
+/* This is part of the shared library ld test.  This file becomes part
+   of a shared library.  */
+
+/* This variable is supplied by the main program.  */
+extern int mainvar;
+
+/* This variable is defined in the shared library, and overridden by
+   the main program.  */
+int overriddenvar = -1;
+
+/* This variable is defined in the shared library.  */
+int shlibvar1 = 3;
+
+/* This variable is defined by another object in the shared library.  */
+extern int shlibvar2;
+
+/* These functions return the values of the above variables as seen in
+   the shared library.  */
+
+int
+shlib_mainvar ()
+{
+  return mainvar;
+}
+
+int
+shlib_overriddenvar ()
+{
+  return overriddenvar;
+}
+
+int
+shlib_shlibvar1 ()
+{
+  return shlibvar1;
+}
+
+int
+shlib_shlibvar2 ()
+{
+  return shlibvar2;
+}
+
+/* This function calls a function defined by another object in the
+   shared library.  */
+
+extern int shlib_shlibcalled ();
+
+int
+shlib_shlibcall ()
+{
+  return shlib_shlibcalled ();
+}
+
+/* This function calls a function defined by the main program.  */
+
+extern int main_called ();
+
+int
+shlib_maincall ()
+{
+  return main_called ();
+}
+
+/* This function is passed a function pointer to shlib_mainvar.  It
+   confirms that the pointer compares equally.  */
+
+int 
+shlib_checkfunptr1 (p)
+     int (*p) ();
+{
+  return p == shlib_mainvar;
+}
+
+/* This function is passed a function pointer to main_called.  It
+   confirms that the pointer compares equally.  */
+
+int
+shlib_checkfunptr2 (p)
+     int (*p) ();
+{
+  return p == main_called;
+}
+
+/* This function returns a pointer to shlib_mainvar.  */
+
+int
+(*shlib_getfunptr1 ()) ()
+{
+  return shlib_mainvar;
+}
+
+/* This function returns a pointer to main_called.  */
+
+int
+(*shlib_getfunptr2 ()) ()
+{
+  return main_called;
+}
+
+/* This function makes sure that constant data and local functions
+   work.  */
+
+#ifndef __STDC__
+#define const
+#endif
+
+static int i = 6;
+static const char *str = "Hello, world\n";
+
+int
+shlib_check ()
+{
+  const char *s1, *s2;
+
+  if (i != 6)
+    return 0;
+
+  /* To isolate the test, don't rely on any external functions, such
+     as strcmp.  */
+  s1 = "Hello, world\n";
+  s2 = str;
+  while (*s1 != '\0')
+    if (*s1++ != *s2++)
+      return 0;
+  if (*s2 != '\0')
+    return 0;
+
+  if (shlib_shlibvar1 () != 3)
+    return 0;
+
+  return 1;
+}
diff --git a/ld/testsuite/ld-shared/sh2.c b/ld/testsuite/ld-shared/sh2.c
new file mode 100644 (file)
index 0000000..013a4e0
--- /dev/null
@@ -0,0 +1,14 @@
+/* This is part of the shared library ld test.  This file becomes part
+   of a shared library.  */
+
+/* This variable is defined here, and referenced by another file in
+   the shared library.  */
+int shlibvar2 = 4;
+
+/* This function is called by another file in the shared library.  */
+
+int
+shlib_shlibcalled ()
+{
+  return 5;
+}
diff --git a/ld/testsuite/ld-shared/shared.dat b/ld/testsuite/ld-shared/shared.dat
new file mode 100644 (file)
index 0000000..12477e2
--- /dev/null
@@ -0,0 +1,14 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_mainvar () == 1
+shlib_overriddenvar () == 2
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+shlib_maincall () == 6
+shlib_checkfunptr1 (shlib_mainvar) == 1
+shlib_checkfunptr2 (main_called) == 1
+shlib_getfunptr1 () == shlib_mainvar
+shlib_getfunptr2 () == main_called
+shlib_check () == 1
diff --git a/ld/testsuite/ld-shared/shared.exp b/ld/testsuite/ld-shared/shared.exp
new file mode 100644 (file)
index 0000000..d836a2a
--- /dev/null
@@ -0,0 +1,146 @@
+# Expect script for ld-shared tests
+#   Copyright (C) 1994 Free Software Foundation
+#
+# 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+#
+# Written by Ian Lance Taylor (ian@cygnus.com)
+#
+
+# Make sure that ld can generate ELF shared libraries.
+# Note that linking against ELF shared libraries is tested by the
+# bootstrap test.
+
+# 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 i386-*-sysv4*] \
+     && ![istarget i486-*-sysv4*] \
+     && ![istarget i586-*-sysv4*] \
+     && ![istarget i386-*-unixware] \
+     && ![istarget i486-*-unixware] \
+     && ![istarget i586-*-unixware] \
+     && ![istarget i386-*-elf*] \
+     && ![istarget i486-*-elf*] \
+     && ![istarget i586-*-elf*] \
+     && ![istarget sparc*-*-elf] \
+     && ![istarget sparc*-*-solaris2*]} then {
+    return
+}
+
+# Compile the main program.
+if ![ld_compile "$CC $CFLAGS" $srcdir$subdir/main.c tmpdir/main.o] {
+    return
+}
+
+# The shared library is composed of two files.  First compile them
+# without using -fpic.  That should work on an ELF system, although it
+# will be less efficient because the dynamic linker will need to do
+# more relocation work.  However, note that not using -fpic will cause
+# some of the tests to return different results.
+if ![ld_compile "$CC $CFLAGS" $srcdir$subdir/sh1.c tmpdir/sh1.o] {
+    return
+}
+if ![ld_compile "$CC $CFLAGS" $srcdir$subdir/sh2.c tmpdir/sh2.o] {
+    return
+}
+
+# Build the shared library.
+if ![ld_simple_link $ld tmpdir/shnonpic.so {-shared tmpdir/sh1.o tmpdir/sh2.o}] {
+    fail "shared (non PIC)"
+} else {
+    # Link against the shared library.  Use -rpath so that the dynamic
+    # linker can locate the shared library at runtime.
+    if ![ld_link $ld tmpdir/shnonpic {-rpath tmpdir tmpdir/main.o tmpdir/shnonpic.so}] {
+       fail "shared (non PIC)"
+    } else {
+       # Run the resulting program
+       send_log "tmpdir/shnonpic >tmpdir/shnonpic.out\n"
+       verbose "tmpdir/shnonpic >tmpdir/shnonpic.out"
+       catch "exec tmpdir/shnonpic >tmpdir/shnonpic.out" exec_output
+       if ![string match "" $exec_output] then {
+           send_log "$exec_output\n"
+           verbose "$exec_output"
+           fail "shared (non PIC)"
+       } else {
+           send_log "diff tmpdir/shnonpic.out $srcdir$subdir/shared.dat\n"
+           verbose "diff tmpdir/shnonpic.out $srcdir$subdir/shared.dat"
+           catch "exec diff tmpdir/shnonpic.out $srcdir$subdir/shared.dat" exec_output
+           if [string match "" $exec_output] then {
+               pass "shared (non PIC)"
+           } else {
+               send_log "$exec_output\n"
+               verbose "$exec_output"
+               fail "shared (non PIC)"
+           }
+       }
+    }
+}
+
+# Now compile the code using -fpic.  Unfortunately, the gcc argument
+# is -fpic and the cc argument is -KPIC.  We have to try both.
+
+set picflag "-fpic"
+send_log "$CC $picflag\n"
+verbose "$CC $picflag"
+catch "exec $CC $picflag" exec_output
+send_log "$exec_output\n"
+verbose "--" "$exec_output"
+if { [string match "*illegal option*" $exec_output] \
+     || [string match "*option ignored*" $exec_output] \
+     || [string match "*unrecognized option*" $exec_output] } then {
+    set picflag "-KPIC"
+}
+verbose "Using $picflag to compile PIC code"
+
+if ![ld_compile "$CC $CFLAGS $picflag" $srcdir$subdir/sh1.c tmpdir/sh1.o] {
+    return
+}
+if ![ld_compile "$CC $CFLAGS $picflag" $srcdir$subdir/sh2.c tmpdir/sh2.o] {
+    return
+}
+
+# Build the shared library.
+if ![ld_simple_link $ld tmpdir/shpic.so {-shared tmpdir/sh1.o tmpdir/sh2.o}] {
+    fail "shared"
+} else {
+    # Link against the shared library.  Use -rpath so that the dynamic
+    # linker can locate the shared library at runtime.
+    if ![ld_link $ld tmpdir/shpic {-rpath tmpdir tmpdir/main.o tmpdir/shpic.so}] {
+       fail "shared"
+    } else {
+       # Run the resulting program
+       send_log "tmpdir/shpic >tmpdir/shpic.out\n"
+       verbose "tmpdir/shpic >tmpdir/shpic.out"
+       catch "exec tmpdir/shpic >tmpdir/shpic.out" exec_output
+       if ![string match "" $exec_output] then {
+           send_log "$exec_output\n"
+           verbose "$exec_output"
+           fail "shared"
+       } else {
+           send_log "diff tmpdir/shpic.out $srcdir$subdir/shared.dat\n"
+           verbose "diff tmpdir/shpic.out $srcdir$subdir/shared.dat"
+           catch "exec diff tmpdir/shpic.out $srcdir$subdir/shared.dat" exec_output
+           if [string match "" $exec_output] then {
+               pass "shared"
+           } else {
+               send_log "$exec_output\n"
+               verbose "$exec_output"
+               fail "shared"
+           }
+       }
+    }
+}