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 |