2000-05-13 H.J. Lu (hjl@gnu.org)
authorH.J. Lu <hjl.tools@gmail.com>
Sat, 13 May 2000 16:54:32 +0000 (16:54 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Sat, 13 May 2000 16:54:32 +0000 (16:54 +0000)
* lib/ld-lib.exp (default_ld_link): Redirect the linker output
to link_output and make it global.

* ld-elfvsb/elf-offset.ld: New. ELF visibility fearture
tests.
* ld-elfvsb/elfvsb.dat: Likewise.
* ld-elfvsb/elfvsb.exp: Likewise.
* ld-elfvsb/main.c: Likewise.
* ld-elfvsb/sh1.c: Likewise.
* ld-elfvsb/sh2.c: Likewise.

ld/testsuite/ChangeLog
ld/testsuite/ld-elfvsb/elf-offset.ld [new file with mode: 0644]
ld/testsuite/ld-elfvsb/elfvsb.dat [new file with mode: 0644]
ld/testsuite/ld-elfvsb/elfvsb.exp [new file with mode: 0644]
ld/testsuite/ld-elfvsb/main.c [new file with mode: 0644]
ld/testsuite/ld-elfvsb/sh1.c [new file with mode: 0644]
ld/testsuite/ld-elfvsb/sh2.c [new file with mode: 0644]
ld/testsuite/lib/ld-lib.exp

index ae88ca1cb4e8add92278c79ce277ffeb8b790cc4..3e286d3d8c4fba442fd61e44313645ab15e6c470 100644 (file)
@@ -1,3 +1,16 @@
+2000-05-13  H.J. Lu  (hjl@gnu.org)
+
+       * lib/ld-lib.exp (default_ld_link): Redirect the linker output
+       to link_output and make it global.
+
+       * ld-elfvsb/elf-offset.ld: New. ELF visibility fearture
+       tests.
+       * ld-elfvsb/elfvsb.dat: Likewise.
+       * ld-elfvsb/elfvsb.exp: Likewise.
+       * ld-elfvsb/main.c: Likewise.
+       * ld-elfvsb/sh1.c: Likewise.
+       * ld-elfvsb/sh2.c: Likewise.
+
 Fri Apr 21 15:16:07 2000  Richard Henderson  <rth@cygnus.com>
 
        * testsuite/ld-scripts/phdrs.exp: IA-64 is 64-bit ELF too.
diff --git a/ld/testsuite/ld-elfvsb/elf-offset.ld b/ld/testsuite/ld-elfvsb/elf-offset.ld
new file mode 100644 (file)
index 0000000..dfe4293
--- /dev/null
@@ -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-elfvsb/elfvsb.dat b/ld/testsuite/ld-elfvsb/elfvsb.dat
new file mode 100644 (file)
index 0000000..9f1778d
--- /dev/null
@@ -0,0 +1,19 @@
+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
+visibility_check () == 1
+visibility_checkfunptr () == 1
+main_visibility_check () == 1
diff --git a/ld/testsuite/ld-elfvsb/elfvsb.exp b/ld/testsuite/ld-elfvsb/elfvsb.exp
new file mode 100644 (file)
index 0000000..746200e
--- /dev/null
@@ -0,0 +1,298 @@
+# Expect script for ld-visibility tests
+#   Copyright (C) 2000 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)
+#           and H.J. Lu (hjl@gnu.org)
+#
+
+# Make sure that ld can generate ELF shared libraries with visibility.
+
+# 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-*-linux*] \
+     && ![istarget i486-*-linux*] \
+     && ![istarget i586-*-linux*] \
+     && ![istarget i686-*-linux*] \
+     && ![istarget m68k-*-linux*] \
+     && ![istarget powerpc-*-linux*] \
+     && ![istarget sparc*-*-linux*] } {
+    return
+}
+
+if { [istarget *-*-linux*aout*] \
+     || [istarget *-*-linux*oldld*] } {
+    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 visibility_test { visibility progname testname main sh1 sh2 dat args } {
+    global ld
+    global srcdir
+    global subdir
+    global exec_output
+    global link_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"] {
+       if { [ string match $visibility "hidden" ]
+            && [string match "*/main.c*: undefined reference to \`visibility\'" $link_output] } {
+           pass "$testname"
+       } else {
+           fail "$testname"
+       }
+       return
+    }
+
+    if [ string match $visibility "hidden" ] {
+       fail "$testname"
+    }
+
+    # 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"
+}
+
+proc visibility_run {visibility} {
+    global CC
+    global CFLAGS
+    global SHCFLAG
+    global srcdir
+    global subdir
+    global tmpdir
+    global picflag
+    global target_triplet
+
+    if [ string match $visibility "hidden" ] {
+       set VSBCFLAG "-DHIDDEN_TEST"
+    } else { if [ string match $visibility "hidden_normal" ] {
+       set VSBCFLAG "-DHIDDEN_NORMAL_TEST"
+    } else { if [ string match $visibility "protected" ] {
+       set VSBCFLAG "-DPROTECTED_TEST"
+    } else {
+       set VSBCFLAG ""
+    }}}
+
+    # Compile the main program.
+    if ![ld_compile "$CC $CFLAGS $SHCFLAG $VSBCFLAG" $srcdir/$subdir/main.c $tmpdir/mainnp.o] {
+       unresolved "visibility ($visibility) (non PIC)"
+       unresolved "visibility ($visibility)"
+    } 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 $VSBCFLAG" $srcdir/$subdir/sh1.c $tmpdir/sh1np.o]
+            || ![ld_compile "$CC $CFLAGS $SHCFLAG $VSBCFLAG" $srcdir/$subdir/sh2.c $tmpdir/sh2np.o] } {
+           unresolved "visibility ($visibility) (non PIC)"
+       } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+           visibility_test $visibility vnp "visibility ($visibility) (nonPIC)" mainnp.o sh1np.o sh2np.o xcoff
+       } else {
+           # SunOS non PIC shared libraries don't permit some cases of
+           # overriding.
+           if [ string match $visibility "protected" ] {
+               setup_xfail $target_triplet
+           } else {
+               setup_xfail "*-*-sunos4*"
+           }
+           visibility_test $visibility vnp "visibility ($visibility) (non PIC)" mainnp.o sh1np.o sh2np.o elfvsb
+
+           # 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).
+           if [ string match $visibility "protected" ] {
+               setup_xfail $target_triplet
+           } else {
+               setup_xfail "*-*-sunos4*"
+               setup_xfail "*-*-linux*libc1"
+           }
+           visibility_test $visibility vnp "visibility ($visibility) (non PIC, load offset)" \
+               mainnp.o sh1np.o sh2np.o elfvsb \
+               "-T $srcdir/$subdir/elf-offset.ld"
+       } }
+
+       # Now compile the code using -fpic.
+
+       if { ![ld_compile "$CC $CFLAGS $SHCFLAG $VSBCFLAG $picflag" $srcdir/$subdir/sh1.c $tmpdir/sh1p.o] 
+           || ![ld_compile "$CC $CFLAGS $SHCFLAG $VSBCFLAG $picflag" $srcdir/$subdir/sh2.c $tmpdir/sh2p.o] } {
+           unresolved "visibility ($visibility)"
+       } else {
+           if [ string match $visibility "protected" ] {
+               setup_xfail $target_triplet
+           }
+           # SunOS can not compare function pointers correctly
+           if [istarget "*-*-sunos4*"] {
+               visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o sun4
+           } else { if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+               visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o xcoff
+           } else {
+               visibility_test $visibility vp "visibility ($visibility)" mainnp.o sh1p.o sh2p.o elfvsb
+           } }
+       }
+    }
+
+    # Now do the same tests again, but this time compile main.c PIC.
+    if ![ld_compile "$CC $CFLAGS $SHCFLAG $VSBCFLAG $picflag" $srcdir/$subdir/main.c $tmpdir/mainp.o] {
+       unresolved "visibility ($visibility) (PIC main, non PIC so)"
+       unresolved "visibility ($visibility) (PIC main)"
+    } else {
+       if { [file exists $tmpdir/sh1np.o ] && [ file exists $tmpdir/sh2np.o ] } {
+           if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+               visibility_test $visibility vmpnp "visibility ($visibility) (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.
+               if [ string match $visibility "protected" ] {
+                   setup_xfail $target_triplet
+               } else {
+                   setup_xfail "*-*-sunos4*"
+               }
+               visibility_test $visibility vmpnp "visibility ($visibility) (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o elfvsb
+           }
+       } else {
+           unresolved "visibility (PIC main, non PIC so)"
+       }
+
+       if { [file exists $tmpdir/sh1p.o ] && [ file exists $tmpdir/sh2p.o ] } {
+           if [ string match $visibility "protected" ] {
+               setup_xfail $target_triplet
+           }
+           if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+               visibility_test $visibility vmpp "visibility ($visibility) (PIC main)" mainp.o sh1p.o sh2p.o xcoff
+           } else {
+               visibility_test $visibility vmpp "visibility ($visibility) (PIC main)" mainp.o sh1p.o sh2p.o elfvsb
+           }
+       } else {
+           unresolved "visibility ($visibility) (PIC main)"
+       }
+    }
+}
+
+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"
+
+visibility_run hidden
+visibility_run hidden_normal
+visibility_run protected
+visibility_run normal
+
+if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+    # Remove the temporary directory.
+    catch "exec rm -rf $tmpdir" exec_status
+}
diff --git a/ld/testsuite/ld-elfvsb/main.c b/ld/testsuite/ld-elfvsb/main.c
new file mode 100644 (file)
index 0000000..4a41315
--- /dev/null
@@ -0,0 +1,104 @@
+/* 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 ();
+extern int shlib_shlibcall2 ();
+extern int visibility ();
+extern int visibility_check ();
+extern int visibility_checkfunptr ();
+extern void *visibility_funptr ();
+
+#if !defined (HIDDEN_TEST) && defined (PROTECTED_TEST)
+int
+visibility ()
+{
+  return 1;
+}
+#endif
+
+static int
+main_visibility_check ()
+{
+  return visibility_funptr () == visibility;
+}
+
+/* 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 ());
+  printf ("visibility_check () == %d\n", visibility_check ());
+  printf ("visibility_checkfunptr () == %d\n",
+         visibility_checkfunptr ());
+  printf ("main_visibility_check () == %d\n", main_visibility_check ());
+  return 0;
+}
diff --git a/ld/testsuite/ld-elfvsb/sh1.c b/ld/testsuite/ld-elfvsb/sh1.c
new file mode 100644 (file)
index 0000000..c4bdcc7
--- /dev/null
@@ -0,0 +1,215 @@
+/* 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_overriddencall2 ();
+
+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;
+}
+
+int
+visibility ()
+{
+  return 2;
+}
+
+#ifdef HIDDEN_NORMAL_TEST
+asm (".hidden visibility_normal");
+
+int
+visibility_normal ()
+{
+  return 2;
+}
+#endif
+
+int
+visibility_checkfunptr ()
+{
+#ifdef HIDDEN_NORMAL_TEST
+  int (*v) () = visibility_normal;
+#else
+  int (*v) () = visibility;
+#endif
+  return (*v) () == 2;
+}
+
+int
+visibility_check ()
+{
+#ifdef HIDDEN_NORMAL_TEST
+  return visibility_normal () == 2;
+#else
+  return visibility () == 2;
+#endif
+}
+
+void *
+visibility_funptr ()
+{
+  return visibility;
+}
+
+#ifdef HIDDEN_TEST
+asm (".hidden visibility");
+#else
+asm (".protected visibility");
+#endif
diff --git a/ld/testsuite/ld-elfvsb/sh2.c b/ld/testsuite/ld-elfvsb/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;
+}
index 1c912578c57fdfb788fb7a784270c3d5dc3e0892..417ccbaf7c6101b7463da9ad14e8fc65dff43834 100644 (file)
@@ -85,6 +85,7 @@ proc default_ld_link { ld target objects } {
     global HOSTING_LIBS
     global LIBS
     global host_triplet
+    global link_output
     
     set objs "$HOSTING_CRT0 $objects"
     set libs "$LIBS $HOSTING_LIBS"
@@ -98,12 +99,12 @@ proc default_ld_link { ld target objects } {
     
     verbose -log "$ld $HOSTING_EMU $flags -o $target $objs $libs"
     
-    catch "exec $ld $HOSTING_EMU $flags -o $target $objs $libs" exec_output
-    set exec_output [prune_warnings $exec_output]
-    if [string match "" $exec_output] then {
+    catch "exec $ld $HOSTING_EMU $flags -o $target $objs $libs" link_output
+    set exec_output [prune_warnings $link_output]
+    if [string match "" $link_output] then {
        return 1
     } else {
-       verbose -log "$exec_output"
+       verbose -log "$link_output"
        return 0
     }
 }