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]

Re: [PATCH][BZ #15022] Correct global-scope dlopen issues in static executables


This patch looks unreviewed since january.

On Thu, Jan 24, 2013 at 12:33:20PM +0000, Maciej W. Rozycki wrote:
> On Wed, 16 Jan 2013, Roland McGrath wrote:
> 
> > As Joseph said, you should file two bugs with appropriate minimal test
> > cases for the two issues.  Then use [BZ #nnn] in the log entry for the
> > change that affects the bug.
> 
>  This is really a single bug only, triggering two different symptoms 
> depending on how you poke at the bug.  The bug is the lack of global scope 
> in static executables.  Now when you attempt to open that scope, as with 
> dlopen (NULL, ...), then owing to how its internals work the dynamic 
> loader engine tries to open a directory and treat it as a DSO.  When on 
> the other hand you attempt to add a DSO to that scope, as with dlopen 
> ("foo", RTLD_GLOBAL), then the engine crashes.
> 
>  I have therefore created one bug report only, #15022.
> 
> > I would like to see a fix that does not change user-visible semantics at
> > all (aside from not crashing, of course).  If the change to the
> > user-visible semantics of dlopen is desireable, then propose it
> > separately.  If it's inordinately difficult or ugly to fix the crash
> > without the semantic change, then let the semantic change go in and
> > settle first.  If it's reasonably doable to fix the problems without the
> > semantic change, then send the fixes first and then if the semantic
> > change is desireable and goes in later, you can send additional cleanup
> > changes to make the code simpler again afterwards.
> 
>  Please elaborate on what user-visible semantics you would like 
> specifically to preserve.
> 
> > Each test case should be minimal and focussed on testing just one thing.
> > For dynamic linking tests, that means they should use pure examples that
> > only rely on linking behavior use trivial functions in the test itself.
> > If it's worthwhile to test something having to do with the value
> > returned by getpagesize, add that as separate test for getpagesize or
> > whatever it is truly testing, not for linking behavior.
> 
>  Well, some code paths can only be tested with more complicated scenarios 
> and whenever a test case regresses you probably want to run `git bisect' 
> on the tree anyway to find the offending change.  Obviously you can't 
> verify that static DSO initialisation works correctly without referring to 
> code that relies on that, like the said getpagesize function.
> 
>  Anyway I can see a benefit in having more limited cases as well, for 
> example to assess a regression quickly without having to look into it in 
> detail.  So I have added two extra test cases now, modelled on the 
> original ones, that merely manipulate some data passed back and forth 
> between a static executable and a DSO, and making sure the changes 
> requested are as expected.  I hope the two new tests meet your 
> expectations and fulfil your requirements.
> 
>  Additionally, I made the error messages more verbose and unique, so that 
> any stage causing a failure is clearly identifiable by just looking at the 
> relevant test case source, without a need to attach with GDB or suchlike.
> 
>  Finally, if you'd rather I split the getpagesize tests off and submitted 
> them separately, then I'm fine with that; obviously the tests would have 
> to be added after the bug fix itself or otherwise they would regress right 
> away.
> 
>  I have smoke-tested the updated test cases, by running them on a 
> big-endian o32 MIPS target.  If you agree this is the right change, then 
> I'll run full testing -- that'll take about a day.  Otherwise I'll 
> appreciate your feedback.  Thanks for your review.
> 
> 2013-01-24  Maciej W. Rozycki  <macro@codesourcery.com>
> 
> 	ChangeLog:
> 	[BZ #15022]
> 	* csu/libc-start.c (LIBC_START_MAIN) [!SHARED]: Prepare a global
> 	search list.
> 	* dlfcn/modstatic3.c: New file.
> 	* dlfcn/modstatic5.c: New file.
> 	* dlfcn/tststatic3.c: New file.
> 	* dlfcn/tststatic4.c: New file.
> 	* dlfcn/tststatic5.c: New file.
> 	* dlfcn/tststatic6.c: New file.
> 	* dlfcn/Makefile (tests): Add tststatic3, tststatic4, tststatic5
> 	and tststatic6.
> 	(tests-static): Likewise.
> 	(modules-names): Add modstatic3 and modstatic5.
> 	(tststatic3-ENV, tststatic4-ENV): New variables.
> 	($(objpfx)tststatic3, $(objpfx)tststatic3.out): New dependencies.
> 	($(objpfx)tststatic4, $(objpfx)tststatic4.out): Likewise.
> 	($(objpfx)tststatic5, $(objpfx)tststatic5.out): Likewise.
> 	($(objpfx)tststatic6, $(objpfx)tststatic6.out): Likewise.
> 
> 	ports/ChangeLog.ia64:
> 	[BZ #15022]
> 	* sysdeps/unix/sysv/linux/ia64/dl-static.c (_dl_static_init):
> 	Exit right away if opening self.
> 
> 	ports/ChangeLog.mips:
> 	[BZ #15022]
> 	* sysdeps/unix/sysv/linux/mips/dl-static.c (_dl_static_init):
> 	Exit right away if opening self.
> 
>   Maciej
> 
> glibc-static-dlopen.diff
> Index: glibc-fsf-trunk-quilt/csu/libc-start.c
> ===================================================================
> --- glibc-fsf-trunk-quilt.orig/csu/libc-start.c	2013-01-23 03:10:20.000000000 +0000
> +++ glibc-fsf-trunk-quilt/csu/libc-start.c	2013-01-23 03:12:02.036666536 +0000
> @@ -15,6 +15,7 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#include <assert.h>
>  #include <stdlib.h>
>  #include <stdio.h>
>  #include <unistd.h>
> @@ -177,6 +178,26 @@ LIBC_START_MAIN (int (*main) (int, char 
>       we need to setup errno.  */
>    __pthread_initialize_minimal ();
>  
> +  /* Create a dummy link_map for the executable, used by dlopen to
> +     access the global scope.  We don't export any symbols ourselves,
> +     so this can be minimal.  */
> +  struct link_map **new_global;
> +  struct link_map *main_map;
> +
> +  main_map = _dl_new_object ("", "", lt_executable, NULL, 0, LM_ID_BASE);
> +  assert (main_map != NULL);
> +
> +  _dl_add_to_namespace_list (main_map, LM_ID_BASE);
> +  assert (main_map == GL(dl_ns)[LM_ID_BASE]._ns_loaded);
> +  GL(dl_nns) = 1;
> +
> +  new_global = malloc (sizeof (struct link_map **));
> +  assert (new_global != NULL);
> +  *new_global = main_map;
> +  main_map->l_searchlist.r_list = new_global;
> +  main_map->l_searchlist.r_nlist = 1;
> +  GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist;
> +
>    /* Set up the stack checker's canary.  */
>    uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
>  # ifdef THREAD_SET_STACK_GUARD
> Index: glibc-fsf-trunk-quilt/dlfcn/Makefile
> ===================================================================
> --- glibc-fsf-trunk-quilt.orig/dlfcn/Makefile	2013-01-23 03:10:20.000000000 +0000
> +++ glibc-fsf-trunk-quilt/dlfcn/Makefile	2013-01-24 10:10:35.846606720 +0000
> @@ -47,11 +47,16 @@ glreflib2.so-no-z-defs = yes
>  errmsg1mod.so-no-z-defs = yes
>  
>  ifeq (yes,$(build-shared))
> -tests += tststatic tststatic2
> -tests-static += tststatic tststatic2
> -modules-names += modstatic modstatic2
> +tests += tststatic tststatic2 tststatic3 tststatic4 tststatic5 tststatic6
> +tests-static += tststatic tststatic2 tststatic3 tststatic4
> +tests-static += tststatic5 tststatic6
> +modules-names += modstatic modstatic2 modstatic3 modstatic5
>  tststatic-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
>  tststatic2-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
> +tststatic3-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
> +tststatic4-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
> +tststatic5-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
> +tststatic6-ENV = LD_LIBRARY_PATH=$(objpfx):$(common-objpfx):$(common-objpfx)elf
>  endif
>  
>  extra-test-objs += $(modules-names:=.os)
> @@ -104,6 +109,18 @@ $(objpfx)tststatic2.out: $(objpfx)tststa
>  
>  $(objpfx)modstatic2.so: $(libdl)
>  
> +$(objpfx)tststatic3: $(objpfx)libdl.a
> +$(objpfx)tststatic3.out: $(objpfx)tststatic3 $(objpfx)modstatic3.so
> +
> +$(objpfx)tststatic4: $(objpfx)libdl.a
> +$(objpfx)tststatic4.out: $(objpfx)tststatic4 $(objpfx)modstatic3.so
> +
> +$(objpfx)tststatic5: $(objpfx)libdl.a
> +$(objpfx)tststatic5.out: $(objpfx)tststatic5 $(objpfx)modstatic5.so
> +
> +$(objpfx)tststatic6: $(objpfx)libdl.a
> +$(objpfx)tststatic6.out: $(objpfx)tststatic6 $(objpfx)modstatic5.so
> +
>  $(objpfx)bug-dlopen1: $(libdl)
>  
>  $(objpfx)bug-dlsym1: $(libdl) $(objpfx)bug-dlsym1-lib2.so
> Index: glibc-fsf-trunk-quilt/dlfcn/modstatic3.c
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ glibc-fsf-trunk-quilt/dlfcn/modstatic3.c	2013-01-24 12:24:09.087820478 +0000
> @@ -0,0 +1,30 @@
> +/* Copyright (C) 2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library 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
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +unsigned int foo;
> +
> +unsigned int
> +getfoo (void)
> +{
> +  return foo;
> +}
> +
> +unsigned int
> +setfoo (unsigned int f)
> +{
> +  foo = f;
> +}
> Index: glibc-fsf-trunk-quilt/dlfcn/modstatic5.c
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ glibc-fsf-trunk-quilt/dlfcn/modstatic5.c	2013-01-23 03:12:02.036666536 +0000
> @@ -0,0 +1,24 @@
> +/* Copyright (C) 2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library 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
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <unistd.h>
> +
> +int
> +my_getpagesize (void)
> +{
> +  return getpagesize ();
> +}
> Index: glibc-fsf-trunk-quilt/dlfcn/tststatic3.c
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ glibc-fsf-trunk-quilt/dlfcn/tststatic3.c	2013-01-24 08:10:13.656588393 +0000
> @@ -0,0 +1,114 @@
> +/* Copyright (C) 2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library 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
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <dlfcn.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +
> +static int
> +do_test (void)
> +{
> +  unsigned int (*getfoo) (void);
> +  void (*setfoo) (unsigned int);
> +  unsigned int *foop;
> +  unsigned int foo;
> +  void *handle;
> +
> +  handle = dlopen ("modstatic3.so", RTLD_LAZY | RTLD_GLOBAL);
> +  if (handle == NULL)
> +    {
> +      printf ("dlopen (modstatic3.so): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  foop = dlsym (handle, "foo");
> +  if (foop == NULL)
> +    {
> +      printf ("dlsym (foo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  getfoo = dlsym (handle, "getfoo");
> +  if (getfoo == NULL)
> +    {
> +      printf ("dlsym (getfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  setfoo = dlsym (handle, "setfoo");
> +  if (setfoo == NULL)
> +    {
> +      printf ("dlsym (setfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  foo = *foop;
> +  if (foo != 0)
> +    {
> +      printf ("*foop: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  foo = getfoo ();
> +  if (foo != 0)
> +    {
> +      printf ("getfoo: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  setfoo (0x5500ffaa);
> +
> +  foo = *foop;
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("*foop: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  foo = getfoo ();
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("getfoo: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  setfoo (0xaaff0055);
> +
> +  foo = *foop;
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("*foop: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  foo = getfoo ();
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("getfoo: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  getfoo = NULL;
> +  setfoo = NULL;
> +  foop = NULL;
> +  dlclose (handle);
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> Index: glibc-fsf-trunk-quilt/dlfcn/tststatic4.c
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ glibc-fsf-trunk-quilt/dlfcn/tststatic4.c	2013-01-24 08:12:43.657338293 +0000
> @@ -0,0 +1,340 @@
> +/* Copyright (C) 2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library 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
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <dlfcn.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +
> +static int
> +do_test (void)
> +{
> +  unsigned int (*initial_getfoo) (void);
> +  void (*initial_setfoo) (unsigned int);
> +  unsigned int (*global_getfoo) (void);
> +  void (*global_setfoo) (unsigned int);
> +  unsigned int (*local_getfoo) (void);
> +  void (*local_setfoo) (unsigned int);
> +  unsigned int *initial_foop;
> +  unsigned int *global_foop;
> +  unsigned int *local_foop;
> +  void *initial_handle;
> +  void *global_handle;
> +  void *local_handle;
> +  unsigned int foo;
> +
> +  initial_handle = dlopen (NULL, RTLD_LAZY | RTLD_GLOBAL);
> +  if (initial_handle == NULL)
> +    {
> +      printf ("dlopen [initial] (NULL): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  initial_foop = dlsym (initial_handle, "foo");
> +  if (initial_foop != NULL)
> +    {
> +      printf ("dlsym [initial] (foo): got %p, expected NULL\n", initial_foop);
> +      return 1;
> +    }
> +
> +  initial_getfoo = dlsym (initial_handle, "getfoo");
> +  if (initial_getfoo != NULL)
> +    {
> +      printf ("dlsym [initial] (getfoo): got %p, expected NULL\n",
> +	      initial_getfoo);
> +      return 1;
> +    }
> +
> +  initial_setfoo = dlsym (initial_handle, "setfoo");
> +  if (initial_setfoo != NULL)
> +    {
> +      printf ("dlsym [initial] (setfoo): got %p, expected NULL\n",
> +	      initial_setfoo);
> +      return 1;
> +    }
> +
> +  global_handle = dlopen ("modstatic3.so", RTLD_LAZY | RTLD_GLOBAL);
> +  if (global_handle == NULL)
> +    {
> +      printf ("dlopen [global] (modstatic3.so): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  global_foop = dlsym (global_handle, "foo");
> +  if (global_foop == NULL)
> +    {
> +      printf ("dlsym [global] (foo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  global_getfoo = dlsym (global_handle, "getfoo");
> +  if (global_getfoo == NULL)
> +    {
> +      printf ("dlsym [global] (getfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  global_setfoo = dlsym (global_handle, "setfoo");
> +  if (global_setfoo == NULL)
> +    {
> +      printf ("dlsym [global] (setfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  local_handle = dlopen (NULL, RTLD_LAZY | RTLD_LOCAL);
> +  if (local_handle == NULL)
> +    {
> +      printf ("dlopen [local] (NULL): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  local_foop = dlsym (local_handle, "foo");
> +  if (local_foop == NULL)
> +    {
> +      printf ("dlsym [local] (foo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  local_getfoo = dlsym (local_handle, "getfoo");
> +  if (local_getfoo == NULL)
> +    {
> +      printf ("dlsym [local] (getfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  local_setfoo = dlsym (local_handle, "setfoo");
> +  if (local_setfoo == NULL)
> +    {
> +      printf ("dlsym [local] (setfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  initial_foop = dlsym (initial_handle, "foo");
> +  if (initial_foop == NULL)
> +    {
> +      printf ("dlsym [local] (foo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  initial_getfoo = dlsym (initial_handle, "getfoo");
> +  if (initial_getfoo == NULL)
> +    {
> +      printf ("dlsym [local] (getfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  initial_setfoo = dlsym (initial_handle, "setfoo");
> +  if (initial_setfoo == NULL)
> +    {
> +      printf ("dlsym [local] (setfoo): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  foo = *initial_foop;
> +  if (foo != 0)
> +    {
> +      printf ("*foop [initial]: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *global_foop;
> +  if (foo != 0)
> +    {
> +      printf ("*foop [global]: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *local_foop;
> +  if (foo != 0)
> +    {
> +      printf ("*foop [local]: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  foo = initial_getfoo ();
> +  if (foo != 0)
> +    {
> +      printf ("getfoo [initial]: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  foo = global_getfoo ();
> +  if (foo != 0)
> +    {
> +      printf ("getfoo [global]: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  foo = local_getfoo ();
> +  if (foo != 0)
> +    {
> +      printf ("getfoo [local]: got 0x%x, expected 0x0\n", foo);
> +      return 1;
> +    }
> +
> +  initial_setfoo (0x5500ffaa);
> +
> +  foo = *initial_foop;
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("*foop [initial]: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *global_foop;
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("*foop [global]: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *local_foop;
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("*foop [local]: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  foo = initial_getfoo ();
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("getfoo [initial]: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  foo = global_getfoo ();
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("getfoo [global]: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  foo = local_getfoo ();
> +  if (foo != 0x5500ffaa)
> +    {
> +      printf ("getfoo [local]: got 0x%x, expected 0x5500ffaa\n", foo);
> +      return 1;
> +    }
> +
> +  global_setfoo (0xaaff0055);
> +
> +  foo = *initial_foop;
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("*foop [initial]: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *global_foop;
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("*foop [global]: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *local_foop;
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("*foop [local]: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  foo = initial_getfoo ();
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("getfoo [initial]: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  foo = global_getfoo ();
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("getfoo [global]: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  foo = local_getfoo ();
> +  if (foo != 0xaaff0055)
> +    {
> +      printf ("getfoo [local]: got 0x%x, expected 0xaaff0055\n", foo);
> +      return 1;
> +    }
> +
> +  local_setfoo (0xff55aa00);
> +
> +  foo = *initial_foop;
> +  if (foo != 0xff55aa00)
> +    {
> +      printf ("*foop [initial]: got 0x%x, expected 0xff55aa00\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *global_foop;
> +  if (foo != 0xff55aa00)
> +    {
> +      printf ("*foop [global]: got 0x%x, expected 0xff55aa00\n", foo);
> +      return 1;
> +    }
> +
> +  foo = *local_foop;
> +  if (foo != 0xff55aa00)
> +    {
> +      printf ("*foop [local]: got 0x%x, expected 0xff55aa00\n", foo);
> +      return 1;
> +    }
> +
> +  foo = initial_getfoo ();
> +  if (foo != 0xff55aa00)
> +    {
> +      printf ("getfoo [initial]: got 0x%x, expected 0xff55aa00\n", foo);
> +      return 1;
> +    }
> +
> +  foo = global_getfoo ();
> +  if (foo != 0xff55aa00)
> +    {
> +      printf ("getfoo [global]: got 0x%x, expected 0xff55aa00\n", foo);
> +      return 1;
> +    }
> +
> +  foo = local_getfoo ();
> +  if (foo != 0xff55aa00)
> +    {
> +      printf ("getfoo [local]: got 0x%x, expected 0xff55aa00\n", foo);
> +      return 1;
> +    }
> +
> +  initial_getfoo = NULL;
> +  initial_setfoo = NULL;
> +  initial_foop = NULL;
> +
> +  local_getfoo = NULL;
> +  local_setfoo = NULL;
> +  local_foop = NULL;
> +  dlclose (local_handle);
> +
> +  global_getfoo = NULL;
> +  global_setfoo = NULL;
> +  global_foop = NULL;
> +  dlclose (global_handle);
> +
> +  dlclose (initial_handle);
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> Index: glibc-fsf-trunk-quilt/dlfcn/tststatic5.c
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ glibc-fsf-trunk-quilt/dlfcn/tststatic5.c	2013-01-24 08:09:14.486499700 +0000
> @@ -0,0 +1,59 @@
> +/* Copyright (C) 2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library 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
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <dlfcn.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +static int
> +do_test (void)
> +{
> +  int pagesize = getpagesize ();
> +  int (*my_getpagesize) (void);
> +  int my_pagesize;
> +  void *handle;
> +
> +  handle = dlopen ("modstatic5.so", RTLD_LAZY | RTLD_GLOBAL);
> +  if (handle == NULL)
> +    {
> +      printf ("dlopen (modstatic5.so): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  my_getpagesize = dlsym (handle, "my_getpagesize");
> +  if (my_getpagesize == NULL)
> +    {
> +      printf ("dlsym (my_getpagesize): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  my_pagesize = my_getpagesize ();
> +  if (my_pagesize != pagesize)
> +    {
> +      printf ("my_getpagesize: got %i, expected %i\n", my_pagesize, pagesize);
> +      return 1;
> +    }
> +
> +  my_getpagesize = NULL;
> +  dlclose (handle);
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> Index: glibc-fsf-trunk-quilt/dlfcn/tststatic6.c
> ===================================================================
> --- /dev/null	1970-01-01 00:00:00.000000000 +0000
> +++ glibc-fsf-trunk-quilt/dlfcn/tststatic6.c	2013-01-24 08:08:54.587145321 +0000
> @@ -0,0 +1,125 @@
> +/* Copyright (C) 2013 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library 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
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include <dlfcn.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +static int
> +do_test (void)
> +{
> +  int (*my_initial_getpagesize) (void);
> +  int (*my_global_getpagesize) (void);
> +  int (*my_local_getpagesize) (void);
> +  int pagesize = getpagesize ();
> +  int my_initial_pagesize;
> +  int my_global_pagesize;
> +  int my_local_pagesize;
> +  void *initial_handle;
> +  void *global_handle;
> +  void *local_handle;
> +
> +  initial_handle = dlopen (NULL, RTLD_LAZY | RTLD_GLOBAL);
> +  if (initial_handle == NULL)
> +    {
> +      printf ("dlopen [initial] (NULL): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  my_initial_getpagesize = dlsym (initial_handle, "my_getpagesize");
> +  if (my_initial_getpagesize != NULL)
> +    {
> +      printf ("dlsym [initial] (my_getpagesize): got %p, expected NULL\n",
> +	      my_initial_getpagesize);
> +      return 1;
> +    }
> +
> +  global_handle = dlopen ("modstatic5.so", RTLD_LAZY | RTLD_GLOBAL);
> +  if (global_handle == NULL)
> +    {
> +      printf ("dlopen [global] (modstatic5.so): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  my_global_getpagesize = dlsym (global_handle, "my_getpagesize");
> +  if (my_global_getpagesize == NULL)
> +    {
> +      printf ("dlsym [global] (my_getpagesize): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  local_handle = dlopen (NULL, RTLD_LAZY | RTLD_LOCAL);
> +  if (local_handle == NULL)
> +    {
> +      printf ("dlopen [local] (NULL): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  my_local_getpagesize = dlsym (local_handle, "my_getpagesize");
> +  if (my_local_getpagesize == NULL)
> +    {
> +      printf ("dlsym [local] (my_getpagesize): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  my_initial_getpagesize = dlsym (initial_handle, "my_getpagesize");
> +  if (my_initial_getpagesize == NULL)
> +    {
> +      printf ("dlsym [initial] (my_getpagesize): %s\n", dlerror ());
> +      return 1;
> +    }
> +
> +  my_initial_pagesize = my_initial_getpagesize ();
> +  if (my_initial_pagesize != pagesize)
> +    {
> +      printf ("my_getpagesize [initial]: got %i, expected %i\n",
> +	      my_initial_pagesize, pagesize);
> +      return 1;
> +    }
> +
> +  my_global_pagesize = my_global_getpagesize ();
> +  if (my_global_pagesize != pagesize)
> +    {
> +      printf ("my_getpagesize [global]: got %i, expected %i\n",
> +	      my_global_pagesize, pagesize);
> +      return 1;
> +    }
> +
> +  my_local_pagesize = my_local_getpagesize ();
> +  if (my_local_pagesize != pagesize)
> +    {
> +      printf ("my_getpagesize [local]: got %i, expected %i\n",
> +	      my_local_pagesize, pagesize);
> +      return 1;
> +    }
> +
> +  my_initial_getpagesize = NULL;
> +
> +  my_local_getpagesize = NULL;
> +  dlclose (local_handle);
> +
> +  my_global_getpagesize = NULL;
> +  dlclose (global_handle);
> +
> +  dlclose (initial_handle);
> +
> +  return 0;
> +}
> +
> +#define TEST_FUNCTION do_test ()
> +#include "../test-skeleton.c"
> Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/ia64/dl-static.c
> ===================================================================
> --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/ia64/dl-static.c	2013-01-23 03:10:20.000000000 +0000
> +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/ia64/dl-static.c	2013-01-23 03:12:02.047777535 +0000
> @@ -52,6 +52,10 @@ _dl_static_init (struct link_map *map)
>    lookup_t loadbase;
>    void (*f) (void *[]);
>  
> +  /* Nothing to do if opening self.  */
> +  if (__builtin_expect (map->l_name[0] == '\0', 0))
> +    return;
> +
>    __libc_lock_lock_recursive (_dl_static_lock);
>  
>    loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref,
> Index: glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-static.c
> ===================================================================
> --- glibc-fsf-trunk-quilt.orig/ports/sysdeps/unix/sysv/linux/mips/dl-static.c	2013-01-23 03:10:20.000000000 +0000
> +++ glibc-fsf-trunk-quilt/ports/sysdeps/unix/sysv/linux/mips/dl-static.c	2013-01-23 03:12:02.047777535 +0000
> @@ -64,6 +64,10 @@ _dl_static_init (struct link_map *l)
>    void (*f) (void *[]);
>    size_t i;
>  
> +  /* Nothing to do if opening self.  */
> +  if (__builtin_expect (l->l_name[0] == '\0', 0))
> +    return;
> +
>    __libc_lock_lock_recursive (_dl_static_lock);
>  
>    loadbase = _dl_lookup_symbol_x ("_dl_var_init", l, &ref, l->l_local_scope,

-- 

Your computer hasn't been returning all the bits it gets from the Internet.


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