Contents of /trunk/glibc/patches/glibc-2.12.1-static-shared-getpagesize.patch
Parent Directory | Revision Log
Revision 1182 -
(show 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 | 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) |