1 |
commit: a5945b83a4ee29d228e1a56101483001da291c54 |
2 |
Author: Sam James <sam <AT> gentoo <DOT> org> |
3 |
AuthorDate: Tue Feb 22 00:29:23 2022 +0000 |
4 |
Commit: Sam James <sam <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Feb 22 00:41:18 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=a5945b83 |
7 |
|
8 |
dev-lang/ocaml: fix 4.09 with glibc 2.34 |
9 |
|
10 |
Bug: https://bugs.gentoo.org/804498 |
11 |
See: https://github.com/gentoo/gentoo/pull/22851#pullrequestreview-882504245 |
12 |
Signed-off-by: Sam James <sam <AT> gentoo.org> |
13 |
|
14 |
dev-lang/ocaml/files/ocaml-4.09.0-glibc-2.34.patch | 193 +++++++++++++++++++++ |
15 |
dev-lang/ocaml/ocaml-4.09.0-r3.ebuild | 105 +++++++++++ |
16 |
2 files changed, 298 insertions(+) |
17 |
|
18 |
diff --git a/dev-lang/ocaml/files/ocaml-4.09.0-glibc-2.34.patch b/dev-lang/ocaml/files/ocaml-4.09.0-glibc-2.34.patch |
19 |
new file mode 100644 |
20 |
index 000000000000..6f74d38e80b6 |
21 |
--- /dev/null |
22 |
+++ b/dev-lang/ocaml/files/ocaml-4.09.0-glibc-2.34.patch |
23 |
@@ -0,0 +1,193 @@ |
24 |
+https://github.com/ocaml/ocaml/commit/8eed2e441222588dc385a98ae8bd6f5820eb0223 |
25 |
+https://github.com/gentoo/gentoo/pull/22851#pullrequestreview-882504245 |
26 |
+ |
27 |
+From 8eed2e441222588dc385a98ae8bd6f5820eb0223 Mon Sep 17 00:00:00 2001 |
28 |
+From: Xavier Leroy <xavierleroy@××××××××××××××××××××.com> |
29 |
+Date: Fri, 5 Mar 2021 19:14:07 +0100 |
30 |
+Subject: [PATCH] Dynamically allocate the alternate signal stack |
31 |
+ |
32 |
+In Glibc 2.34 and later, SIGSTKSZ may not be a compile-time constant. |
33 |
+It is no longer possible to statically allocate the alternate signal |
34 |
+stack for the main thread, as we've been doing for the last 25 years. |
35 |
+ |
36 |
+This commit implements dynamic allocation of the alternate signal stack |
37 |
+even for the main thread. It reuses the code already in place to allocate |
38 |
+the alternate signal stack for other threads. |
39 |
+ |
40 |
+The alternate signal stack is freed when the main OCaml code / an OCaml thread |
41 |
+stops. |
42 |
+ |
43 |
+(partial back-port of PR#10266 and PR#10726) |
44 |
+--- |
45 |
+ runtime/fail_nat.c | 7 ++++- |
46 |
+ runtime/signals_nat.c | 64 +++++++++++++++++++++++++++++++++++++------ |
47 |
+ runtime/startup_nat.c | 7 ++++- |
48 |
+ runtime/sys.c | 5 ++++ |
49 |
+ 4 files changed, 72 insertions(+), 11 deletions(-) |
50 |
+ |
51 |
+diff --git a/runtime/fail_nat.c b/runtime/fail_nat.c |
52 |
+index e1f687d379e..cbf7633ee9e 100644 |
53 |
+--- a/runtime/fail_nat.c |
54 |
++++ b/runtime/fail_nat.c |
55 |
+@@ -31,6 +31,8 @@ |
56 |
+ #include "caml/roots.h" |
57 |
+ #include "caml/callback.h" |
58 |
+ |
59 |
++extern void caml_terminate_signals(void); |
60 |
++ |
61 |
+ /* The globals holding predefined exceptions */ |
62 |
+ |
63 |
+ typedef value caml_generated_constant[1]; |
64 |
+@@ -60,7 +62,10 @@ char * caml_exception_pointer = NULL; |
65 |
+ void caml_raise(value v) |
66 |
+ { |
67 |
+ Unlock_exn(); |
68 |
+- if (caml_exception_pointer == NULL) caml_fatal_uncaught_exception(v); |
69 |
++ if (caml_exception_pointer == NULL) { |
70 |
++ caml_terminate_signals(); |
71 |
++ caml_fatal_uncaught_exception(v); |
72 |
++ } |
73 |
+ |
74 |
+ while (caml_local_roots != NULL && |
75 |
+ (char *) caml_local_roots < caml_exception_pointer) { |
76 |
+diff --git a/runtime/signals_nat.c b/runtime/signals_nat.c |
77 |
+index 29a5f49e625..351b575a08e 100644 |
78 |
+--- a/runtime/signals_nat.c |
79 |
++++ b/runtime/signals_nat.c |
80 |
+@@ -182,7 +182,6 @@ DECLARE_SIGNAL_HANDLER(trap_handler) |
81 |
+ #ifdef HAS_STACK_OVERFLOW_DETECTION |
82 |
+ |
83 |
+ static char * system_stack_top; |
84 |
+-static char sig_alt_stack[SIGSTKSZ]; |
85 |
+ |
86 |
+ #if defined(SYS_linux) |
87 |
+ /* PR#4746: recent Linux kernels with support for stack randomization |
88 |
+@@ -275,14 +274,61 @@ void caml_init_signals(void) |
89 |
+ { |
90 |
+ stack_t stk; |
91 |
+ struct sigaction act; |
92 |
+- stk.ss_sp = sig_alt_stack; |
93 |
+- stk.ss_size = SIGSTKSZ; |
94 |
+- stk.ss_flags = 0; |
95 |
+- SET_SIGACT(act, segv_handler); |
96 |
+- act.sa_flags |= SA_ONSTACK | SA_NODEFER; |
97 |
+- sigemptyset(&act.sa_mask); |
98 |
+- system_stack_top = (char *) &act; |
99 |
+- if (sigaltstack(&stk, NULL) == 0) { sigaction(SIGSEGV, &act, NULL); } |
100 |
++ /* Allocate and select an alternate stack for handling signals, |
101 |
++ especially SIGSEGV signals. |
102 |
++ The alternate stack used to be statically-allocated for the main thread, |
103 |
++ but this is incompatible with Glibc 2.34 and newer, where SIGSTKSZ |
104 |
++ may not be a compile-time constant. */ |
105 |
++ stk.ss_sp = malloc(SIGSTKSZ); |
106 |
++ if (stk.ss_sp != NULL) { |
107 |
++ stk.ss_size = SIGSTKSZ; |
108 |
++ stk.ss_flags = 0; |
109 |
++ SET_SIGACT(act, segv_handler); |
110 |
++ act.sa_flags |= SA_ONSTACK | SA_NODEFER; |
111 |
++ sigemptyset(&act.sa_mask); |
112 |
++ system_stack_top = (char *) &act; |
113 |
++ if (sigaltstack(&stk, NULL) == 0) |
114 |
++ sigaction(SIGSEGV, &act, NULL); |
115 |
++ else |
116 |
++ free(stk.ss_sp); |
117 |
++ } |
118 |
++ } |
119 |
++#endif |
120 |
++} |
121 |
++ |
122 |
++/* Termination of signal stuff */ |
123 |
++ |
124 |
++#if defined(TARGET_power) || defined(TARGET_s390x) \ |
125 |
++ || defined(HAS_STACK_OVERFLOW_DETECTION) |
126 |
++static void set_signal_default(int signum) |
127 |
++{ |
128 |
++ struct sigaction act; |
129 |
++ sigemptyset(&act.sa_mask); |
130 |
++ act.sa_handler = SIG_DFL; |
131 |
++ act.sa_flags = 0; |
132 |
++ sigaction(signum, &act, NULL); |
133 |
++} |
134 |
++#endif |
135 |
++ |
136 |
++void caml_terminate_signals(void) |
137 |
++{ |
138 |
++#if defined(TARGET_power) |
139 |
++ set_signal_default(SIGTRAP); |
140 |
++#endif |
141 |
++ |
142 |
++#if defined(TARGET_s390x) |
143 |
++ set_signal_default(SIGFPE); |
144 |
++#endif |
145 |
++ |
146 |
++#ifdef HAS_STACK_OVERFLOW_DETECTION |
147 |
++ set_signal_default(SIGSEGV); |
148 |
++ stack_t oldstk, stk; |
149 |
++ stk.ss_flags = SS_DISABLE; |
150 |
++ if (sigaltstack(&stk, &oldstk) == 0) { |
151 |
++ /* If caml_init_signals failed, we are not using an alternate signal stack. |
152 |
++ SS_DISABLE will be set in oldstk, and there is nothing to free in this |
153 |
++ case. */ |
154 |
++ if (! (oldstk.ss_flags & SS_DISABLE)) free(oldstk.ss_sp); |
155 |
+ } |
156 |
+ #endif |
157 |
+ } |
158 |
+diff --git a/runtime/startup_nat.c b/runtime/startup_nat.c |
159 |
+index 7eca5fa5581..f52bec980b6 100644 |
160 |
+--- a/runtime/startup_nat.c |
161 |
++++ b/runtime/startup_nat.c |
162 |
+@@ -92,6 +92,7 @@ void (*caml_termination_hook)(void *) = NULL; |
163 |
+ extern value caml_start_program (void); |
164 |
+ extern void caml_init_ieee_floats (void); |
165 |
+ extern void caml_init_signals (void); |
166 |
++extern void caml_terminate_signals(void); |
167 |
+ #ifdef _WIN32 |
168 |
+ extern void caml_win32_overflow_detection (void); |
169 |
+ #endif |
170 |
+@@ -106,6 +107,7 @@ extern void caml_install_invalid_parameter_handler(); |
171 |
+ value caml_startup_common(char_os **argv, int pooling) |
172 |
+ { |
173 |
+ char_os * exe_name, * proc_self_exe; |
174 |
++ value res; |
175 |
+ char tos; |
176 |
+ |
177 |
+ /* Determine options */ |
178 |
+@@ -153,10 +155,13 @@ value caml_startup_common(char_os **argv, int pooling) |
179 |
+ exe_name = caml_search_exe_in_path(exe_name); |
180 |
+ caml_sys_init(exe_name, argv); |
181 |
+ if (sigsetjmp(caml_termination_jmpbuf.buf, 0)) { |
182 |
++ caml_terminate_signals(); |
183 |
+ if (caml_termination_hook != NULL) caml_termination_hook(NULL); |
184 |
+ return Val_unit; |
185 |
+ } |
186 |
+- return caml_start_program(); |
187 |
++ res = caml_start_program(); |
188 |
++ caml_terminate_signals(); |
189 |
++ return res; |
190 |
+ } |
191 |
+ |
192 |
+ value caml_startup_exn(char_os **argv) |
193 |
+diff --git a/runtime/sys.c b/runtime/sys.c |
194 |
+index 226d596cdff..9e201354e1e 100644 |
195 |
+--- a/runtime/sys.c |
196 |
++++ b/runtime/sys.c |
197 |
+@@ -112,6 +112,8 @@ static void caml_sys_check_path(value name) |
198 |
+ } |
199 |
+ } |
200 |
+ |
201 |
++extern void caml_terminate_signals(void); |
202 |
++ |
203 |
+ CAMLprim value caml_sys_exit(value retcode_v) |
204 |
+ { |
205 |
+ int retcode = Int_val(retcode_v); |
206 |
+@@ -155,6 +157,9 @@ CAMLprim value caml_sys_exit(value retcode_v) |
207 |
+ caml_shutdown(); |
208 |
+ #ifdef _WIN32 |
209 |
+ caml_restore_win32_terminal(); |
210 |
++#endif |
211 |
++#ifdef NATIVE_CODE |
212 |
++ caml_terminate_signals(); |
213 |
+ #endif |
214 |
+ exit(retcode); |
215 |
+ } |
216 |
+ |
217 |
|
218 |
diff --git a/dev-lang/ocaml/ocaml-4.09.0-r3.ebuild b/dev-lang/ocaml/ocaml-4.09.0-r3.ebuild |
219 |
new file mode 100644 |
220 |
index 000000000000..8bf41d439d5a |
221 |
--- /dev/null |
222 |
+++ b/dev-lang/ocaml/ocaml-4.09.0-r3.ebuild |
223 |
@@ -0,0 +1,105 @@ |
224 |
+# Copyright 1999-2022 Gentoo Authors |
225 |
+# Distributed under the terms of the GNU General Public License v2 |
226 |
+ |
227 |
+EAPI=7 |
228 |
+ |
229 |
+inherit flag-o-matic |
230 |
+ |
231 |
+HOMEPAGE="https://ocaml.org/" |
232 |
+SRC_URI="https://github.com/ocaml/ocaml/archive/${PV}.tar.gz -> ${P}.tar.gz" |
233 |
+DESCRIPTION="Programming language supporting functional, imperative & object-oriented styles" |
234 |
+ |
235 |
+LICENSE="LGPL-2.1" |
236 |
+SLOT="0/$(ver_cut 1-2)" |
237 |
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~mips ~ppc ~ppc64 ~x86 ~amd64-linux ~x86-linux ~ppc-macos ~sparc-solaris ~x86-solaris" |
238 |
+IUSE="emacs flambda latex +ocamlopt spacetime xemacs" |
239 |
+ |
240 |
+RDEPEND="sys-libs/binutils-libs:= |
241 |
+ spacetime? ( sys-libs/libunwind:= )" |
242 |
+BDEPEND="${RDEPEND} |
243 |
+ virtual/pkgconfig" |
244 |
+PDEPEND="emacs? ( app-emacs/ocaml-mode ) |
245 |
+ xemacs? ( app-xemacs/ocaml )" |
246 |
+ |
247 |
+QA_FLAGS_IGNORED='usr/lib.*/ocaml/bigarray.cmxs' |
248 |
+ |
249 |
+PATCHES=( |
250 |
+ "${FILESDIR}"/${PN}-4.09.0-gcc-10.patch |
251 |
+ "${FILESDIR}"/${P}-cflags.patch |
252 |
+ "${FILESDIR}"/${P}-glibc-2.34.patch |
253 |
+) |
254 |
+ |
255 |
+src_prepare() { |
256 |
+ default |
257 |
+ |
258 |
+ cp "${FILESDIR}"/ocaml.conf "${T}" || die |
259 |
+ |
260 |
+ # Broken until 4.12 |
261 |
+ # bug #818445 |
262 |
+ filter-flags '-flto*' |
263 |
+ append-flags -fno-strict-aliasing |
264 |
+ |
265 |
+ # OCaml generates textrels on 32-bit arches |
266 |
+ # We can't do anything about it, but disabling it means that tests |
267 |
+ # for OCaml-based packages won't fail on unexpected output |
268 |
+ # bug #773226 |
269 |
+ if use arm || use ppc || use x86 ; then |
270 |
+ append-ldflags "-Wl,-z,notext" |
271 |
+ fi |
272 |
+ |
273 |
+ # Upstream build ignores LDFLAGS in several places. |
274 |
+ sed -i -e 's/\(^MKDLL=.*\)/\1 $(LDFLAGS)/' \ |
275 |
+ -e 's/\(^OC_CFLAGS=.*\)/\1 $(LDFLAGS)/' \ |
276 |
+ -e 's/\(^OC_LDFLAGS=.*\)/\1 $(LDFLAGS)/' \ |
277 |
+ Makefile.config.in || die "LDFLAGS fix failed" |
278 |
+ # ${P} overrides upstream build's own P due to a wrong assignment operator. |
279 |
+ sed -i -e 's/^P ?=/P =/' stdlib/StdlibModules || die "P fix failed" |
280 |
+} |
281 |
+ |
282 |
+src_configure() { |
283 |
+ local opt=( |
284 |
+ --bindir="${EPREFIX}/usr/bin" |
285 |
+ --libdir="${EPREFIX}/usr/$(get_libdir)/ocaml" |
286 |
+ --mandir="${EPREFIX}/usr/share/man" |
287 |
+ --prefix="${EPREFIX}/usr" |
288 |
+ $(use_enable flambda) |
289 |
+ $(use_enable spacetime) |
290 |
+ ) |
291 |
+ econf ${opt[@]} |
292 |
+} |
293 |
+ |
294 |
+src_compile() { |
295 |
+ if use ocamlopt ; then |
296 |
+ emake world.opt |
297 |
+ else |
298 |
+ emake world |
299 |
+ fi |
300 |
+} |
301 |
+ |
302 |
+src_test() { |
303 |
+ if use ocamlopt ; then |
304 |
+ # OCaml tests only work when run sequentially |
305 |
+ emake -j1 -C testsuite all |
306 |
+ else |
307 |
+ ewarn "${PN} was built without 'ocamlopt' USE flag; skipping tests." |
308 |
+ fi |
309 |
+} |
310 |
+ |
311 |
+src_install() { |
312 |
+ default |
313 |
+ dodir /usr/include |
314 |
+ # Create symlink for header files |
315 |
+ dosym "../$(get_libdir)/ocaml/caml" /usr/include/caml |
316 |
+ dodoc Changes README.adoc |
317 |
+ # Create envd entry for latex input files |
318 |
+ if use latex ; then |
319 |
+ echo "TEXINPUTS=\"${EPREFIX}/usr/$(get_libdir)/ocaml/ocamldoc:\"" > "${T}"/99ocamldoc || die |
320 |
+ doenvd "${T}"/99ocamldoc |
321 |
+ fi |
322 |
+ |
323 |
+ sed -i -e "s:lib:$(get_libdir):" "${T}"/ocaml.conf || die |
324 |
+ |
325 |
+ # Install ocaml-rebuild portage set |
326 |
+ insinto /usr/share/portage/config/sets |
327 |
+ doins "${T}"/ocaml.conf |
328 |
+} |