@@ -68,3 +68,45 @@ tt_engine_xetex_main(
6868 ttbc_global_engine_exit ();
6969 return rv ;
7070}
71+
72+
73+ /* "What is happening here?", you might ask. Good question!
74+ *
75+ * My first attempt (PKGW, 2023 Sep) to build a static version of Tectonic
76+ * for the aarch64 platform using Tectonic's cross-compilation framework
77+ * ran into the following error when trying to link the final executable:
78+ *
79+ * /home/rust/sysroot-aarch64/usr/lib/libc.a(sigsetjmp.lo): in function `sigsetjmp':
80+ * /home/buildozer/aports/main/musl/src/v1.2.3/src/signal/aarch64/sigsetjmp.s:7:(.text+0x0):
81+ * relocation truncated to fit: R_AARCH64_CONDBR19 against symbol `setjmp'
82+ * defined in .text section in /home/rust/sysroot-aarch64/usr/lib/libc.a(setjmp.lo)
83+ *
84+ * So, musl libc's implementation of sigsetjmp() invokes setjmp() in some
85+ * hand-written assembly. It appears that for whatever reason, when the linker
86+ * is trying to build the Tectonic executable on aarch64, it ends up wanting to
87+ * locate setjmp() and sigsetjmp() far away from each other in the final file,
88+ * and the particular branch instruction used in sigsetjmp() can only specify a
89+ * relatively small offset that cannot capture the location of setjmp(). The musl
90+ * developers tentatively agree that this seems to be a bug in musl's
91+ * implementation.
92+ *
93+ * I had the idea that maybe if I referenced both functions in my code, that
94+ * would encourage the linker to place them closer to each other. And, guess
95+ * what, it seems to work! Bananas!
96+ *
97+ * This hardly costs us anything so we don't bother to try to #ifdef it for the
98+ * specific circumstances given above, but Windows doesn't provide sigsetjmp.
99+ */
100+ #ifndef _WIN32
101+ void __terrible_aarch64_musl_linker_hack_never_call_me (void );
102+
103+ void
104+ __terrible_aarch64_musl_linker_hack_never_call_me (void )
105+ {
106+ jmp_buf buf1 ;
107+ sigjmp_buf buf2 ;
108+
109+ setjmp (buf1 );
110+ sigsetjmp (buf2 , 0 );
111+ }
112+ #endif
0 commit comments