From e29d8c3f3659083a5c8cd69979db306b4ae86257 Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Mon, 18 Aug 2025 21:29:00 +0300 Subject: [PATCH 01/10] [druntime-test]: exceptions: Drop musl auto-detection The cmake files already check the triple for musl and that is a more reliable check compared to looking for Alpine's apk. Signed-off-by: Andrei Horodniceanu --- runtime/druntime/test/exceptions/Makefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/runtime/druntime/test/exceptions/Makefile b/runtime/druntime/test/exceptions/Makefile index 7565e42506..ed8c7e9f85 100644 --- a/runtime/druntime/test/exceptions/Makefile +++ b/runtime/druntime/test/exceptions/Makefile @@ -3,13 +3,6 @@ ifdef IN_LDC include ../../../../dmd/osmodel.mak endif -ifeq ($(OS),linux) - # FIXME: detect musl libc robustly; just checking Alpine Linux' apk tool for now - ifeq (1,$(shell which apk &>/dev/null && echo 1)) - IS_MUSL:=1 - endif -endif - TESTS=stderr_msg unittest_assert invalid_memory_operation static_dtor \ future_message refcounted rt_trap_exceptions_drt catch_in_finally \ message_with_null From c84b65202dbf1217664bf98a613121f387dc63a9 Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Mon, 18 Aug 2025 21:41:34 +0300 Subject: [PATCH 02/10] [druntime-test]: importc_compare: Drop musl auto-detection Signed-off-by: Andrei Horodniceanu --- runtime/druntime/test/importc_compare/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/druntime/test/importc_compare/Makefile b/runtime/druntime/test/importc_compare/Makefile index 983c19bc8a..ea2a467e8f 100644 --- a/runtime/druntime/test/importc_compare/Makefile +++ b/runtime/druntime/test/importc_compare/Makefile @@ -8,7 +8,7 @@ TESTS := importc_compare # FIXME: fails on Alpine v3.21 with conflicting struct declarations in the C headers: # /usr/include/asm-generic/fcntl.h(195): Error: struct `importc_includes.flock` conflicts with struct `importc_includes.flock` at /usr/include/fcntl.h(24) ifeq ($(OS),linux) - ifeq (1,$(shell which apk &>/dev/null && echo 1)) + ifeq (1,$(IS_MUSL)) TESTS := endif endif From d1f74c905b6a1662c4b124b00bf1d7b442e96eb6 Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Sat, 16 Aug 2025 13:23:57 +0300 Subject: [PATCH 03/10] [druntime-test]: memoryerror_stackoverflow.d: Prevent hangs with >=llvm-20 Since llvm-20, the stack variables are optimized away leading to an infinite loop. The affected assembly became: ``` Disassembly of section .text._D25memoryerror_stackoverflow1fFKG1024hZv: 0000000000000000 <_D25memoryerror_stackoverflow1fFKG1024hZv>: 0: e9 00 00 00 00 jmp 5 <_D25memoryerror_stackoverflow1fFKG1024hZv+0x5> Disassembly of section .text._D25memoryerror_stackoverflow1gFKG1024hZv: 0000000000000000 <_D25memoryerror_stackoverflow1gFKG1024hZv>: 0: e9 00 00 00 00 jmp 5 <_D25memoryerror_stackoverflow1gFKG1024hZv+0x5> ``` Compared to the llvm-19 optimized version: ``` Disassembly of section .text._D25memoryerror_stackoverflow1fFKG1024hZv: 0000000000000000 <_D25memoryerror_stackoverflow1fFKG1024hZv>: 0: 53 push %rbx 1: 48 81 ec 00 04 00 00 sub $0x400,%rsp 8: 48 89 fe mov %rdi,%rsi b: 48 89 e3 mov %rsp,%rbx e: ba 00 04 00 00 mov $0x400,%edx 13: 48 89 df mov %rbx,%rdi 16: e8 00 00 00 00 call 1b <_D25memoryerror_stackoverflow1fFKG1024hZv+0x1b> 1b: 48 89 df mov %rbx,%rdi 1e: e8 00 00 00 00 call 23 <_D25memoryerror_stackoverflow1fFKG1024hZv+0x23> 23: 48 81 c4 00 04 00 00 add $0x400,%rsp 2a: 5b pop %rbx 2b: c3 ret Disassembly of section .text._D25memoryerror_stackoverflow1gFKG1024hZv: 0000000000000000 <_D25memoryerror_stackoverflow1gFKG1024hZv>: 0: 53 push %rbx 1: 48 81 ec 00 04 00 00 sub $0x400,%rsp 8: 48 89 fe mov %rdi,%rsi b: 48 89 e3 mov %rsp,%rbx e: ba 00 04 00 00 mov $0x400,%edx 13: 48 89 df mov %rbx,%rdi 16: e8 00 00 00 00 call 1b <_D25memoryerror_stackoverflow1gFKG1024hZv+0x1b> 1b: 48 89 df mov %rbx,%rdi 1e: e8 00 00 00 00 call 23 <_D25memoryerror_stackoverflow1gFKG1024hZv+0x23> 23: 48 81 c4 00 04 00 00 add $0x400,%rsp 2a: 5b pop %rbx 2b: c3 ret ``` Signed-off-by: Andrei Horodniceanu --- .../druntime/test/exceptions/src/memoryerror_stackoverflow.d | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/druntime/test/exceptions/src/memoryerror_stackoverflow.d b/runtime/druntime/test/exceptions/src/memoryerror_stackoverflow.d index f54d78d26a..729174f199 100644 --- a/runtime/druntime/test/exceptions/src/memoryerror_stackoverflow.d +++ b/runtime/druntime/test/exceptions/src/memoryerror_stackoverflow.d @@ -1,16 +1,19 @@ import etc.linux.memoryerror; +import core.volatile; pragma(inline, false): void f(ref ubyte[1024] buf) { ubyte[1024] cpy = buf; + volatileStore(&cpy[0], 1); g(cpy); } void g(ref ubyte[1024] buf) { ubyte[1024] cpy = buf; + volatileStore(&cpy[0], 2); f(cpy); } From 4d2dd8d956000c4189b5a686d801c16844f2e7bf Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Wed, 20 Aug 2025 21:24:21 +0300 Subject: [PATCH 04/10] [druntime]: Fix posix.sys.shm.shmid_ds on (some) non-x86_64 Check glibc's sysdeps/unix/sysv/linux/**/bits/types/struct_shmid_ds.h for correctness. Some arches still look like they have an incorrect declaration but this, at least, fixes aarch64 which is the more common one. Signed-off-by: Andrei Horodniceanu --- runtime/druntime/src/core/sys/posix/sys/shm.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime/druntime/src/core/sys/posix/sys/shm.d b/runtime/druntime/src/core/sys/posix/sys/shm.d index 6ecdc0defe..7481d8cc60 100644 --- a/runtime/druntime/src/core/sys/posix/sys/shm.d +++ b/runtime/druntime/src/core/sys/posix/sys/shm.d @@ -66,11 +66,11 @@ version (linux) ipc_perm shm_perm; size_t shm_segsz; time_t shm_atime; - version (X86_64) {} else c_ulong __unused1; + static if (time_t.sizeof == 4) c_ulong __unused1; time_t shm_dtime; - version (X86_64) {} else c_ulong __unused2; + static if (time_t.sizeof == 4) c_ulong __unused2; time_t shm_ctime; - version (X86_64) {} else c_ulong __unused3; + static if (time_t.sizeof == 4) c_ulong __unused3; pid_t shm_cpid; pid_t shm_lpid; shmatt_t shm_nattch; From 0f40c477afee5c696dea165faa0715456c99c277 Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Wed, 20 Aug 2025 21:38:51 +0300 Subject: [PATCH 05/10] [druntime]: Fix sys.posix.sys.types.nlink_t definition The definitions I've taken from glibc's sysdeps/unix/sysv/linux/**/bits/typesizes.h. Signed-off-by: Andrei Horodniceanu --- runtime/druntime/src/core/sys/posix/sys/types.d | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/runtime/druntime/src/core/sys/posix/sys/types.d b/runtime/druntime/src/core/sys/posix/sys/types.d index 642b3839aa..081748ac60 100644 --- a/runtime/druntime/src/core/sys/posix/sys/types.d +++ b/runtime/druntime/src/core/sys/posix/sys/types.d @@ -103,7 +103,20 @@ version (linux) alias ulong dev_t; alias uint gid_t; alias uint mode_t; - alias ulong_t nlink_t; + + version (X86_64) + alias ulong nlink_t; + else version (S390) + alias size_t nlink_t; + else version (PPC64) + alias size_t nlink_t; + else version (MIPS64) + alias size_t nlink_t; + else version (HPPA64) + alias size_t nlink_t; + else + alias uint nlink_t; + alias int pid_t; //size_t (defined in core.stdc.stddef) alias c_long ssize_t; From 305909f285f1f0e14a92c8d7d9ea471671af2e28 Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Thu, 21 Aug 2025 21:00:20 +0300 Subject: [PATCH 06/10] [druntime-test]: exceptions: Skip memoryerror_null_call on linux-aarch64 Signed-off-by: Andrei Horodniceanu --- runtime/druntime/test/exceptions/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/runtime/druntime/test/exceptions/Makefile b/runtime/druntime/test/exceptions/Makefile index ed8c7e9f85..12221117ff 100644 --- a/runtime/druntime/test/exceptions/Makefile +++ b/runtime/druntime/test/exceptions/Makefile @@ -58,6 +58,16 @@ endif ifeq ($(OS),windows) TESTS+=winstack endif + +ifdef IN_LDC + ifeq ($(OS)-$(ARCH),linux-aarch64) + # This hits the "should never happen" default branch in the + # rt.dwarfeh._d_throw_exception:399 unwind switch statement. + # The value is 0xf7fe7fb8 which is complete garbage. + TESTS := $(filter-out memoryerror_null_call,$(TESTS)) + endif +endif + include ../common.mak $(ROOT)/line_trace.done: $(ROOT)/line_trace$(DOTEXE) From 2f6c206ba7eca493428a1788aeda5da693912bfd Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Thu, 21 Aug 2025 23:07:52 +0300 Subject: [PATCH 07/10] [druntime-test]: exceptions: Skip spurious memoryerror These tests seem to fail with a shared druntime (depending on arch as well), and work with a static one. CI fails with a static druntime though. A gdb backtrace with a shared druntime: ``` Reading symbols from ./a... (No debugging symbols found in ./a) (gdb) r Starting program: /root/build/a [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib64/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x0000005555550afc in D main () (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x0000007ff77432f0 in ?? () from /usr/lib/gcc/aarch64-unknown-linux-gnu/15/libgcc_s.so.1 (gdb) bt \#0 0x0000007ff77432f0 in ?? () from /usr/lib/gcc/aarch64-unknown-linux-gnu/15/libgcc_s.so.1 \#1 0x0000007ff77563b8 in ?? () from /usr/lib/gcc/aarch64-unknown-linux-gnu/15/libgcc_s.so.1 \#2 0x0000007ff7757000 in _Unwind_Backtrace () from /usr/lib/gcc/aarch64-unknown-linux-gnu/15/libgcc_s.so.1 \#3 0x0000007ff78b2c6c in backtrace () from /usr/lib64/libc.so.6 \#4 0x0000007ff7aee058 in core.lifetime.emplace!(core.runtime.DefaultTraceInfo).emplace(core.runtime.DefaultTraceInfo) () from /usr/lib/ldc2/1.41/lib64/libdruntime-ldc-shared.so.111 \#5 0x0000007ff7aed1f0 in core.runtime.defaultTraceHandler(void*) () from /usr/lib/ldc2/1.41/lib64/libdruntime-ldc-shared.so.111 \#6 0x0000007ff7b09614 in _d_createTrace () from /usr/lib/ldc2/1.41/lib64/libdruntime-ldc-shared.so.111 \#7 0x0000007ff7b0a7a0 in _d_throw_exception () from /usr/lib/ldc2/1.41/lib64/libdruntime-ldc-shared.so.111 \#8 0x0000007ff7acb418 in _d_assert_msg () from /usr/lib/ldc2/1.41/lib64/libdruntime-ldc-shared.so.111 \#9 0x0000005555550d18 in etc.linux.memoryerror.registerMemoryAssertHandler!().registerMemoryAssertHandler()._d_handleSignalAssert(int, core.sys.posix.signal.siginfo_t*, void*) () \#10 \#11 0x0000005555550afc in D main () ``` And with a static druntime: ``` Reading symbols from ./a... (No debugging symbols found in ./a) (gdb) r Starting program: /tmp/a [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib64/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. 0x000000555556a4bc in D main () (gdb) c Continuing. core.exception.AssertError@/usr/lib/ldc2/1.41/include/d/etc/linux/memoryerror.d(415): segmentation fault: null pointer read/write operation ---------------- ??:? [0x555557fa2f] ??:? [0x555557f1ab] ??:? [0x5555581d17] ??:? [0x5555570893] ??:? [0x555556b2ab] ??:? [0x555556a6d7] ??:? [0x7ff7ffb797] ??:? [0x555556a4bb] ??:? [0x5555570567] ??:? [0x5555570413] ??:? [0x5555570277] ??:? [0x555556a5a3] ??:? [0x7ff7d02053] ??:? __libc_start_main [0x7ff7d02137] ??:? [0x555556a3af] Program received signal SIGSEGV, Segmentation fault. 0x0000007ffffffdd0 in ?? () ``` Signed-off-by: Andrei Horodniceanu --- runtime/DRuntimeIntegrationTests.cmake | 2 +- runtime/druntime/test/exceptions/Makefile | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/runtime/DRuntimeIntegrationTests.cmake b/runtime/DRuntimeIntegrationTests.cmake index 1927c0b010..c131c0e511 100644 --- a/runtime/DRuntimeIntegrationTests.cmake +++ b/runtime/DRuntimeIntegrationTests.cmake @@ -89,7 +89,7 @@ foreach(name ${testnames}) ROOT=${outdir} DMD=${LDMD_EXE_FULL} BUILD=${build} SHARED=1 DRUNTIME=${druntime_path_build} DRUNTIMESO=${shared_druntime_path_build} ${cc} ${cxx} CFLAGS_BASE=${cflags_base} DFLAGS_BASE=${dflags_base} ${linkdl} - IN_LDC=1 ${musl} + IN_LDC=1 ${musl} BUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ) set_tests_properties(${fullname} PROPERTIES DEPENDS clean-${fullname}) endforeach() diff --git a/runtime/druntime/test/exceptions/Makefile b/runtime/druntime/test/exceptions/Makefile index 12221117ff..012b8c1d08 100644 --- a/runtime/druntime/test/exceptions/Makefile +++ b/runtime/druntime/test/exceptions/Makefile @@ -65,6 +65,23 @@ ifdef IN_LDC # rt.dwarfeh._d_throw_exception:399 unwind switch statement. # The value is 0xf7fe7fb8 which is complete garbage. TESTS := $(filter-out memoryerror_null_call,$(TESTS)) + + # The aarch64 github runners fail but it works locally + TESTS := $(filter-out memoryerror_%,$(TESTS)) + endif + + ifeq ($(OS),linux) + # These maybe fail with a shared runtime. + # + # CircleCI fails on x86_64, other CI and locally work. + # aarch64 fails locally, shared-only is not tested in CI. + # + # The failure is caused by the backtrace call in + # core.runtime.DefaultTraceInfo.this + ifeq ($(BUILD_SHARED_LIBS),ON) + TESTS := $(filter-out memoryerror_%,$(TESTS)) + endif + $(ROOT)/memoryerror_%: private extra_ldflags.d += -link-defaultlib-shared=false endif endif From e5c33a1badef08ec35e6a070d2ae92449fa5eb4b Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Sun, 24 Aug 2025 13:31:31 +0300 Subject: [PATCH 08/10] [importc]: Fix math.h on glibc aarch64 Signed-off-by: Andrei Horodniceanu --- runtime/druntime/src/__importc_builtins.di | 7 +++++++ runtime/druntime/src/importc.h | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/runtime/druntime/src/__importc_builtins.di b/runtime/druntime/src/__importc_builtins.di index 312e16c62c..476852cd82 100644 --- a/runtime/druntime/src/__importc_builtins.di +++ b/runtime/druntime/src/__importc_builtins.di @@ -193,3 +193,10 @@ else version (LDC) version (X86) public import ldc.gccbuiltins_x86; version (X86_64) public import ldc.gccbuiltins_x86; } + +version (CRuntime_Glibc) version (AArch64) +{ + // math.h needs these + alias __Float32x4_t = __vector(float[4]); + alias __Float64x2_t = __vector(double[2]); +} diff --git a/runtime/druntime/src/importc.h b/runtime/druntime/src/importc.h index d60fcfff75..02e16adf76 100644 --- a/runtime/druntime/src/importc.h +++ b/runtime/druntime/src/importc.h @@ -187,8 +187,16 @@ typedef unsigned long long __uint64_t; #define _Float128 long double #define __float128 long double #endif + +#ifdef __aarch64__ +// glibc's math.h needs these types to be defined +typedef struct {} __SVBool_t; +typedef struct {} __SVFloat32_t; +typedef struct {} __SVFloat64_t; #endif +#endif // __linux__ + #if __APPLE__ #undef __SIZEOF_INT128__ #endif From 1ae78081b8ceca69f4bbddea65a64ebb10e7c6cc Mon Sep 17 00:00:00 2001 From: Andrei Horodniceanu Date: Sun, 24 Aug 2025 15:04:49 +0300 Subject: [PATCH 09/10] [dmd-testsuite]: compilable/stdcheaders: Reenable math.h on linux aarch64 Signed-off-by: Andrei Horodniceanu --- tests/dmd/compilable/stdcheaders.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/dmd/compilable/stdcheaders.c b/tests/dmd/compilable/stdcheaders.c index 12674dce37..0d8e0f0422 100644 --- a/tests/dmd/compilable/stdcheaders.c +++ b/tests/dmd/compilable/stdcheaders.c @@ -21,12 +21,10 @@ #include #include -#if !(defined(__linux__) && defined(__aarch64__)) // /usr/include/bits/math-vector.h(162): Error: undefined identifier `__Float32x4_t` #include #ifndef _MSC_VER // C:\Program Files (x86)\Windows Kits\10\include\10.0.26100.0\ucrt\corecrt_math.h(93): Error: reinterpretation through overlapped field `f` is not allowed in CTFE float x = NAN; #endif -#endif #ifndef _MSC_VER // setjmp.h(51): Error: missing tag `identifier` after `struct #include @@ -66,11 +64,9 @@ float x = NAN; // Apple: /Applications/Xcode-14.2.0.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/tgmath.h(39): Error: named parameter required before `...` // OpenBSD: /usr/lib/clang/13.0.0/include/tgmath.h(34): Error: named parameter required before `...` // Linux: /tmp/clang/lib/clang/15.0.3/include/tgmath.h(34): Error: named parameter required before `...` -#if !(defined(__linux__) && defined(__aarch64__)) // /usr/include/bits/math-vector.h(162): Error: undefined identifier `__Float32x4_t` #include #endif #endif -#endif #ifndef __linux__ #ifndef __APPLE__ From 85cc74b7a8385ce5eb3d9c73dbd590be299cf8c2 Mon Sep 17 00:00:00 2001 From: Martin Kinkelin Date: Mon, 25 Aug 2025 16:23:08 +0200 Subject: [PATCH 10/10] [reduce LDC-specific diff wrt. IS_MUSL] Based on https://github.com/dlang/dmd/pull/21779. For LDC, always define IS_MUSL externally, not just to `1` for musl targets. --- runtime/DRuntimeIntegrationTests.cmake | 2 +- runtime/druntime/test/exceptions/Makefile | 9 +++++++++ runtime/druntime/test/importc_compare/Makefile | 15 +++++++++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/runtime/DRuntimeIntegrationTests.cmake b/runtime/DRuntimeIntegrationTests.cmake index c131c0e511..152e79067e 100644 --- a/runtime/DRuntimeIntegrationTests.cmake +++ b/runtime/DRuntimeIntegrationTests.cmake @@ -57,7 +57,7 @@ else() list(REMOVE_ITEM testnames uuid) endif() -set(musl "") +set(musl "IS_MUSL=0") if(TARGET_SYSTEM MATCHES "musl") set(musl "IS_MUSL=1") endif() diff --git a/runtime/druntime/test/exceptions/Makefile b/runtime/druntime/test/exceptions/Makefile index 012b8c1d08..0c630d0517 100644 --- a/runtime/druntime/test/exceptions/Makefile +++ b/runtime/druntime/test/exceptions/Makefile @@ -3,6 +3,15 @@ ifdef IN_LDC include ../../../../dmd/osmodel.mak endif +ifndef IS_MUSL # LDC defines it externally + ifeq ($(OS),linux) + # FIXME: detect musl libc robustly; just checking Alpine Linux' apk tool for now + ifeq (1,$(shell which apk >/dev/null 2>&1 && echo 1)) + IS_MUSL := 1 + endif + endif +endif + TESTS=stderr_msg unittest_assert invalid_memory_operation static_dtor \ future_message refcounted rt_trap_exceptions_drt catch_in_finally \ message_with_null diff --git a/runtime/druntime/test/importc_compare/Makefile b/runtime/druntime/test/importc_compare/Makefile index ea2a467e8f..5a50aef521 100644 --- a/runtime/druntime/test/importc_compare/Makefile +++ b/runtime/druntime/test/importc_compare/Makefile @@ -5,12 +5,19 @@ endif TESTS := importc_compare +ifndef IS_MUSL # LDC defines it externally + ifeq ($(OS),linux) + # FIXME: detect musl libc robustly; just checking Alpine Linux' apk tool for now + ifeq (1,$(shell which apk >/dev/null 2>&1 && echo 1)) + IS_MUSL := 1 + endif + endif +endif + # FIXME: fails on Alpine v3.21 with conflicting struct declarations in the C headers: # /usr/include/asm-generic/fcntl.h(195): Error: struct `importc_includes.flock` conflicts with struct `importc_includes.flock` at /usr/include/fcntl.h(24) -ifeq ($(OS),linux) - ifeq (1,$(IS_MUSL)) - TESTS := - endif +ifeq ($(IS_MUSL),1) + TESTS := endif # FIXME: fails on macOS arm64, e.g., due to unsupported `_Float16`