]>
Commit | Line | Data |
---|---|---|
b5aaf4cf AM |
1 | http://thread.gmane.org/gmane.comp.lib.glibc.user/579 |
2 | http://sources.redhat.com/bugzilla/show_bug.cgi?id=11929 | |
3 | http://bugs.gentoo.org/332927 | |
4 | ||
5 | a simple statically linked app fails with glibc-2.12: | |
6 | $ cat test.c | |
7 | main(){getpwnam("root");} | |
8 | $ gcc -static test.c | |
9 | $ ./a.out | |
10 | a.out: ../sysdeps/unix/sysv/linux/getpagesize.c:32: __getpagesize: | |
11 | Assertion `_rtld_global_ro._dl_pagesize != 0' failed. | |
12 | Aborted (core dumped) | |
13 | ||
14 | the crux of the matter seems to be the fact that static apps with | |
15 | glibc will dynamically load nss shared libraries when necessary. the | |
16 | static code will initialize GLRO(dl_pagesize) just fine from the | |
17 | kernel auxv, but this being the static code paths, GLRO(dl_pagesize) | |
18 | expands into _dl_pagesize. when the nss shared libraries are loaded | |
19 | up, the ldso is also mapped in, but it doesnt process the kernel auxv | |
20 | (_dl_sysdep_start() is not called). so the shared library | |
21 | GLRO(dl_pagesize) expands into _rtld_global_ro._dl_pagesize and that | |
22 | field stays at 0. | |
23 | ||
24 | then when the nss shared libs process the request and gets to the | |
25 | standard "passwd" database, it calls the shared lib versions of | |
26 | malloc/stdio which rely on the __getpagesize() function. but this | |
27 | being in the shared library, it reads the shared GLRO(dl_pagesize) | |
28 | which is 0, and the assert() is triggered. | |
29 | ||
30 | i think running nscd makes things work because its nss module that | |
31 | talks to the nscd daemon doesnt call any routines that implicitly rely | |
32 | on __getpagesize(). | |
33 | ||
34 | this all started happening after this commit: | |
35 | From 8f4a5048eea6536ee85c0f2670adbb97d71e427d Mon Sep 17 00:00:00 2001 | |
36 | From: Ulrich Drepper <drepper@redhat.com> | |
37 | Date: Sat, 27 Mar 2010 06:19:50 -0700 | |
38 | Subject: [PATCH] Optimize __getpagesize a bit. | |
39 | ||
40 | if we look at the ia64 port, we see that it has had similar logic for | |
41 | its __getpagesize function forever. so take its DL_STATIC_INIT code | |
42 | and move it up to the common linux tree. | |
43 | ||
f69cae76 JR |
44 | 2010-08-18 Mike Frysinger <vapier@gentoo.org> |
45 | ||
46 | * sysdeps/unix/sysv/linux/ia64/Makefile: Move dl-static addition to | |
47 | sysdep vars for subdir==elf to ... | |
48 | * sysdeps/unix/sysv/linux/Makefile: ... here. | |
49 | * sysdeps/unix/sysv/linux/ia64/dl-static.c: Move file to ... | |
50 | * sysdeps/unix/sysv/linux/dl-static.c: ... here. | |
51 | * sysdeps/unix/sysv/linux/ia64/ldsodefs.h: Delete, and move the | |
52 | DL_STATIC_INIT defines to ... | |
53 | * sysdeps/unix/sysv/linux/ldsodefs.h: ... here. | |
54 | * sysdeps/unix/sysv/linux/ia64/getpagesize.c: Delete. | |
55 | ||
56 | diff --git a/sysdeps/unix/sysv/linux/ia64/Makefile b/sysdeps/unix/sysv/linux/ia64/Makefile | |
57 | index d9a35a7..3bb1ce0 100644 | |
58 | --- a/sysdeps/unix/sysv/linux/ia64/Makefile | |
59 | +++ b/sysdeps/unix/sysv/linux/ia64/Makefile | |
60 | @@ -12,12 +12,6 @@ sysdep_headers += sys/io.h | |
61 | sysdep_routines += ioperm clone2 | |
62 | endif | |
63 | ||
64 | -ifeq ($(subdir),elf) | |
65 | -sysdep-dl-routines += dl-static | |
66 | -sysdep_routines += $(sysdep-dl-routines) | |
67 | -sysdep-rtld-routines += $(sysdep-dl-routines) | |
68 | -endif | |
69 | - | |
70 | ifeq ($(subdir),rt) | |
71 | librt-routines += rt-sysdep | |
72 | endif | |
73 | diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile | |
74 | index 4302bd3..37c56a3 100644 | |
75 | --- a/sysdeps/unix/sysv/linux/Makefile | |
76 | +++ b/sysdeps/unix/sysv/linux/Makefile | |
f2b5e8be | 77 | @@ -147,8 +147,10 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ |
f69cae76 JR |
78 | endif |
79 | ||
80 | ifeq ($(subdir),elf) | |
f2b5e8be AM |
81 | -sysdep-rtld-routines += dl-brk dl-sbrk dl-getcwd dl-openat64 dl-opendir \ |
82 | - dl-fxstatat64 | |
f69cae76 JR |
83 | +sysdep-dl-routines += dl-static |
84 | +sysdep_routines += dl-static | |
f2b5e8be | 85 | +sysdep-rtld-routines += dl-brk dl-sbrk dl-getcwd dl-openat64 dl-opendir \ |
9d0a498b | 86 | + dl-fxstatat64 dl-static |
f69cae76 JR |
87 | |
88 | CPPFLAGS-lddlibc4 += -DNOT_IN_libc | |
89 | endif | |
90 | diff --git a/sysdeps/unix/sysv/linux/ia64/dl-static.c b/sysdeps/unix/sysv/linux/ia64/dl-static.c | |
91 | deleted file mode 100644 | |
92 | index 4efc077..0000000 | |
93 | --- a/sysdeps/unix/sysv/linux/ia64/dl-static.c | |
94 | +++ /dev/null | |
95 | @@ -1,69 +0,0 @@ | |
96 | -/* Variable initialization. IA-64 version. | |
97 | - Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | |
98 | - This file is part of the GNU C Library. | |
99 | - | |
100 | - The GNU C Library is free software; you can redistribute it and/or | |
101 | - modify it under the terms of the GNU Lesser General Public | |
102 | - License as published by the Free Software Foundation; either | |
103 | - version 2.1 of the License, or (at your option) any later version. | |
104 | - | |
105 | - The GNU C Library is distributed in the hope that it will be useful, | |
106 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
107 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
108 | - Lesser General Public License for more details. | |
109 | - | |
110 | - You should have received a copy of the GNU Lesser General Public | |
111 | - License along with the GNU C Library; if not, write to the Free | |
112 | - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
113 | - 02111-1307 USA. */ | |
114 | - | |
115 | -#include <ldsodefs.h> | |
116 | - | |
117 | -#ifdef SHARED | |
118 | - | |
119 | -void | |
120 | -_dl_var_init (void *array[]) | |
121 | -{ | |
122 | - /* It has to match "variables" below. */ | |
123 | - enum | |
124 | - { | |
125 | - DL_PAGESIZE = 0, | |
126 | - DL_CLKTCK | |
127 | - }; | |
128 | - | |
129 | - GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); | |
130 | - GLRO(dl_clktck) = *((int *) array[DL_CLKTCK]); | |
131 | -} | |
132 | - | |
133 | -#else | |
134 | -#include <bits/libc-lock.h> | |
135 | - | |
136 | -__libc_lock_define_initialized_recursive (static, _dl_static_lock) | |
137 | - | |
138 | -static void *variables[] = | |
139 | -{ | |
140 | - &GLRO(dl_pagesize), | |
141 | - &GLRO(dl_clktck) | |
142 | -}; | |
143 | - | |
144 | -void | |
145 | -_dl_static_init (struct link_map *map) | |
146 | -{ | |
147 | - const ElfW(Sym) *ref = NULL; | |
148 | - lookup_t loadbase; | |
149 | - void (*f) (void *[]); | |
150 | - | |
151 | - __libc_lock_lock_recursive (_dl_static_lock); | |
152 | - | |
153 | - loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref, | |
154 | - map->l_local_scope, NULL, 0, 1, NULL); | |
155 | - if (ref != NULL) | |
156 | - { | |
157 | - f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref); | |
158 | - f (variables); | |
159 | - } | |
160 | - | |
161 | - __libc_lock_unlock_recursive (_dl_static_lock); | |
162 | -} | |
163 | - | |
164 | -#endif | |
165 | diff --git a/sysdeps/unix/sysv/linux/dl-static.c b/sysdeps/unix/sysv/linux/dl-static.c | |
166 | new file mode 100644 | |
167 | index 0000000..fa70811 | |
168 | --- /dev/null | |
169 | +++ b/sysdeps/unix/sysv/linux/dl-static.c | |
170 | @@ -0,0 +1,69 @@ | |
171 | +/* Variable initialization. | |
172 | + Copyright (C) 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc. | |
173 | + This file is part of the GNU C Library. | |
174 | + | |
175 | + The GNU C Library is free software; you can redistribute it and/or | |
176 | + modify it under the terms of the GNU Lesser General Public | |
177 | + License as published by the Free Software Foundation; either | |
178 | + version 2.1 of the License, or (at your option) any later version. | |
179 | + | |
180 | + The GNU C Library is distributed in the hope that it will be useful, | |
181 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
182 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
183 | + Lesser General Public License for more details. | |
184 | + | |
185 | + You should have received a copy of the GNU Lesser General Public | |
186 | + License along with the GNU C Library; if not, write to the Free | |
187 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
188 | + 02111-1307 USA. */ | |
189 | + | |
190 | +#include <ldsodefs.h> | |
191 | + | |
192 | +#ifdef SHARED | |
193 | + | |
194 | +void | |
195 | +_dl_var_init (void *array[]) | |
196 | +{ | |
197 | + /* It has to match "variables" below. */ | |
198 | + enum | |
199 | + { | |
200 | + DL_PAGESIZE = 0, | |
201 | + DL_CLKTCK | |
202 | + }; | |
203 | + | |
204 | + GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); | |
205 | + GLRO(dl_clktck) = *((int *) array[DL_CLKTCK]); | |
206 | +} | |
207 | + | |
208 | +#else | |
209 | +#include <bits/libc-lock.h> | |
210 | + | |
211 | +__libc_lock_define_initialized_recursive (static, _dl_static_lock) | |
212 | + | |
213 | +static void *variables[] = | |
214 | +{ | |
215 | + &GLRO(dl_pagesize), | |
216 | + &GLRO(dl_clktck) | |
217 | +}; | |
218 | + | |
219 | +void | |
220 | +_dl_static_init (struct link_map *map) | |
221 | +{ | |
222 | + const ElfW(Sym) *ref = NULL; | |
223 | + lookup_t loadbase; | |
224 | + void (*f) (void *[]); | |
225 | + | |
226 | + __libc_lock_lock_recursive (_dl_static_lock); | |
227 | + | |
228 | + loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref, | |
229 | + map->l_local_scope, NULL, 0, 1, NULL); | |
230 | + if (ref != NULL) | |
231 | + { | |
232 | + f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref); | |
233 | + f (variables); | |
234 | + } | |
235 | + | |
236 | + __libc_lock_unlock_recursive (_dl_static_lock); | |
237 | +} | |
238 | + | |
239 | +#endif | |
240 | diff --git a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h b/sysdeps/unix/sysv/linux/ia64/ldsodefs.h | |
241 | deleted file mode 100644 | |
242 | index 31af624..0000000 | |
243 | --- a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h | |
244 | +++ /dev/null | |
245 | @@ -1,33 +0,0 @@ | |
246 | -/* Run-time dynamic linker data structures for loaded ELF shared objects. IA64. | |
247 | - Copyright (C) 2001 Free Software Foundation, Inc. | |
248 | - This file is part of the GNU C Library. | |
249 | - | |
250 | - The GNU C Library is free software; you can redistribute it and/or | |
251 | - modify it under the terms of the GNU Lesser General Public | |
252 | - License as published by the Free Software Foundation; either | |
253 | - version 2.1 of the License, or (at your option) any later version. | |
254 | - | |
255 | - The GNU C Library is distributed in the hope that it will be useful, | |
256 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
257 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
258 | - Lesser General Public License for more details. | |
259 | - | |
260 | - You should have received a copy of the GNU Lesser General Public | |
261 | - License along with the GNU C Library; if not, write to the Free | |
262 | - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
263 | - 02111-1307 USA. */ | |
264 | - | |
265 | -#ifndef _LDSODEFS_H | |
266 | - | |
267 | -/* Get the real definitions. */ | |
268 | -#include_next <ldsodefs.h> | |
269 | - | |
270 | -/* Now define our stuff. */ | |
271 | - | |
272 | -/* We need special support to initialize DSO loaded for statically linked | |
273 | - binaries. */ | |
274 | -extern void _dl_static_init (struct link_map *map); | |
275 | -#undef DL_STATIC_INIT | |
276 | -#define DL_STATIC_INIT(map) _dl_static_init (map) | |
277 | - | |
278 | -#endif /* ldsodefs.h */ | |
279 | diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h | |
280 | index 5d5b1b4..ecb5d4f 100644 | |
281 | --- a/sysdeps/unix/sysv/linux/ldsodefs.h | |
282 | +++ b/sysdeps/unix/sysv/linux/ldsodefs.h | |
283 | @@ -36,6 +36,12 @@ extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function; | |
284 | /* Initialization which is normally done by the dynamic linker. */ | |
285 | extern void _dl_non_dynamic_init (void) internal_function; | |
286 | ||
287 | +/* We need special support to initialize DSO loaded for statically linked | |
288 | + binaries. */ | |
289 | +extern void _dl_static_init (struct link_map *map); | |
290 | +#undef DL_STATIC_INIT | |
291 | +#define DL_STATIC_INIT(map) _dl_static_init (map) | |
292 | + | |
293 | /* We can assume that the kernel always provides the AT_UID, AT_EUID, | |
294 | AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */ | |
295 | #if __ASSUME_AT_XID | |
296 | diff --git a/sysdeps/unix/sysv/linux/ia64/getpagesize.c b/sysdeps/unix/sysv/linux/ia64/getpagesize.c | |
297 | deleted file mode 100644 | |
298 | index 1155dfd..0000000 | |
299 | --- a/sysdeps/unix/sysv/linux/ia64/getpagesize.c | |
300 | +++ /dev/null | |
301 | @@ -1,39 +0,0 @@ | |
302 | -/* Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. | |
303 | - This file is part of the GNU C Library. | |
304 | - | |
305 | - The GNU C Library is free software; you can redistribute it and/or | |
306 | - modify it under the terms of the GNU Lesser General Public | |
307 | - License as published by the Free Software Foundation; either | |
308 | - version 2.1 of the License, or (at your option) any later version. | |
309 | - | |
310 | - The GNU C Library is distributed in the hope that it will be useful, | |
311 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | |
312 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
313 | - Lesser General Public License for more details. | |
314 | - | |
315 | - You should have received a copy of the GNU Lesser General Public | |
316 | - License along with the GNU C Library; if not, write to the Free | |
317 | - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
318 | - 02111-1307 USA. */ | |
319 | - | |
320 | -#include <assert.h> | |
321 | -#include <unistd.h> | |
322 | -#include <sys/param.h> | |
323 | - | |
324 | -#include <ldsodefs.h> | |
325 | -#include <sysdep.h> | |
326 | -#include <sys/syscall.h> | |
327 | - | |
328 | -/* Return the system page size. The return value will depend on how | |
329 | - the kernel is configured. A program must use this call to | |
330 | - determine the page size to ensure proper alignment for calls such | |
331 | - as mmap and friends. --davidm 99/11/30 */ | |
332 | - | |
333 | -int | |
334 | -__getpagesize () | |
335 | -{ | |
336 | - assert (GLRO(dl_pagesize) != 0); | |
337 | - return GLRO(dl_pagesize); | |
338 | -} | |
339 | -libc_hidden_def (__getpagesize) | |
340 | -weak_alias (__getpagesize, getpagesize) |