aboutsummaryrefslogtreecommitdiff
path: root/ld/testsuite/ld-shared
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>1999-05-03 07:29:11 +0000
committerRichard Henderson <rth@redhat.com>1999-05-03 07:29:11 +0000
commit252b5132c753830d5fd56823373aed85f2a0db63 (patch)
tree1af963bfd8d3e55167b81def4207f175eaff3a56 /ld/testsuite/ld-shared
downloadgdb-252b5132c753830d5fd56823373aed85f2a0db63.zip
gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.gz
gdb-252b5132c753830d5fd56823373aed85f2a0db63.tar.bz2
19990502 sourceware importbinu_ss_19990502
Diffstat (limited to 'ld/testsuite/ld-shared')
-rw-r--r--ld/testsuite/ld-shared/elf-offset.ld168
-rw-r--r--ld/testsuite/ld-shared/main.c81
-rw-r--r--ld/testsuite/ld-shared/sh1.c166
-rw-r--r--ld/testsuite/ld-shared/sh2.c14
-rw-r--r--ld/testsuite/ld-shared/shared.dat16
-rw-r--r--ld/testsuite/ld-shared/shared.exp264
-rw-r--r--ld/testsuite/ld-shared/sun4.dat16
-rw-r--r--ld/testsuite/ld-shared/xcoff.dat10
8 files changed, 735 insertions, 0 deletions
diff --git a/ld/testsuite/ld-shared/elf-offset.ld b/ld/testsuite/ld-shared/elf-offset.ld
new file mode 100644
index 0000000..dfe4293
--- /dev/null
+++ b/ld/testsuite/ld-shared/elf-offset.ld
@@ -0,0 +1,168 @@
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = 0x100000;
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rel.text :
+ {
+ *(.rel.text)
+ *(.rel.text.*)
+ *(.rel.gnu.linkonce.t*)
+ }
+ .rela.text :
+ {
+ *(.rela.text)
+ *(.rela.text.*)
+ *(.rela.gnu.linkonce.t*)
+ }
+ .rel.data :
+ {
+ *(.rel.data)
+ *(.rel.data.*)
+ *(.rel.gnu.linkonce.d*)
+ }
+ .rela.data :
+ {
+ *(.rela.data)
+ *(.rela.data.*)
+ *(.rela.gnu.linkonce.d*)
+ }
+ .rel.rodata :
+ {
+ *(.rel.rodata)
+ *(.rel.rodata.*)
+ *(.rel.gnu.linkonce.r*)
+ }
+ .rela.rodata :
+ {
+ *(.rela.rodata)
+ *(.rela.rodata.*)
+ *(.rela.gnu.linkonce.r*)
+ }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.init : { *(.rel.init) }
+ .rela.init : { *(.rela.init) }
+ .rel.fini : { *(.rel.fini) }
+ .rela.fini : { *(.rela.fini) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { KEEP (*(.init)) }
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ }
+ _etext = .;
+ PROVIDE (etext = .);
+ .fini : { KEEP (*(.fini)) } =0x9090
+ .rodata :
+ {
+ *(.rodata)
+ *(.rodata.*)
+ *(.gnu.linkonce.r*)
+ }
+ .rodata1 : { *(.rodata1) }
+ /* Adjust the address for the data segment. We want to adjust up to
+ the same address within the page on the next page up. */
+ . = ALIGN(0x1000) + (. & (0x1000 - 1));
+ .data :
+ {
+ *(.data)
+ *(.data.*)
+ *(.gnu.linkonce.d*)
+ SORT(CONSTRUCTORS)
+ }
+ .data1 : { *(.data1) }
+ .ctors :
+ {
+ /* gcc uses crtbegin.o to find the start of the constructors, so
+ we make sure it is first. Because this is a wildcard, it
+ doesn't matter if the user does not actually link against
+ crtbegin.o; the linker won't look for a file to match a
+ wildcard. The wildcard also means that it doesn't matter which
+ directory crtbegin.o is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+ .got : { *(.got.plt) *(.got) }
+ .dynamic : { *(.dynamic) }
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) *(.sdata.*) }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ .sbss : { *(.sbss) *(.scommon) }
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ }
+ . = ALIGN(32 / 8);
+ _end = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
diff --git a/ld/testsuite/ld-shared/main.c b/ld/testsuite/ld-shared/main.c
new file mode 100644
index 0000000..4fcfdaa
--- /dev/null
+++ b/ld/testsuite/ld-shared/main.c
@@ -0,0 +1,81 @@
+/* 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;
+}
+
+/* This function overrides a function in the shared library. */
+
+int
+shlib_overriddencall2 ()
+{
+ return 8;
+}
+
+int
+main ()
+{
+ int (*p) ();
+
+ printf ("mainvar == %d\n", mainvar);
+ printf ("overriddenvar == %d\n", overriddenvar);
+ printf ("shlibvar1 == %d\n", shlibvar1);
+#ifndef XCOFF_TEST
+ printf ("shlib_mainvar () == %d\n", shlib_mainvar ());
+ printf ("shlib_overriddenvar () == %d\n", shlib_overriddenvar ());
+#endif
+ printf ("shlib_shlibvar1 () == %d\n", shlib_shlibvar1 ());
+ printf ("shlib_shlibvar2 () == %d\n", shlib_shlibvar2 ());
+ printf ("shlib_shlibcall () == %d\n", shlib_shlibcall ());
+#ifndef XCOFF_TEST
+ printf ("shlib_shlibcall2 () == %d\n", shlib_shlibcall2 ());
+ printf ("shlib_maincall () == %d\n", shlib_maincall ());
+#endif
+ printf ("main_called () == %d\n", main_called ());
+ printf ("shlib_checkfunptr1 (shlib_shlibvar1) == %d\n",
+ shlib_checkfunptr1 (shlib_shlibvar1));
+#ifndef XCOFF_TEST
+ printf ("shlib_checkfunptr2 (main_called) == %d\n",
+ shlib_checkfunptr2 (main_called));
+#endif
+ p = shlib_getfunptr1 ();
+ printf ("shlib_getfunptr1 () ");
+ if (p == shlib_shlibvar1)
+ printf ("==");
+ else
+ printf ("!=");
+ printf (" shlib_shlibvar1\n");
+#ifndef XCOFF_TEST
+ p = shlib_getfunptr2 ();
+ printf ("shlib_getfunptr2 () ");
+ if (p == main_called)
+ printf ("==");
+ else
+ printf ("!=");
+ printf (" main_called\n");
+#endif
+ 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
index 0000000..e31e06a
--- /dev/null
+++ b/ld/testsuite/ld-shared/sh1.c
@@ -0,0 +1,166 @@
+/* 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. */
+#ifndef XCOFF_TEST
+extern int mainvar;
+#endif
+
+/* This variable is defined in the shared library, and overridden by
+ the main program. */
+#ifndef XCOFF_TEST
+int overriddenvar = -1;
+#endif
+
+/* 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. */
+
+#ifndef XCOFF_TEST
+int
+shlib_mainvar ()
+{
+ return mainvar;
+}
+#endif
+
+#ifndef XCOFF_TEST
+int
+shlib_overriddenvar ()
+{
+ return overriddenvar;
+}
+#endif
+
+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 ();
+}
+
+#ifndef XCOFF_TEST
+/* This function calls a function defined in this object in the shared
+ library. The main program will override the called function. */
+
+extern int shlib_overiddencall2 ();
+
+int
+shlib_shlibcall2 ()
+{
+ return shlib_overriddencall2 ();
+}
+
+int
+shlib_overriddencall2 ()
+{
+ return 7;
+}
+#endif
+
+/* This function calls a function defined by the main program. */
+
+#ifndef XCOFF_TEST
+extern int main_called ();
+
+int
+shlib_maincall ()
+{
+ return main_called ();
+}
+#endif
+
+/* 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_shlibvar1;
+}
+
+/* This function is passed a function pointer to main_called. It
+ confirms that the pointer compares equally. */
+
+#ifndef XCOFF_TEST
+int
+shlib_checkfunptr2 (p)
+ int (*p) ();
+{
+ return p == main_called;
+}
+#endif
+
+/* This function returns a pointer to shlib_mainvar. */
+
+int
+(*shlib_getfunptr1 ()) ()
+{
+ return shlib_shlibvar1;
+}
+
+/* This function returns a pointer to main_called. */
+
+#ifndef XCOFF_TEST
+int
+(*shlib_getfunptr2 ()) ()
+{
+ return main_called;
+}
+#endif
+
+/* 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
index 0000000..013a4e0
--- /dev/null
+++ b/ld/testsuite/ld-shared/sh2.c
@@ -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
index 0000000..40ee37f
--- /dev/null
+++ b/ld/testsuite/ld-shared/shared.dat
@@ -0,0 +1,16 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_mainvar () == 1
+shlib_overriddenvar () == 2
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+shlib_shlibcall2 () == 8
+shlib_maincall () == 6
+main_called () == 6
+shlib_checkfunptr1 (shlib_shlibvar1) == 1
+shlib_checkfunptr2 (main_called) == 1
+shlib_getfunptr1 () == shlib_shlibvar1
+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
index 0000000..8939c3d
--- /dev/null
+++ b/ld/testsuite/ld-shared/shared.exp
@@ -0,0 +1,264 @@
+# Expect script for ld-shared tests
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 i386-*-linux*] \
+ && ![istarget i486-*-linux*] \
+ && ![istarget i586-*-linux*] \
+ && ![istarget m68k-*-linux*] \
+ && ![istarget mips*-*-irix5*] \
+ && ![istarget powerpc-*-elf*] \
+ && ![istarget powerpc-*-linux*] \
+ && ![istarget powerpc-*-sysv4*] \
+ && ![istarget sparc*-*-elf] \
+ && ![istarget sparc*-*-solaris2*] \
+ && ![istarget sparc*-*-sunos4*] \
+ && ![istarget rs6000*-*-aix*] \
+ && ![istarget powerpc*-*-aix*] } {
+ return
+}
+
+if { [istarget i386-*-linuxaout*] \
+ || [istarget i486-*-linuxaout*] \
+ || [istarget i586-*-linuxaout*] \
+ || [istarget i386-*-linuxoldld*] \
+ || [istarget i486-*-linuxoldld*] \
+ || [istarget i586-*-linuxoldld*] \
+ || [istarget m68k-*-linuxaout*] } {
+ return
+}
+
+set tmpdir tmpdir
+set SHCFLAG ""
+
+if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+
+ # AIX shared libraries do not seem to support useful features,
+ # like overriding the shared library function or letting the
+ # shared library refer to objects defined in the main program. We
+ # avoid testing those features.
+ set SHCFLAG "-DXCOFF_TEST"
+
+ # The AIX 3.2.5 loader appears to randomly fail when loading
+ # shared libraries from NSF mounted partitions, so we avoid any
+ # potential problems by using a local directory.
+ catch {exec /bin/sh -c "echo $$"} pid
+ set tmpdir /usr/tmp/ld.$pid
+ catch "exec mkdir $tmpdir" exec_status
+
+ # On AIX, we need to explicitly export the symbols the shared
+ # library is going to provide, and need.
+ set file [open $tmpdir/xcoff.exp w]
+ puts $file shlibvar1
+ puts $file shlibvar2
+ puts $file shlib_shlibvar1
+ puts $file shlib_shlibvar2
+ puts $file shlib_shlibcall
+ puts $file shlib_shlibcalled
+ puts $file shlib_checkfunptr1
+ puts $file shlib_getfunptr1
+ puts $file shlib_check
+ close $file
+}
+
+# The test procedure.
+proc shared_test { progname testname main sh1 sh2 dat args } {
+ global ld
+ global srcdir
+ global subdir
+ global exec_output
+ global host_triplet
+ global tmpdir
+
+ if [llength $args] { set shldflags [lindex $args 0] } else { set shldflags "" }
+
+ # Build the shared library.
+ # On AIX, we need to use an export file.
+ set shared -shared
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ set shared "-bM:SRE -bE:$tmpdir/xcoff.exp"
+ }
+ if {![ld_simple_link $ld $tmpdir/$progname.so "$shared $shldflags $tmpdir/$sh1 $tmpdir/$sh2"]} {
+ fail "$testname"
+ return
+ }
+
+ # Link against the shared library. Use -rpath so that the
+ # dynamic linker can locate the shared library at runtime.
+ # On AIX, we must include /lib in -rpath, as otherwise the loader
+ # can not find -lc.
+ set rpath $tmpdir
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ set rpath /lib:$tmpdir
+ }
+ if ![ld_link $ld $tmpdir/$progname "-rpath $rpath $tmpdir/$main $tmpdir/$progname.so"] {
+ fail "$testname"
+ return
+ }
+
+ # Run the resulting program
+ send_log "$tmpdir/$progname >$tmpdir/$progname.out\n"
+ verbose "$tmpdir/$progname >$tmpdir/$progname.out"
+ catch "exec $tmpdir/$progname >$tmpdir/$progname.out" exec_output
+ if ![string match "" $exec_output] then {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ fail "$testname"
+ return
+ }
+
+ send_log "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat\n"
+ verbose "diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat"
+ catch "exec diff $tmpdir/$progname.out $srcdir/$subdir/$dat.dat" exec_output
+ set exec_output [prune_warnings $exec_output]
+
+ if {![string match "" $exec_output]} then {
+ send_log "$exec_output\n"
+ verbose "$exec_output"
+ fail "$testname"
+ return
+ }
+
+ pass "$testname"
+}
+
+if [istarget mips*-*-*] {
+ set picflag ""
+} else {
+ # 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] \
+ || [string match "*passed to ld*" $exec_output] } {
+ if [istarget *-*-sunos4*] {
+ set picflag "-pic"
+ } else {
+ set picflag "-KPIC"
+ }
+ }
+}
+verbose "Using $picflag to compile PIC code"
+
+# Compile the main program.
+if ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] {
+ unresolved "shared (non PIC)"
+ unresolved "shared"
+} else {
+ # 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 $SHCFLAG" $srcdir/$subdir/sh1.c $tmpdir/sh1np.o]
+ || ![ld_compile "$CC $CFLAGS $SHCFLAG" $srcdir/$subdir/sh2.c $tmpdir/sh2np.o] } {
+ unresolved "shared (non PIC)"
+ } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shnp "shared (nonPIC)" mainnp.o sh1np.o sh2np.o xcoff
+ } else {
+ # SunOS non PIC shared libraries don't permit some cases of
+ # overriding.
+ setup_xfail "*-*-sunos4*"
+ shared_test shnp "shared (non PIC)" mainnp.o sh1np.o sh2np.o shared
+
+ # Test ELF shared library relocations with a non-zero load
+ # address for the library. Near as I can tell, the R_*_RELATIVE
+ # relocations for various targets are broken in the case where
+ # the load address is not zero (which is the default).
+ setup_xfail "*-*-sunos4*"
+ shared_test shnp "shared (non PIC, load offset)" \
+ mainnp.o sh1np.o sh2np.o shared \
+ "-T $srcdir/$subdir/elf-offset.ld"
+ } }
+
+ # Now compile the code using -fpic.
+
+ if { ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh1.c $tmpdir/sh1p.o]
+ || ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/sh2.c $tmpdir/sh2p.o] } {
+ unresolved "shared"
+ } else {
+ # SunOS can not compare function pointers correctly
+ if [istarget "*-*-sunos4*"] {
+ shared_test shp "shared" mainnp.o sh1p.o sh2p.o sun4
+ } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shp "shared" mainnp.o sh1p.o sh2p.o xcoff
+ } else {
+ shared_test shp "shared" mainnp.o sh1p.o sh2p.o shared
+ } }
+ }
+}
+
+# Now do the same tests again, but this time compile main.c PIC.
+if ![ld_compile "$CC $CFLAGS $SHCFLAG $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] {
+ unresolved "shared (PIC main, non PIC so)"
+ unresolved "shared (PIC main)"
+} else {
+ if { [file exists $tmpdir/sh1np.o ] && [ file exists $tmpdir/sh2np.o ] } {
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o xcoff
+ } else {
+ # SunOS non PIC shared libraries don't permit some cases of
+ # overriding.
+ setup_xfail "*-*-sunos4*"
+ shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o shared
+ }
+ } else {
+ unresolved "shared (PIC main, non PIC so)"
+ }
+
+ if { [file exists $tmpdir/sh1p.o ] && [ file exists $tmpdir/sh2p.o ] } {
+ if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o xcoff
+ } else {
+ shared_test shmpp "shared (PIC main)" mainp.o sh1p.o sh2p.o shared
+ }
+ } else {
+ unresolved "shared (PIC main)"
+ }
+}
+
+if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+ # Remove the temporary directory.
+ catch "exec rm -rf $tmpdir" exec_status
+}
diff --git a/ld/testsuite/ld-shared/sun4.dat b/ld/testsuite/ld-shared/sun4.dat
new file mode 100644
index 0000000..be0d87d
--- /dev/null
+++ b/ld/testsuite/ld-shared/sun4.dat
@@ -0,0 +1,16 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_mainvar () == 1
+shlib_overriddenvar () == 2
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+shlib_shlibcall2 () == 8
+shlib_maincall () == 6
+main_called () == 6
+shlib_checkfunptr1 (shlib_shlibvar1) == 0
+shlib_checkfunptr2 (main_called) == 1
+shlib_getfunptr1 () != shlib_shlibvar1
+shlib_getfunptr2 () == main_called
+shlib_check () == 1
diff --git a/ld/testsuite/ld-shared/xcoff.dat b/ld/testsuite/ld-shared/xcoff.dat
new file mode 100644
index 0000000..a409d96
--- /dev/null
+++ b/ld/testsuite/ld-shared/xcoff.dat
@@ -0,0 +1,10 @@
+mainvar == 1
+overriddenvar == 2
+shlibvar1 == 3
+shlib_shlibvar1 () == 3
+shlib_shlibvar2 () == 4
+shlib_shlibcall () == 5
+main_called () == 6
+shlib_checkfunptr1 (shlib_shlibvar1) == 1
+shlib_getfunptr1 () == shlib_shlibvar1
+shlib_check () == 1