Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo commit in src/patchsets/glibc/2.16.0: 1507_all_hppa-ia64-DL_AUTO_FUNCTION_ADDRESS.patch
Date: Sat, 23 Nov 2013 05:16:57
Message-Id: 20131123051653.E98DB2004B@flycatcher.gentoo.org
1 vapier 13/11/23 05:16:53
2
3 Added: 1507_all_hppa-ia64-DL_AUTO_FUNCTION_ADDRESS.patch
4 Log:
5 add fix from upstream for crashes w/gcc-4.7 on hppa #486618 & ia64 #486974
6
7 Revision Changes Path
8 1.1 src/patchsets/glibc/2.16.0/1507_all_hppa-ia64-DL_AUTO_FUNCTION_ADDRESS.patch
9
10 file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.16.0/1507_all_hppa-ia64-DL_AUTO_FUNCTION_ADDRESS.patch?rev=1.1&view=markup
11 plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.16.0/1507_all_hppa-ia64-DL_AUTO_FUNCTION_ADDRESS.patch?rev=1.1&content-type=text/plain
12
13 Index: 1507_all_hppa-ia64-DL_AUTO_FUNCTION_ADDRESS.patch
14 ===================================================================
15 https://bugs.gentoo.org/486618
16 https://bugs.gentoo.org/486974
17
18 From daf75146de07303ea0c5ad700ec5ef703ec114a1 Mon Sep 17 00:00:00 2001
19 From: Guy Martin <gmsoft@×××××××××.be>
20 Date: Thu, 21 Nov 2013 13:23:16 -0500
21 Subject: [PATCH] Don't use broken DL_AUTO_FUNCTION_ADDRESS()
22
23 On hppa and ia64, the macro DL_AUTO_FUNCTION_ADDRESS() uses the
24 variable fptr[2] in it's own scope.
25
26 The content of fptr[] is thus undefined right after the macro exits.
27 Newer gcc's (>= 4.7) reuse the stack space of this variable triggering
28 a segmentation fault in dl-init.c:69.
29
30 To fix this we rewrite the macros to make the call directly to init
31 and fini without needing to pass back a constructed function pointer.
32 ---
33 ChangeLog | 9 +++++++
34 elf/dl-close.c | 5 ++--
35 elf/dl-fini.c | 2 +-
36 elf/dl-init.c | 8 +-----
37 ports/ChangeLog.hppa | 9 +++++++
38 ports/ChangeLog.ia64 | 9 +++++++
39 ports/sysdeps/hppa/dl-lookupcfg.h | 56 +++++++++++++++++++++------------------
40 ports/sysdeps/hppa/dl-machine.h | 8 ++++--
41 ports/sysdeps/ia64/dl-lookupcfg.h | 40 +++++++++++++++-------------
42 ports/sysdeps/ia64/dl-machine.h | 8 ++++--
43 sysdeps/generic/ldsodefs.h | 5 ++--
44 11 files changed, 98 insertions(+), 61 deletions(-)
45
46 2013-11-21 Guy Martin <gmsoft@×××××××××.be>
47
48 * sysdeps/generic/ldsodefs.h: Replace DL_DT_INIT_ADDRESS() and
49 DL_DT_FINI_ADDRESS() macro with DL_CALL_DT_INIT() and
50 DL_CALL_DT_FINI() that call the functions directly.
51 * elf/dl-init.c: Use the new DL_CALL_DT_INIT() macro.
52 * elf/dl-close.c: Use the new DL_CALL_DT_FINI() macro.
53 * elf/dl-fini.c: Likewise.
54
55 diff --git a/elf/dl-close.c b/elf/dl-close.c
56 index fe3014c..407926b 100644
57 --- a/elf/dl-close.c
58 +++ b/elf/dl-close.c
59 @@ -274,9 +274,8 @@ _dl_close_worker (struct link_map *map)
60
61 /* Next try the old-style destructor. */
62 if (imap->l_info[DT_FINI] != NULL)
63 - (*(void (*) (void)) DL_DT_FINI_ADDRESS
64 - (imap, ((void *) imap->l_addr
65 - + imap->l_info[DT_FINI]->d_un.d_ptr))) ();
66 + DL_CALL_DT_FINI (imap, ((void *) imap->l_addr
67 + + imap->l_info[DT_FINI]->d_un.d_ptr));
68 }
69
70 #ifdef SHARED
71 diff --git a/elf/dl-fini.c b/elf/dl-fini.c
72 index 6b245f0..db5269c 100644
73 --- a/elf/dl-fini.c
74 +++ b/elf/dl-fini.c
75 @@ -254,7 +254,7 @@ _dl_fini (void)
76
77 /* Next try the old-style destructor. */
78 if (l->l_info[DT_FINI] != NULL)
79 - ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
80 + DL_CALL_DT_FINI(l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr);
81 }
82
83 #ifdef SHARED
84 diff --git a/elf/dl-init.c b/elf/dl-init.c
85 index a657eb6..4078368 100644
86 --- a/elf/dl-init.c
87 +++ b/elf/dl-init.c
88 @@ -61,13 +61,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
89 - the others in the DT_INIT_ARRAY.
90 */
91 if (l->l_info[DT_INIT] != NULL)
92 - {
93 - init_t init = (init_t) DL_DT_INIT_ADDRESS
94 - (l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
95 -
96 - /* Call the function. */
97 - init (argc, argv, env);
98 - }
99 + DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
100
101 /* Next see whether there is an array with initialization functions. */
102 ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
103
104 2013-11-21 Guy Martin <gmsoft@×××××××××.be>
105
106 * sysdeps/hppa/dl-lookupcfg.h: Remove obsolete
107 DL_DT_INIT_ADDRESS() and DL_DT_FINI_ADDRESS() macro and implement
108 DL_CALL_DT_INIT() as well as DL_CALL_DT_FINI().
109 Define DL_DT_FUNCTION_ADDRESS().
110 * sysdeps/hppa/dl-machine.h: Update ELF_MACHINE_START_ADDRESS()
111 to use DL_DT_FUNCTION_ADDRESS().
112
113 2013-11-21 Guy Martin <gmsoft@×××××××××.be>
114
115 * sysdeps/ia64/dl-lookupcfg.h: Remove obsolete
116 DL_DT_INIT_ADDRESS() and DL_DT_FINI_ADDRESS() macro and implement
117 DL_CALL_DT_INIT() as well as DL_CALL_DT_FINI().
118 Define DL_DT_FUNCTION_ADDRESS().
119 * sysdeps/ia64/dl-machine.h: Update ELF_MACHINE_START_ADDRESS()
120 to use DL_DT_FUNCTION_ADDRESS().
121
122 diff --git a/ports/sysdeps/hppa/dl-lookupcfg.h b/ports/sysdeps/hppa/dl-lookupcfg.h
123 index f3125e5..feea320 100644
124 --- a/ports/sysdeps/hppa/dl-lookupcfg.h
125 +++ b/ports/sysdeps/hppa/dl-lookupcfg.h
126 @@ -38,32 +38,36 @@ void _dl_unmap (struct link_map *map);
127
128 #define DL_UNMAP(map) _dl_unmap (map)
129
130 -#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \
131 -({ \
132 - unsigned int fptr[2]; \
133 - fptr[0] = (unsigned int) (addr); \
134 - fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
135 - /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
136 - (ElfW(Addr))((unsigned int)fptr | 2); \
137 -})
138 -
139 -#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \
140 -({ \
141 - static unsigned int fptr[2]; \
142 - fptr[0] = (unsigned int) (addr); \
143 - fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
144 - /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
145 - (ElfW(Addr))((unsigned int)fptr | 2); \
146 -})
147 -
148 -
149 -/* The test for "addr & 2" below is to accomodate old binaries which
150 - violated the ELF ABI by pointing DT_INIT and DT_FINI at a function
151 - descriptor. */
152 -#define DL_DT_INIT_ADDRESS(map, addr) \
153 - ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
154 -#define DL_DT_FINI_ADDRESS(map, addr) \
155 - ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
156 +#define DL_DT_FUNCTION_ADDRESS(map, start, attr, addr) \
157 + attr volatile unsigned int fptr[2]; \
158 + /* The test for "start & 2" below is to accommodate old binaries which \
159 + violated the ELF ABI by pointing DT_INIT and DT_FINI at a function \
160 + descriptor. */ \
161 + if ((ElfW(Addr)) (start) & 2) \
162 + addr = (ElfW(Addr)) start; \
163 + else \
164 + { \
165 + fptr[0] = (unsigned int) (start); \
166 + fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
167 + /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
168 + addr = (ElfW(Addr))((unsigned int)fptr | 2); \
169 + } \
170 +
171 +#define DL_CALL_DT_INIT(map, start, argc, argv, env) \
172 +{ \
173 + ElfW(Addr) addr; \
174 + DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
175 + init_t init = (init_t) addr; \
176 + init (argc, argv, env); \
177 +}
178 +
179 +#define DL_CALL_DT_FINI(map, start) \
180 +{ \
181 + ElfW(Addr) addr; \
182 + DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
183 + fini_t fini = (fini_t) addr; \
184 + fini (); \
185 +}
186
187 /* The type of the return value of fixup/profile_fixup */
188 #define DL_FIXUP_VALUE_TYPE struct fdesc
189 diff --git a/ports/sysdeps/hppa/dl-machine.h b/ports/sysdeps/hppa/dl-machine.h
190 index d2411a6..e47e947 100644
191 --- a/ports/sysdeps/hppa/dl-machine.h
192 +++ b/ports/sysdeps/hppa/dl-machine.h
193 @@ -490,8 +490,12 @@ asm ( \
194 #define ELF_MACHINE_NO_REL 1
195
196 /* Return the address of the entry point. */
197 -#define ELF_MACHINE_START_ADDRESS(map, start) \
198 - DL_STATIC_FUNCTION_ADDRESS (map, start)
199 +#define ELF_MACHINE_START_ADDRESS(map, start) \
200 +({ \
201 + ElfW(Addr) addr; \
202 + DL_DT_FUNCTION_ADDRESS(map, start, static, addr) \
203 + addr; \
204 +})
205
206 /* We define an initialization functions. This is called very early in
207 * _dl_sysdep_start. */
208 diff --git a/ports/sysdeps/ia64/dl-lookupcfg.h b/ports/sysdeps/ia64/dl-lookupcfg.h
209 index 4da1263..cfaa252 100644
210 --- a/ports/sysdeps/ia64/dl-lookupcfg.h
211 +++ b/ports/sysdeps/ia64/dl-lookupcfg.h
212 @@ -39,24 +39,28 @@ extern void _dl_unmap (struct link_map *map);
213
214 #define DL_UNMAP(map) _dl_unmap (map)
215
216 -#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \
217 -({ \
218 - unsigned long int fptr[2]; \
219 - fptr[0] = (unsigned long int) (addr); \
220 - fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
221 - (Elf64_Addr) fptr; \
222 -})
223 -
224 -#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \
225 -({ \
226 - static unsigned long int fptr[2]; \
227 - fptr[0] = (unsigned long int) (addr); \
228 - fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
229 - (Elf64_Addr) fptr; \
230 -})
231 -
232 -#define DL_DT_INIT_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
233 -#define DL_DT_FINI_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
234 +#define DL_DT_FUNCTION_ADDRESS(map, start, attr, addr) \
235 + attr volatile unsigned long int fptr[2]; \
236 + fptr[0] = (unsigned long int) (start); \
237 + fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
238 + addr = (ElfW(Addr)) fptr; \
239 +
240 +#define DL_CALL_DT_INIT(map, start, argc, argv, env) \
241 +{ \
242 + ElfW(Addr) addr; \
243 + DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
244 + init_t init = (init_t) addr; \
245 + init (argc, argv, env); \
246 +}
247 +
248 +#define DL_CALL_DT_FINI(map, start) \
249 +{ \
250 + ElfW(Addr) addr; \
251 + DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
252 + fini_t fini = (fini_t) addr; \
253 + fini (); \
254 +}
255 +
256 /* The type of the return value of fixup/profile_fixup. */
257 #define DL_FIXUP_VALUE_TYPE struct fdesc
258 /* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
259 diff --git a/ports/sysdeps/ia64/dl-machine.h b/ports/sysdeps/ia64/dl-machine.h
260 index dd469d7..6123637 100644
261 --- a/ports/sysdeps/ia64/dl-machine.h
262 +++ b/ports/sysdeps/ia64/dl-machine.h
263 @@ -322,8 +322,12 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
264 #define ELF_MACHINE_NO_REL 1
265
266 /* Return the address of the entry point. */
267 -#define ELF_MACHINE_START_ADDRESS(map, start) \
268 - DL_STATIC_FUNCTION_ADDRESS (map, start)
269 +#define ELF_MACHINE_START_ADDRESS(map, start) \
270 +({ \
271 + ElfW(Addr) addr; \
272 + DL_DT_FUNCTION_ADDRESS(map, start, static, addr) \
273 + addr; \
274 +})
275
276 /* Fixup a PLT entry to bounce directly to the function at VALUE. */
277 static inline struct fdesc __attribute__ ((always_inline))
278 diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
279 index e7b0516..146aca4 100644
280 --- a/sysdeps/generic/ldsodefs.h
281 +++ b/sysdeps/generic/ldsodefs.h
282 @@ -76,8 +76,9 @@ typedef struct link_map *lookup_t;
283 # define DL_SYMBOL_ADDRESS(map, ref) \
284 (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
285 # define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
286 -# define DL_DT_INIT_ADDRESS(map, start) (start)
287 -# define DL_DT_FINI_ADDRESS(map, start) (start)
288 +# define DL_CALL_DT_INIT(map, start, argc, argv, env) \
289 + ((init_t) (start)) (argc, argv, env)
290 +# define DL_CALL_DT_FINI(map, start) ((fini_t) (start)) ()
291 #endif
292
293 /* On some architectures dladdr can't use st_size of all symbols this way. */
294 --
295 1.8.4.3