This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] PE direct linking to dlls, accept any filename.
- From: Christopher Faylor <cgf-use-the-mailinglist-please at sourceware dot org>
- To: Pedro Alves <pedro_alves at portugalmail dot pt>, binutils at sourceware dot org
- Date: Fri, 15 Dec 2006 10:48:25 -0500
- Subject: Re: [PATCH] PE direct linking to dlls, accept any filename.
- References: <4582C2FF.6060402@portugalmail.pt>
On Fri, Dec 15, 2006 at 03:45:03PM +0000, Pedro Alves wrote:
>Hi all,
>
>The gdb testsuite in some shared lib tests, builds shared libs with .so
>or .sl extension uncondicionally,
>and then tries to do a direct link, even on PE platforms (eg:cygwin).
>That fails to link with current ld.
>I sent a patch there to fix a few cases, by introducing a $SOEXT var in
>the testsuite.
>But thinking again, I can't see a reason ld doesn't let us do a direct
>link to a dll with an extension
>other than ".dll" or ".DLL". The Windows loader is happy to load the
>dlls, and in fact there are many
>examples of dlls without a ".dll" extension in production.
>
>The attached patch makes ld be able to direct link any dll without
>looking at the filename extension.
>
>Built and regtested on i686-pc-cygwin, and confirmed manually that we
>identify dlls as dlls no matter
>what the filename is, that we don't mistake exe images with dlls. Also
>confirmed linking with msvcrt.dll
>to be sure we can identify a dll built with MSVC as such.
>
>Please review and commit.
Wow. I'm giddy. I like patches which generalize things like this and
you even included a test case!
Unless someone (Danny?) objects in the next few days, I'll check this
in.
Thank you, Pedro.
cgf
>ld/
>
>2006-12-15 Pedro Alves <pedro_alves@portugalmail.pt>
>
> * emultempl/pe.em (gld_${EMULATION_NAME}_recognized_file):
> Detect dlls using bfd not the filename extension.
>
>ld/testsuite/
>
>2006-12-15 Pedro Alves <pedro_alves@portugalmail.pt>
>
> * ld-pe/direct.exp: New file.
> * ld-pe/direct_client.c: Likewise.
> * ld-pe/direct_dll.c: Likewise.
>
>
>Index: emultempl/pe.em
>===================================================================
>RCS file: /cvs/src/src/ld/emultempl/pe.em,v
>retrieving revision 1.121
>diff -u -p -r1.121 pe.em
>--- emultempl/pe.em 3 Oct 2006 10:06:26 -0000 1.121
>+++ emultempl/pe.em 15 Dec 2006 15:17:21 -0000
>@@ -1418,15 +1418,13 @@ gld_${EMULATION_NAME}_recognized_file (l
> if (bfd_get_format (entry->the_bfd) == bfd_object)
> {
> char fbuf[LD_PATHMAX + 1];
>- const char *ext;
>
> if (REALPATH (entry->filename, fbuf) == NULL)
> strncpy (fbuf, entry->filename, sizeof (fbuf));
>
>- ext = fbuf + strlen (fbuf) - 4;
>-
>- if (strcmp (ext, ".dll") == 0 || strcmp (ext, ".DLL") == 0)
>- return pe_implied_import_dll (fbuf);
>+ if (obj_pe (entry->the_bfd)
>+ && pe_data (entry->the_bfd)->dll)
>+ return pe_implied_import_dll (fbuf);
> }
> #endif
> return FALSE;
>--- /dev/null 2006-12-15 15:20:26.499625000 +0000
>+++ testsuite/ld-pe/direct.exp 2006-12-15 15:12:19.062125000 +0000
>@@ -0,0 +1,91 @@
>+# Expect script for direct linking from dll tests
>+# Copyright 2006
>+# 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
>+#
>+# Written by Pedro Alves <pedro_alves@portugalmail.pt>
>+#
>+
>+# Note:
>+#
>+# This test checks the "direct linking to a dll" functionality.
>+#
>+# The test has 4 stages:
>+#
>+# 1. compile and link a test dll with ".dll" extension.
>+#
>+# 2. compile and link a test dll with ".sl" (i.e. != ".dll") extension.
>+#
>+# 3. compile and link a client application linking directly to the ".dll" dll built in 1.
>+# This should produce no errors.
>+#
>+# 4. compile and link a client application linking directly to the ".sl" dll built in 2.
>+# This should produce no errors.
>+
>+# This test can only be run on PE/COFF platforms.
>+if { ![istarget *-*-cygwin*]
>+ && ![istarget *-*-mingw*]
>+ && ![istarget *-*-pe] } {
>+ return
>+}
>+
>+# No compiler, no test.
>+if { [which $CC] == 0 } {
>+ untested "Direct linking to dll test"
>+ return
>+}
>+
>+set tmpdir tmpdir
>+
>+proc test_direct_link_dll {} {
>+ global CC
>+ global CFLAGS
>+ global srcdir
>+ global subdir
>+ global tmpdir
>+
>+ # Compile the dll.
>+ if ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/direct_dll.c $tmpdir/direct_dll.o ] {
>+ fail "compiling shared lib"
>+ } elseif ![ld_simple_link "$CC -shared" $tmpdir/direct_dll.dll "$tmpdir/direct_dll.o" ] {
>+ fail "linking shared lib (.dll)"
>+ } elseif ![ld_simple_link "$CC -shared" $tmpdir/direct_dll.sl "$tmpdir/direct_dll.o" ] {
>+ fail "linking shared lib (.sl)"
>+ } else {
>+ # Compile and link the client program.
>+ if ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/direct_client.c $tmpdir/direct_client.o ] {
>+ fail "compiling client"
>+ } else {
>+ # Check linking directly to direct_dll.dll.
>+ set msg "linking client (.dll)"
>+ if [ld_simple_link $CC $tmpdir/direct_client.exe "$tmpdir/direct_client.o $tmpdir/direct_dll.dll" ] {
>+ pass $msg
>+ } else {
>+ fail $msg
>+ }
>+
>+ # Check linking directly to direct_dll.sl.
>+ set msg "linking client (.sl)"
>+ if [ld_simple_link $CC $tmpdir/direct_client.exe "$tmpdir/direct_client.o $tmpdir/direct_dll.sl" ] {
>+ pass $msg
>+ } else {
>+ fail $msg
>+ }
>+ }
>+ }
>+}
>+
>+test_direct_link_dll
>--- /dev/null 2006-12-15 15:20:35.921500000 +0000
>+++ testsuite/ld-pe/direct_dll.c 2006-12-15 15:10:30.609000000 +0000
>@@ -0,0 +1,5 @@
>+__declspec(dllexport) int
>+dll_func (void)
>+{
>+ return 10;
>+}
>--- /dev/null 2006-12-15 15:20:40.265250000 +0000
>+++ testsuite/ld-pe/direct_client.c 2006-12-15 15:10:50.640250000 +0000
>@@ -0,0 +1,8 @@
>+__declspec(dllimport) int dll_func (void);
>+
>+int
>+main()
>+{
>+ dll_func ();
>+ return 0;
>+}