Annotation of /trunk/glibc/patches/glibc-2.12.1-static-shared-getpagesize.patch
Parent Directory | Revision Log
Revision 1182 -
(hide annotations)
(download)
Tue Oct 19 17:32:42 2010 UTC (13 years, 11 months ago) by niro
File size: 11637 byte(s)
Tue Oct 19 17:32:42 2010 UTC (13 years, 11 months ago) by niro
File size: 11637 byte(s)
fix static programs; see: http://bugs.gentoo.org/332927
1 | niro | 1182 | 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 | |||
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 | ||
77 | @@ -147,7 +147,9 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \ | ||
78 | endif | ||
79 | |||
80 | ifeq ($(subdir),elf) | ||
81 | -sysdep-rtld-routines += dl-brk dl-sbrk | ||
82 | +sysdep-dl-routines += dl-static | ||
83 | +sysdep_routines += dl-static | ||
84 | +sysdep-rtld-routines += dl-brk dl-sbrk dl-static | ||
85 | |||
86 | CPPFLAGS-lddlibc4 += -DNOT_IN_libc | ||
87 | endif | ||
88 | diff --git a/sysdeps/unix/sysv/linux/ia64/dl-static.c b/sysdeps/unix/sysv/linux/ia64/dl-static.c | ||
89 | deleted file mode 100644 | ||
90 | index 4efc077..0000000 | ||
91 | --- a/sysdeps/unix/sysv/linux/ia64/dl-static.c | ||
92 | +++ /dev/null | ||
93 | @@ -1,69 +0,0 @@ | ||
94 | -/* Variable initialization. IA-64 version. | ||
95 | - Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. | ||
96 | - This file is part of the GNU C Library. | ||
97 | - | ||
98 | - The GNU C Library is free software; you can redistribute it and/or | ||
99 | - modify it under the terms of the GNU Lesser General Public | ||
100 | - License as published by the Free Software Foundation; either | ||
101 | - version 2.1 of the License, or (at your option) any later version. | ||
102 | - | ||
103 | - The GNU C Library is distributed in the hope that it will be useful, | ||
104 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
105 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
106 | - Lesser General Public License for more details. | ||
107 | - | ||
108 | - You should have received a copy of the GNU Lesser General Public | ||
109 | - License along with the GNU C Library; if not, write to the Free | ||
110 | - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
111 | - 02111-1307 USA. */ | ||
112 | - | ||
113 | -#include <ldsodefs.h> | ||
114 | - | ||
115 | -#ifdef SHARED | ||
116 | - | ||
117 | -void | ||
118 | -_dl_var_init (void *array[]) | ||
119 | -{ | ||
120 | - /* It has to match "variables" below. */ | ||
121 | - enum | ||
122 | - { | ||
123 | - DL_PAGESIZE = 0, | ||
124 | - DL_CLKTCK | ||
125 | - }; | ||
126 | - | ||
127 | - GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); | ||
128 | - GLRO(dl_clktck) = *((int *) array[DL_CLKTCK]); | ||
129 | -} | ||
130 | - | ||
131 | -#else | ||
132 | -#include <bits/libc-lock.h> | ||
133 | - | ||
134 | -__libc_lock_define_initialized_recursive (static, _dl_static_lock) | ||
135 | - | ||
136 | -static void *variables[] = | ||
137 | -{ | ||
138 | - &GLRO(dl_pagesize), | ||
139 | - &GLRO(dl_clktck) | ||
140 | -}; | ||
141 | - | ||
142 | -void | ||
143 | -_dl_static_init (struct link_map *map) | ||
144 | -{ | ||
145 | - const ElfW(Sym) *ref = NULL; | ||
146 | - lookup_t loadbase; | ||
147 | - void (*f) (void *[]); | ||
148 | - | ||
149 | - __libc_lock_lock_recursive (_dl_static_lock); | ||
150 | - | ||
151 | - loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref, | ||
152 | - map->l_local_scope, NULL, 0, 1, NULL); | ||
153 | - if (ref != NULL) | ||
154 | - { | ||
155 | - f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref); | ||
156 | - f (variables); | ||
157 | - } | ||
158 | - | ||
159 | - __libc_lock_unlock_recursive (_dl_static_lock); | ||
160 | -} | ||
161 | - | ||
162 | -#endif | ||
163 | diff --git a/sysdeps/unix/sysv/linux/dl-static.c b/sysdeps/unix/sysv/linux/dl-static.c | ||
164 | new file mode 100644 | ||
165 | index 0000000..fa70811 | ||
166 | --- /dev/null | ||
167 | +++ b/sysdeps/unix/sysv/linux/dl-static.c | ||
168 | @@ -0,0 +1,69 @@ | ||
169 | +/* Variable initialization. | ||
170 | + Copyright (C) 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc. | ||
171 | + This file is part of the GNU C Library. | ||
172 | + | ||
173 | + The GNU C Library is free software; you can redistribute it and/or | ||
174 | + modify it under the terms of the GNU Lesser General Public | ||
175 | + License as published by the Free Software Foundation; either | ||
176 | + version 2.1 of the License, or (at your option) any later version. | ||
177 | + | ||
178 | + The GNU C Library is distributed in the hope that it will be useful, | ||
179 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
180 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
181 | + Lesser General Public License for more details. | ||
182 | + | ||
183 | + You should have received a copy of the GNU Lesser General Public | ||
184 | + License along with the GNU C Library; if not, write to the Free | ||
185 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
186 | + 02111-1307 USA. */ | ||
187 | + | ||
188 | +#include <ldsodefs.h> | ||
189 | + | ||
190 | +#ifdef SHARED | ||
191 | + | ||
192 | +void | ||
193 | +_dl_var_init (void *array[]) | ||
194 | +{ | ||
195 | + /* It has to match "variables" below. */ | ||
196 | + enum | ||
197 | + { | ||
198 | + DL_PAGESIZE = 0, | ||
199 | + DL_CLKTCK | ||
200 | + }; | ||
201 | + | ||
202 | + GLRO(dl_pagesize) = *((size_t *) array[DL_PAGESIZE]); | ||
203 | + GLRO(dl_clktck) = *((int *) array[DL_CLKTCK]); | ||
204 | +} | ||
205 | + | ||
206 | +#else | ||
207 | +#include <bits/libc-lock.h> | ||
208 | + | ||
209 | +__libc_lock_define_initialized_recursive (static, _dl_static_lock) | ||
210 | + | ||
211 | +static void *variables[] = | ||
212 | +{ | ||
213 | + &GLRO(dl_pagesize), | ||
214 | + &GLRO(dl_clktck) | ||
215 | +}; | ||
216 | + | ||
217 | +void | ||
218 | +_dl_static_init (struct link_map *map) | ||
219 | +{ | ||
220 | + const ElfW(Sym) *ref = NULL; | ||
221 | + lookup_t loadbase; | ||
222 | + void (*f) (void *[]); | ||
223 | + | ||
224 | + __libc_lock_lock_recursive (_dl_static_lock); | ||
225 | + | ||
226 | + loadbase = _dl_lookup_symbol_x ("_dl_var_init", map, &ref, | ||
227 | + map->l_local_scope, NULL, 0, 1, NULL); | ||
228 | + if (ref != NULL) | ||
229 | + { | ||
230 | + f = (void (*) (void *[])) DL_SYMBOL_ADDRESS (loadbase, ref); | ||
231 | + f (variables); | ||
232 | + } | ||
233 | + | ||
234 | + __libc_lock_unlock_recursive (_dl_static_lock); | ||
235 | +} | ||
236 | + | ||
237 | +#endif | ||
238 | diff --git a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h b/sysdeps/unix/sysv/linux/ia64/ldsodefs.h | ||
239 | deleted file mode 100644 | ||
240 | index 31af624..0000000 | ||
241 | --- a/sysdeps/unix/sysv/linux/ia64/ldsodefs.h | ||
242 | +++ /dev/null | ||
243 | @@ -1,33 +0,0 @@ | ||
244 | -/* Run-time dynamic linker data structures for loaded ELF shared objects. IA64. | ||
245 | - Copyright (C) 2001 Free Software Foundation, Inc. | ||
246 | - This file is part of the GNU C Library. | ||
247 | - | ||
248 | - The GNU C Library is free software; you can redistribute it and/or | ||
249 | - modify it under the terms of the GNU Lesser General Public | ||
250 | - License as published by the Free Software Foundation; either | ||
251 | - version 2.1 of the License, or (at your option) any later version. | ||
252 | - | ||
253 | - The GNU C Library is distributed in the hope that it will be useful, | ||
254 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
255 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
256 | - Lesser General Public License for more details. | ||
257 | - | ||
258 | - You should have received a copy of the GNU Lesser General Public | ||
259 | - License along with the GNU C Library; if not, write to the Free | ||
260 | - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
261 | - 02111-1307 USA. */ | ||
262 | - | ||
263 | -#ifndef _LDSODEFS_H | ||
264 | - | ||
265 | -/* Get the real definitions. */ | ||
266 | -#include_next <ldsodefs.h> | ||
267 | - | ||
268 | -/* Now define our stuff. */ | ||
269 | - | ||
270 | -/* We need special support to initialize DSO loaded for statically linked | ||
271 | - binaries. */ | ||
272 | -extern void _dl_static_init (struct link_map *map); | ||
273 | -#undef DL_STATIC_INIT | ||
274 | -#define DL_STATIC_INIT(map) _dl_static_init (map) | ||
275 | - | ||
276 | -#endif /* ldsodefs.h */ | ||
277 | diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h | ||
278 | index 5d5b1b4..ecb5d4f 100644 | ||
279 | --- a/sysdeps/unix/sysv/linux/ldsodefs.h | ||
280 | +++ b/sysdeps/unix/sysv/linux/ldsodefs.h | ||
281 | @@ -36,6 +36,12 @@ extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function; | ||
282 | /* Initialization which is normally done by the dynamic linker. */ | ||
283 | extern void _dl_non_dynamic_init (void) internal_function; | ||
284 | |||
285 | +/* We need special support to initialize DSO loaded for statically linked | ||
286 | + binaries. */ | ||
287 | +extern void _dl_static_init (struct link_map *map); | ||
288 | +#undef DL_STATIC_INIT | ||
289 | +#define DL_STATIC_INIT(map) _dl_static_init (map) | ||
290 | + | ||
291 | /* We can assume that the kernel always provides the AT_UID, AT_EUID, | ||
292 | AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */ | ||
293 | #if __ASSUME_AT_XID | ||
294 | diff --git a/sysdeps/unix/sysv/linux/ia64/getpagesize.c b/sysdeps/unix/sysv/linux/ia64/getpagesize.c | ||
295 | deleted file mode 100644 | ||
296 | index 1155dfd..0000000 | ||
297 | --- a/sysdeps/unix/sysv/linux/ia64/getpagesize.c | ||
298 | +++ /dev/null | ||
299 | @@ -1,39 +0,0 @@ | ||
300 | -/* Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc. | ||
301 | - This file is part of the GNU C Library. | ||
302 | - | ||
303 | - The GNU C Library is free software; you can redistribute it and/or | ||
304 | - modify it under the terms of the GNU Lesser General Public | ||
305 | - License as published by the Free Software Foundation; either | ||
306 | - version 2.1 of the License, or (at your option) any later version. | ||
307 | - | ||
308 | - The GNU C Library is distributed in the hope that it will be useful, | ||
309 | - but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
310 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
311 | - Lesser General Public License for more details. | ||
312 | - | ||
313 | - You should have received a copy of the GNU Lesser General Public | ||
314 | - License along with the GNU C Library; if not, write to the Free | ||
315 | - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
316 | - 02111-1307 USA. */ | ||
317 | - | ||
318 | -#include <assert.h> | ||
319 | -#include <unistd.h> | ||
320 | -#include <sys/param.h> | ||
321 | - | ||
322 | -#include <ldsodefs.h> | ||
323 | -#include <sysdep.h> | ||
324 | -#include <sys/syscall.h> | ||
325 | - | ||
326 | -/* Return the system page size. The return value will depend on how | ||
327 | - the kernel is configured. A program must use this call to | ||
328 | - determine the page size to ensure proper alignment for calls such | ||
329 | - as mmap and friends. --davidm 99/11/30 */ | ||
330 | - | ||
331 | -int | ||
332 | -__getpagesize () | ||
333 | -{ | ||
334 | - assert (GLRO(dl_pagesize) != 0); | ||
335 | - return GLRO(dl_pagesize); | ||
336 | -} | ||
337 | -libc_hidden_def (__getpagesize) | ||
338 | -weak_alias (__getpagesize, getpagesize) |