This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc 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]

PATCH: Support DF_1_GLOBAL


Hi,

This patch adds DF_1_GLOBAL support. Tested on x86-64, using linkers
with and without -z global support.  OK to install?

Thanks.


H.J.
---
2012-11-21  H.J. Lu  <hongjiu.lu@intel.com>

	* config.make.in (have-z-global): New variable.
	* configure.in: Check if linker supports -z global.
	* configure: Regenerated.
	* elf/Makefile (tests): Add reldep10 if linker supports -z global.
	(modules-names): Add reldepmod7.
	(LDFLAGS-reldepmod7.so): New macro.
	($(objpfx)reldep10): New target.
	($(objpfx)reldep10.out): Likewise.
	* elf/dl-open.c (dl_open_worker): Support DF_1_GLOBAL.
	* elf/reldep10.c: New file.
	* elf/reldepmod7.c: Likewise.
	* include/elf.h (DT_1_SUPPORTED_MASK): Add DF_1_GLOBAL.

diff --git a/config.make.in b/config.make.in
index 7f1bbb5..b282f1c 100644
--- a/config.make.in
+++ b/config.make.in
@@ -51,6 +51,7 @@ all-warnings = @all_warnings@
 
 have-z-combreloc = @libc_cv_z_combreloc@
 have-z-execstack = @libc_cv_z_execstack@
+have-z-global = @libc_cv_z_global@
 have-Bgroup = @libc_cv_Bgroup@
 with-fp = @with_fp@
 old-glibc-headers = @old_glibc_headers@
diff --git a/configure b/configure
index ff2d34c..e5b1e16 100755
--- a/configure
+++ b/configure
@@ -613,6 +613,7 @@ fno_unit_at_a_time
 libc_cv_output_format
 libc_cv_hashstyle
 libc_cv_fpie
+libc_cv_z_global
 libc_cv_z_execstack
 libc_cv_z_combreloc
 ASFLAGS_config
@@ -6559,6 +6560,39 @@ fi
 $as_echo "$libc_linker_feature" >&6; }
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker that supports -z global" >&5
+$as_echo_n "checking for linker that supports -z global... " >&6; }
+libc_linker_feature=no
+if test x"$gnu_ld" = x"yes"; then
+  libc_linker_check=`$LD -v --help 2>/dev/null | grep "\-z global"`
+  if test -n "$libc_linker_check"; then
+    cat > conftest.c <<EOF
+int _start (void) { return 42; }
+EOF
+    if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS
+				-Wl,-z,global -nostdlib -nostartfiles
+				-fPIC -shared -o conftest.so conftest.c
+				1>&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+      libc_linker_feature=yes
+    fi
+    rm -f conftest*
+  fi
+fi
+if test $libc_linker_feature = yes; then
+  libc_cv_z_global=yes
+else
+  libc_cv_z_global=no
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_linker_feature" >&5
+$as_echo "$libc_linker_feature" >&6; }
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fpie" >&5
 $as_echo_n "checking for -fpie... " >&6; }
 if ${libc_cv_fpie+:} false; then :
diff --git a/configure.in b/configure.in
index a7f7198..55c46ad 100644
--- a/configure.in
+++ b/configure.in
@@ -1561,6 +1561,10 @@ LIBC_LINKER_FEATURE([-z execstack], [-Wl,-z,execstack],
 		    [libc_cv_z_execstack=yes], [libc_cv_z_execstack=no])
 AC_SUBST(libc_cv_z_execstack)
 
+LIBC_LINKER_FEATURE([-z global], [-Wl,-z,global],
+		    [libc_cv_z_global=yes], [libc_cv_z_global=no])
+AC_SUBST(libc_cv_z_global)
+
 AC_CACHE_CHECK(for -fpie, libc_cv_fpie, [dnl
 LIBC_TRY_CC_OPTION([-fpie], [libc_cv_fpie=yes], [libc_cv_fpie=no])
 ])
diff --git a/elf/Makefile b/elf/Makefile
index 7e5c9c8..fa7b6c3 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -147,6 +147,9 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
 	 tst-unique1 tst-unique2 tst-unique3 tst-unique4 \
 	 tst-initorder tst-initorder2 tst-relsort1
 #	 reldep9
+ifeq (yes,$(have-z-global))
+tests += reldep10
+endif
 test-srcs = tst-pathopt
 selinux-enabled := $(shell cat /selinux/enforce 2> /dev/null)
 ifneq ($(selinux-enabled),1)
@@ -214,7 +217,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
 		tst-initorder2a tst-initorder2b tst-initorder2c \
 		tst-initorder2d \
 		tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
-		tst-array5dep
+		tst-array5dep reldepmod7
 ifeq (yesyes,$(have-fpie)$(build-shared))
 modules-names += tst-piemod1
 tests += tst-pie1
@@ -745,6 +748,10 @@ $(objpfx)nodelete2.out: $(objpfx)nodel2mod3.so
 $(objpfx)reldep9: $(libdl)
 $(objpfx)reldep9.out: $(objpfx)reldep9mod3.so
 
+LDFLAGS-reldepmod7.so = -Wl,-z,global
+$(objpfx)reldep10: $(libdl)
+$(objpfx)reldep10.out: $(objpfx)reldepmod7.so $(objpfx)reldepmod3.so
+
 $(objpfx)tst-tls3: $(objpfx)tst-tlsmod1.so
 
 $(objpfx)tst-tls4: $(libdl)
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 9c39a34..2e3e7ec 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -240,6 +240,11 @@ dl_open_worker (void *a)
     /* This happens only if we load a DSO for 'sprof'.  */
     return;
 
+  /* Make the symbols defined in the object available for symbol resolution
+     of subsequently loaded objects if it is marked with DF_1_GLOBAL.  */
+  if (__builtin_expect (new->l_flags_1 & DF_1_GLOBAL, 0))
+    mode |= RTLD_GLOBAL;
+
   /* This object is directly loaded.  */
   ++new->l_direct_opencount;
 
diff --git a/elf/reldep10.c b/elf/reldep10.c
new file mode 100644
index 0000000..c6dba73
--- /dev/null
+++ b/elf/reldep10.c
@@ -0,0 +1,101 @@
+#include <dlfcn.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (void)
+{
+  void *h1;
+  void *h2;
+  int (*fp) (void);
+  int *vp;
+
+  mtrace ();
+
+  /* Open the two objects.  reldepmod7.so is marked with DF_1_GLOBAL.  */
+  h1 = dlopen ("reldepmod7.so", RTLD_LAZY);
+  if (h1 == NULL)
+    {
+      printf ("cannot open reldepmod7.so: %s\n", dlerror ());
+      exit (1);
+    }
+  h2 = dlopen ("reldepmod3.so", RTLD_LAZY);
+  if (h2 == NULL)
+    {
+      printf ("cannot open reldepmod3.so: %s\n", dlerror ());
+      exit (1);
+    }
+
+  /* Get the address of the variable in reldepmod1.so.  */
+  vp = dlsym (h1, "some_var");
+  if (vp == NULL)
+    {
+      printf ("cannot get address of \"some_var\": %s\n", dlerror ());
+      exit (1);
+    }
+
+  *vp = 42;
+
+  /* Get the function `call_me' in the second object.  This has a
+     dependency which is resolved by a definition in reldepmod1.so.  */
+  fp = dlsym (h2, "call_me");
+  if (fp == NULL)
+    {
+      printf ("cannot get address of \"call_me\": %s\n", dlerror ());
+      exit (1);
+    }
+
+  /* Call the function.  */
+  if (fp () != 0)
+    {
+      puts ("function \"call_me\" returned wrong result");
+      exit (1);
+    }
+
+  /* Now close the first object.  It must still be around since we have
+     an implicit dependency.  */
+  if (dlclose (h1) != 0)
+    {
+      printf ("closing h1 failed: %s\n", dlerror ());
+      exit (1);
+    }
+
+  /* Open the first object again.   */
+  h1 = dlopen ("reldepmod7.so", RTLD_LAZY);
+  if (h1 == NULL)
+    {
+      printf ("cannot open reldepmod7.so the second time: %s\n", dlerror ());
+      exit (1);
+    }
+
+  /* Get the variable address again.  */
+  vp = dlsym (h1, "some_var");
+  if (vp == NULL)
+    {
+      printf ("cannot get address of \"some_var\" the second time: %s\n",
+	      dlerror ());
+      exit (1);
+    }
+
+  /* The variable now must have its originial value.  */
+  if (*vp != 42)
+    {
+      puts ("variable \"some_var\" reset");
+      exit (1);
+    }
+
+  /* Close the first object again, we are done.  */
+  if (dlclose (h1) != 0)
+    {
+      printf ("closing h1 failed: %s\n", dlerror ());
+      exit (1);
+    }
+  if (dlclose (h2) != 0)
+    {
+      printf ("closing h2 failed: %s\n", dlerror ());
+      exit (1);
+    }
+
+  return 0;
+}
diff --git a/elf/reldepmod7.c b/elf/reldepmod7.c
new file mode 100644
index 0000000..b8ef640
--- /dev/null
+++ b/elf/reldepmod7.c
@@ -0,0 +1,10 @@
+extern int foo (void);
+
+int some_var;
+
+
+int
+foo (void)
+{
+  return some_var;
+}
diff --git a/include/elf.h b/include/elf.h
index 60658c6..d594bf5 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -7,6 +7,6 @@
 #  error DT_1_SUPPORTED_MASK is defined!
 # endif
 # define DT_1_SUPPORTED_MASK \
-   (DF_1_NOW | DF_1_NODELETE | DF_1_INITFIRST | DF_1_NOOPEN \
+   (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE | DF_1_INITFIRST | DF_1_NOOPEN \
     | DF_1_ORIGIN | DF_1_NODEFLIB)
 #endif


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