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