This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: Add some ELF weak tests for linker.


I'd like to check in this test. The current ELF weak implmentation is
not the same as Solaris for some historic reasons in glibc. Some tests
will fail today. I will make the BFD change when glibc is ready to
switch.

BTW, I will add more ELF weak tests after this patch is checked in.


H.J.
-----
2001-09-09  H.J. Lu  <hjl@gnu.org>

	* ld-elfweak/elfweak.exp: New.
	* ld-elfweak/bar.c: Likewise.
	* ld-elfweak/foo.c: Likewise.
	* ld-elfweak/main.c: Likewise.
	* ld-elfweak/dso.dsym: Likewise.
	* ld-elfweak/dsow.dsym: Likewise.
	* ld-elfweak/strong.sym: Likewise.
	* ld-elfweak/strong.dat: Likewise.
	* ld-elfweak/weak.dat: Likewise.

--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/bar.c	Sun Sep  9 11:49:42 2001
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+extern void foo ();
+
+void
+foo ()
+{
+  printf ("strong foo\n");
+}
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/dso.dsym	Sun Sep  9 18:01:21 2001
@@ -0,0 +1 @@
+[0-9a-f]*[ 	]+g[ 	]+DF[ 	]+.text[	]+[0-9a-f]*[ 	]+foo
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/dsow.dsym	Sun Sep  9 18:01:45 2001
@@ -0,0 +1 @@
+[0-9a-f]*[ 	]+w[ 	]+DF[ 	]+.text[	]+[0-9a-f]*[ 	]+foo
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/elfweak.exp	Sun Sep  9 18:10:42 2001
@@ -0,0 +1,394 @@
+# Expect script for ld-weak tests
+#   Copyright 2001 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 H.J. Lu (hjl@gnu.org)
+#	     Eric Youngdale (eric@andante.jic.com)
+#
+
+# 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.
+# This is similar to the test that is used in ld-shared, BTW.
+if { ![istarget i?86-*-sysv4*] \
+     && ![istarget i?86-*-unixware] \
+     && ![istarget i?86-*-elf*] \
+     && ![istarget i?86-*-linux*] \
+     && ![istarget ia64-*-elf*] \
+     && ![istarget ia64-*-linux*] \
+     && ![istarget m68k-*-linux*] \
+     && ![istarget mips*-*-irix5*] \
+     && ![istarget powerpc-*-elf*] \
+     && ![istarget powerpc-*-linux*] \
+     && ![istarget powerpc-*-sysv4*] \
+     && ![istarget sparc*-*-elf] \
+     && ![istarget sparc*-*-solaris2*] \
+     && ![istarget sparc*-*-linux*] \
+     && ![istarget arm*-*-linux*] \
+     && ![istarget mips*-*-linux*] \
+     && ![istarget alpha*-*-linux*] } {
+    return
+}
+
+if { [istarget i?86-*-linux*aout*] \
+     || [istarget i?86-*-linux*oldld*] \
+     || [istarget m68k-*-linux*aout*] } {
+    return
+}
+
+if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
+    return
+}
+
+set diff diff
+set tmpdir tmpdir
+set DOBJDUMP_FLAGS --dynamic-syms
+set SOBJDUMP_FLAGS --syms
+set shared --shared
+
+#
+# objdump_symstuff
+#	Dump non-dynamic symbol stuff and make sure that it is sane.
+#
+proc objdump_symstuff { objdump object expectfile } {
+    global SOBJDUMP_FLAGS
+    global version_output
+    global diff
+    global tmpdir
+
+    if ![info exists SOBJDUMP_FLAGS] { set SOBJDUMP_FLAGS "" }
+
+    verbose -log "$objdump $SOBJDUMP_FLAGS $object | grep foo$  > $tmpdir/objdump.out"
+
+    catch "exec $objdump $SOBJDUMP_FLAGS $object | grep foo$  > $tmpdir/objdump.out" exec_output
+    set exec_output [prune_warnings $exec_output]
+    if [string match "" $exec_output] then {
+
+# Now do a line-by-line comparison to effectively diff the darned things
+# The stuff coming from the expectfile is actually a regex, so we can
+# skip over the actual addresses and so forth.  This is currently very
+# simpleminded - it expects a one-to-one correspondence in terms of line
+# numbers.
+
+	if [file exists $expectfile] then {
+	    set file_a [open $expectfile r]
+	} else {
+	    perror "$expectfile doesn't exist"
+	    return 0
+	}
+	
+	if [file exists $tmpdir/objdump.out] then {
+	    set file_b [open $tmpdir/objdump.out r]
+	} else {
+	    perror "$tmpdir/objdump.out doesn't exist"
+	    return 0
+	}
+
+	verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2
+
+	set eof -1
+	set differences 0
+
+	while { [gets $file_a line] != $eof } {
+	    if [regexp "^#.*$" $line] then {
+		continue
+	    } else {
+		lappend list_a $line
+	    }
+	}
+	close $file_a
+
+	while { [gets $file_b line] != $eof } {
+	    if [regexp "^#.*$" $line] then {
+		continue
+	    } else {
+		lappend list_b $line
+	    }
+	}
+	close $file_b
+	
+	for { set i 0 } { $i < [llength $list_a] } { incr i } {
+	    set line_a [lindex $list_a $i]
+	    set line_b [lindex $list_b $i]
+	    
+
+	    verbose "\t$expectfile: $i: $line_a" 3
+	    verbose "\t/tmp/objdump.out: $i: $line_b" 3
+	    if [regexp $line_a $line_b] then {
+		continue
+	    } else {
+		verbose -log "\t$expectfile: $i: $line_a"
+		verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
+		
+		return 0
+	    }
+	}
+	
+	if { [llength $list_a] != [llength $list_b] } {
+	    verbose -log "Line count"
+	    return 0
+	}
+	
+	if $differences<1 then {
+	    return 1
+	}
+	
+	return 0
+    } else {
+	verbose -log "$exec_output"
+	return 0
+    }
+
+}
+
+#
+# objdump_dymsymstuff
+#	Dump dynamic symbol stuff and make sure that it is sane.
+#
+proc objdump_dynsymstuff { objdump object expectfile } {
+    global DOBJDUMP_FLAGS
+    global version_output
+    global diff
+    global tmpdir
+
+    if ![info exists DOBJDUMP_FLAGS] { set DOBJDUMP_FLAGS "" }
+
+    verbose -log "$objdump $DOBJDUMP_FLAGS $object | grep foo$ > $tmpdir/objdump.out"
+
+    catch "exec $objdump $DOBJDUMP_FLAGS $object | grep foo$ > $tmpdir/objdump.out" exec_output
+    set exec_output [prune_warnings $exec_output]
+    if [string match "" $exec_output] then {
+
+# Now do a line-by-line comparison to effectively diff the darned things
+# The stuff coming from the expectfile is actually a regex, so we can
+# skip over the actual addresses and so forth.  This is currently very
+# simpleminded - it expects a one-to-one correspondence in terms of line
+# numbers.
+
+	if [file exists $expectfile] then {
+	    set file_a [open $expectfile r]
+	} else {
+	    warning "$expectfile doesn't exist"
+	    return 0
+	}
+	
+	if [file exists $tmpdir/objdump.out] then {
+	    set file_b [open $tmpdir/objdump.out r]
+	} else {
+	    fail "$tmpdir/objdump.out doesn't exist"
+	    return 0
+	}
+
+	verbose "# Diff'ing: $expectfile $tmpdir/objdump.out" 2
+
+	set eof -1
+	set differences 0
+
+	while { [gets $file_a line] != $eof } {
+	    if [regexp "^#.*$" $line] then {
+		continue
+	    } else {
+		lappend list_a $line
+	    }
+	}
+	close $file_a
+
+	while { [gets $file_b line] != $eof } {
+	    if [regexp "^#.*$" $line] then {
+		continue
+	    } else {
+		lappend list_b $line
+	    }
+	}
+	close $file_b
+	
+	for { set i 0 } { $i < [llength $list_b] } { incr i } {
+	    set line_b [lindex $list_b $i]
+	    
+# The tests are rigged so that we should never export a symbol with the
+# word 'hide' in it.  Thus we just search for it, and bail if we find it.
+	    if [regexp "hide" $line_b] then {
+		verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
+		
+		return 0
+	    }
+
+	    verbose "\t$expectfile: $i: $line_b" 3
+
+	    # We can't assume that the sort is consistent across
+	    # systems, so we must check each regexp.  When we find a
+	    # regexp, we null it out, so we don't match it twice.
+	    for { set j 0 } { $j < [llength $list_a] } { incr j } {
+		set line_a [lindex $list_a $j]
+
+		if [regexp $line_a $line_b] then {
+		    lreplace $list_a $j $j "CAN NOT MATCH"
+		    break
+		}
+	    }
+
+	    if { $j >= [llength $list_a] } {
+		verbose -log "\t$tmpdir/objdump.out: $i: $line_b"
+		
+		return 0
+	    }
+	}
+	
+	if { [llength $list_a] != [llength $list_b] } {
+	    verbose -log "Line count"
+	    return 0
+	}
+	
+	if $differences<1 then {
+	    return 1
+	}
+	
+	return 0
+    } else {
+	verbose -log "$exec_output"
+	return 0
+    }
+
+}
+
+proc build_lib {test libname obj1 obj2 dynsymexp} {
+    global ld
+    global objdump
+    global tmpdir
+    global shared
+    global srcdir
+    global subdir
+
+    if {![ld_simple_link $ld $tmpdir/$libname.so "$shared $tmpdir/$obj1 $tmpdir/$obj2"]} {
+	fail $test
+	return
+    }
+
+    if {![objdump_dynsymstuff $objdump $tmpdir/$libname.so $srcdir/$subdir/$dynsymexp]} {
+	fail $test
+	return
+    }
+    pass $test
+}
+
+proc build_exec { test execname obj1 obj2 flags dat dynsymexp symexp} {
+    global ld
+    global objdump
+    global tmpdir
+    global shared
+    global srcdir
+    global subdir
+    global exec_output
+
+    if {![ld_link $ld $tmpdir/$execname "$flags $tmpdir/$obj1 $tmpdir/$obj2"]} {
+	fail "$test"
+	return
+    }
+
+    if {![string match "" $dynsymexp]} then {
+        if {![objdump_dynsymstuff $objdump $tmpdir/$execname $srcdir/$subdir/$dynsymexp]} {
+	    fail $test
+	    return
+	}
+    }
+
+    if {![string match "" $symexp]} then {
+        if {![objdump_symstuff $objdump $tmpdir/$execname $srcdir/$subdir/$symexp]} {
+	    fail $test
+	    return
+	}
+    }
+
+    # Run the resulting program
+    send_log "$tmpdir/$execname >$tmpdir/$execname.out\n"
+    verbose "$tmpdir/$execname >$tmpdir/$execname.out"
+    catch "exec $tmpdir/$execname >$tmpdir/$execname.out" exec_output
+    if ![string match "" $exec_output] then {
+	send_log "$exec_output\n"
+	verbose "$exec_output"
+	fail $test
+	return
+    }
+
+    send_log "diff $tmpdir/$execname.out $srcdir/$subdir/$dat.dat\n"
+    verbose "diff $tmpdir/$execname.out $srcdir/$subdir/$dat.dat"
+    catch "exec diff $tmpdir/$execname.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 $test
+        return
+    }
+
+    pass $test
+}
+
+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"
+
+if ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/foo.c $tmpdir/foo.o] {
+    unresolved "ELF weak"
+    return
+}
+
+if ![ld_compile "$CC $CFLAGS $picflag" $srcdir/$subdir/bar.c $tmpdir/bar.o] {
+    unresolved "ELF weak"
+    return
+}
+
+if ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/main.c $tmpdir/main.o] {
+    unresolved "ELF weak"
+    return
+}
+
+if {![ld_simple_link $ld $tmpdir/libbar.so "$shared $tmpdir/bar.o"]} {
+    fail "ELF weak"
+    return
+}
+
+build_lib "ELF DSO weak first" libfoo foo.o bar.o dso.dsym
+build_lib "ELF DSO weak last" libfoo bar.o foo.o dso.dsym
+build_lib "ELF DSO weak first DSO" libfoo foo.o libbar.so dsow.dsym
+build_lib "ELF DSO weak last DSO" libfoo libbar.so foo.o dsow.dsym
+build_exec "ELF weak first" foo main.o bar.o "" strong "" strong.sym
+build_exec "ELF weak last" foo bar.o main.o "" strong "" strong.sym
+build_exec "ELF weak first DSO" foo main.o libbar.so "-rpath ." weak weak.dsym ""
+build_exec "ELF weak last DSO" foo libbar.so main.o "-rpath ." weak weak.dsym ""
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/foo.c	Sun Sep  9 11:50:12 2001
@@ -0,0 +1,8 @@
+#pragma weak foo
+
+extern void foo ();
+
+void
+foo ()
+{
+}
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/main.c	Sun Sep  9 11:50:46 2001
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+#pragma weak foo
+
+extern void foo ();
+
+void
+foo ()
+{
+  printf ("weak foo\n");
+}
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/strong.dat	Sun Sep  9 18:11:00 2001
@@ -0,0 +1 @@
+strong foo
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/strong.sym	Sun Sep  9 18:01:57 2001
@@ -0,0 +1 @@
+[0-9a-f]*[ 	]+g[ 	]+F[ 	]+.text[	]+[0-9a-f]*[ 	]+foo
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/weak.dat	Sun Sep  9 18:08:08 2001
@@ -0,0 +1 @@
+weak foo
--- /dev/null	Fri Mar 23 20:37:44 2001
+++ ld-elfweak/weak.dsym	Sun Sep  9 18:02:21 2001
@@ -0,0 +1 @@
+[0-9a-f]*[ 	]+w[ 	]+DF[ 	]+.text[	]+[0-9a-f]*[ 	]+(Base[ 	]+|[ 	]*)foo


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]