mirror of
https://gitdl.cn/https://github.com/chakralinux/core.git
synced 2025-02-03 20:07:14 +08:00
339 lines
11 KiB
Diff
339 lines
11 KiB
Diff
http://thread.gmane.org/gmane.comp.lib.glibc.user/579
|
|
http://sources.redhat.com/bugzilla/show_bug.cgi?id=11929
|
|
http://bugs.gentoo.org/332927
|
|
|
|
a simple statically linked app fails with glibc-2.12:
|
|
$ cat test.c
|
|
main(){getpwnam("root");}
|
|
$ gcc -static test.c
|
|
$ ./a.out
|
|
a.out: ../sysdeps/unix/sysv/linux/getpagesize.c:32: __getpagesize:
|
|
Assertion `_rtld_global_ro._dl_pagesize != 0' failed.
|
|
Aborted (core dumped)
|
|
|
|
the crux of the matter seems to be the fact that static apps with
|
|
glibc will dynamically load nss shared libraries when necessary. the
|
|
static code will initialize GLRO(dl_pagesize) just fine from the
|
|
kernel auxv, but this being the static code paths, GLRO(dl_pagesize)
|
|
expands into _dl_pagesize. when the nss shared libraries are loaded
|
|
up, the ldso is also mapped in, but it doesnt process the kernel auxv
|
|
(_dl_sysdep_start() is not called). so the shared library
|
|
GLRO(dl_pagesize) expands into _rtld_global_ro._dl_pagesize and that
|
|
field stays at 0.
|
|
|
|
then when the nss shared libs process the request and gets to the
|
|
standard "passwd" database, it calls the shared lib versions of
|
|
malloc/stdio which rely on the __getpagesize() function. but this
|
|
being in the shared library, it reads the shared GLRO(dl_pagesize)
|
|
which is 0, and the assert() is triggered.
|
|
|
|
i think running nscd makes things work because its nss module that
|
|
talks to the nscd daemon doesnt call any routines that implicitly rely
|
|
on __getpagesize().
|
|
|
|
this all started happening after this commit:
|
|
From 8f4a5048eea6536ee85c0f2670adbb97d71e427d Mon Sep 17 00:00:00 2001
|
|
From: Ulrich Drepper <drepper@redhat.com>
|
|
Date: Sat, 27 Mar 2010 06:19:50 -0700
|
|
Subject: [PATCH] Optimize __getpagesize a bit.
|
|
|
|
if we look at the ia64 port, we see that it has had similar logic for
|
|
its __getpagesize function forever. so take its DL_STATIC_INIT code
|
|
and move it up to the common linux tree.
|
|
|
|
2010-08-18 Mike Frysinger <vapier@gentoo.org>
|
|
|
|
* sysdeps/unix/sysv/linux/ia64/Makefile: Move dl-static addition to
|
|
sysdep vars for subdir==elf to ...
|
|
* sysdeps/unix/sysv/linux/Makefile: ... here.
|
|
* sysdeps/unix/sysv/linux/ia64/dl-static.c: Move file to ...
|
|
* sysdeps/unix/sysv/linux/dl-static.c: ... here.
|
|
* sysdeps/unix/sysv/linux/ia64/ldsodefs.h: Delete, and move the
|
|
DL_STATIC_INIT defines to ...
|
|
* sysdeps/unix/sysv/linux/ldsodefs.h: ... here.
|
|
* sysdeps/unix/sysv/linux/ia64/getpagesize.c: Delete.
|
|
|
|
diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile
|
|
index d9a35a7..3bb1ce0 100644
|
|
--- a/sysdeps/unix/sysv/linux/ia64/Makefile
|
|
+++ b/sysdeps/unix/sysv/linux/ia64/Makefile
|
|
@@ -12,12 +12,6 @@ sysdep_headers += sys/io.h
|
|
sysdep_routines += ioperm clone2
|
|
endif
|
|
|
|
-ifeq ($(subdir),elf)
|
|
-sysdep-dl-routines += dl-static
|
|
-sysdep_routines += $(sysdep-dl-routines)
|
|
-sysdep-rtld-routines += $(sysdep-dl-routines)
|
|
-endif
|
|
-
|
|
ifeq ($(subdir),rt)
|
|
librt-routines += rt-sysdep
|
|
endif
|
|
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
|
|
index 4302bd3..37c56a3 100644
|
|
--- a/sysdeps/unix/sysv/linux/Makefile
|
|
+++ b/sysdeps/unix/sysv/linux/Makefile
|
|
@@ -147,7 +147,9 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
|
|
endif
|
|
|
|
ifeq ($(subdir),elf)
|
|
-sysdep-rtld-routines += dl-brk dl-sbrk
|
|
+sysdep-dl-routines += dl-static
|
|
+sysdep_routines += dl-static
|
|
+sysdep-rtld-routines += dl-brk dl-sbrk dl-static
|
|
|
|
CPPFLAGS-lddlibc4 += -DNOT_IN_libc
|
|
endif
|
|
diff --git a/sysdeps/unix/sysv/linux/ia64/dl-static.c b/sysdeps/unix/sysv/linux/ia64/dl-static.c
|
|
deleted file mode 100644
|
|
index 4efc077..0000000
|
|
--- a/sysdeps/unix/sysv/linux/ia64/dl-static.c
|
|
+++ /dev/null
|
|
@@ -1,69 +0,0 @@
|
|
-/* Variable initialization. IA-64 version.
|
|
- Copyright (C) 2001, 2002, 2003, 2004 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, write to the Free
|
|
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
- 02111-1307 USA. */
|
|
-
|
|
-#include <ldsodefs.h>
|
|
-
|
|
-#ifdef SHARED
|
|
-
|
|
-void
|
|
-_dl_var_init (void *array[])
|
|
-{
|
|
- /* It has to match "variables" below. */
|
|
- enum
|
|
- {
|
|
- DL_PAGESIZE = 0,
|
|
- DL_CLKTCK
|
|
- };
|
|
-
|
|
- GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]);
|
|
- GLRO(dl_clktck) = *((int *) array[DL_CLKTCK]);
|
|
-}
|
|
-
|
|
-#else
|
|
-#include <bits/libc-lock.h>
|
|
-
|
|
-__libc_lock_define_initialized_recursive (static, _dl_static_lock)
|
|
-
|
|
-static void *variables[] =
|
|
-{
|
|
- &GLRO(dl_pagesize),
|
|
- &GLRO(dl_clktck)
|
|
-};
|
|
-
|
|
-void
|
|
-_dl_static_init (struct link_map *map)
|
|
-{
|
|
- const ElfW(Sym) *ref = NULL;
|
|
- lookup_t loadbase;
|
|
- void (*f) (void *[]);
|
|
-
|
|
- __libc_lock_lock_recursive (_dl_static_lock);
|
|
-
|
|
- loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref,
|
|
- map->l_local_scope, NULL, 0, 1, NULL);
|
|
- if (ref != NULL)
|
|
- {
|
|
- f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref);
|
|
- f (variables);
|
|
- }
|
|
-
|
|
- __libc_lock_unlock_recursive (_dl_static_lock);
|
|
-}
|
|
-
|
|
-#endif
|
|
diff --git a/sysdeps/unix/sysv/linux/dl-static.c b/sysdeps/unix/sysv/linux/dl-static.c
|
|
new file mode 100644
|
|
index 0000000..fa70811
|
|
--- /dev/null
|
|
+++ b/sysdeps/unix/sysv/linux/dl-static.c
|
|
@@ -0,0 +1,69 @@
|
|
+/* Variable initialization.
|
|
+ Copyright (C) 2001, 2002, 2003, 2004, 2010 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, write to the Free
|
|
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
+ 02111-1307 USA. */
|
|
+
|
|
+#include <ldsodefs.h>
|
|
+
|
|
+#ifdef SHARED
|
|
+
|
|
+void
|
|
+_dl_var_init (void *array[])
|
|
+{
|
|
+ /* It has to match "variables" below. */
|
|
+ enum
|
|
+ {
|
|
+ DL_PAGESIZE = 0,
|
|
+ DL_CLKTCK
|
|
+ };
|
|
+
|
|
+ GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]);
|
|
+ GLRO(dl_clktck) = *((int *) array[DL_CLKTCK]);
|
|
+}
|
|
+
|
|
+#else
|
|
+#include <bits/libc-lock.h>
|
|
+
|
|
+__libc_lock_define_initialized_recursive (static, _dl_static_lock)
|
|
+
|
|
+static void *variables[] =
|
|
+{
|
|
+ &GLRO(dl_pagesize),
|
|
+ &GLRO(dl_clktck)
|
|
+};
|
|
+
|
|
+void
|
|
+_dl_static_init (struct link_map *map)
|
|
+{
|
|
+ const ElfW(Sym) *ref = NULL;
|
|
+ lookup_t loadbase;
|
|
+ void (*f) (void *[]);
|
|
+
|
|
+ __libc_lock_lock_recursive (_dl_static_lock);
|
|
+
|
|
+ loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref,
|
|
+ map->l_local_scope, NULL, 0, 1, NULL);
|
|
+ if (ref != NULL)
|
|
+ {
|
|
+ f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref);
|
|
+ f (variables);
|
|
+ }
|
|
+
|
|
+ __libc_lock_unlock_recursive (_dl_static_lock);
|
|
+}
|
|
+
|
|
+#endif
|
|
diff --git a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h b/sysdeps/unix/sysv/linux/ia64/ldsodefs.h
|
|
deleted file mode 100644
|
|
index 31af624..0000000
|
|
--- a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h
|
|
+++ /dev/null
|
|
@@ -1,33 +0,0 @@
|
|
-/* Run-time dynamic linker data structures for loaded ELF shared objects. IA64.
|
|
- Copyright (C) 2001 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, write to the Free
|
|
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
- 02111-1307 USA. */
|
|
-
|
|
-#ifndef _LDSODEFS_H
|
|
-
|
|
-/* Get the real definitions. */
|
|
-#include_next <ldsodefs.h>
|
|
-
|
|
-/* Now define our stuff. */
|
|
-
|
|
-/* We need special support to initialize DSO loaded for statically linked
|
|
- binaries. */
|
|
-extern void _dl_static_init (struct link_map *map);
|
|
-#undef DL_STATIC_INIT
|
|
-#define DL_STATIC_INIT(map) _dl_static_init (map)
|
|
-
|
|
-#endif /* ldsodefs.h */
|
|
diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h
|
|
index 5d5b1b4..ecb5d4f 100644
|
|
--- a/sysdeps/unix/sysv/linux/ldsodefs.h
|
|
+++ b/sysdeps/unix/sysv/linux/ldsodefs.h
|
|
@@ -36,6 +36,12 @@ extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function;
|
|
/* Initialization which is normally done by the dynamic linker. */
|
|
extern void _dl_non_dynamic_init (void) internal_function;
|
|
|
|
+/* We need special support to initialize DSO loaded for statically linked
|
|
+ binaries. */
|
|
+extern void _dl_static_init (struct link_map *map);
|
|
+#undef DL_STATIC_INIT
|
|
+#define DL_STATIC_INIT(map) _dl_static_init (map)
|
|
+
|
|
/* We can assume that the kernel always provides the AT_UID, AT_EUID,
|
|
AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */
|
|
#if __ASSUME_AT_XID
|
|
diff --git a/sysdeps/unix/sysv/linux/ia64/getpagesize.c b/sysdeps/unix/sysv/linux/ia64/getpagesize.c
|
|
deleted file mode 100644
|
|
index 1155dfd..0000000
|
|
--- a/sysdeps/unix/sysv/linux/ia64/getpagesize.c
|
|
+++ /dev/null
|
|
@@ -1,39 +0,0 @@
|
|
-/* Copyright (C) 1999, 2000, 2001, 2002, 2004 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, write to the Free
|
|
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
- 02111-1307 USA. */
|
|
-
|
|
-#include <assert.h>
|
|
-#include <unistd.h>
|
|
-#include <sys/param.h>
|
|
-
|
|
-#include <ldsodefs.h>
|
|
-#include <sysdep.h>
|
|
-#include <sys/syscall.h>
|
|
-
|
|
-/* Return the system page size. The return value will depend on how
|
|
- the kernel is configured. A program must use this call to
|
|
- determine the page size to ensure proper alignment for calls such
|
|
- as mmap and friends. --davidm 99/11/30 */
|
|
-
|
|
-int
|
|
-__getpagesize ()
|
|
-{
|
|
- assert (GLRO(dl_pagesize) != 0);
|
|
- return GLRO(dl_pagesize);
|
|
-}
|
|
-libc_hidden_def (__getpagesize)
|
|
-weak_alias (__getpagesize, getpagesize)
|