This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

[PATCHx3] LD plugins: matters outstanding.


    Hello binutils,

  The attached three patches fix two small bugs in the LD plugin interface,
and add support for MinGW.

[PATCH] Avoid testsuite errors when no cross compiler is available.

ld/testsuite/ChangeLog:

	* ld-plugin/plugin.exp: Don't error out if there is no target compiler
	available, make tests UNSUPPORTED instead.

  This is just a repost of the patch I sent earlier to prevent noise in
cross-target testsuite runs.

[PATCH] Fix potential use-after-free bugs.

ld/ChangeLog:

	* plugin.c (add_input_file): Take copy of input string.
	(add_input_library): Likewise.
	(set_extra_library_path): Likewise.

  This patch fixes a bug I found while porting the GCC lto-plugin.  The
strings passed to these callbacks belong to the plugin, and it is allowed to
free them after the callback returns.  So ld can't hang on to a copy of a
pointer to the string (embedded in a lang input statement); it has to make a
dup.  Without this fix, plugin pass-through filenames were getting mangled.

[PATCH] Provide win32-based dlapi replacements on windows platforms without
dlfcn.h.

ld/ChangeLog:

	* configure.in: If <dlfcn.h> can't be found, try for <Windows.h>
	* configure: Regenerate.
	* config.in: Likewise.
	* plugin.c [!HAVE_DLFCN_H && HAVE_WINDOWS_H] (dlopen): Provide
	trival LoadLibrary-based replacement for Windows systems.
	[!HAVE_DLFCN_H && HAVE_WINDOWS_H] (dlsym): Likewise trivial
	replacement based on GetProcAddress.
	[!HAVE_DLFCN_H && HAVE_WINDOWS_H] (dlsym): Likewise FreeLibrary.
	* sysdep.h: Don't infer presence of <dlfcn.h> from ENABLE_PLUGINS
	anymore, use its own guard.

  I took a look at libltdl, and decided it was too much of a top-heavy and
intrusive solution.  Given that so far it's looking like Windows is going to
be the only non-ELF platform fully supporting LTO, I decided just to slap a
trivial shim layer in for MinGW's sake.

  Built and tested on i686-pc-cygwin.  Built on i686-pc-mingw32, but there's
no dejagnu on that platform, so I just manually ran the equivalent of the most
basic plugin load test.  (It worked.)

  These patches complete the LD plugin interface work.  (Tristan, the patch I
thought I might need to do about rescanning libs turns out not to be needed,
so this is everything.)

  OK for trunk?

    cheers,
      DaveK

>From babff63d4d6d96ab9fae22b67a729445d767d459 Mon Sep 17 00:00:00 2001
From: Dave Korn <dave.korn.cygwin@gmail.com>
Date: Fri, 15 Oct 2010 16:05:51 +0100
Subject: [PATCH] Avoid testsuite errors when no cross compiler is available.

ld/testsuite/ChangeLog:

	* ld-plugin/plugin.exp: Don't error out if there is no target compiler
	available, make tests UNSUPPORTED instead.
---
 ld/testsuite/ld-plugin/plugin.exp |   20 +++++++++++++++-----
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/ld/testsuite/ld-plugin/plugin.exp b/ld/testsuite/ld-plugin/plugin.exp
index 796cb0e..416159a 100644
--- a/ld/testsuite/ld-plugin/plugin.exp
+++ b/ld/testsuite/ld-plugin/plugin.exp
@@ -24,6 +24,13 @@ if ![check_plugin_api_available] {
     return
 }
 
+# And a compiler to be available.
+set can_compile 1
+if { [which $CC] == 0 } {
+  # Don't fail immediately, 
+  set can_compile 0
+}
+
 pass "plugin API enabled"
 
 global base_dir
@@ -62,12 +69,15 @@ set regcln "-plugin-opt registercleanup"
 set failed_compile 0
 set _ ""
 set plugin_nm_output ""
-if { ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/main.c tmpdir/main.o]
-	|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/func.c tmpdir/func.o]
-	|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/text.c tmpdir/text.o] } {
+if { $can_compile && \
+	(![ld_compile "$CC $CFLAGS" $srcdir/$subdir/main.c tmpdir/main.o] \
+	|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/func.c tmpdir/func.o] \
+	|| ![ld_compile "$CC $CFLAGS" $srcdir/$subdir/text.c tmpdir/text.o]) } {
     # Defer fail until we have list of tests set.
     set failed_compile 1
-} else {
+}
+
+if { $can_compile && !$failed_compile } {
     # Find out if symbols have prefix on this platform before setting tests.
     catch "exec $NM tmpdir/func.o" plugin_nm_output
     if { [regexp "_func" "$plugin_nm_output"] } {
@@ -142,7 +152,7 @@ set plugin_extra_elf_tests [list \
 				{readelf -s plugin-vis-1.d}} "main.x" ] \
 ]
 
-if { $failed_compile != 0 } {
+if { !$can_compile || $failed_compile } {
     foreach testitem $plugin_tests {
 	unresolved [lindex $testitem 0]
     }
>From 1478b11d6ed70bde869ad90d52a6194abd92d88d Mon Sep 17 00:00:00 2001
From: Dave Korn <dave.korn.cygwin@gmail.com>
Date: Fri, 15 Oct 2010 16:09:56 +0100
Subject: [PATCH] Fix potential use-after-free bugs.

ld/ChangeLog:

	* plugin.c (add_input_file): Take copy of input string.
	(add_input_library): Likewise.
	(set_extra_library_path): Likewise.
---
 ld/plugin.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/ld/plugin.c b/ld/plugin.c
index b484bd0..0c88ef8 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -433,7 +433,8 @@ static enum ld_plugin_status
 add_input_file (const char *pathname)
 {
   ASSERT (called_plugin);
-  if (!lang_add_input_file (pathname, lang_input_file_is_file_enum, NULL))
+  if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_file_enum,
+	NULL))
     return LDPS_ERR;
   return LDPS_OK;
 }
@@ -443,7 +444,8 @@ static enum ld_plugin_status
 add_input_library (const char *pathname)
 {
   ASSERT (called_plugin);
-  if (!lang_add_input_file (pathname, lang_input_file_is_l_enum, NULL))
+  if (!lang_add_input_file (xstrdup (pathname), lang_input_file_is_l_enum,
+	NULL))
     return LDPS_ERR;
   return LDPS_OK;
 }
@@ -454,7 +456,7 @@ static enum ld_plugin_status
 set_extra_library_path (const char *path)
 {
   ASSERT (called_plugin);
-  ldfile_add_library_path (path, FALSE);
+  ldfile_add_library_path (xstrdup (path), FALSE);
   return LDPS_OK;
 }
 
>From 9b6758820e42a6b6ea97226f860a22dfb4b653e6 Mon Sep 17 00:00:00 2001
From: Dave Korn <dave.korn.cygwin@gmail.com>
Date: Fri, 15 Oct 2010 16:34:37 +0100
Subject: [PATCH] Provide win32-based dlapi replacements on windows platforms without dlfcn.h.

ld/ChangeLog:

	* configure.in: If <dlfcn.h> can't be found, try for <Windows.h>
	* configure: Regenerate.
	* config.in: Likewise.
	* plugin.c [!HAVE_DLFCN_H && HAVE_WINDOWS_H] (dlopen): Provide
	trival LoadLibrary-based replacement for Windows systems.
	[!HAVE_DLFCN_H && HAVE_WINDOWS_H] (dlsym): Likewise trivial
	replacement based on GetProcAddress.
	[!HAVE_DLFCN_H && HAVE_WINDOWS_H] (dlsym): Likewise FreeLibrary.
	* sysdep.h: Don't infer presence of <dlfcn.h> from ENABLE_PLUGINS
	anymore, use its own guard.
---
 ld/config.in    |    3 +++
 ld/configure    |   16 ++++++++++++++++
 ld/configure.in |    4 ++++
 ld/plugin.c     |   28 ++++++++++++++++++++++++++++
 ld/sysdep.h     |    3 +--
 5 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/ld/config.in b/ld/config.in
index 9e6e97b..f49327c 100644
--- a/ld/config.in
+++ b/ld/config.in
@@ -129,6 +129,9 @@
 /* Define to 1 if you have the `waitpid' function. */
 #undef HAVE_WAITPID
 
+/* Define to 1 if you have the <Windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
 /* Define to 1 if you have the <zlib.h> header file. */
 #undef HAVE_ZLIB_H
 
diff --git a/ld/configure b/ld/configure
index 9ff8529..3367a88 100755
--- a/ld/configure
+++ b/ld/configure
@@ -12919,6 +12919,22 @@ else
 fi
 done
 
+# We also support plugins on Windows (MinGW).
+if test x$enable_plugins = xno ; then
+  for ac_header in Windows.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "Windows.h" "ac_cv_header_Windows_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_Windows_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+ enable_plugins=yes
+fi
+
+done
+
+fi
  if test x$enable_plugins = xyes; then
   ENABLE_PLUGINS_TRUE=
   ENABLE_PLUGINS_FALSE='#'
diff --git a/ld/configure.in b/ld/configure.in
index 29d01cc..122f65e 100644
--- a/ld/configure.in
+++ b/ld/configure.in
@@ -169,6 +169,10 @@ enable_plugins=yes
 AC_CHECK_HEADER([dlfcn.h],[],[enable_plugins=no],[AC_INCLUDES_DEFAULT])
 AC_SEARCH_LIBS([dlopen],[dl],[],[enable_plugins=no],[])
 AC_CHECK_FUNCS([dlopen dlsym dlclose],[],[enable_plugins=no])
+# We also support plugins on Windows (MinGW).
+if test x$enable_plugins = xno ; then
+  AC_CHECK_HEADERS([Windows.h],[enable_plugins=yes],[],[AC_INCLUDES_DEFAULT])
+fi
 AM_CONDITIONAL([ENABLE_PLUGINS], [test x$enable_plugins = xyes])
 
 AC_MSG_CHECKING(for a known getopt prototype in unistd.h)
diff --git a/ld/plugin.c b/ld/plugin.c
index 0c88ef8..caf8a34 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -32,6 +32,9 @@
 #include "plugin.h"
 #include "plugin-api.h"
 #include "elf-bfd.h"
+#if defined (HAVE_WINDOWS_H)
+#include <Windows.h>
+#endif
 
 /* The suffix to append to the name of the real (claimed) object file
    when generating a dummy BFD to hold the IR symbols sent from the
@@ -128,6 +131,31 @@ static const enum ld_plugin_tag tv_header_tags[] =
 /* How many entries in the constant leading part of the tv array.  */
 static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
 
+#if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
+
+#define RTLD_NOW 0	/* Dummy value.  */
+
+static void *
+dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
+{
+  return LoadLibrary (file);
+}
+
+static void *
+dlsym (void *handle, const char *name)
+{
+  return GetProcAddress (handle, name);
+}
+
+static int
+dlclose (void *handle)
+{
+  FreeLibrary (handle);
+  return 0;
+}
+
+#endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)  */
+
 /* Helper function for exiting with error status.  */
 static int
 set_plugin_error (const char *plugin)
diff --git a/ld/sysdep.h b/ld/sysdep.h
index 9dfae10..b7d5b88 100644
--- a/ld/sysdep.h
+++ b/ld/sysdep.h
@@ -90,8 +90,7 @@ extern char *strrchr ();
 #endif
 #endif
 
-/* This is both more precise than and includes HAVE_DLFCN_H.  */
-#ifdef ENABLE_PLUGINS
+#ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
 #endif
 

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