summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYelninei <yelninei@tutamail.com>2026-03-13 18:56:33 +0000
committerJanneke Nieuwenhuizen <janneke@gnu.org>2026-05-10 19:08:07 +0200
commite5b92baa27e63d0a18960e596aaee98e4dc90477 (patch)
treeaab47c225de87975eebd7512e0853ba314e1e244
parent0c53e15628f0a6cf293d226bba81112c7bba6a3d (diff)
gnu: dmd: Support GNU/Hurd.hurd-team
* gnu/packages/patches/dmd-hurd.patch, gnu/packages/patches/phobos-hurd.patch : New patches. * gnu/local.mk: Register them. * gnu/packages/dlang.scm (dmd-bootstrap): Add dmd patch. [native-inputs]: Make gdb/pinned linux-only, add patch to phobos. [#:make-flags]: Set DISABLED_TESTS. [#:phases]: In 'patch-tests disable more tests. Change-Id: Id5e2fee30bb48a27785682d1b6a30666f33e37c5 Change-Id: I16ad0cba2666fe475cd4028287316e9f8cbad2fe
-rw-r--r--gnu/local.mk2
-rw-r--r--gnu/packages/dlang.scm62
-rw-r--r--gnu/packages/patches/dmd-hurd.patch5161
-rw-r--r--gnu/packages/patches/phobos-hurd.patch64
4 files changed, 5273 insertions, 16 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index c8fa40c0f4c..49d224a0d4c 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -1199,6 +1199,7 @@ dist_patch_DATA = \
1199 %D%/packages/patches/directfb-davinci-glibc-228-compat.patch \ 1199 %D%/packages/patches/directfb-davinci-glibc-228-compat.patch \
1200 %D%/packages/patches/django-compressor-build-with-beautifulsoup-4.14+.patch \ 1200 %D%/packages/patches/django-compressor-build-with-beautifulsoup-4.14+.patch \
1201 %D%/packages/patches/dkimproxy-add-ipv6-support.patch \ 1201 %D%/packages/patches/dkimproxy-add-ipv6-support.patch \
1202 %D%/packages/patches/dmd-hurd.patch \
1202 %D%/packages/patches/doc++-gcc-14.patch \ 1203 %D%/packages/patches/doc++-gcc-14.patch \
1203 %D%/packages/patches/docbook-utils-documentation-edits.patch \ 1204 %D%/packages/patches/docbook-utils-documentation-edits.patch \
1204 %D%/packages/patches/docbook-utils-escape-characters.patch \ 1205 %D%/packages/patches/docbook-utils-escape-characters.patch \
@@ -2101,6 +2102,7 @@ dist_patch_DATA = \
2101 %D%/packages/patches/pdl-2.100-reproducibility.patch \ 2102 %D%/packages/patches/pdl-2.100-reproducibility.patch \
2102 %D%/packages/patches/petri-foo-0.1.87-fix-recent-file-not-exist.patch \ 2103 %D%/packages/patches/petri-foo-0.1.87-fix-recent-file-not-exist.patch \
2103 %D%/packages/patches/pharo-vm-cmake.patch \ 2104 %D%/packages/patches/pharo-vm-cmake.patch \
2105 %D%/packages/patches/phobos-hurd.patch \
2104 %D%/packages/patches/plasma-framework-fix-KF5PlasmaMacros.cmake.patch \ 2106 %D%/packages/patches/plasma-framework-fix-KF5PlasmaMacros.cmake.patch \
2105 %D%/packages/patches/plasp-fix-normalization.patch \ 2107 %D%/packages/patches/plasp-fix-normalization.patch \
2106 %D%/packages/patches/plasp-include-iostream.patch \ 2108 %D%/packages/patches/plasp-include-iostream.patch \
diff --git a/gnu/packages/dlang.scm b/gnu/packages/dlang.scm
index 649a0962a40..63186768048 100644
--- a/gnu/packages/dlang.scm
+++ b/gnu/packages/dlang.scm
@@ -351,7 +351,9 @@ integration tests...\n")
351 (file-name (git-file-name "dmd" version)) 351 (file-name (git-file-name "dmd" version))
352 (sha256 352 (sha256
353 (base32 353 (base32
354 "0qvg2fb73kyng8k1wj482g07ar2qw5laa5fynwx7pdd610n0pjpc")))) 354 "0qvg2fb73kyng8k1wj482g07ar2qw5laa5fynwx7pdd610n0pjpc"))
355 (patches
356 (search-patches "dmd-hurd.patch"))))
355 (build-system gnu-build-system) 357 (build-system gnu-build-system)
356 (arguments 358 (arguments
357 (list 359 (list
@@ -372,7 +374,16 @@ integration tests...\n")
372 ;; Do not build the shared libphobos2.so library, to avoid 374 ;; Do not build the shared libphobos2.so library, to avoid
373 ;; retaining a reference to gcc:lib. 375 ;; retaining a reference to gcc:lib.
374 "SHARED=0" 376 "SHARED=0"
375 "DIFFABLE=1" ;constant timestamp 377 #$@(if (target-hurd?)
378 (list (string-append "DISABLED_TESTS=core/thread/osthread "
379 "std/parallelism " ;; pthread stubs
380 "std/file " ;; rename (NULL, "")
381 "std/socket " ;; ENOPROTOOPT
382 "std/datetime/systime "
383 "std/datetime/timezone " ;; TZDIR
384 "std/net/curl ")) ;; dlopen curl
385 '())
386 "DIFFABLE=1" ;constant timestamp
376 "VERBOSE=1") 387 "VERBOSE=1")
377 #:modules 388 #:modules
378 `(,@%default-gnu-modules 389 `(,@%default-gnu-modules
@@ -470,7 +481,19 @@ integration tests...\n")
470 "long_backtrace_trunc rt_trap_exceptions ")) 481 "long_backtrace_trunc rt_trap_exceptions "))
471 "")) 482 ""))
472 (substitute* "dmd/druntime/test/gc/Makefile" 483 (substitute* "dmd/druntime/test/gc/Makefile"
473 ((" invariant ") " ")))) 484 ((" invariant ") " "))
485
486 #$@(if (target-hurd?)
487 '((for-each
488 delete-file
489 ;; environment differs in LD_ORIGIN_PATH
490 '("dmd/compiler/test/dshell/sameenv.d"
491 ;; Non _GLIBCXX_USE_CXX98_ABI version prints a warning
492 "dmd/compiler/test/runnable_cxx/cppa.d"))
493 ;; Segfault
494 (substitute* "dmd/druntime/test/shared/Makefile"
495 (("loadDR host ") "")))
496 '())))
474 (delete 'bootstrap) 497 (delete 'bootstrap)
475 (delete 'configure) 498 (delete 'configure)
476 (replace 'build 499 (replace 'build
@@ -492,7 +515,8 @@ integration tests...\n")
492 (phase-in-sub-dir 'check "phobos")) 515 (phase-in-sub-dir 'check "phobos"))
493 (replace 'install 516 (replace 'install
494 (lambda* (#:key outputs #:allow-other-keys) 517 (lambda* (#:key outputs #:allow-other-keys)
495 (let* ((platform (cond (#$(target-linux?) "linux"))) 518 (let* ((platform (cond (#$(target-linux?) "linux")
519 (#$(target-hurd?) "hurd")))
496 (bits (if #$(target-64bit?) 64 32)) 520 (bits (if #$(target-64bit?) 64 32))
497 (build-sub-dir (format #f "generated/~a/release/~a" 521 (build-sub-dir (format #f "generated/~a/release/~a"
498 platform bits)) 522 platform bits))
@@ -536,17 +560,22 @@ integration tests...\n")
536 (inputs 560 (inputs
537 (list bash-minimal)) 561 (list bash-minimal))
538 (native-inputs 562 (native-inputs
539 (list gdmd which 563 (append
540 gdb/pinned ; for tests 564 (if (target-linux?)
541 (origin 565 ;; gdb tests only on on linux
542 (method git-fetch) 566 (list gdb/pinned)
543 (uri (git-reference 567 '())
544 (url "https://github.com/dlang/phobos") 568 (list gdmd which
545 (commit (string-append "v" version)))) 569 (origin
546 (file-name (git-file-name "phobos" version)) 570 (method git-fetch)
547 (sha256 571 (uri (git-reference
548 (base32 572 (url "https://github.com/dlang/phobos")
549 "0afi5glnf96242cbnr10ccjvfsgkh4k5y7qnmxv4ph5g0izvi1dc"))))) 573 (commit (string-append "v" version))))
574 (file-name (git-file-name "phobos" version))
575 (sha256
576 (base32
577 "0afi5glnf96242cbnr10ccjvfsgkh4k5y7qnmxv4ph5g0izvi1dc"))
578 (patches (search-patches "phobos-hurd.patch"))))))
550 (outputs '("out" "lib" "debug")) 579 (outputs '("out" "lib" "debug"))
551 (synopsis "Reference D Programming Language compiler") 580 (synopsis "Reference D Programming Language compiler")
552 (description "@acronym{DMD, Digital Mars D compiler} is the reference 581 (description "@acronym{DMD, Digital Mars D compiler} is the reference
@@ -555,7 +584,8 @@ compiler for the D programming language.")
555 (home-page "https://github.com/dlang/dmd") 584 (home-page "https://github.com/dlang/dmd")
556 ;; As reported by upstream: 585 ;; As reported by upstream:
557 ;; https://wiki.dlang.org/Compilers#Comparison 586 ;; https://wiki.dlang.org/Compilers#Comparison
558 (supported-systems '("i686-linux" "x86_64-linux" "aarch64-linux")) 587 (supported-systems '("i686-linux" "x86_64-linux" "aarch64-linux"
588 "i586-gnu" "x86_64-gnu"))
559 589
560 ;; This variant exists only for bootstrapping purposes. 590 ;; This variant exists only for bootstrapping purposes.
561 (properties '((hidden? . #t))))) 591 (properties '((hidden? . #t)))))
diff --git a/gnu/packages/patches/dmd-hurd.patch b/gnu/packages/patches/dmd-hurd.patch
new file mode 100644
index 00000000000..cd249eb07c4
--- /dev/null
+++ b/gnu/packages/patches/dmd-hurd.patch
@@ -0,0 +1,5161 @@
1Taken from:
2 * https://github.com/dlang/dmd/pull/22787
3
4
5From 049fc0b537bcc921ca66fb07c9ba147c11ea67a8 Mon Sep 17 00:00:00 2001
6From: Yelninei <yelninei@tutamail.com>
7Date: Sat, 21 Mar 2026 15:45:23 +0000
8Subject: [PATCH 1/5] dmd: file: Add PROT_READ to mmap protections.
9
10---
11 compiler/src/dmd/common/file.d | 6 +++---
12 1 file changed, 3 insertions(+), 3 deletions(-)
13
14diff --git a/compiler/src/dmd/common/file.d b/compiler/src/dmd/common/file.d
15index 203ee27abd..0b4ef3c73e 100644
16--- a/compiler/src/dmd/common/file.d
17+++ b/compiler/src/dmd/common/file.d
18@@ -122,7 +122,7 @@ struct FileMapping(Datum)
19
20 if (size > 0 && size != ulong.max && size <= size_t.max)
21 {
22- auto p = mmap(null, cast(size_t) size, is(Datum == const) ? PROT_READ : PROT_WRITE, MAP_SHARED, handle, 0);
23+ auto p = mmap(null, cast(size_t) size, is(Datum == const) ? PROT_READ : (PROT_READ | PROT_WRITE), MAP_SHARED, handle, 0);
24 if (p == MAP_FAILED)
25 {
26 fprintf(stderr, "mmap(null, %zu) for \"%s\" failed: %s\n", cast(size_t) size, filename, strerror(errno));
27@@ -383,8 +383,8 @@ struct FileMapping(Datum)
28 }
29 if (size > 0)
30 {
31- auto p = mmap(null, size, PROT_WRITE, MAP_SHARED, handle, 0);
32- if (cast(ssize_t) p == -1)
33+ auto p = mmap(null, size, PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0);
34+ if (p == MAP_FAILED)
35 {
36 fprintf(stderr, "mmap() failed for \"%s\": %s\n", filename, strerror(errno));
37 exit(1);
38--
392.52.0
40
41From a28335402798ae7754e3b97dae6d9971243d4b17 Mon Sep 17 00:00:00 2001
42From: Yelninei <yelninei@tutamail.com>
43Date: Sat, 21 Mar 2026 15:42:32 +0000
44Subject: [PATCH 2/5] dmd: Port to GNU Hurd
45
46---
47 compiler/ini/hurd/bin32/dmd.conf | 5 +++
48 compiler/ini/hurd/bin64/dmd.conf | 5 +++
49 compiler/src/build.d | 4 ++-
50 compiler/src/dmd/backend/arm/cod1.d | 2 +-
51 compiler/src/dmd/backend/backconfig.d | 46 ++++++++++++++++++++++++---
52 compiler/src/dmd/backend/cdef.d | 12 +++++--
53 compiler/src/dmd/backend/elfobj.d | 9 ++++--
54 compiler/src/dmd/backend/melf.d | 3 +-
55 compiler/src/dmd/backend/x86/cod1.d | 21 ++++++------
56 compiler/src/dmd/backend/x86/cod3.d | 6 ++--
57 compiler/src/dmd/cli.d | 13 ++++++--
58 compiler/src/dmd/dmdparams.d | 2 ++
59 compiler/src/dmd/dmsc.d | 1 +
60 compiler/src/dmd/json.d | 2 ++
61 compiler/src/dmd/main.d | 2 +-
62 compiler/src/dmd/mars.d | 7 ++--
63 compiler/src/dmd/target.d | 41 +++++++++++++++---------
64 compiler/src/osmodel.mak | 7 ++--
65 18 files changed, 139 insertions(+), 49 deletions(-)
66 create mode 100644 compiler/ini/hurd/bin32/dmd.conf
67 create mode 100644 compiler/ini/hurd/bin64/dmd.conf
68
69diff --git a/compiler/ini/hurd/bin32/dmd.conf b/compiler/ini/hurd/bin32/dmd.conf
70new file mode 100644
71index 0000000000..15f03e72fe
72--- /dev/null
73+++ b/compiler/ini/hurd/bin32/dmd.conf
74@@ -0,0 +1,5 @@
75+[Environment32]
76+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -fPIC
77+
78+[Environment64]
79+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -fPIC
80diff --git a/compiler/ini/hurd/bin64/dmd.conf b/compiler/ini/hurd/bin64/dmd.conf
81new file mode 100644
82index 0000000000..15f03e72fe
83--- /dev/null
84+++ b/compiler/ini/hurd/bin64/dmd.conf
85@@ -0,0 +1,5 @@
86+[Environment32]
87+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -fPIC
88+
89+[Environment64]
90+DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -fPIC
91diff --git a/compiler/src/build.d b/compiler/src/build.d
92index ac50483e47..5349778ffa 100755
93--- a/compiler/src/build.d
94+++ b/compiler/src/build.d
95@@ -1680,7 +1680,7 @@ bool download(string to, string from, uint tries = 3)
96 /**
97 Detects the host OS.
98
99-Returns: a string from `{windows, osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris}`
100+Returns: a string from `{windows, osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris,hurd}`
101 */
102 string detectOS()
103 {
104@@ -1700,6 +1700,8 @@ string detectOS()
105 return "dragonflybsd";
106 else version(Solaris)
107 return "solaris";
108+ else version(Hurd)
109+ return "hurd";
110 else
111 static assert(0, "Unrecognized or unsupported OS.");
112 }
113diff --git a/compiler/src/dmd/backend/arm/cod1.d b/compiler/src/dmd/backend/arm/cod1.d
114index faa7207589..f9f2384e36 100644
115--- a/compiler/src/dmd/backend/arm/cod1.d
116+++ b/compiler/src/dmd/backend/arm/cod1.d
117@@ -1580,7 +1580,7 @@ void cdfunc(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
118
119 /* Assume called function access statics
120 */
121- if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64) &&
122+ if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_HURD | EX_HURD64) &&
123 config.flags3 & CFG3pic)
124 cgstate.accessedTLS = true;
125
126diff --git a/compiler/src/dmd/backend/backconfig.d b/compiler/src/dmd/backend/backconfig.d
127index 1cdff29ede..77b104cdad 100644
128--- a/compiler/src/dmd/backend/backconfig.d
129+++ b/compiler/src/dmd/backend/backconfig.d
130@@ -288,6 +288,42 @@ void out_config_init(
131 cfg.objfmt = OBJ_ELF;
132 cfg.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE;
133 }
134+ else if (cfg.exe & (EX_HURD | EX_HURD64))
135+ {
136+ cfg.fpxmmregs = true;
137+ cfg.avx = avx;
138+ if (model == 64)
139+ {
140+ cfg.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE;
141+ }
142+ else
143+ {
144+ cfg.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE;
145+ if (!exe)
146+ cfg.flags |= CFGromable; // put switch tables in code segment
147+ }
148+ cfg.flags |= CFGnoebp;
149+ switch (pic)
150+ {
151+ case 0: // PIC.fixed
152+ break;
153+
154+ case 1: // PIC.pic
155+ cfg.flags3 |= CFG3pic;
156+ break;
157+
158+ case 2: // PIC.pie
159+ cfg.flags3 |= CFG3pic | CFG3pie;
160+ break;
161+
162+ default:
163+ assert(0);
164+ }
165+ if (symdebug)
166+ cfg.flags |= CFGalwaysframe;
167+
168+ cfg.objfmt = OBJ_ELF;
169+ }
170
171 cfg.flags2 |= CFG2nodeflib; // no default library
172 cfg.flags3 |= CFG3eseqds;
173@@ -320,7 +356,7 @@ static if (0)
174 if (symdebug)
175 {
176 if (cfg.exe & (EX_LINUX | EX_LINUX64 | EX_OPENBSD | EX_OPENBSD64 | EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64 |
177- EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64))
178+ EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64 | EX_HURD | EX_HURD64))
179 {
180 configv.addlinenumbers = 1;
181 cfg.fulltypes = (symdebug == 1) ? CVDWARF_D : CVDWARF_C;
182@@ -446,7 +482,7 @@ void util_set32(exefmt_t exe)
183 _tysize[TYnullptr] = LONGSIZE;
184 _tysize[TYnptr] = LONGSIZE;
185 _tysize[TYnref] = LONGSIZE;
186-if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64))
187+if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_HURD | EX_HURD64))
188 {
189 _tysize[TYldouble] = 12;
190 _tysize[TYildouble] = 12;
191@@ -477,7 +513,7 @@ if (exe & EX_windos)
192 _tyalignsize[TYnullptr] = LONGSIZE;
193 _tyalignsize[TYnref] = LONGSIZE;
194 _tyalignsize[TYnptr] = LONGSIZE;
195-if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64))
196+if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_HURD | EX_HURD64))
197 {
198 _tyalignsize[TYldouble] = 4;
199 _tyalignsize[TYildouble] = 4;
200@@ -533,7 +569,7 @@ void util_set64(exefmt_t exe)
201 _tysize[TYnptr] = 8;
202 _tysize[TYnref] = 8;
203 if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD |
204- EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64))
205+ EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_OSX | EX_OSX64 | EX_HURD | EX_HURD64))
206 {
207 _tysize[TYldouble] = 16;
208 _tysize[TYildouble] = 16;
209@@ -557,7 +593,7 @@ void util_set64(exefmt_t exe)
210 _tyalignsize[TYnullptr] = 8;
211 _tyalignsize[TYnptr] = 8;
212 _tyalignsize[TYnref] = 8;
213- if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64))
214+ if (exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS | EX_SOLARIS64 | EX_HURD | EX_HURD64))
215 {
216 _tyalignsize[TYldouble] = 16;
217 _tyalignsize[TYildouble] = 16;
218diff --git a/compiler/src/dmd/backend/cdef.d b/compiler/src/dmd/backend/cdef.d
219index d242a260a0..f1e9c94cb2 100644
220--- a/compiler/src/dmd/backend/cdef.d
221+++ b/compiler/src/dmd/backend/cdef.d
222@@ -44,6 +44,7 @@ enum TARGET_OPENBSD = xversion!`OpenBSD`;
223 enum TARGET_SOLARIS = xversion!`Solaris`;
224 enum TARGET_WINDOS = xversion!`Windows`;
225 enum TARGET_DRAGONFLYBSD = xversion!`DragonFlyBSD`;
226+enum TARGET_HURD = xversion!`Hurd`;
227
228 //
229 // Attributes
230@@ -304,6 +305,8 @@ enum
231 EX_OPENBSD = 0x400000,
232 EX_OPENBSD64 = 0x800000,
233 EX_DRAGONFLYBSD64 = 0x1000000,
234+ EX_HURD = 0x2000000,
235+ EX_HURD64 = 0x4000000,
236 }
237
238 // All of them
239@@ -328,7 +331,9 @@ enum exefmt_t EX_all =
240 EX_SOLARIS64 |
241 EX_OPENBSD |
242 EX_OPENBSD64 |
243- EX_DRAGONFLYBSD64;
244+ EX_DRAGONFLYBSD64 |
245+ EX_HURD |
246+ EX_HURD64;
247
248 // All segmented memory models
249 enum exefmt_t EX_segmented = EX_DOSX | EX_ZPM | EX_RATIONAL | EX_PHARLAP |
250@@ -350,6 +355,7 @@ enum exefmt_t EX_posix = EX_LINUX | EX_LINUX64 |
251 EX_FREEBSD | EX_FREEBSD64 |
252 EX_SOLARIS | EX_SOLARIS64 |
253 EX_OPENBSD | EX_OPENBSD64 |
254+ EX_HURD | EX_HURD64 |
255 EX_DRAGONFLYBSD64;
256
257 // All 16 bit targets
258@@ -362,7 +368,8 @@ enum exefmt_t EX_32 = EX_DOSX | EX_OS2 | EX_PHARLAP |
259 EX_OSX |
260 EX_FREEBSD |
261 EX_SOLARIS |
262- EX_OPENBSD;
263+ EX_OPENBSD |
264+ EX_HURD;
265
266 // All 64 bit targets
267 enum exefmt_t EX_64 =
268@@ -372,6 +379,7 @@ enum exefmt_t EX_64 =
269 EX_FREEBSD64 |
270 EX_SOLARIS64 |
271 EX_OPENBSD64 |
272+ EX_HURD64 |
273 EX_DRAGONFLYBSD64;
274
275 // Constraints
276diff --git a/compiler/src/dmd/backend/elfobj.d b/compiler/src/dmd/backend/elfobj.d
277index 64005973f3..be19711757 100644
278--- a/compiler/src/dmd/backend/elfobj.d
279+++ b/compiler/src/dmd/backend/elfobj.d
280@@ -68,7 +68,7 @@ else
281 enum DMDV2 = false;
282 bool REQUIRE_DSO_REGISTRY()
283 {
284- return DMDV2 && (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64));
285+ return DMDV2 && (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_DRAGONFLYBSD64 | EX_HURD | EX_HURD64));
286 }
287
288 /**
289@@ -81,7 +81,7 @@ bool USE_INIT_ARRAY() { return true; }
290 * FreeBSD defaults to lld as of FreeBSD 13 (2021); OpenBSD as of 6.5 (2019).
291 */
292
293-bool ELF_COMDAT() { return (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64)) != 0; }
294+bool ELF_COMDAT() { return (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_HURD | EX_HURD64)) != 0; }
295
296 /***************************************************
297 * Correspondence of relocation types
298@@ -1240,6 +1240,11 @@ void ElfObj_term(const(char)[] objfilename)
299 ELFOSABI = ELFOSABI_OPENBSD;
300 break;
301
302+ case EX_HURD:
303+ case EX_HURD64:
304+ ELFOSABI = ELFOSABI_GNU;
305+ break;
306+
307 case EX_SOLARIS:
308 case EX_SOLARIS64:
309 case EX_DRAGONFLYBSD64:
310diff --git a/compiler/src/dmd/backend/melf.d b/compiler/src/dmd/backend/melf.d
311index 300061cfb1..6e9c8ff0d5 100644
312--- a/compiler/src/dmd/backend/melf.d
313+++ b/compiler/src/dmd/backend/melf.d
314@@ -54,7 +54,8 @@ nothrow:
315 enum ELFOSABI_SYSV = 0; /* UNIX System V ABI */
316 enum ELFOSABI_HPUX = 1; /* HP-UX */
317 enum ELFOSABI_NETBSD = 2;
318- enum ELFOSABI_LINUX = 3;
319+ enum ELFOSABI_GNU = 3;
320+ enum ELFOSABI_LINUX = ELFOSABI_GNU;
321 enum ELFOSABI_FREEBSD = 9;
322 enum ELFOSABI_OPENBSD = 12;
323 enum ELFOSABI_ARM = 97; /* ARM */
324diff --git a/compiler/src/dmd/backend/x86/cod1.d b/compiler/src/dmd/backend/x86/cod1.d
325index dd40dbf591..e15f6017ea 100644
326--- a/compiler/src/dmd/backend/x86/cod1.d
327+++ b/compiler/src/dmd/backend/x86/cod1.d
328@@ -2152,7 +2152,8 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
329 EX_FREEBSD | EX_FREEBSD64 |
330 EX_OPENBSD | EX_OPENBSD64 |
331 EX_DRAGONFLYBSD64 |
332- EX_SOLARIS | EX_SOLARIS64);
333+ EX_SOLARIS | EX_SOLARIS64 |
334+ EX_HURD | EX_HURD64);
335
336 switch (clib)
337 {
338@@ -2174,7 +2175,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
339
340 case CLIB.ldiv:
341 cinfo.retregs16 = mDX|mAX;
342- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
343+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
344 {
345 s = symboly("__divdi3", mAX|mBX|mCX|mDX);
346 cinfo.flags = INFpushebx;
347@@ -2202,7 +2203,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
348
349 case CLIB.lmod:
350 cinfo.retregs16 = mCX|mBX;
351- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
352+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
353 {
354 s = symboly("__moddi3", mAX|mBX|mCX|mDX);
355 cinfo.flags = INFpushebx;
356@@ -2230,7 +2231,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
357
358 case CLIB.uldiv:
359 cinfo.retregs16 = mDX|mAX;
360- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
361+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
362 {
363 s = symboly("__udivdi3", mAX|mBX|mCX|mDX);
364 cinfo.flags = INFpushebx;
365@@ -2258,7 +2259,7 @@ void getClibFunction(uint clib, ref Symbol* s, ref ClibInfo* cinfo, objfmt_t obj
366
367 case CLIB.ulmod:
368 cinfo.retregs16 = mCX|mBX;
369- if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD))
370+ if (exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_HURD))
371 {
372 s = symboly("__umoddi3", mAX|mBX|mCX|mDX);
373 cinfo.flags = INFpushebx;
374@@ -2899,7 +2900,7 @@ void callclib(ref CodeBuilder cdb, elem* e, uint clib, ref regm_t pretregs, regm
375 }
376 if (pushebx)
377 {
378- if (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64))
379+ if (config.exe & (EX_LINUX | EX_LINUX64 | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_HURD | EX_HURD64))
380 {
381 cdb.gen1(0x50 + CX); // PUSH ECX
382 cdb.gen1(0x50 + BX); // PUSH EBX
383@@ -2920,7 +2921,7 @@ void callclib(ref CodeBuilder cdb, elem* e, uint clib, ref regm_t pretregs, regm
384 cdb.gen1(0x50 + DX); // PUSH EDX
385 cdb.gen1(0x50 + AX); // PUSH EAX
386 }
387- if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS))
388+ if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD))
389 {
390 // Note: not for OSX
391 /* Pass EBX on the stack instead, this is because EBX is used
392@@ -3383,7 +3384,7 @@ void cdfunc(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
393
394 /* Assume called function access statics
395 */
396- if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64) &&
397+ if (config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_FREEBSD | EX_FREEBSD64 | EX_OPENBSD | EX_OPENBSD64 | EX_HURD | EX_HURD64) &&
398 config.flags3 & CFG3pic)
399 cgstate.accessedTLS = true;
400
401@@ -3430,7 +3431,7 @@ void cdfunc(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
402 parameters[i].numalign = 0;
403 if (alignsize > stackalign &&
404 (I64 || (alignsize >= 16 &&
405- (config.exe & (EX_OSX | EX_LINUX) && (tyaggregate(ep.Ety) || tyvector(ep.Ety))))))
406+ (config.exe & (EX_OSX | EX_LINUX | EX_HURD) && (tyaggregate(ep.Ety) || tyvector(ep.Ety))))))
407 {
408 if (alignsize > STACKALIGN)
409 {
410@@ -3998,7 +3999,7 @@ private void funccall(ref CodeBuilder cdb, elem* e, uint numpara, uint numalign,
411 tym_t e11ty = tybasic(e11.Ety);
412 assert(!I16 || (e11ty == (farfunc ? TYfptr : TYnptr)));
413 load_localgot(cdb);
414- if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS)) // 32 bit only
415+ if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD)) // 32 bit only
416 {
417 if (config.flags3 & CFG3pic)
418 keepmsk |= mBX;
419diff --git a/compiler/src/dmd/backend/x86/cod3.d b/compiler/src/dmd/backend/x86/cod3.d
420index e93f304c06..740b030e3e 100644
421--- a/compiler/src/dmd/backend/x86/cod3.d
422+++ b/compiler/src/dmd/backend/x86/cod3.d
423@@ -2225,7 +2225,7 @@ void outjmptab(block* b)
424 break;
425 }
426 }
427- if (config.exe & (EX_LINUX64 | EX_FREEBSD64 | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS64))
428+ if (config.exe & (EX_LINUX64 | EX_FREEBSD64 | EX_OPENBSD64 | EX_DRAGONFLYBSD64 | EX_SOLARIS64 | EX_HURD64))
429 {
430 if (config.flags3 & CFG3pic)
431 {
432@@ -2238,7 +2238,7 @@ void outjmptab(block* b)
433 *poffset += 8;
434 }
435 }
436- else if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS))
437+ else if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD))
438 {
439 if (config.flags3 & CFG3pic)
440 {
441@@ -2891,7 +2891,7 @@ void cdgot(ref CGstate cg, ref CodeBuilder cdb, elem* e, ref regm_t pretregs)
442 @trusted
443 void load_localgot(ref CodeBuilder cdb)
444 {
445- if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS)) // note: I32 only
446+ if (config.exe & (EX_LINUX | EX_FREEBSD | EX_OPENBSD | EX_SOLARIS | EX_HURD)) // note: I32 only
447 {
448 if (config.flags3 & CFG3pic)
449 {
450diff --git a/compiler/src/dmd/cli.d b/compiler/src/dmd/cli.d
451index beb8ab745d..8ad82c3b1b 100644
452--- a/compiler/src/dmd/cli.d
453+++ b/compiler/src/dmd/cli.d
454@@ -31,10 +31,11 @@ enum TargetOS : ubyte
455 FreeBSD = 0x10,
456 Solaris = 0x20,
457 DragonFlyBSD = 0x40,
458+ Hurd = 0x80,
459
460 // Combination masks
461- all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
462- Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
463+ all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
464+ Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
465 }
466
467 // Detect the current TargetOS
468@@ -66,6 +67,10 @@ else version(Solaris)
469 {
470 private enum targetOS = TargetOS.Solaris;
471 }
472+else version(Hurd)
473+{
474+ private enum targetOS = TargetOS.Hurd;
475+}
476 else
477 {
478 private enum targetOS = TargetOS.all;
479@@ -782,6 +787,7 @@ dmd -cov -unittest myprog.d
480 $(LI $(I openbsd): OpenBSD)
481 $(LI $(I osx): OSX)
482 $(LI $(I solaris): Solaris)
483+ $(LI $(I hurd): Hurd)
484 $(LI $(I windows): Windows)
485 )`
486 ),
487@@ -869,7 +875,8 @@ dmd -cov -unittest myprog.d
488 $(I os) is the operating system, this may have a trailing version number:
489 `freestanding` for no operating system,
490 `darwin` or `osx` for MacOS, `dragonfly` or `dragonflybsd` for DragonflyBSD,
491- `freebsd`, `openbsd`, `linux`, `solaris` or `windows` for their respective operating systems.
492+ `freebsd`, `openbsd`, `linux`, `solaris`, `hurd` or `windows` for their
493+ respective operating systems.
494 $(I cenv) is the C runtime environment and is optional: `musl` for musl-libc,
495 `msvc` for the MSVC runtime, `bionic` for the Andriod libc, `gnu` or `glibc`
496 for the GCC C runtime, `newlib` or `uclibc` for their respective C runtimes.
497diff --git a/compiler/src/dmd/dmdparams.d b/compiler/src/dmd/dmdparams.d
498index 7d82c1e2b4..d80fcec0d6 100644
499--- a/compiler/src/dmd/dmdparams.d
500+++ b/compiler/src/dmd/dmdparams.d
501@@ -227,6 +227,8 @@ struct Triple
502 os = Target.OS.OpenBSD;
503 else if (matches("linux"))
504 os = Target.OS.linux;
505+ else if (matches("hurd"))
506+ os = Target.OS.Hurd;
507 else if (matches("windows"))
508 os = Target.OS.Windows;
509 else
510diff --git a/compiler/src/dmd/dmsc.d b/compiler/src/dmd/dmsc.d
511index 1c80135396..ef39b209d5 100644
512--- a/compiler/src/dmd/dmsc.d
513+++ b/compiler/src/dmd/dmsc.d
514@@ -55,6 +55,7 @@ void backend_init(const ref Param params, const ref DMDparams driverParams, cons
515 case Target.OS.OpenBSD: exfmt = is64 ? EX_OPENBSD64 : EX_OPENBSD; break;
516 case Target.OS.Solaris: exfmt = is64 ? EX_SOLARIS64 : EX_SOLARIS; break;
517 case Target.OS.DragonFlyBSD: assert(is64); exfmt = EX_DRAGONFLYBSD64; break;
518+ case Target.OS.Hurd: exfmt = is64 ? EX_HURD64 : EX_HURD; break;
519 default: assert(0);
520 }
521
522diff --git a/compiler/src/dmd/json.d b/compiler/src/dmd/json.d
523index 080870aa47..1a1fabd367 100644
524--- a/compiler/src/dmd/json.d
525+++ b/compiler/src/dmd/json.d
526@@ -867,6 +867,8 @@ public:
527 item("solaris");
528 item("bsd");
529 }
530+ else if (target.os == Target.OS.Hurd)
531+ item("hurd");
532 }
533 arrayEnd();
534
535diff --git a/compiler/src/dmd/main.d b/compiler/src/dmd/main.d
536index a574bfdb4b..29f91ab8af 100644
537--- a/compiler/src/dmd/main.d
538+++ b/compiler/src/dmd/main.d
539@@ -1037,7 +1037,7 @@ void reconcileCommands(ref Param params, ref Target target)
540 error(Loc.initial, "`-m32` is not supported on DragonFlyBSD, it is 64-bit only");
541 }
542
543- if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
544+ if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
545 {
546 if (driverParams.lib && driverParams.dll)
547 error(Loc.initial, "cannot mix `-lib` and `-shared`");
548diff --git a/compiler/src/dmd/mars.d b/compiler/src/dmd/mars.d
549index cca1ff3272..606f5a1233 100644
550--- a/compiler/src/dmd/mars.d
551+++ b/compiler/src/dmd/mars.d
552@@ -377,7 +377,7 @@ void setDefaultLibraries(const ref Target target, ref const(char)[] defaultlibna
553 {
554 defaultlibname = target.isX86_64 ? "phobos64" : "phobos32mscoff";
555 }
556- else if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
557+ else if (target.os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
558 {
559 defaultlibname = "libphobos2.a";
560 }
561@@ -1150,7 +1150,7 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, out Param
562 enum len = "-os=".length;
563 // Parse:
564 // -os=identifier
565- immutable string msg = "Only `host`, `linux`, `windows`, `osx`,`openbsd`, `freebsd`, `solaris`, `dragonflybsd` allowed for `-os`";
566+ immutable string msg = "Only `host`, `linux`, `windows`, `osx`,`openbsd`, `freebsd`, `solaris`, `dragonflybsd`, `hurd` allowed for `-os`";
567 if (Identifier.isValidIdentifier(p + len))
568 {
569 const ident = p + len;
570@@ -1164,6 +1164,7 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, out Param
571 case "freebsd": target.os = Target.OS.FreeBSD; break;
572 case "solaris": target.os = Target.OS.Solaris; break;
573 case "dragonflybsd": target.os = Target.OS.DragonFlyBSD; break;
574+ case "hurd": target.os = Target.OS.Hurd; break;
575 default:
576 errorInvalidSwitch(p, msg);
577 return false;
578@@ -1898,7 +1899,7 @@ bool createModule(const(char)* file, ref Strings libmodules, ref Param params, c
579 libmodules.push(file);
580 return false;
581 }
582- if (target.os & (Target.OS.linux | Target.OS.OSX| Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
583+ if (target.os & (Target.OS.linux | Target.OS.OSX| Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
584 {
585 if (FileName.equals(ext, target.dll_ext))
586 {
587diff --git a/compiler/src/dmd/target.d b/compiler/src/dmd/target.d
588index f739cbfe35..b226b9200c 100644
589--- a/compiler/src/dmd/target.d
590+++ b/compiler/src/dmd/target.d
591@@ -65,6 +65,8 @@ Target.OS defaultTargetOS() @safe
592 return Target.OS.Solaris;
593 else version (DragonFlyBSD)
594 return Target.OS.DragonFlyBSD;
595+ else version (Hurd)
596+ return Target.OS.Hurd;
597 else
598 static assert(0, "unknown TARGET");
599 }
600@@ -179,7 +181,7 @@ void addPredefinedGlobalIdentifiers(const ref Target tgt)
601 {
602 if (tgt.os & OS.Posix)
603 predef("Posix");
604- if (tgt.os & (OS.linux | OS.FreeBSD | OS.OpenBSD | OS.DragonFlyBSD | OS.Solaris))
605+ if (tgt.os & (OS.linux | OS.FreeBSD | OS.OpenBSD | OS.DragonFlyBSD | OS.Solaris | OS.Hurd))
606 predef("ELFv1");
607 switch (tgt.os)
608 {
609@@ -188,6 +190,7 @@ void addPredefinedGlobalIdentifiers(const ref Target tgt)
610 case OS.OpenBSD: { predef("OpenBSD"); break; }
611 case OS.DragonFlyBSD: { predef("DragonFlyBSD"); break; }
612 case OS.Solaris: { predef("Solaris"); break; }
613+ case OS.Hurd: { predef("Hurd"); break; }
614 case OS.Windows:
615 {
616 predef("Windows");
617@@ -330,10 +333,11 @@ extern (C++) struct Target
618 FreeBSD = 0x10,
619 Solaris = 0x20,
620 DragonFlyBSD = 0x40,
621+ Hurd = 0x80,
622
623 // Combination masks
624- all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
625- Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD,
626+ all = linux | Windows | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
627+ Posix = linux | OSX | OpenBSD | FreeBSD | Solaris | DragonFlyBSD | Hurd,
628 }
629
630 extern(D) enum ObjectFormat : ubyte
631@@ -455,7 +459,7 @@ extern (C++) struct Target
632 classinfosize = 0x98+16; // 168
633 }
634
635- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
636+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
637 {
638 realsize = 12;
639 realpad = 2;
640@@ -478,7 +482,7 @@ extern (C++) struct Target
641
642 if (isX86_64 || isAArch64)
643 {
644- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
645+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
646 {
647 realsize = 16;
648 realpad = 6;
649@@ -506,7 +510,7 @@ extern (C++) struct Target
650 dll_ext = "dll";
651 run_noext = false;
652 }
653- else if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.OSX))
654+ else if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.OSX | Target.OS.Hurd))
655 {
656 obj_ext = "o";
657 lib_ext = "a";
658@@ -1074,7 +1078,8 @@ extern (C++) struct Target
659 if (tns.ty != TY.Tstruct)
660 {
661 L2:
662- if (os == Target.OS.linux && tf.linkage != LINK.d && isX86)
663+ if ((os & (Target.OS.linux | Target.OS.Hurd)) &&
664+ tf.linkage != LINK.d && isX86)
665 {
666 // 32 bit C/C++ structs always on stack
667 }
668@@ -1101,7 +1106,8 @@ extern (C++) struct Target
669 if (auto ts = tns.isTypeStruct())
670 {
671 auto sd = ts.sym;
672- if (os == Target.OS.linux && tf.linkage != LINK.d && isX86)
673+ if ((os & (Target.OS.linux | Target.OS.Hurd)) &&
674+ tf.linkage != LINK.d && isX86)
675 {
676 //printf(" 2 true\n");
677 return true; // 32 bit C/C++ structs always on stack
678@@ -1418,7 +1424,7 @@ struct TargetC
679 shortsize = 2;
680 intsize = 4;
681 long_longsize = 8;
682- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
683+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
684 longsize = 4;
685 else if (os == Target.OS.OSX)
686 longsize = 4;
687@@ -1428,7 +1434,7 @@ struct TargetC
688 assert(0);
689 if (target.isX86_64 || target.isAArch64)
690 {
691- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
692+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
693 longsize = 8;
694 else if (os == Target.OS.OSX)
695 longsize = 8;
696@@ -1453,11 +1459,16 @@ struct TargetC
697 else
698 runtime = Runtime.Glibc;
699 }
700+ else if (os == Target.OS.Hurd)
701+ {
702+ runtime = Runtime.Glibc;
703+ }
704
705 if (os == Target.OS.Windows)
706 bitFieldStyle = BitFieldStyle.MS;
707 else if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OSX |
708- Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
709+ Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris |
710+ Target.OS.Hurd))
711 bitFieldStyle = BitFieldStyle.Gcc_Clang;
712 else
713 assert(0);
714@@ -1518,7 +1529,7 @@ struct TargetCPP
715 extern (D) void initialize(ref const Param params, ref const Target target) @safe
716 {
717 const os = target.os;
718- if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris))
719+ if (os & (Target.OS.linux | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.DragonFlyBSD | Target.OS.Solaris | Target.OS.Hurd))
720 twoDtorInVtable = true;
721 else if (os == Target.OS.OSX)
722 twoDtorInVtable = true;
723@@ -1532,7 +1543,7 @@ struct TargetCPP
724 exceptions = (os & Target.OS.Posix) != 0;
725 if (os == Target.OS.Windows)
726 runtime = Runtime.Microsoft;
727- else if (os & (Target.OS.linux | Target.OS.DragonFlyBSD))
728+ else if (os & (Target.OS.linux | Target.OS.DragonFlyBSD | Target.OS.Hurd))
729 runtime = Runtime.GNU;
730 else if (os & (Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD))
731 runtime = Runtime.LLVM;
732@@ -1556,7 +1567,7 @@ struct TargetCPP
733 import dmd.mangle.cpp : toCppMangleItanium;
734 import dmd.mangle.cppwin : toCppMangleMSVC;
735
736- if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
737+ if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
738 return toCppMangleItanium(s);
739 if (target.os == Target.OS.Windows)
740 return toCppMangleMSVC(s);
741@@ -1576,7 +1587,7 @@ struct TargetCPP
742 import dmd.mangle.cpp : cppTypeInfoMangleItanium;
743 import dmd.mangle.cppwin : cppTypeInfoMangleMSVC;
744
745- if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD))
746+ if (target.os & (Target.OS.linux | Target.OS.OSX | Target.OS.FreeBSD | Target.OS.OpenBSD | Target.OS.Solaris | Target.OS.DragonFlyBSD | Target.OS.Hurd))
747 return cppTypeInfoMangleItanium(cd);
748 if (target.os == Target.OS.Windows)
749 return cppTypeInfoMangleMSVC(cd);
750diff --git a/compiler/src/osmodel.mak b/compiler/src/osmodel.mak
751index 69676c18b0..443509c61e 100644
752--- a/compiler/src/osmodel.mak
753+++ b/compiler/src/osmodel.mak
754@@ -2,7 +2,7 @@
755 #
756 # Detects and sets the macros:
757 #
758-# OS = one of {windows,osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris}
759+# OS = one of {windows,osx,linux,freebsd,openbsd,netbsd,dragonflybsd,solaris,hurd}
760 # MODEL = one of { 32, 64 }
761 # MODEL_FLAG = one of { -m32, -m64 }
762 # ARCH = one of { x86, x86_64, aarch64 }
763@@ -40,6 +40,9 @@ ifeq (,$(OS))
764 ifeq (SunOS,$(uname_S))
765 OS:=solaris
766 endif
767+ ifeq (GNU,$(uname_S))
768+ OS:=hurd
769+ endif
770 ifeq (,$(OS))
771 $(error Unrecognized or unsupported OS for uname: $(uname_S))
772 endif
773@@ -87,7 +90,7 @@ ifeq (,$(MODEL))
774 MODEL:=64
775 ARCH:=aarch64
776 endif
777- ifneq (,$(findstring $(uname_M),i386 i586 i686))
778+ ifneq (,$(findstring $(uname_M),i386 i586 i686 i686-AT386))
779 MODEL:=32
780 ARCH:=x86
781 endif
782--
7832.52.0
784
785From b8e5e52a8c3701b73424b094382c8ab0e3e5b6d5 Mon Sep 17 00:00:00 2001
786From: Yelninei <yelninei@tutamail.com>
787Date: Sat, 21 Mar 2026 15:47:08 +0000
788Subject: [PATCH 3/5] dmd: Fix tests on Hurd
789
790---
791 compiler/test/compilable/cdcmp.d | 2 +-
792 compiler/test/compilable/test21672.d | 2 +-
793 compiler/test/compilable/test22346.c | 2 +-
794 compiler/test/compilable/test23875.c | 2 +-
795 compiler/test/compilable/test24130.c | 2 +-
796 compiler/test/compilable/vcg-ast.d | 2 +-
797 compiler/test/fail_compilation/fail17105.d | 2 +-
798 compiler/test/fail_compilation/fail18372.d | 2 +-
799 .../test/fail_compilation/fail21227_win.d | 2 +-
800 compiler/test/fail_compilation/fail3753.d | 2 +-
801 compiler/test/fail_compilation/fail6451.d | 2 +-
802 compiler/test/fail_compilation/ice20042.d | 2 +-
803 compiler/test/fail_compilation/ice20264.d | 2 +-
804 compiler/test/fail_compilation/impconv.d | 2 +-
805 compiler/test/fail_compilation/invalid_lib.d | 2 +-
806 compiler/test/fail_compilation/vector_types.d | 2 +-
807 compiler/test/fail_compilation/xmmslice.d | 2 +-
808 compiler/test/run.d | 2 +-
809 compiler/test/runnable/bitfieldsms.c | 2 +-
810 compiler/test/runnable/bitfieldsposix32.c | 2 +-
811 compiler/test/runnable/bitfieldsposix64.c | 2 +-
812 compiler/test/runnable/dbitfieldsms.d | 2 +-
813 compiler/test/runnable/dbitfieldsposix32.d | 2 +-
814 compiler/test/runnable/dbitfieldsposix64.d | 2 +-
815 compiler/test/runnable/dhry.d | 15 ++++++++++
816 compiler/test/runnable/ice21727.d | 2 +-
817 compiler/test/runnable/test22.d | 30 +++++++++++++++++++
818 compiler/test/runnable/test23343.c | 2 +-
819 compiler/test/runnable/test_cdstrpar.d | 2 +-
820 compiler/test/runnable/testargtypes.d | 2 +-
821 compiler/test/runnable_cxx/cpp_abi_tests.d | 2 +-
822 compiler/test/runnable_cxx/cppa.d | 2 +-
823 compiler/test/runnable_cxx/nonpod_byval.d | 2 +-
824 compiler/test/tools/paths.d | 2 ++
825 34 files changed, 78 insertions(+), 31 deletions(-)
826
827diff --git a/compiler/test/compilable/cdcmp.d b/compiler/test/compilable/cdcmp.d
828index 16abde0bd5..f8f9106e5f 100644
829--- a/compiler/test/compilable/cdcmp.d
830+++ b/compiler/test/compilable/cdcmp.d
831@@ -2,7 +2,7 @@
832 // REQUIRED_ARGS: -O
833 // POST_SCRIPT: compilable/extra-files/objdump-postscript.sh
834 // only testing on SYSV-ABI, but backend code is identical across platforms
835-// DISABLED: win32 win64 osx linux32 freebsd32 freebsd64 openbsd32 openbsd64
836+// DISABLED: win32 win64 osx linux32 freebsd32 freebsd64 openbsd32 openbsd64 hurd32
837
838 bool test_ltz(ubyte x) { return x < 0; }
839 bool test_lez(ubyte x) { return x <= 0; }
840diff --git a/compiler/test/compilable/test21672.d b/compiler/test/compilable/test21672.d
841index abad340fcc..81ab7622b7 100644
842--- a/compiler/test/compilable/test21672.d
843+++ b/compiler/test/compilable/test21672.d
844@@ -1,5 +1,5 @@
845 // REQUIRED_ARGS: -mcpu=avx2 -O
846-// DISABLED: win32 linux32 freebsd32 openbsd32
847+// DISABLED: win32 linux32 freebsd32 openbsd32 hurd32
848
849 // https://issues.dlang.org/show_bug.cgi?id=21672
850
851diff --git a/compiler/test/compilable/test22346.c b/compiler/test/compilable/test22346.c
852index 9d1444ad74..8c4d85b6cf 100644
853--- a/compiler/test/compilable/test22346.c
854+++ b/compiler/test/compilable/test22346.c
855@@ -1,4 +1,4 @@
856-/* DISABLED: win32 win64 linux32 osx32 osx64 freebsd32 openbsd32
857+/* DISABLED: win32 win64 linux32 osx32 osx64 freebsd32 openbsd32 hurd32
858 */
859
860 // https://issues.dlang.org/show_bug.cgi?id=23346
861diff --git a/compiler/test/compilable/test23875.c b/compiler/test/compilable/test23875.c
862index c5ee060cc6..b074f12680 100644
863--- a/compiler/test/compilable/test23875.c
864+++ b/compiler/test/compilable/test23875.c
865@@ -1,4 +1,4 @@
866-/* DISABLED: win32 linux32
867+/* DISABLED: win32 linux32 hurd32
868 */
869
870 // https://issues.dlang.org/show_bug.cgi?id=23875
871diff --git a/compiler/test/compilable/test24130.c b/compiler/test/compilable/test24130.c
872index 5f7f69f6cc..5160968b55 100644
873--- a/compiler/test/compilable/test24130.c
874+++ b/compiler/test/compilable/test24130.c
875@@ -1,5 +1,5 @@
876 /*
877- * DISABLED: freebsd32 freebsd64 linux32 linux64 osx32 osx64 win64 dragonflybsd openbsd
878+ * DISABLED: freebsd32 freebsd64 linux32 linux64 osx32 osx64 win64 dragonflybsd openbsd hurd
879 */
880
881 // https://issues.dlang.org/show_bug.cgi?id=24130
882diff --git a/compiler/test/compilable/vcg-ast.d b/compiler/test/compilable/vcg-ast.d
883index 6a90555740..3e0647f50b 100644
884--- a/compiler/test/compilable/vcg-ast.d
885+++ b/compiler/test/compilable/vcg-ast.d
886@@ -5,7 +5,7 @@ OUTPUT_FILES: compilable/vcg-ast.d.cg
887 EXTRA_FILES: imports/vcg_ast_import.d
888 TEST_OUTPUT_FILE: extra-files/vcg-ast.d.cg
889 // size_t currently must be ulong in this test, not uint
890-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
891+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
892 */
893
894 module vcg;
895diff --git a/compiler/test/fail_compilation/fail17105.d b/compiler/test/fail_compilation/fail17105.d
896index 407c40222c..14be167f9c 100644
897--- a/compiler/test/fail_compilation/fail17105.d
898+++ b/compiler/test/fail_compilation/fail17105.d
899@@ -1,5 +1,5 @@
900 /* REQUIRED_ARGS: -m64
901-DISABLED: win32 linux32 osx32 freebsd32 openbsd32
902+DISABLED: win32 linux32 osx32 freebsd32 openbsd32 hurd32
903 TEST_OUTPUT:
904 ---
905 fail_compilation/fail17105.d(20): Error: missing 4th parameter to `__simd()`
906diff --git a/compiler/test/fail_compilation/fail18372.d b/compiler/test/fail_compilation/fail18372.d
907index 6100894bb0..8eb92786c0 100644
908--- a/compiler/test/fail_compilation/fail18372.d
909+++ b/compiler/test/fail_compilation/fail18372.d
910@@ -1,5 +1,5 @@
911 /*
912-DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32
913+DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32 hurd32
914 TEST_OUTPUT:
915 ---
916 fail_compilation/fail18372.d(103): Error: `__va_list_tag` is not defined, perhaps `import core.stdc.stdarg;` ?
917diff --git a/compiler/test/fail_compilation/fail21227_win.d b/compiler/test/fail_compilation/fail21227_win.d
918index a0a029f08f..00305ae7c9 100644
919--- a/compiler/test/fail_compilation/fail21227_win.d
920+++ b/compiler/test/fail_compilation/fail21227_win.d
921@@ -1,6 +1,6 @@
922 /*
923 REQUIRED_ARGS: -Jfail_compilation
924-DISABLED: linux osx freebsd dragonflybsd netbsd openbsd
925+DISABLED: linux osx freebsd dragonflybsd netbsd openbsd hurd
926 TEST_OUTPUT:
927 ---
928 fail_compilation\fail21227_win.d(2): Error: absolute path is not allowed in import expression: `"\\\\UNC\\path\\to\\file.txt"`
929diff --git a/compiler/test/fail_compilation/fail3753.d b/compiler/test/fail_compilation/fail3753.d
930index 97deb00eb8..98ac1a3231 100644
931--- a/compiler/test/fail_compilation/fail3753.d
932+++ b/compiler/test/fail_compilation/fail3753.d
933@@ -1,5 +1,5 @@
934 /*
935-DISABLED: dragonflybsd freebsd linux osx win32 openbsd
936+DISABLED: dragonflybsd freebsd linux osx win32 openbsd hurd
937 TEST_OUTPUT:
938 ---
939 Error: cannot mix `core.std.stdlib.alloca()` and exception handling in `_Dmain()`
940diff --git a/compiler/test/fail_compilation/fail6451.d b/compiler/test/fail_compilation/fail6451.d
941index fcc1d76a70..7e1977bba9 100644
942--- a/compiler/test/fail_compilation/fail6451.d
943+++ b/compiler/test/fail_compilation/fail6451.d
944@@ -1,5 +1,5 @@
945 /*
946-DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32
947+DISABLED: win32 win64 linux32 osx32 freebsd32 openbsd32 hurd32
948 TEST_OUTPUT:
949 ---
950 fail_compilation/fail6451.d(9): Error: `__va_list_tag` is not defined, perhaps `import core.stdc.stdarg;` ?
951diff --git a/compiler/test/fail_compilation/ice20042.d b/compiler/test/fail_compilation/ice20042.d
952index 7a674b3c54..3836932195 100644
953--- a/compiler/test/fail_compilation/ice20042.d
954+++ b/compiler/test/fail_compilation/ice20042.d
955@@ -1,5 +1,5 @@
956 /*
957-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
958+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
959 TEST_OUTPUT:
960 ---
961 fail_compilation/ice20042.d(18): Error: slice operation `cast(__vector(float[4]))[nanF, nanF, nanF, nanF] = [1.0F, 2.0F, 3.0F, 4.0F][0..4]` cannot be evaluated at compile time
962diff --git a/compiler/test/fail_compilation/ice20264.d b/compiler/test/fail_compilation/ice20264.d
963index a8a1e7119b..03ffa77931 100644
964--- a/compiler/test/fail_compilation/ice20264.d
965+++ b/compiler/test/fail_compilation/ice20264.d
966@@ -1,5 +1,5 @@
967 /*
968-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
969+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
970 TEST_OUTPUT:
971 ---
972 fail_compilation/ice20264.d(12): Error: cannot modify expression `cast(__vector(float[4]))a` because it is not an lvalue
973diff --git a/compiler/test/fail_compilation/impconv.d b/compiler/test/fail_compilation/impconv.d
974index 0cc2deb13d..e4026957f2 100644
975--- a/compiler/test/fail_compilation/impconv.d
976+++ b/compiler/test/fail_compilation/impconv.d
977@@ -3,7 +3,7 @@ FIXME: DMD host compilers < 2.073 with faulty optimization
978 lead to unfortunate test failures, see
979 https://github.com/dlang/dmd/pull/6831#issuecomment-304495842.
980
981-DISABLED: win32 win64 linux osx freebsd openbsd
982+DISABLED: win32 win64 linux osx freebsd openbsd hurd
983 */
984
985 /*
986diff --git a/compiler/test/fail_compilation/invalid_lib.d b/compiler/test/fail_compilation/invalid_lib.d
987index 70121123a7..19eb4eaddf 100644
988--- a/compiler/test/fail_compilation/invalid_lib.d
989+++ b/compiler/test/fail_compilation/invalid_lib.d
990@@ -1,6 +1,6 @@
991 /*
992 REQUIRED_ARGS: -lib
993-REQUIRED_ARGS(linux freebsd osx openbsd): fail_compilation/extra-files/fake.a
994+REQUIRED_ARGS(linux freebsd osx openbsd hurd): fail_compilation/extra-files/fake.a
995 REQUIRED_ARGS(windows): -m32 fail_compilation/extra-files/fake.lib
996
997 Use a regex because the path is really strange on Azure (OMF_32, 64):
998diff --git a/compiler/test/fail_compilation/vector_types.d b/compiler/test/fail_compilation/vector_types.d
999index 322bbc66cb..f17dbc25e2 100644
1000--- a/compiler/test/fail_compilation/vector_types.d
1001+++ b/compiler/test/fail_compilation/vector_types.d
1002@@ -1,7 +1,7 @@
1003 /*
1004 REQUIRED_ARGS: -o-
1005 TEST_OUTPUT:
1006-DISABLED: freebsd32 openbsd32 linux32 osx32 win32
1007+DISABLED: freebsd32 openbsd32 linux32 osx32 win32 hurd32
1008 ---
1009 fail_compilation/vector_types.d(15): Error: 32 byte vector type `__vector(double[4])` is not supported on this platform
1010 fail_compilation/vector_types.d(16): Error: 32 byte vector type `__vector(float[8])` is not supported on this platform
1011diff --git a/compiler/test/fail_compilation/xmmslice.d b/compiler/test/fail_compilation/xmmslice.d
1012index f91ac1f525..48f79c65d2 100644
1013--- a/compiler/test/fail_compilation/xmmslice.d
1014+++ b/compiler/test/fail_compilation/xmmslice.d
1015@@ -1,6 +1,6 @@
1016
1017 /* REQUIRED_ARGS: -mcpu=avx
1018-DISABLED: win32 freebsd32 openbsd32 linux32 osx32
1019+DISABLED: win32 freebsd32 openbsd32 linux32 osx32 hurd32
1020 TEST_OUTPUT:
1021 ---
1022 fail_compilation/xmmslice.d(110): Error: `__vector(int[4])` cannot be sliced with `[]`
1023diff --git a/compiler/test/run.d b/compiler/test/run.d
1024index cf7b3d1986..137b7393bd 100755
1025--- a/compiler/test/run.d
1026+++ b/compiler/test/run.d
1027@@ -575,7 +575,7 @@ string[string] getEnvironment()
1028 env["PIC_FLAG"] = pic ? "-fPIC" : "";
1029 env["DFLAGS"] = "-I%s/import -I%s".format(druntimePath, phobosPath)
1030 ~ " -L-L%s/%s".format(phobosPath, generatedSuffix);
1031- bool isShared = environment.get("SHARED") != "0" && os.among("linux", "freebsd") > 0;
1032+ bool isShared = environment.get("SHARED") != "0" && os.among("linux", "freebsd", "hurd") > 0;
1033 if (isShared)
1034 env["DFLAGS"] = env["DFLAGS"] ~ " -defaultlib=libphobos2.so -L-rpath=%s/%s".format(phobosPath, generatedSuffix);
1035
1036diff --git a/compiler/test/runnable/bitfieldsms.c b/compiler/test/runnable/bitfieldsms.c
1037index 5aee443d55..85af0eb5f8 100644
1038--- a/compiler/test/runnable/bitfieldsms.c
1039+++ b/compiler/test/runnable/bitfieldsms.c
1040@@ -1,5 +1,5 @@
1041 /* test bitfields for Microsoft C
1042- * DISABLED: win32 linux freebsd openbsd osx
1043+ * DISABLED: win32 linux freebsd openbsd osx hurd
1044 * RUN_OUTPUT:
1045 ---
1046 DM | MS | P32 | P64
1047diff --git a/compiler/test/runnable/bitfieldsposix32.c b/compiler/test/runnable/bitfieldsposix32.c
1048index 790b594912..19804a06db 100644
1049--- a/compiler/test/runnable/bitfieldsposix32.c
1050+++ b/compiler/test/runnable/bitfieldsposix32.c
1051@@ -1,5 +1,5 @@
1052 /* test bitfields
1053- * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64
1054+ * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64 hurd64
1055 * RUN_OUTPUT:
1056 ---
1057 T0 = 1 1 | 1 1
1058diff --git a/compiler/test/runnable/bitfieldsposix64.c b/compiler/test/runnable/bitfieldsposix64.c
1059index 8a2b089334..d4196376a9 100644
1060--- a/compiler/test/runnable/bitfieldsposix64.c
1061+++ b/compiler/test/runnable/bitfieldsposix64.c
1062@@ -1,5 +1,5 @@
1063 /* test bitfields
1064- * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32
1065+ * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32 hurd32
1066 * RUN_OUTPUT:
1067 ---
1068 T0 = 1 1 | 1 1
1069diff --git a/compiler/test/runnable/dbitfieldsms.d b/compiler/test/runnable/dbitfieldsms.d
1070index 42157f7c7b..bcffb18a9d 100644
1071--- a/compiler/test/runnable/dbitfieldsms.d
1072+++ b/compiler/test/runnable/dbitfieldsms.d
1073@@ -1,6 +1,6 @@
1074 /* test bitfields for Microsoft C
1075 * REQUIRED_ARGS: -preview=bitfields
1076- * DISABLED: win32 linux freebsd openbsd osx
1077+ * DISABLED: win32 linux freebsd openbsd osx hurd
1078 * RUN_OUTPUT:
1079 ---
1080 DM | MS | P32 | P64
1081diff --git a/compiler/test/runnable/dbitfieldsposix32.d b/compiler/test/runnable/dbitfieldsposix32.d
1082index 33ef3acdb4..cf9d0be9cd 100644
1083--- a/compiler/test/runnable/dbitfieldsposix32.d
1084+++ b/compiler/test/runnable/dbitfieldsposix32.d
1085@@ -1,6 +1,6 @@
1086 /* test bitfields
1087 * REQUIRED_ARGS: -preview=bitfields
1088- * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64
1089+ * DISABLED: win32 win64 linux64 freebsd64 openbsd64 osx64 hurd64
1090 * RUN_OUTPUT:
1091 ---
1092 T0 = 1 1 | 1 1
1093diff --git a/compiler/test/runnable/dbitfieldsposix64.d b/compiler/test/runnable/dbitfieldsposix64.d
1094index 59aaf27327..6af0ab32b5 100644
1095--- a/compiler/test/runnable/dbitfieldsposix64.d
1096+++ b/compiler/test/runnable/dbitfieldsposix64.d
1097@@ -1,6 +1,6 @@
1098 /* test bitfields
1099 * REQUIRED_ARGS: -preview=bitfields
1100- * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32
1101+ * DISABLED: win32 win64 linux32 freebsd32 openbsd32 osx32 hurd32
1102 * RUN_OUTPUT:
1103 ---
1104 T0 = 1 1 | 1 1
1105diff --git a/compiler/test/runnable/dhry.d b/compiler/test/runnable/dhry.d
1106index 4d2e1b3c64..598feda290 100644
1107--- a/compiler/test/runnable/dhry.d
1108+++ b/compiler/test/runnable/dhry.d
1109@@ -945,3 +945,18 @@ version (OpenBSD)
1110 return q;
1111 }
1112 }
1113+version (Hurd)
1114+{
1115+ import core.sys.posix.sys.time;
1116+
1117+ double dtime()
1118+ {
1119+ double q;
1120+ timeval tv;
1121+
1122+ gettimeofday(&tv,null);
1123+ q = cast(double)tv.tv_sec + cast(double)tv.tv_usec * 1.0e-6;
1124+
1125+ return q;
1126+ }
1127+}
1128diff --git a/compiler/test/runnable/ice21727.d b/compiler/test/runnable/ice21727.d
1129index c373c53c25..e4f615297b 100644
1130--- a/compiler/test/runnable/ice21727.d
1131+++ b/compiler/test/runnable/ice21727.d
1132@@ -1,5 +1,5 @@
1133 // REQUIRED_ARGS: -m64 -O -inline
1134-// DISABLED: win32 linux32 freebsd32 osx32 openbsd32 netbsd32 dragonflybsd32
1135+// DISABLED: win32 linux32 freebsd32 osx32 openbsd32 netbsd32 dragonflybsd32 hurd32
1136 // https://issues.dlang.org/show_bug.cgi?id=21727
1137
1138 import core.simd;
1139diff --git a/compiler/test/runnable/test22.d b/compiler/test/runnable/test22.d
1140index 38a9cc367e..2087c17ff8 100644
1141--- a/compiler/test/runnable/test22.d
1142+++ b/compiler/test/runnable/test22.d
1143@@ -756,6 +756,36 @@ do
1144 fxch ST(1) ; // ST1 = r, ST0 = x
1145 fstp ST(0) ; // dump x
1146 align 4 ;
1147+ return_ST: ;
1148+ ;
1149+ }
1150+ }
1151+ else version (Hurd)
1152+ {
1153+ asm // assembler by W. Bright
1154+ {
1155+ // EDX = (A.length - 1) * real.sizeof
1156+ mov ECX,A[EBP] ; // ECX = A.length
1157+ dec ECX ;
1158+ lea EDX,[ECX][ECX*8] ;
1159+ add EDX,ECX ;
1160+ add EDX,ECX ;
1161+ add EDX,ECX ;
1162+ add EDX,A+4[EBP] ;
1163+ fld real ptr [EDX] ; // ST0 = coeff[ECX]
1164+ jecxz return_ST ;
1165+ fld x[EBP] ; // ST0 = x
1166+ fxch ST(1) ; // ST1 = x, ST0 = r
1167+ align 4 ;
1168+ L2: fmul ST,ST(1) ; // r *= x
1169+ fld real ptr -12[EDX] ;
1170+ sub EDX,12 ; // deg--
1171+ faddp ST(1),ST ;
1172+ dec ECX ;
1173+ jne L2 ;
1174+ fxch ST(1) ; // ST1 = r, ST0 = x
1175+ fstp ST(0) ; // dump x
1176+ align 4 ;
1177 return_ST: ;
1178 ;
1179 }
1180diff --git a/compiler/test/runnable/test23343.c b/compiler/test/runnable/test23343.c
1181index 27ff5a7cb8..eeb3f1054e 100644
1182--- a/compiler/test/runnable/test23343.c
1183+++ b/compiler/test/runnable/test23343.c
1184@@ -1,4 +1,4 @@
1185-/* DISABLED: win linux freebsd openbsd osx32 dragonflybsd netbsd
1186+/* DISABLED: win linux freebsd openbsd osx32 dragonflybsd netbsd hurd
1187 */
1188
1189 /* https://issues.dlang.org/show_bug.cgi?id=23343
1190diff --git a/compiler/test/runnable/test_cdstrpar.d b/compiler/test/runnable/test_cdstrpar.d
1191index 90aa499ab9..1a2907de96 100644
1192--- a/compiler/test/runnable/test_cdstrpar.d
1193+++ b/compiler/test/runnable/test_cdstrpar.d
1194@@ -1,7 +1,7 @@
1195 // REQUIRED_ARGS: -O -fPIC
1196 // PERMUTE_ARGS:
1197 // only testing on SYSV-ABI, but backend code is identical across platforms
1198-// DISABLED: win32 win64 osx linux32 freebsd32 openbsd32
1199+// DISABLED: win32 win64 osx linux32 freebsd32 openbsd32 hurd32
1200 debug = PRINTF;
1201 debug (PRINTF) import core.stdc.stdio;
1202
1203diff --git a/compiler/test/runnable/testargtypes.d b/compiler/test/runnable/testargtypes.d
1204index 4492420aa8..8f08348a61 100644
1205--- a/compiler/test/runnable/testargtypes.d
1206+++ b/compiler/test/runnable/testargtypes.d
1207@@ -1,5 +1,5 @@
1208 /*
1209-DISABLED: win32 win64 osx32 linux32 freebsd32 openbsd32
1210+DISABLED: win32 win64 osx32 linux32 freebsd32 openbsd32 hurd32
1211 */
1212
1213 void chkArgTypes(S, V...)()
1214diff --git a/compiler/test/runnable_cxx/cpp_abi_tests.d b/compiler/test/runnable_cxx/cpp_abi_tests.d
1215index 4e241749fb..5240009816 100644
1216--- a/compiler/test/runnable_cxx/cpp_abi_tests.d
1217+++ b/compiler/test/runnable_cxx/cpp_abi_tests.d
1218@@ -1,5 +1,5 @@
1219 // EXTRA_CPP_SOURCES: cpp_abi_tests.cpp
1220-// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd): -std=c++11
1221+// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd hurd): -std=c++11
1222
1223 // N.B MSVC doesn't have a C++11 switch, but it defaults to the latest fully-supported standard
1224 // N.B MSVC 2013 doesn't support char16_t/char32_t
1225diff --git a/compiler/test/runnable_cxx/cppa.d b/compiler/test/runnable_cxx/cppa.d
1226index c62bc6face..f7bc035895 100644
1227--- a/compiler/test/runnable_cxx/cppa.d
1228+++ b/compiler/test/runnable_cxx/cppa.d
1229@@ -2,7 +2,7 @@
1230 // PERMUTE_ARGS: -g
1231 // EXTRA_CPP_SOURCES: cppb.cpp
1232 // EXTRA_FILES: extra-files/cppb.h
1233-// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd): -std=c++11
1234+// CXXFLAGS(linux freebsd osx openbsd netbsd dragonflybsd hurd): -std=c++11
1235 // druntime isn't linked, this prevents missing symbols '_d_arraybounds_slicep':
1236 // REQUIRED_ARGS: -checkaction=C
1237 // TRANSFORM_OUTPUT: remove_lines("warning: vsprintf\(\) is often misused")
1238diff --git a/compiler/test/runnable_cxx/nonpod_byval.d b/compiler/test/runnable_cxx/nonpod_byval.d
1239index c7fac46a04..4314d6b3a8 100644
1240--- a/compiler/test/runnable_cxx/nonpod_byval.d
1241+++ b/compiler/test/runnable_cxx/nonpod_byval.d
1242@@ -1,5 +1,5 @@
1243 // EXTRA_CPP_SOURCES: cpp_nonpod_byval.cpp
1244-// CXXFLAGS(linux osx freebsd dragonflybsd): -std=c++11
1245+// CXXFLAGS(linux osx freebsd dragonflybsd hurd): -std=c++11
1246
1247 extern (C) int printf(const(char)*, ...);
1248
1249diff --git a/compiler/test/tools/paths.d b/compiler/test/tools/paths.d
1250index acb525bda7..1b1ca9d07c 100644
1251--- a/compiler/test/tools/paths.d
1252+++ b/compiler/test/tools/paths.d
1253@@ -27,6 +27,8 @@ else version (Solaris)
1254 enum os = "solaris";
1255 else version (SunOS)
1256 enum os = "solaris";
1257+else version (Hurd)
1258+ enum os = "hurd";
1259 else
1260 static assert(0, "Unrecognized or unsupported OS.");
1261
1262--
12632.52.0
1264
1265From 6def98d60826b4c1d366e5b56ee47bae984c08a4 Mon Sep 17 00:00:00 2001
1266From: Yelninei <yelninei@tutamail.com>
1267Date: Fri, 27 Mar 2026 17:55:01 +0000
1268Subject: [PATCH 4/5] dmd: Regenerate frontend.h
1269
1270---
1271 compiler/src/dmd/frontend.h | 5 +++--
1272 1 file changed, 3 insertions(+), 2 deletions(-)
1273
1274diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h
1275index b697cdacf6..be7f2acc65 100644
1276--- a/compiler/src/dmd/frontend.h
1277+++ b/compiler/src/dmd/frontend.h
1278@@ -7593,8 +7593,9 @@ struct Target final
1279 FreeBSD = 16u,
1280 Solaris = 32u,
1281 DragonFlyBSD = 64u,
1282- all = 127u,
1283- Posix = 125u,
1284+ Hurd = 128u,
1285+ all = 255u,
1286+ Posix = 253u,
1287 };
1288
1289 OS os;
1290--
12912.52.0
1292
1293From 887fac44cb9347fc4dc28cf1d3c4c21cd01c4ddf Mon Sep 17 00:00:00 2001
1294From: Yelninei <yelninei@tutamail.com>
1295Date: Fri, 27 Mar 2026 14:56:20 +0000
1296Subject: [PATCH 5/5] dmd: Port druntime to GNU/Hurd
1297
1298---
1299 druntime/Makefile | 2 +-
1300 druntime/mak/COPY | 10 +
1301 druntime/src/core/demangle.d | 1 +
1302 druntime/src/core/internal/backtrace/elf.d | 5 +
1303 druntime/src/core/internal/elf/dl.d | 14 +
1304 druntime/src/core/internal/elf/io.d | 9 +
1305 druntime/src/core/internal/execinfo.d | 2 +
1306 druntime/src/core/internal/gc/os.d | 2 +
1307 druntime/src/core/stdc/config.d | 4 +
1308 druntime/src/core/stdc/errno.d | 107 +++
1309 druntime/src/core/stdc/limits.d | 14 +
1310 druntime/src/core/sys/hurd/config.d | 30 +
1311 druntime/src/core/sys/hurd/dlfcn.d | 114 +++
1312 druntime/src/core/sys/hurd/elf.d | 162 +++++
1313 druntime/src/core/sys/hurd/errno.d | 21 +
1314 druntime/src/core/sys/hurd/execinfo.d | 16 +
1315 druntime/src/core/sys/hurd/link.d | 134 ++++
1316 druntime/src/core/sys/hurd/sys/types.d | 22 +
1317 druntime/src/core/sys/hurd/time.d | 15 +
1318 druntime/src/core/sys/hurd/unistd.d | 30 +
1319 druntime/src/core/sys/linux/stdio.d | 1 +
1320 druntime/src/core/sys/posix/dirent.d | 11 +
1321 druntime/src/core/sys/posix/fcntl.d | 107 +++
1322 druntime/src/core/sys/posix/netinet/in_.d | 58 +-
1323 druntime/src/core/sys/posix/poll.d | 16 +
1324 druntime/src/core/sys/posix/pthread.d | 218 ++++--
1325 druntime/src/core/sys/posix/sched.d | 11 +
1326 druntime/src/core/sys/posix/semaphore.d | 32 +-
1327 druntime/src/core/sys/posix/signal.d | 189 ++++-
1328 druntime/src/core/sys/posix/spawn.d | 42 ++
1329 druntime/src/core/sys/posix/sys/ioctl.d | 37 +
1330 druntime/src/core/sys/posix/sys/ipc.d | 43 ++
1331 druntime/src/core/sys/posix/sys/mman.d | 33 +
1332 druntime/src/core/sys/posix/sys/msg.d | 44 ++
1333 druntime/src/core/sys/posix/sys/resource.d | 58 ++
1334 druntime/src/core/sys/posix/sys/shm.d | 26 +
1335 druntime/src/core/sys/posix/sys/socket.d | 161 +++++
1336 druntime/src/core/sys/posix/sys/stat.d | 74 ++
1337 druntime/src/core/sys/posix/sys/statvfs.d | 152 ++--
1338 druntime/src/core/sys/posix/sys/types.d | 669 +++++++++++-------
1339 druntime/src/core/sys/posix/sys/un.d | 9 +
1340 druntime/src/core/sys/posix/sys/utsname.d | 39 +-
1341 druntime/src/core/sys/posix/sys/wait.d | 23 +
1342 druntime/src/core/sys/posix/termios.d | 97 +++
1343 druntime/src/core/sys/posix/time.d | 12 +
1344 .../core/thread/fiber/switch_context_asm.S | 2 +-
1345 druntime/src/core/thread/osthread.d | 8 +
1346 druntime/src/core/time.d | 25 +
1347 druntime/src/importc.h | 4 +-
1348 druntime/src/rt/sections_elf_shared.d | 8 +
1349 .../importc_compare/src/importc_compare.d | 4 +
1350 .../test/profile/myprofilegc.log.hurd.32.exp | 18 +
1351 .../test/profile/myprofilegc.log.hurd.64.exp | 18 +
1352 druntime/test/shared/src/load.d | 1 +
1353 54 files changed, 2562 insertions(+), 402 deletions(-)
1354 create mode 100644 druntime/src/core/sys/hurd/config.d
1355 create mode 100644 druntime/src/core/sys/hurd/dlfcn.d
1356 create mode 100644 druntime/src/core/sys/hurd/elf.d
1357 create mode 100644 druntime/src/core/sys/hurd/errno.d
1358 create mode 100644 druntime/src/core/sys/hurd/execinfo.d
1359 create mode 100644 druntime/src/core/sys/hurd/link.d
1360 create mode 100644 druntime/src/core/sys/hurd/sys/types.d
1361 create mode 100644 druntime/src/core/sys/hurd/time.d
1362 create mode 100644 druntime/src/core/sys/hurd/unistd.d
1363 create mode 100644 druntime/test/profile/myprofilegc.log.hurd.32.exp
1364 create mode 100644 druntime/test/profile/myprofilegc.log.hurd.64.exp
1365
1366diff --git a/druntime/Makefile b/druntime/Makefile
1367index 89f5297fac..a3dfd5421e 100644
1368--- a/druntime/Makefile
1369+++ b/druntime/Makefile
1370@@ -76,7 +76,7 @@ endif
1371
1372 # build with shared library support
1373 # (defaults to true on supported platforms, can be overridden w/ make SHARED=0)
1374-SHARED=$(if $(findstring $(OS),linux freebsd dragonflybsd),1,)
1375+SHARED=$(if $(findstring $(OS),linux freebsd dragonflybsd hurd),1,)
1376
1377 LINKDL=$(if $(findstring $(OS),linux),-L-ldl,)
1378
1379diff --git a/druntime/mak/COPY b/druntime/mak/COPY
1380index 644013386e..7d3babd60a 100644
1381--- a/druntime/mak/COPY
1382+++ b/druntime/mak/COPY
1383@@ -390,6 +390,16 @@ COPY=\
1384 $(IMPDIR)\core\sys\solaris\sys\regset.d \
1385 $(IMPDIR)\core\sys\solaris\sys\types.d \
1386 \
1387+ $(IMPDIR)\core\sys\hurd\config.d \
1388+ $(IMPDIR)\core\sys\hurd\dlfcn.d \
1389+ $(IMPDIR)\core\sys\hurd\elf.d \
1390+ $(IMPDIR)\core\sys\hurd\execinfo.d \
1391+ $(IMPDIR)\core\sys\hurd\errno.d \
1392+ $(IMPDIR)\core\sys\hurd\link.d \
1393+ $(IMPDIR)\core\sys\hurd\sys\types.d \
1394+ $(IMPDIR)\core\sys\hurd\time.d \
1395+ $(IMPDIR)\core\sys\hurd\unistd.d \
1396+ \
1397 $(IMPDIR)\core\sys\windows\accctrl.d \
1398 $(IMPDIR)\core\sys\windows\aclapi.d \
1399 $(IMPDIR)\core\sys\windows\aclui.d \
1400diff --git a/druntime/src/core/demangle.d b/druntime/src/core/demangle.d
1401index e7efc8c3ec..e95984c26c 100644
1402--- a/druntime/src/core/demangle.d
1403+++ b/druntime/src/core/demangle.d
1404@@ -2996,6 +2996,7 @@ CXX_DEMANGLER getCXXDemangler() nothrow @trusted
1405 version (OpenBSD) import core.sys.openbsd.dlfcn : RTLD_DEFAULT;
1406 version (Darwin) import core.sys.darwin.dlfcn : RTLD_DEFAULT;
1407 version (Solaris) import core.sys.solaris.dlfcn : RTLD_DEFAULT;
1408+ version (Hurd) import core.sys.hurd.dlfcn : RTLD_DEFAULT;
1409
1410 if (auto found = cast(CXX_DEMANGLER) dlsym(RTLD_DEFAULT, "__cxa_demangle"))
1411 atomicStore(__cxa_demangle, found);
1412diff --git a/druntime/src/core/internal/backtrace/elf.d b/druntime/src/core/internal/backtrace/elf.d
1413index 1a235537bb..6da1ef1ecb 100644
1414--- a/druntime/src/core/internal/backtrace/elf.d
1415+++ b/druntime/src/core/internal/backtrace/elf.d
1416@@ -36,6 +36,11 @@ else version (Solaris)
1417 import core.sys.solaris.sys.elf : SHF_COMPRESSED, ET_DYN;
1418 version = LinuxOrBSD;
1419 }
1420+else version (Hurd)
1421+{
1422+ import core.sys.hurd.elf : SHF_COMPRESSED, ET_DYN;
1423+ version = LinuxOrBSD;
1424+}
1425
1426 version (LinuxOrBSD):
1427
1428diff --git a/druntime/src/core/internal/elf/dl.d b/druntime/src/core/internal/elf/dl.d
1429index 963b4249a3..c7b24e854a 100644
1430--- a/druntime/src/core/internal/elf/dl.d
1431+++ b/druntime/src/core/internal/elf/dl.d
1432@@ -41,6 +41,11 @@ else version (Solaris)
1433 import core.sys.solaris.link : dl_iterate_phdr, dl_phdr_info, ElfW;
1434 version = LinuxOrBSD;
1435 }
1436+else version (Hurd)
1437+{
1438+ import core.sys.hurd.link : dl_iterate_phdr, dl_phdr_info, ElfW;
1439+ version = LinuxOrBSD;
1440+}
1441
1442 version (LinuxOrBSD):
1443
1444@@ -93,6 +98,7 @@ struct SharedObject
1445 else version (NetBSD) enum IterateManually = true;
1446 else version (OpenBSD) enum IterateManually = true;
1447 else version (Solaris) enum IterateManually = true;
1448+ else version (Hurd) enum IterateManually = true;
1449 else enum IterateManually = false;
1450
1451 static if (IterateManually)
1452@@ -225,6 +231,14 @@ version (Linux_Use_GNU)
1453 return program_invocation_name;
1454 }
1455 }
1456+else version (Hurd)
1457+{
1458+ const(char)* getprogname()
1459+ {
1460+ import core.sys.hurd.errno : program_invocation_name;
1461+ return program_invocation_name;
1462+ }
1463+}
1464 else // Bionic, BSDs
1465 {
1466 extern(C) const(char)* getprogname();
1467diff --git a/druntime/src/core/internal/elf/io.d b/druntime/src/core/internal/elf/io.d
1468index 80c9415e14..437589ec97 100644
1469--- a/druntime/src/core/internal/elf/io.d
1470+++ b/druntime/src/core/internal/elf/io.d
1471@@ -50,6 +50,11 @@ else version (Solaris)
1472 import core.sys.solaris.link : ElfW;
1473 version = LinuxOrBSD;
1474 }
1475+else version (Hurd)
1476+{
1477+ import core.sys.hurd.link : ElfW;
1478+ version = LinuxOrBSD;
1479+}
1480
1481 /**
1482 * File-based memory-mapped I/O (read-only).
1483@@ -403,6 +408,10 @@ char* thisExePath()
1484 import core.sys.openbsd.stdlib : getprogname;
1485 return strdup(getprogname());
1486 }
1487+ else version (Hurd)
1488+ {
1489+ return readLink("/proc/self/exe");
1490+ }
1491 else
1492 {
1493 version (DragonFlyBSD)
1494diff --git a/druntime/src/core/internal/execinfo.d b/druntime/src/core/internal/execinfo.d
1495index 1ea467afbe..ce7d6de36e 100644
1496--- a/druntime/src/core/internal/execinfo.d
1497+++ b/druntime/src/core/internal/execinfo.d
1498@@ -68,6 +68,8 @@ else version (DragonFlyBSD)
1499 import _execinfo = core.sys.dragonflybsd.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd;
1500 else version (Solaris)
1501 import _execinfo = core.sys.solaris.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd;
1502+else version (Hurd)
1503+ import _execinfo = core.sys.hurd.execinfo : backtrace, backtrace_symbols, backtrace_symbols_fd;
1504
1505 /// Indicates the availability of backtrace functions
1506 enum bool hasExecinfo = is(_execinfo == module);
1507diff --git a/druntime/src/core/internal/gc/os.d b/druntime/src/core/internal/gc/os.d
1508index e9a253369e..b72c4db93a 100644
1509--- a/druntime/src/core/internal/gc/os.d
1510+++ b/druntime/src/core/internal/gc/os.d
1511@@ -95,6 +95,8 @@ else version (Posix)
1512 version = GCSignalsUnblock;
1513 version (Solaris)
1514 version = GCSignalsUnblock;
1515+ version (Hurd)
1516+ version = GCSignalsUnblock;
1517
1518 //version = GC_Use_Alloc_MMap;
1519 }
1520diff --git a/druntime/src/core/stdc/config.d b/druntime/src/core/stdc/config.d
1521index 952ceacb21..14d08a5057 100644
1522--- a/druntime/src/core/stdc/config.d
1523+++ b/druntime/src/core/stdc/config.d
1524@@ -259,6 +259,8 @@ else version (DigitalMars)
1525 alias real c_long_double;
1526 else version (Darwin)
1527 alias real c_long_double;
1528+ else version (Hurd)
1529+ alias real c_long_double;
1530 }
1531 else version (AArch64)
1532 {
1533@@ -276,6 +278,8 @@ else version (DigitalMars)
1534 alias real c_long_double;
1535 else version (Darwin)
1536 alias real c_long_double;
1537+ else version (Hurd)
1538+ alias real c_long_double;
1539 }
1540 }
1541
1542diff --git a/druntime/src/core/stdc/errno.d b/druntime/src/core/stdc/errno.d
1543index db347e404b..ee48ac2e17 100644
1544--- a/druntime/src/core/stdc/errno.d
1545+++ b/druntime/src/core/stdc/errno.d
1546@@ -2457,6 +2457,113 @@ else version (WASI)
1547 enum ERFKILL = 132;
1548 enum EHWPOISON = 133;
1549 }
1550+else version (Hurd)
1551+{
1552+ enum EPERM = 0x40000001; /* Operation not permitted */
1553+ enum ENOENT = 0x40000002; /* No such file or directory */
1554+ enum ESRCH = 0x40000003; /* No such process */
1555+ enum EINTR = 0x40000004; /* Interrupted system call */
1556+ enum EIO = 0x40000005; /* Input/output error */
1557+ enum ENXIO = 0x40000006; /* No such device or address */
1558+ enum E2BIG = 0x40000007; /* Argument list too long */
1559+ enum ENOEXEC = 0x40000008; /*enum Exec format error */
1560+ enum EBADF = 0x40000009; /* Bad file descriptor */
1561+ enum ECHILD = 0x4000000a; /* No child processes */
1562+ enum EDEADLK = 0x4000000b; /* Resource deadlock avoided */
1563+ enum ENOMEM = 0x4000000c; /* Cannot allocate memory */
1564+ enum EACCES = 0x4000000d; /* Permission denied */
1565+ enum EFAULT = 0x4000000e; /* Bad address */
1566+ enum ENOTBLK = 0x4000000f; /* Block device required */
1567+ enum EBUSY = 0x40000010; /* Device or resource busy */
1568+ enum EEXIST = 0x40000011; /* File exists */
1569+ enum EXDEV = 0x40000012; /* Invalid cross-device link */
1570+ enum ENODEV = 0x40000013; /* No such device */
1571+ enum ENOTDIR = 0x40000014; /* Not a directory */
1572+ enum EISDIR = 0x40000015; /* Is a directory */
1573+ enum EINVAL = 0x40000016; /* Invalid argument */
1574+ enum EMFILE = 0x40000018; /* Too many open files */
1575+ enum ENFILE = 0x40000017; /* Too many open files in system */
1576+ enum ENOTTY = 0x40000019; /* Inappropriate ioctl for device */
1577+ enum ETXTBSY = 0x4000001a; /* Text file busy */
1578+ enum EFBIG = 0x4000001b; /* File too large */
1579+ enum ENOSPC = 0x4000001c; /* No space left on device */
1580+ enum ESPIPE = 0x4000001d; /* Illegal seek */
1581+ enum EROFS = 0x4000001e; /* Read-only file system */
1582+ enum EMLINK = 0x4000001f; /* Too many links */
1583+ enum EPIPE = 0x40000020; /* Broken pipe */
1584+ enum EDOM = 0x40000021; /* Numerical argument out of domain */
1585+ enum ERANGE = 0x40000022; /* Numerical result out of range */
1586+ enum EAGAIN = 0x40000023; /* Resource temporarily unavailable */
1587+ enum EINPROGRESS = 0x40000024; /* Operation now in progress */
1588+ enum EALREADY = 0x40000025; /* Operation already in progress */
1589+ enum ENOTSOCK = 0x40000026; /* Socket operation on non-socket */
1590+ enum EMSGSIZE = 0x40000028; /* Message too long */
1591+ enum EPROTOTYPE = 0x40000029; /* Protocol wrong type for socket */
1592+ enum ENOPROTOOPT = 0x4000002a; /* Protocol not available */
1593+ enum EPROTONOSUPPORT = 0x4000002b; /* Protocol not supported */
1594+ enum ESOCKTNOSUPPORT = 0x4000002c; /* Socket type not supported */
1595+ enum EOPNOTSUPP = 0x4000002d; /* Operation not supported */
1596+ enum EPFNOSUPPORT = 0x4000002e; /* Protocol family not supported */
1597+ enum EAFNOSUPPORT = 0x4000002f; /* Address family not supported by protocol */
1598+ enum EADDRINUSE = 0x40000030; /* Address already in use */
1599+ enum EADDRNOTAVAIL = 0x40000031; /* Cannot assign requested address */
1600+ enum ENETDOWN = 0x40000032; /* Network is down */
1601+ enum ENETUNREACH = 0x40000033; /* Network is unreachable */
1602+ enum ENETRESET = 0x40000034; /* Network dropped connection on reset */
1603+ enum ECONNABORTED = 0x40000035; /* Software caused connection abort */
1604+ enum ECONNRESET = 0x40000036; /* Connection reset by peer */
1605+ enum ENOBUFS = 0x40000037; /* No buffer space available */
1606+ enum EISCONN = 0x40000038; /* Transport endpoint is already connected */
1607+ enum ENOTCONN = 0x40000039; /* Transport endpoint is not connected */
1608+ enum EDESTADDRREQ = 0x40000027; /* Destination address required */
1609+ enum ESHUTDOWN = 0x4000003a; /* Cannot send after transport endpoint shutdown */
1610+ enum ETOOMANYREFS = 0x4000003b; /* Too many references: cannot splice */
1611+ enum ETIMEDOUT = 0x4000003c; /* Connection timed out */
1612+ enum ECONNREFUSED = 0x4000003d; /* Connection refused */
1613+ enum ELOOP = 0x4000003e; /* Too many levels of symbolic links */
1614+ enum ENAMETOOLONG = 0x4000003f; /* File name too long */
1615+ enum EHOSTDOWN = 0x40000040; /* Host is down */
1616+ enum EHOSTUNREACH = 0x40000041; /* No route to host */
1617+ enum ENOTEMPTY = 0x40000042; /* Directory not empty */
1618+ enum EPROCLIM = 0x40000043; /* Too many processes */
1619+ enum EUSERS = 0x40000044; /* Too many users */
1620+ enum EDQUOT = 0x40000045; /* Disk quota exceeded */
1621+ enum ESTALE = 0x40000046; /* Stale file handle */
1622+ enum EREMOTE = 0x40000047; /* Object is remote */
1623+ enum EBADRPC = 0x40000048; /* RPC struct is bad */
1624+ enum ERPCMISMATCH = 0x40000049; /* RPC version wrong */
1625+ enum EPROGUNAVAIL = 0x4000004a; /* RPC program not available */
1626+ enum EPROGMISMATCH = 0x4000004b; /* RPC program version wrong */
1627+ enum EPROCUNAVAIL = 0x4000004c; /* RPC bad procedure for program */
1628+ enum ENOLCK = 0x4000004d; /* No locks available */
1629+ enum EFTYPE = 0x4000004f; /* Inappropriate file type or format */
1630+ enum EAUTH = 0x40000050; /* Authentication error */
1631+ enum ENEEDAUTH = 0x40000051; /* Need authenticator */
1632+ enum ENOSYS = 0x4000004e; /* Function not implemented */
1633+ enum ELIBEXEC = 0x40000053; /* Cannot exec a shared library directly */
1634+ enum ENOTSUP = 0x40000076; /* Not supported */
1635+ enum EILSEQ = 0x4000006a; /* Invalid or incomplete multibyte or wide character */
1636+ enum EBACKGROUND = 0x40000064; /* Inappropriate operation for background process */
1637+ enum EDIED = 0x40000065; /* Translator died */
1638+ enum ED = 0x40000066; /* ? */
1639+ enum EGREGIOUS = 0x40000067; /* You really blew it this time */
1640+ enum EIEIO = 0x40000068; /* Computer bought the farm */
1641+ enum EGRATUITOUS = 0x40000069; /* Gratuitous error */
1642+ enum EBADMSG = 0x4000006b; /* Bad message */
1643+ enum EIDRM = 0x4000006c; /* Identifier removed */
1644+ enum EMULTIHOP = 0x4000006d; /* Multihop attempted */
1645+ enum ENODATA = 0x4000006e; /* No data available */
1646+ enum ENOLINK = 0x4000006f; /* Link has been severed */
1647+ enum ENOMSG = 0x40000070; /* No message of desired type */
1648+ enum ENOSR = 0x40000071; /* Out of streams resources */
1649+ enum ENOSTR = 0x40000072; /* Device not a stream */
1650+ enum EOVERFLOW = 0x40000073; /* Value too large for defined data type */
1651+ enum EPROTO = 0x40000074; /* Protocol error */
1652+ enum ETIME = 0x40000075; /* Timer expired */
1653+ enum ECANCELED = 0x40000077; /* Operation canceled */
1654+ enum EOWNERDEAD = 0x40000078; /* Owner died */
1655+ enum ENOTRECOVERABLE = 0x40000079; /* State not recoverable */
1656+ }
1657 else
1658 {
1659 static assert(false, "Unsupported platform");
1660diff --git a/druntime/src/core/stdc/limits.d b/druntime/src/core/stdc/limits.d
1661index 2684b22bfc..35ee96a052 100644
1662--- a/druntime/src/core/stdc/limits.d
1663+++ b/druntime/src/core/stdc/limits.d
1664@@ -181,5 +181,19 @@ else version (Windows)
1665 ///
1666 enum PIPE_BUF = 5120;
1667 }
1668+else version (Hurd)
1669+{
1670+ // no arbitrary fixed limits
1671+ ///
1672+ // enum MAX_CANON
1673+ ///
1674+ // enum MAX_INPUT
1675+ ///
1676+ enum NAME_MAX = 255;
1677+ ///
1678+ // enum PATH_MAX
1679+ ///
1680+ // enum PIPE_BUF
1681+}
1682 else
1683 static assert(0, "unsupported OS");
1684diff --git a/druntime/src/core/sys/hurd/config.d b/druntime/src/core/sys/hurd/config.d
1685new file mode 100644
1686index 0000000000..109990d544
1687--- /dev/null
1688+++ b/druntime/src/core/sys/hurd/config.d
1689@@ -0,0 +1,30 @@
1690+/**
1691+ * D header file for GNU/Hurd.
1692+ *
1693+ * Copyright: Copyright (c) 2026 D Language Foundation
1694+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1695+ */
1696+module core.sys.hurd.config;
1697+
1698+version (Hurd):
1699+
1700+public import core.sys.posix.config;
1701+
1702+// man 7 feature_test_macros
1703+// http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
1704+enum _GNU_SOURCE = true;
1705+// deduced <features.h>
1706+// http://sourceware.org/git/?p=glibc.git;a=blob;f=include/features.h
1707+enum _DEFAULT_SOURCE = true;
1708+enum _ATFILE_SOURCE = true;
1709+
1710+// _BSD_SOURCE and _SVID_SOURCE are deprecated aliases for _DEFAULT_SOURCE.
1711+deprecated("use _DEFAULT_SOURCE")
1712+{
1713+ enum _BSD_SOURCE = true;
1714+ enum _SVID_SOURCE = true;
1715+}
1716+
1717+enum __USE_MISC = _DEFAULT_SOURCE;
1718+enum __USE_ATFILE = _ATFILE_SOURCE;
1719+enum __USE_GNU = _GNU_SOURCE;
1720diff --git a/druntime/src/core/sys/hurd/dlfcn.d b/druntime/src/core/sys/hurd/dlfcn.d
1721new file mode 100644
1722index 0000000000..430857621b
1723--- /dev/null
1724+++ b/druntime/src/core/sys/hurd/dlfcn.d
1725@@ -0,0 +1,114 @@
1726+/**
1727+ * D header file for GNU/Hurd.
1728+ *
1729+ * Copyright: Copyright (c) 2026 D Language Foundation
1730+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1731+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=dlfcn/dlfcn.h, glibc dlfcn/dlfcn.h)
1732+ */
1733+module core.sys.hurd.dlfcn;
1734+
1735+version (Hurd):
1736+extern (C):
1737+nothrow:
1738+@nogc:
1739+@system:
1740+
1741+
1742+public import core.sys.posix.dlfcn;
1743+import core.sys.hurd.config;
1744+
1745+// <bits/dlfcn.h>
1746+
1747+// http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/dlfcn.h
1748+// enum RTLD_LAZY = 0x00001; // POSIX
1749+// enum RTLD_NOW = 0x00002; // POSIX
1750+enum RTLD_BINDING_MASK = 0x3;
1751+enum RTLD_NOLOAD = 0x00004;
1752+enum RTLD_DEEPBIND = 0x00008;
1753+
1754+// enum RTLD_GLOBAL = 0x00100; // POSIX
1755+// enum RTLD_LOCAL = 0; // POSIX
1756+enum RTLD_NODELETE = 0x01000;
1757+
1758+static if (__USE_GNU)
1759+{
1760+ RT DL_CALL_FCT(RT, Args...)(RT function(Args) fctp, auto ref Args args)
1761+ {
1762+ _dl_mcount_wrapper_check(cast(void*)fctp);
1763+ return fctp(args);
1764+ }
1765+
1766+ void _dl_mcount_wrapper_check(void* __selfpc);
1767+}
1768+// <bits/dlfcn.h>
1769+
1770+static if (__USE_GNU)
1771+{
1772+ enum RTLD_NEXT = cast(void *)-1L;
1773+ enum RTLD_DEFAULT = cast(void *)0;
1774+ alias c_long Lmid_t;
1775+ enum LM_ID_BASE = 0;
1776+ enum LM_ID_NEWLM = -1;
1777+}
1778+
1779+// void* dlopen(const scope char* __file, int __mode); // POSIX
1780+// int dlclose(void* __handle); // POSIX
1781+// void* dlsym(void* __handle, const scope char* __name); // POSIX
1782+
1783+static if (__USE_GNU)
1784+{
1785+ void* dlmopen(Lmid_t __nsid, const scope char* __file, int __mode);
1786+ void* dlvsym(void* __handle, const scope char* __name, const scope char* __version);
1787+}
1788+
1789+// char* dlerror(); // POSIX
1790+
1791+static if (__USE_GNU)
1792+{
1793+ struct Dl_info
1794+ {
1795+ const(char)* dli_fname;
1796+ void* dli_fbase;
1797+ const(char)* dli_sname;
1798+ void* dli_saddr;
1799+ }
1800+
1801+ int dladdr(const scope void* __address, Dl_info* __info);
1802+ int dladdr1(void* __address, Dl_info* __info, void** __extra_info, int __flags);
1803+
1804+ enum
1805+ {
1806+ RTLD_DL_SYMENT = 1,
1807+ RTLD_DL_LINKMAP = 2,
1808+ }
1809+
1810+ int dlinfo(void* __handle, int __request, void* __arg);
1811+
1812+ enum
1813+ {
1814+ RTLD_DI_LMID = 1,
1815+ RTLD_DI_LINKMAP = 2,
1816+ RTLD_DI_CONFIGADDR = 3,
1817+ RTLD_DI_SERINFO = 4,
1818+ RTLD_DI_SERINFOSIZE = 5,
1819+ RTLD_DI_ORIGIN = 6,
1820+ RTLD_DI_PROFILENAME = 7,
1821+ RTLD_DI_PROFILEOUT = 8,
1822+ RTLD_DI_TLS_MODID = 9,
1823+ RTLD_DI_TLS_DATA = 10,
1824+ RTLD_DI_MAX = 10,
1825+ }
1826+
1827+ struct Dl_serpath
1828+ {
1829+ char* dls_name;
1830+ uint dls_flags;
1831+ }
1832+
1833+ struct Dl_serinfo
1834+ {
1835+ size_t dls_size;
1836+ uint dls_cnt;
1837+ Dl_serpath[1] dls_serpath;
1838+ }
1839+}
1840diff --git a/druntime/src/core/sys/hurd/elf.d b/druntime/src/core/sys/hurd/elf.d
1841new file mode 100644
1842index 0000000000..0cdc29c5a2
1843--- /dev/null
1844+++ b/druntime/src/core/sys/hurd/elf.d
1845@@ -0,0 +1,162 @@
1846+/**
1847+ * D header file for GNU/Hurd.
1848+ *
1849+ * Copyright: Copyright (c) 2026 D Language Foundation
1850+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1851+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/elf.h, glibc elf/elf.h)
1852+ */
1853+module core.sys.hurd.elf;
1854+
1855+version (Hurd):
1856+extern (C):
1857+pure:
1858+nothrow:
1859+@system:
1860+
1861+import core.stdc.stdint;
1862+public import core.sys.elf;
1863+
1864+extern (D)
1865+{
1866+ auto ELF32_ST_VISIBILITY(O)(O o) { return o & 0x03; }
1867+ alias ELF32_ST_VISIBILITY ELF64_ST_VISIBILITY;
1868+}
1869+
1870+struct Elf32_Nhdr
1871+{
1872+ Elf32_Word n_namesz;
1873+ Elf32_Word n_descsz;
1874+ Elf32_Word n_type;
1875+}
1876+
1877+struct Elf64_Nhdr
1878+{
1879+ Elf64_Word n_namesz;
1880+ Elf64_Word n_descsz;
1881+ Elf64_Word n_type;
1882+}
1883+
1884+enum NT_PRSTATUS = 1;
1885+enum NT_FPREGSET = 2;
1886+enum NT_PRPSINFO = 3;
1887+enum NT_PRXREG = 4;
1888+enum NT_TASKSTRUCT = 4;
1889+enum NT_PLATFORM = 5;
1890+enum NT_AUXV = 6;
1891+enum NT_GWINDOWS = 7;
1892+enum NT_ASRS = 8;
1893+enum NT_PSTATUS = 10;
1894+enum NT_PSINFO = 13;
1895+enum NT_PRCRED = 14;
1896+enum NT_UTSNAME = 15;
1897+enum NT_LWPSTATUS = 16;
1898+enum NT_LWPSINFO = 17;
1899+enum NT_PRFPXREG = 20;
1900+enum NT_SIGINFO = 0x53494749;
1901+enum NT_FILE = 0x46494c45;
1902+enum NT_PRXFPREG = 0x46e62b7f;
1903+enum NT_PPC_VMX = 0x100;
1904+enum NT_PPC_SPE = 0x101;
1905+enum NT_PPC_VSX = 0x102;
1906+enum NT_386_TLS = 0x200;
1907+enum NT_386_IOPERM = 0x201;
1908+enum NT_X86_XSTATE = 0x202;
1909+enum NT_S390_HIGH_GPRS = 0x300;
1910+enum NT_S390_TIMER = 0x301;
1911+enum NT_S390_TODCMP = 0x302;
1912+enum NT_S390_TODPREG = 0x303;
1913+enum NT_S390_CTRS = 0x304;
1914+enum NT_S390_PREFIX = 0x305;
1915+enum NT_S390_LAST_BREAK = 0x306;
1916+enum NT_S390_SYSTEM_CALL = 0x307;
1917+enum NT_S390_TDB = 0x308;
1918+enum NT_ARM_VFP = 0x400;
1919+enum NT_ARM_TLS = 0x401;
1920+enum NT_ARM_HW_BREAK = 0x402;
1921+enum NT_ARM_HW_WATCH = 0x403;
1922+
1923+enum NT_VERSION = 1;
1924+
1925+struct Elf32_Dyn
1926+{
1927+ Elf32_Sword d_tag;
1928+ union _d_un
1929+ {
1930+ Elf32_Word d_val;
1931+ Elf32_Addr d_ptr;
1932+ } _d_un d_un;
1933+}
1934+
1935+struct Elf64_Dyn
1936+{
1937+ Elf64_Sxword d_tag;
1938+ union _d_un
1939+ {
1940+ Elf64_Xword d_val;
1941+ Elf64_Addr d_ptr;
1942+ } _d_un d_un;
1943+}
1944+
1945+enum NT_GNU_ABI_TAG = 1;
1946+enum NT_GNU_HWCAP = 2;
1947+enum NT_GNU_BUILD_ID = 3;
1948+enum NT_GNU_GOLD_VERSION = 4;
1949+
1950+struct Elf32_auxv_t
1951+{
1952+ uint32_t a_type;
1953+ union _a_un
1954+ {
1955+ uint32_t a_val;
1956+ } _a_un a_un;
1957+}
1958+
1959+struct Elf64_auxv_t
1960+{
1961+ uint64_t a_type;
1962+ union _a_un
1963+ {
1964+ uint64_t a_val;
1965+ } _a_un a_un;
1966+}
1967+
1968+enum AT_NULL = 0;
1969+enum AT_IGNORE = 1;
1970+enum AT_EXECFD = 2;
1971+enum AT_PHDR = 3;
1972+enum AT_PHENT = 4;
1973+enum AT_PHNUM = 5;
1974+enum AT_PAGESZ = 6;
1975+enum AT_BASE = 7;
1976+enum AT_FLAGS = 8;
1977+enum AT_ENTRY = 9;
1978+enum AT_NOTELF = 10;
1979+enum AT_UID = 11;
1980+enum AT_EUID = 12;
1981+enum AT_GID = 13;
1982+enum AT_EGID = 14;
1983+enum AT_CLKTCK = 17;
1984+enum AT_PLATFORM = 15;
1985+enum AT_HWCAP = 16;
1986+enum AT_FPUCW = 18;
1987+enum AT_DCACHEBSIZE = 19;
1988+enum AT_ICACHEBSIZE = 20;
1989+enum AT_UCACHEBSIZE = 21;
1990+enum AT_IGNOREPPC = 22;
1991+
1992+enum AT_SECURE = 23;
1993+
1994+enum AT_BASE_PLATFORM = 24;
1995+
1996+enum AT_RANDOM = 25;
1997+
1998+enum AT_HWCAP2 = 26;
1999+
2000+enum AT_EXECFN = 31;
2001+enum AT_SYSINFO = 32;
2002+enum AT_SYSINFO_EHDR = 33;
2003+
2004+enum AT_L1I_CACHESHAPE = 34;
2005+enum AT_L1D_CACHESHAPE = 35;
2006+enum AT_L2_CACHESHAPE = 36;
2007+enum AT_L3_CACHESHAPE = 37;
2008diff --git a/druntime/src/core/sys/hurd/errno.d b/druntime/src/core/sys/hurd/errno.d
2009new file mode 100644
2010index 0000000000..db9c83c901
2011--- /dev/null
2012+++ b/druntime/src/core/sys/hurd/errno.d
2013@@ -0,0 +1,21 @@
2014+/**
2015+ * D header file for GNU/Hurd
2016+ *
2017+ * Copyright: Copyright (c) 2026 D Language Foundation
2018+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2019+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/errno.h, glibc stdlib/errno.h)
2020+ */
2021+module core.sys.hurd.errno;
2022+
2023+version (Hurd):
2024+extern (C):
2025+nothrow:
2026+
2027+public import core.stdc.errno;
2028+import core.sys.hurd.config;
2029+
2030+static if (_GNU_SOURCE)
2031+{
2032+ extern __gshared char* program_invocation_name, program_invocation_short_name;
2033+ alias error_t = int;
2034+}
2035diff --git a/druntime/src/core/sys/hurd/execinfo.d b/druntime/src/core/sys/hurd/execinfo.d
2036new file mode 100644
2037index 0000000000..4afeffa8ff
2038--- /dev/null
2039+++ b/druntime/src/core/sys/hurd/execinfo.d
2040@@ -0,0 +1,16 @@
2041+/**
2042+ * D header file for GNU/Hurd.
2043+ *
2044+ * Copyright: Copyright (c) 2026 D Language Foundation
2045+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2046+ */
2047+module core.sys.hurd.execinfo;
2048+
2049+version (Hurd):
2050+extern (C):
2051+nothrow:
2052+@nogc:
2053+
2054+int backtrace(void** buffer, int size);
2055+char** backtrace_symbols(const(void*)* buffer, int size);
2056+void backtrace_symbols_fd(const(void*)* buffer, int size, int fd);
2057diff --git a/druntime/src/core/sys/hurd/link.d b/druntime/src/core/sys/hurd/link.d
2058new file mode 100644
2059index 0000000000..e9df0fc0bc
2060--- /dev/null
2061+++ b/druntime/src/core/sys/hurd/link.d
2062@@ -0,0 +1,134 @@
2063+/**
2064+ * D header file for GNU/Hurd.
2065+ * Copyright: Copyright (c) 2026 D Language Foundation
2066+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2067+ *
2068+ * $(LINK2 http://sourceware.org/git/?p=glibc.git;a=blob;f=elf/link.h, glibc elf/link.h)
2069+ */
2070+module core.sys.hurd.link;
2071+
2072+version (Hurd):
2073+extern (C):
2074+nothrow:
2075+@system:
2076+
2077+version (X86) version = X86_Any;
2078+version (X86_64) version = X86_Any;
2079+
2080+import core.stdc.stdint : uintptr_t, uint32_t, uint64_t;
2081+import core.sys.hurd.config : __WORDSIZE;
2082+import core.sys.hurd.dlfcn : Lmid_t;
2083+import core.sys.hurd.elf;
2084+
2085+version (X86_Any)
2086+{
2087+ // http://sourceware.org/git/?p=glibc.git;a=blob;f=bits/elfclass.h
2088+ alias __WORDSIZE __ELF_NATIVE_CLASS;
2089+ alias uint32_t Elf_Symndx;
2090+}
2091+else
2092+ static assert(0, "unimplemented");
2093+// <bits/elfclass.h>
2094+
2095+template ElfW(string type)
2096+{
2097+ mixin("alias Elf"~__ELF_NATIVE_CLASS.stringof~"_"~type~" ElfW;");
2098+}
2099+
2100+enum
2101+{
2102+ RT_CONSISTENT,
2103+ RT_ADD,
2104+ RT_DELETE,
2105+}
2106+
2107+struct r_debug
2108+{
2109+ int r_version;
2110+ link_map* r_map;
2111+ ElfW!"Addr" r_brk;
2112+ typeof(RT_CONSISTENT) r_state;
2113+ ElfW!"Addr" r_ldbase;
2114+}
2115+
2116+extern r_debug _r_debug;
2117+extern ElfW!"Dyn"* _DYNAMIC;
2118+
2119+struct link_map
2120+{
2121+ ElfW!"Addr" l_addr;
2122+ char* l_name;
2123+ ElfW!"Dyn"* l_ld;
2124+ link_map* l_next, l_prev;
2125+}
2126+
2127+enum
2128+{
2129+ LA_ACT_CONSISTENT,
2130+ LA_ACT_ADD,
2131+ LA_ACT_DELETE,
2132+}
2133+
2134+enum
2135+{
2136+ LA_SER_ORIG = 0x01,
2137+ LA_SER_LIBPATH = 0x02,
2138+ LA_SER_RUNPATH = 0x04,
2139+ LA_SER_CONFIG = 0x08,
2140+ LA_SER_DEFAULT = 0x40,
2141+ LA_SER_SECURE = 0x80,
2142+}
2143+
2144+
2145+enum
2146+{
2147+ LA_FLG_BINDTO = 0x01,
2148+ LA_FLG_BINDFROM = 0x02,
2149+}
2150+
2151+
2152+enum
2153+{
2154+ LA_SYMB_NOPLTENTER = 0x01,
2155+ LA_SYMB_NOPLTEXIT = 0x02,
2156+ LA_SYMB_STRUCTCALL = 0x04,
2157+ LA_SYMB_DLSYM = 0x08,
2158+ LA_SYMB_ALTVALUE = 0x10,
2159+}
2160+
2161+struct dl_phdr_info
2162+{
2163+ ElfW!"Addr" dlpi_addr;
2164+ const(char)* dlpi_name;
2165+ const(ElfW!"Phdr")* dlpi_phdr;
2166+ ElfW!"Half" dlpi_phnum;
2167+
2168+ // check the SIZE argument of the dl_iterate_phdr callback whether
2169+ // the following members are available
2170+ ulong dlpi_adds;
2171+ ulong dlpi_subs;
2172+
2173+ size_t dlpi_tls_modid;
2174+ void *dlpi_tls_data;
2175+}
2176+
2177+private alias extern(C) int function(dl_phdr_info*, size_t, void *) dl_iterate_phdr_cb;
2178+private alias extern(C) int function(dl_phdr_info*, size_t, void *) @nogc dl_iterate_phdr_cb_ngc;
2179+extern int dl_iterate_phdr(dl_iterate_phdr_cb __callback, void*__data);
2180+extern int dl_iterate_phdr(dl_iterate_phdr_cb_ngc __callback, void*__data) @nogc;
2181+
2182+// ld.so auditing interfaces prototypes have to be defined by the auditing DSO.
2183+extern uint la_version(uint __version);
2184+extern void la_activity(uintptr_t *__cookie, uint __flag);
2185+extern char* la_objsearch(const(char)* __name, uintptr_t* __cookie,
2186+ uint __flag);
2187+extern uint la_objopen(link_map* __map, Lmid_t __lmid,
2188+ uintptr_t* __cookie);
2189+extern void la_preinit(uintptr_t* __cookie);
2190+extern uintptr_t la_symbind32(Elf32_Sym* __sym, uint __ndx,
2191+ uintptr_t* __refcook, uintptr_t* __defcook,
2192+ uint *__flags, const(char)* __symname);
2193+extern uintptr_t la_symbind64(Elf64_Sym* __sym, uint __ndx,
2194+ uintptr_t* __refcook, uintptr_t* __defcook,
2195+ uint* __flags, const(char)* __symname);
2196+extern uint la_objclose(uintptr_t *__cookie);
2197diff --git a/druntime/src/core/sys/hurd/sys/types.d b/druntime/src/core/sys/hurd/sys/types.d
2198new file mode 100644
2199index 0000000000..a523a8df35
2200--- /dev/null
2201+++ b/druntime/src/core/sys/hurd/sys/types.d
2202@@ -0,0 +1,22 @@
2203+/**
2204+ * D header file for Hurd extensions to POSIX's sys/types.h.
2205+ *
2206+ * Copyright: Copyright (c) 2026 D Language Foundation
2207+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2208+ */
2209+
2210+module core.sys.hurd.sys.types;
2211+
2212+import core.sys.posix.config;
2213+
2214+version (Hurd):
2215+extern(C):
2216+@nogc:
2217+nothrow:
2218+
2219+static if (__WORDSIZE == 32)
2220+ alias ushort ipc_pid_t;
2221+else
2222+ alias int ipc_pid_t;
2223+
2224+alias fsid_t = ulong;
2225diff --git a/druntime/src/core/sys/hurd/time.d b/druntime/src/core/sys/hurd/time.d
2226new file mode 100644
2227index 0000000000..12031e599c
2228--- /dev/null
2229+++ b/druntime/src/core/sys/hurd/time.d
2230@@ -0,0 +1,15 @@
2231+/**
2232+ * D header file for Hurd extensions to POSIX's time.h.
2233+ *
2234+ * Copyright: Copyright (c) 2026 D Language Foundation
2235+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2236+ */
2237+module core.sys.hurd.time;
2238+
2239+public import core.sys.posix.time;
2240+
2241+version (Hurd):
2242+
2243+enum CLOCK_MONOTONIC_RAW = 4;
2244+enum CLOCK_REALTIME_COARSE = 5;
2245+enum CLOCK_MONOTONIC_COARSE = 6;
2246diff --git a/druntime/src/core/sys/hurd/unistd.d b/druntime/src/core/sys/hurd/unistd.d
2247new file mode 100644
2248index 0000000000..a351134cd4
2249--- /dev/null
2250+++ b/druntime/src/core/sys/hurd/unistd.d
2251@@ -0,0 +1,30 @@
2252+/**
2253+ * D header file for GNU/Hurd.
2254+ *
2255+ * Copyright: Copyright (c) 2026 D Language Foundation
2256+ * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
2257+ */
2258+module core.sys.hurd.unistd;
2259+
2260+public import core.sys.posix.unistd;
2261+
2262+version (Hurd):
2263+extern(C):
2264+nothrow:
2265+@nogc:
2266+
2267+
2268+// Additional seek constants for sparse file handling
2269+// from Hurds's unistd.h, stdio.h
2270+enum {
2271+ /// Offset is relative to the next location containing data
2272+ SEEK_DATA = 3,
2273+ /// Offset is relative to the next hole (or EOF if file is not sparse)
2274+ SEEK_HOLE = 4
2275+}
2276+
2277+/// Prompt for a password without echoing it.
2278+char* getpass(const(char)* prompt);
2279+
2280+/// Close all open file descriptors greater or equal to `lowfd`
2281+void closefrom(int lowfd);
2282diff --git a/druntime/src/core/sys/linux/stdio.d b/druntime/src/core/sys/linux/stdio.d
2283index 2d079fd71f..0b2ea266b7 100644
2284--- a/druntime/src/core/sys/linux/stdio.d
2285+++ b/druntime/src/core/sys/linux/stdio.d
2286@@ -6,6 +6,7 @@
2287 * Authors: Danny Milosavljevic
2288 */
2289 module core.sys.linux.stdio;
2290+version (linux):
2291 version (CRuntime_Glibc):
2292 public import core.sys.posix.stdio;
2293 import core.sys.posix.sys.types : ssize_t, off64_t = off_t;
2294diff --git a/druntime/src/core/sys/posix/dirent.d b/druntime/src/core/sys/posix/dirent.d
2295index 0e822f556c..f576342bdc 100644
2296--- a/druntime/src/core/sys/posix/dirent.d
2297+++ b/druntime/src/core/sys/posix/dirent.d
2298@@ -158,6 +158,17 @@ else version (Solaris)
2299 char[1] d_name = 0;
2300 }
2301 }
2302+else version (Hurd)
2303+{
2304+ struct dirent
2305+ {
2306+ ino_t d_ino;
2307+ ushort d_reclen;
2308+ ubyte d_type;
2309+ ubyte d_namlen;
2310+ char[1] d_name = 0;
2311+ }
2312+}
2313 else
2314 {
2315 static assert(false, "Unsupported platform");
2316diff --git a/druntime/src/core/sys/posix/fcntl.d b/druntime/src/core/sys/posix/fcntl.d
2317index 4f7a22592d..1584c792bc 100644
2318--- a/druntime/src/core/sys/posix/fcntl.d
2319+++ b/druntime/src/core/sys/posix/fcntl.d
2320@@ -870,6 +870,113 @@ else version (Solaris)
2321 enum AT_REMOVEDIR = 0x1;
2322 enum AT_EACCESS = 0x4;
2323 }
2324+else version (Hurd)
2325+{
2326+ enum F_DUPFD = 0;
2327+ enum F_GETFD = 1;
2328+ enum F_SETFD = 2;
2329+ enum F_GETFL = 3;
2330+ enum F_SETFL = 4;
2331+ enum F_GETOWN = 5;
2332+ enum F_SETOWN = 6;
2333+
2334+ static if ( __USE_FILE_OFFSET64 )
2335+ {
2336+ enum F_GETLK = F_GETLK64;
2337+ enum F_SETLK = F_SETLK64;
2338+ enum F_SETLKW = F_SETLKW64;
2339+ }
2340+ else
2341+ {
2342+ enum F_GETLK = 7;
2343+ enum F_SETLK = 8;
2344+ enum F_SETLKW = 9;
2345+ }
2346+ enum F_GETLK64 = 10;
2347+ enum F_SETLK64 = 11;
2348+ enum F_SETLKW64 = 12;
2349+
2350+ enum F_DUPFD_CLOEXEC = 1030;
2351+
2352+ enum FD_CLOEXEC = 1;
2353+
2354+ enum F_RDLCK = 1;
2355+ enum F_WRLCK = 2;
2356+ enum F_UNLCK = 3;
2357+
2358+ enum O_CREAT = 0x0010;
2359+ enum O_EXCL = 0x0020;
2360+ enum O_NOCTTY = 0;
2361+ enum O_TRUNC = 0x00010000;
2362+
2363+ enum O_APPEND = 0x0100;
2364+ enum O_DSYNC = O_SYNC;
2365+ enum O_NONBLOCK = 0x0004;
2366+ enum O_RSYNC = O_SYNC;
2367+
2368+
2369+ enum O_ACCMODE = O_RDWR;
2370+ enum O_RDONLY = 0x0001;
2371+ enum O_WRONLY = 0x0002;
2372+ enum O_RDWR = (O_RDONLY|O_WRONLY);
2373+
2374+ enum O_SYNC = O_FSYNC;
2375+ enum O_FSYNC = 0x0400;
2376+
2377+ enum O_READ = O_RDONLY;
2378+ enum O_WRITE = O_WRONLY;
2379+ enum O_EXEC = 0x0004;
2380+ enum O_NORW = 0;
2381+ enum O_LARGEFILE = 0;
2382+ enum O_NOLINK = 0x0040;
2383+ enum O_NOTRANS = 0x0080;
2384+ enum O_NOFOLLOW = 0x00100000;
2385+ enum O_DIRECTORY = 0x00200000;
2386+ enum O_ASYNC = 0x0200;
2387+ enum O_NOATIME = 0x0800;
2388+ enum O_SHLOCK = 0x00020000;
2389+ enum O_EXLOCK = 0x00040000;
2390+ enum O_NDELAY = O_NONBLOCK;
2391+ enum O_HURD = (0xffff | O_EXLOCK | O_SHLOCK);
2392+ enum O_CLOEXEC = 0x00400000;
2393+ enum O_TMPFILE = 0x00800000;
2394+ enum O_IGNORE_CTTY = 0x00080000;
2395+
2396+
2397+ version (X86)
2398+ {
2399+ struct flock
2400+ {
2401+ int l_type;
2402+ int l_whence;
2403+ off_t l_start;
2404+ off_t l_len;
2405+ pid_t l_pid;
2406+ }
2407+ }
2408+ else version (X86_64)
2409+ {
2410+ struct flock
2411+ {
2412+ short l_type;
2413+ short l_whence;
2414+ off_t l_start;
2415+ off_t l_len;
2416+ pid_t l_pid;
2417+ }
2418+ }
2419+ else
2420+ {
2421+ static assert(false, "Unsupported platform");
2422+ }
2423+
2424+ enum AT_FDCWD = -100;
2425+
2426+ enum AT_EACCESS = 0x200;
2427+ enum AT_SYMLINK_NOFOLLOW = 0x100;
2428+ enum AT_SYMLINK_FOLLOW = 0x400;
2429+ enum AT_REMOVEDIR = 0x200;
2430+}
2431 else
2432 {
2433 static assert(false, "Unsupported platform");
2434diff --git a/druntime/src/core/sys/posix/netinet/in_.d b/druntime/src/core/sys/posix/netinet/in_.d
2435index 09a4a5e07d..5f9eaa80a1 100644
2436--- a/druntime/src/core/sys/posix/netinet/in_.d
2437+++ b/druntime/src/core/sys/posix/netinet/in_.d
2438@@ -85,18 +85,31 @@ version (CRuntime_Glibc)
2439 //{
2440 // in_addr_t s_addr;
2441 //}
2442+ version (linux)
2443+ {
2444+ private enum __SOCK_SIZE__ = 16;
2445
2446- private enum __SOCK_SIZE__ = 16;
2447+ struct sockaddr_in
2448+ {
2449+ sa_family_t sin_family;
2450+ in_port_t sin_port;
2451+ in_addr sin_addr;
2452
2453- struct sockaddr_in
2454+ /* Pad to size of `struct sockaddr'. */
2455+ ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -
2456+ in_port_t.sizeof - in_addr.sizeof] __pad;
2457+ }
2458+ }
2459+ else version (Hurd)
2460 {
2461- sa_family_t sin_family;
2462- in_port_t sin_port;
2463- in_addr sin_addr;
2464-
2465- /* Pad to size of `struct sockaddr'. */
2466- ubyte[__SOCK_SIZE__ - sa_family_t.sizeof -
2467- in_port_t.sizeof - in_addr.sizeof] __pad;
2468+ struct sockaddr_in
2469+ {
2470+ ubyte sin_len;
2471+ sa_family_t sin_family;
2472+ in_port_t sin_port;
2473+ in_addr sin_addr;
2474+ ubyte[8] sin_zero;
2475+ }
2476 }
2477
2478 enum
2479@@ -513,13 +526,28 @@ version (CRuntime_Glibc)
2480 }
2481 }
2482
2483- struct sockaddr_in6
2484+ version (linux)
2485 {
2486- sa_family_t sin6_family;
2487- in_port_t sin6_port;
2488- uint32_t sin6_flowinfo;
2489- in6_addr sin6_addr;
2490- uint32_t sin6_scope_id;
2491+ struct sockaddr_in6
2492+ {
2493+ ushort sin6_family;
2494+ uint16_t sin6_port;
2495+ uint32_t sin6_flowinfo;
2496+ in6_addr sin6_addr;
2497+ uint32_t sin6_scope_id;
2498+ }
2499+ }
2500+ else version (Hurd)
2501+ {
2502+ struct sockaddr_in6
2503+ {
2504+ uint8_t sin6_len;
2505+ sa_family_t sin6_family;
2506+ uint16_t sin6_port;
2507+ uint32_t sin6_flowinfo;
2508+ in6_addr sin6_addr;
2509+ uint32_t sin6_scope_id;
2510+ }
2511 }
2512
2513 extern __gshared immutable in6_addr in6addr_any;
2514diff --git a/druntime/src/core/sys/posix/poll.d b/druntime/src/core/sys/posix/poll.d
2515index 5901f62b5c..eeaea0b364 100644
2516--- a/druntime/src/core/sys/posix/poll.d
2517+++ b/druntime/src/core/sys/posix/poll.d
2518@@ -338,6 +338,22 @@ else version (Solaris)
2519 POLLNVAL = 0x0020,
2520 }
2521 }
2522+else version (Hurd)
2523+{
2524+ enum
2525+ {
2526+ POLLIN = 0x001,
2527+ POLLRDNORM = POLLIN,
2528+ POLLRDBAND = POLLPRI,
2529+ POLLPRI = 0x002,
2530+ POLLOUT = 0x004,
2531+ POLLWRNORM = POLLOUT,
2532+ POLLWRBAND = POLLOUT,
2533+ POLLERR = 0x008, /* ocatal 010 */
2534+ POLLHUP = 0x010, /* ocatal 020 */
2535+ POLLNVAL = 0x020, /* ocatal 040 */
2536+ }
2537+}
2538 else
2539 {
2540 static assert(false, "Unsupported platform");
2541diff --git a/druntime/src/core/sys/posix/pthread.d b/druntime/src/core/sys/posix/pthread.d
2542index 86844f9c5c..abfbae335d 100644
2543--- a/druntime/src/core/sys/posix/pthread.d
2544+++ b/druntime/src/core/sys/posix/pthread.d
2545@@ -104,41 +104,83 @@ void pthread_testcancel();
2546 */
2547 version (CRuntime_Glibc)
2548 {
2549- enum
2550+ version (linux)
2551 {
2552- PTHREAD_CANCEL_ENABLE,
2553- PTHREAD_CANCEL_DISABLE
2554- }
2555+ enum
2556+ {
2557+ PTHREAD_CANCEL_ENABLE,
2558+ PTHREAD_CANCEL_DISABLE
2559+ }
2560
2561- enum
2562- {
2563- PTHREAD_CANCEL_DEFERRED,
2564- PTHREAD_CANCEL_ASYNCHRONOUS
2565- }
2566+ enum
2567+ {
2568+ PTHREAD_CANCEL_DEFERRED,
2569+ PTHREAD_CANCEL_ASYNCHRONOUS
2570+ }
2571
2572- enum PTHREAD_CANCELED = cast(void*) -1;
2573+ enum PTHREAD_CANCELED = cast(void*) -1;
2574
2575- //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
2576+ //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
2577
2578- enum
2579- {
2580- PTHREAD_CREATE_JOINABLE,
2581- PTHREAD_CREATE_DETACHED
2582- }
2583+ enum
2584+ {
2585+ PTHREAD_CREATE_JOINABLE,
2586+ PTHREAD_CREATE_DETACHED
2587+ }
2588
2589- enum
2590- {
2591- PTHREAD_INHERIT_SCHED,
2592- PTHREAD_EXPLICIT_SCHED
2593- }
2594+ enum
2595+ {
2596+ PTHREAD_INHERIT_SCHED,
2597+ PTHREAD_EXPLICIT_SCHED
2598+ }
2599
2600- enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
2601- enum PTHREAD_ONCE_INIT = pthread_once_t.init;
2602+ enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
2603+ enum PTHREAD_ONCE_INIT = pthread_once_t.init;
2604
2605- enum
2606+ enum
2607+ {
2608+ PTHREAD_PROCESS_PRIVATE,
2609+ PTHREAD_PROCESS_SHARED
2610+ }
2611+ }
2612+ else version (Hurd)
2613 {
2614- PTHREAD_PROCESS_PRIVATE,
2615- PTHREAD_PROCESS_SHARED
2616+ enum
2617+ {
2618+ PTHREAD_CANCEL_DISABLE,
2619+ PTHREAD_CANCEL_ENABLE,
2620+ }
2621+
2622+ enum
2623+ {
2624+ PTHREAD_CANCEL_DEFERRED,
2625+ PTHREAD_CANCEL_ASYNCHRONOUS
2626+ }
2627+
2628+ enum PTHREAD_CANCELED = cast(void*) -1;
2629+
2630+ // enum __pthread_cond PTHREAD_COND_INITIALIZER = { __PTHREAD_SPIN_LOCK_INITIALIZER, NULL, NULL, 0, NULL }
2631+
2632+ enum
2633+ {
2634+ PTHREAD_CREATE_JOINABLE = 0,
2635+ PTHREAD_CREATE_DETACHED,
2636+ }
2637+
2638+ enum
2639+ {
2640+ PTHREAD_EXPLICIT_SCHED = 0,
2641+ PTHREAD_INHERIT_SCHED ,
2642+ }
2643+
2644+ enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
2645+ enum PTHREAD_ONCE_INIT = pthread_once_t.init;
2646+
2647+ enum
2648+ {
2649+ PTHREAD_PROCESS_PRIVATE = 0,
2650+ PTHREAD_PROCESS_SHARED,
2651+ }
2652 }
2653 }
2654 else version (Darwin)
2655@@ -477,32 +519,70 @@ alias void function(void*) _pthread_cleanup_routine;
2656 alias void function(void*) @nogc _pthread_cleanup_routine_nogc;
2657 version (CRuntime_Glibc)
2658 {
2659- struct _pthread_cleanup_buffer
2660+ version (linux)
2661 {
2662- _pthread_cleanup_routine __routine;
2663- void* __arg;
2664- int __canceltype;
2665- _pthread_cleanup_buffer* __prev;
2666- }
2667+ struct _pthread_cleanup_buffer
2668+ {
2669+ _pthread_cleanup_routine __routine;
2670+ void* __arg;
2671+ int __canceltype;
2672+ _pthread_cleanup_buffer* __prev;
2673+ }
2674
2675- void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);
2676- void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;
2677- void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
2678+ void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);
2679+ void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;
2680+ void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
2681
2682- struct pthread_cleanup
2683- {
2684- _pthread_cleanup_buffer buffer = void;
2685+ struct pthread_cleanup
2686+ {
2687+ _pthread_cleanup_buffer buffer = void;
2688
2689- extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )
2690+ extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg )
2691+ {
2692+ _pthread_cleanup_push( &buffer, routine, arg );
2693+ }
2694+
2695+ extern (D) void pop()( int execute )
2696+ {
2697+ _pthread_cleanup_pop( &buffer, execute );
2698+ }
2699+ }
2700+ }
2701+ else version (Hurd)
2702+ {
2703+ struct __pthread_cancelation_handler
2704 {
2705- _pthread_cleanup_push( &buffer, routine, arg );
2706+ _pthread_cleanup_routine __handler;
2707+ void* __arg;
2708+ __pthread_cancelation_handler* __next;
2709 }
2710
2711- extern (D) void pop()( int execute )
2712+ private __pthread_cancelation_handler** __pthread_get_cleanup_stack();
2713+
2714+ struct pthread_cleanup
2715 {
2716- _pthread_cleanup_pop( &buffer, execute );
2717+ __pthread_cancelation_handler** handlers = void;
2718+ __pthread_cancelation_handler handler = void;
2719+
2720+ extern (D) void push(F: _pthread_cleanup_routine)(F routine, void* arg)
2721+ {
2722+ handlers = __pthread_get_cleanup_stack();
2723+ handler = __pthread_cancelation_handler(routine, arg, *handlers);
2724+ *handlers = &handler;
2725+ }
2726+ extern (D) void pop()(int execute)
2727+ {
2728+ if (execute)
2729+ handler.__handler(handler.__arg);
2730+ *handlers = handler.__next;
2731+ }
2732 }
2733 }
2734+ else
2735+ {
2736+ static assert(false, "Unsupported platform");
2737+ }
2738+
2739 }
2740 else version (Darwin)
2741 {
2742@@ -1064,9 +1144,24 @@ int pthread_setconcurrency(int);
2743
2744 version (CRuntime_Glibc)
2745 {
2746- enum PTHREAD_MUTEX_NORMAL = 0;
2747- enum PTHREAD_MUTEX_RECURSIVE = 1;
2748- enum PTHREAD_MUTEX_ERRORCHECK = 2;
2749+
2750+ version(linux)
2751+ {
2752+ enum PTHREAD_MUTEX_NORMAL = 0;
2753+ enum PTHREAD_MUTEX_RECURSIVE = 1;
2754+ enum PTHREAD_MUTEX_ERRORCHECK = 2;
2755+ }
2756+ else version(Hurd)
2757+ {
2758+ enum PTHREAD_MUTEX_NORMAL = 0;
2759+ enum PTHREAD_MUTEX_ERRORCHECK = 1;
2760+ enum PTHREAD_MUTEX_RECURSIVE = 2;
2761+
2762+ }
2763+ else
2764+ {
2765+ static assert(false, "Unsupported platform");
2766+ }
2767 enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
2768
2769 int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
2770@@ -1400,6 +1495,22 @@ else version (Solaris)
2771 int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
2772 int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
2773 }
2774+else version (Hurd)
2775+{
2776+ enum
2777+ {
2778+ PTHREAD_PRIO_NONE = 0,
2779+ PTHREAD_PRIO_INHERIT,
2780+ PTHREAD_PRIO_PROTECT,
2781+ }
2782+
2783+ int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*);
2784+ int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);
2785+ int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*);
2786+ int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*);
2787+ int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
2788+ int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
2789+}
2790
2791 //
2792 // Scheduling (TPS)
2793@@ -1421,10 +1532,21 @@ int pthread_setschedprio(pthread_t, int);
2794
2795 version (CRuntime_Glibc)
2796 {
2797- enum
2798+ version (linux)
2799 {
2800- PTHREAD_SCOPE_SYSTEM,
2801- PTHREAD_SCOPE_PROCESS
2802+ enum
2803+ {
2804+ PTHREAD_SCOPE_SYSTEM,
2805+ PTHREAD_SCOPE_PROCESS
2806+ }
2807+ }
2808+ else version (Hurd)
2809+ {
2810+ enum
2811+ {
2812+ PTHREAD_SCOPE_SYSTEM = 0,
2813+ PTHREAD_SCOPE_PROCESS,
2814+ }
2815 }
2816
2817 int pthread_attr_getinheritsched(const scope pthread_attr_t*, int*);
2818diff --git a/druntime/src/core/sys/posix/sched.d b/druntime/src/core/sys/posix/sched.d
2819index d579835841..8b0ccea877 100644
2820--- a/druntime/src/core/sys/posix/sched.d
2821+++ b/druntime/src/core/sys/posix/sched.d
2822@@ -169,6 +169,17 @@ else version (Solaris)
2823 enum SCHED_FX = 6;
2824 enum _SCHED_NEXT = 7;
2825 }
2826+else version (Hurd)
2827+{
2828+ struct sched_param
2829+ {
2830+ int sched_priority;
2831+ }
2832+
2833+ enum SCHED_FIFO = 1;
2834+ enum SCHED_OTHER = 0;
2835+ enum SCHED_RR = 2;
2836+}
2837 else
2838 {
2839 static assert(false, "Unsupported platform");
2840diff --git a/druntime/src/core/sys/posix/semaphore.d b/druntime/src/core/sys/posix/semaphore.d
2841index 4f3b6e951c..ead305cced 100644
2842--- a/druntime/src/core/sys/posix/semaphore.d
2843+++ b/druntime/src/core/sys/posix/semaphore.d
2844@@ -51,19 +51,31 @@ int sem_wait(sem_t*);
2845
2846 version (CRuntime_Glibc)
2847 {
2848- private alias int __atomic_lock_t;
2849-
2850- private struct _pthread_fastlock
2851+ version(linux)
2852 {
2853- c_long __status;
2854- __atomic_lock_t __spinlock;
2855- }
2856+ private alias int __atomic_lock_t;
2857
2858- struct sem_t
2859+ private struct _pthread_fastlock
2860+ {
2861+ c_long __status;
2862+ __atomic_lock_t __spinlock;
2863+ }
2864+
2865+ struct sem_t
2866+ {
2867+ _pthread_fastlock __sem_lock;
2868+ int __sem_value;
2869+ void* __sem_waiting;
2870+ }
2871+ }
2872+ else version (Hurd)
2873 {
2874- _pthread_fastlock __sem_lock;
2875- int __sem_value;
2876- void* __sem_waiting;
2877+ private enum __SIZEOF_SEM_T = 20;
2878+ union sem_t
2879+ {
2880+ byte[__SIZEOF_SEM_T] __size;
2881+ c_long __align;
2882+ }
2883 }
2884
2885 enum SEM_FAILED = cast(sem_t*) null;
2886diff --git a/druntime/src/core/sys/posix/signal.d b/druntime/src/core/sys/posix/signal.d
2887index bdc68687d0..9703ac9707 100644
2888--- a/druntime/src/core/sys/posix/signal.d
2889+++ b/druntime/src/core/sys/posix/signal.d
2890@@ -168,6 +168,9 @@ else version (NetBSD)
2891 enum SIGRTMIN = 33;
2892 enum SIGRTMAX = 63;
2893 }
2894+else version (Hurd)
2895+{
2896+}
2897 else version (linux)
2898 {
2899 // Note: CRuntime_Bionic switched to calling these functions
2900@@ -561,6 +564,24 @@ else version (Solaris)
2901 enum SIGUSR2 = 17;
2902 enum SIGURG = 21;
2903 }
2904+else version (Hurd)
2905+{
2906+ enum SIGALRM = 14;
2907+ enum SIGBUS = 10;
2908+ enum SIGCHLD = 20;
2909+ enum SIGCONT = 19;
2910+ enum SIGHUP = 1;
2911+ enum SIGKILL = 9;
2912+ enum SIGPIPE = 13;
2913+ enum SIGQUIT = 3;
2914+ enum SIGSTOP = 17;
2915+ enum SIGTSTP = 18;
2916+ enum SIGTTIN = 21;
2917+ enum SIGTTOU = 22;
2918+ enum SIGUSR1 = 30;
2919+ enum SIGUSR2 = 31;
2920+ enum SIGURG = 16;
2921+}
2922 else
2923 {
2924 static assert(false, "Unsupported platform");
2925@@ -848,6 +869,26 @@ else version (Darwin)
2926 int sa_flags;
2927 }
2928 }
2929+else version (Hurd)
2930+{
2931+ struct sigaction_t
2932+ {
2933+ static if ( true /* __USE_POSIX199309 */ )
2934+ {
2935+ union
2936+ {
2937+ sigfn_t sa_handler;
2938+ sigactfn_t sa_sigaction;
2939+ }
2940+ }
2941+ else
2942+ {
2943+ sigfn_t sa_handler;
2944+ }
2945+ sigset_t sa_mask;
2946+ int sa_flags;
2947+ }
2948+}
2949 else
2950 {
2951 static assert(false, "Unsupported platform");
2952@@ -1417,6 +1458,41 @@ else version (Solaris)
2953 enum SI_ASYNCIO = -4;
2954 enum SI_MESGQ = -5;
2955 }
2956+else version(Hurd)
2957+{
2958+ enum SIG_HOLD = cast(sigfn_t2) 2;
2959+
2960+ alias c_ulong sigset_t;
2961+
2962+ enum SA_NOCLDSTOP = 0x0008; // (CX|XSI)
2963+
2964+ enum SIG_BLOCK = 1;
2965+ enum SIG_UNBLOCK = 2;
2966+ enum SIG_SETMASK = 3;
2967+
2968+ struct siginfo_t
2969+ {
2970+ int si_signo;
2971+ int si_errno;
2972+ int si_code;
2973+
2974+ pid_t si_pid;
2975+ uid_t si_uid;
2976+ void* si_addr;
2977+ int si_status;
2978+ c_long si_band;
2979+ sigval si_value;
2980+ }
2981+
2982+ enum
2983+ {
2984+ SI_ASYNCIO = -4,
2985+ SI_MESGQ,
2986+ SI_TIMER,
2987+ SI_QUEUE,
2988+ SI_USER
2989+ }
2990+}
2991 else
2992 {
2993 static assert(false, "Unsupported platform");
2994@@ -2375,6 +2451,89 @@ else version (Solaris)
2995 POLL_HUP,
2996 }
2997 }
2998+else version(Hurd)
2999+{
3000+ enum SIGPOLL = 23;
3001+ enum SIGPROF = 27;
3002+ enum SIGSYS = 12;
3003+ enum SIGTRAP = 5;
3004+ enum SIGVTALRM = 26;
3005+ enum SIGXCPU = 24;
3006+ enum SIGXFSZ = 25;
3007+
3008+ enum
3009+ {
3010+ SA_ONSTACK = 0x0001,
3011+ SA_RESETHAND = 0x0004,
3012+ SA_RESTART = 0x0002,
3013+ SA_SIGINFO = 0x0040,
3014+ // SA_NOCLDWAIT = ,
3015+ SA_NODEFER = 0x00010,
3016+ }
3017+
3018+ enum
3019+ {
3020+ ILL_ILLOPC = 1,
3021+ ILL_ILLOPN,
3022+ ILL_ILLADR,
3023+ ILL_ILLTRP,
3024+ ILL_PRVOPC,
3025+ ILL_PRVREG,
3026+ ILL_COPROC,
3027+ ILL_BADSTK
3028+ }
3029+
3030+ enum
3031+ {
3032+ FPE_INTDIV = 1,
3033+ FPE_INTOVF,
3034+ FPE_FLTDIV,
3035+ FPE_FLTOVF,
3036+ FPE_FLTUND,
3037+ FPE_FLTRES,
3038+ FPE_FLTINV,
3039+ FPE_FLTSUB
3040+ }
3041+
3042+ enum
3043+ {
3044+ SEGV_MAPERR = 1,
3045+ SEGV_ACCERR
3046+ }
3047+
3048+ enum
3049+ {
3050+ BUS_ADRALN = 1,
3051+ BUS_ADRERR,
3052+ BUS_OBJERR
3053+ }
3054+
3055+ enum
3056+ {
3057+ TRAP_BRKPT = 1,
3058+ TRAP_TRACE
3059+ }
3060+
3061+ enum
3062+ {
3063+ CLD_EXITED = 1,
3064+ CLD_KILLED,
3065+ CLD_DUMPED,
3066+ CLD_TRAPPED,
3067+ CLD_STOPPED,
3068+ CLD_CONTINUED
3069+ }
3070+
3071+ enum
3072+ {
3073+ POLL_IN = 1,
3074+ POLL_OUT,
3075+ POLL_MSG,
3076+ POLL_ERR,
3077+ POLL_PRI,
3078+ POLL_HUP
3079+ }
3080+}
3081 else
3082 {
3083 static assert(false, "Unsupported platform");
3084@@ -2416,11 +2575,21 @@ int sigrelse(int);
3085
3086 version (CRuntime_Glibc)
3087 {
3088- enum SS_ONSTACK = 1;
3089- enum SS_DISABLE = 2;
3090- enum MINSIGSTKSZ = 2048;
3091- enum SIGSTKSZ = 8192;
3092+ version (linux)
3093+ {
3094+ enum SS_ONSTACK = 1;
3095+ enum SS_DISABLE = 2;
3096+ enum MINSIGSTKSZ = 2048;
3097+ enum SIGSTKSZ = 8192;
3098+ }
3099
3100+ version (Hurd)
3101+ {
3102+ enum SS_ONSTACK = 0x0001;
3103+ enum SS_DISABLE = 0x0004;
3104+ enum MINSIGSTKSZ = 8192;
3105+ enum SIGSTKSZ = (MINSIGSTKSZ + 32768);
3106+ }
3107 //ucontext_t (defined in core.sys.posix.ucontext)
3108 //mcontext_t (defined in core.sys.posix.ucontext)
3109
3110@@ -2990,6 +3159,18 @@ else version (Solaris)
3111 int __sigev_pad2;
3112 }
3113 }
3114+else version (Hurd)
3115+{
3116+ struct sigevent
3117+ {
3118+ sigval sigev_value;
3119+ int sigev_signo;
3120+ int sigev_notify;
3121+
3122+ void function(sigval) sigev_notify_function;
3123+ void* sigev_notify_attributes;
3124+ }
3125+}
3126 else
3127 {
3128 static assert(false, "Unsupported platform");
3129diff --git a/druntime/src/core/sys/posix/spawn.d b/druntime/src/core/sys/posix/spawn.d
3130index 081270b42c..ece7ff7e25 100644
3131--- a/druntime/src/core/sys/posix/spawn.d
3132+++ b/druntime/src/core/sys/posix/spawn.d
3133@@ -34,6 +34,8 @@ OpenBSD: https://github.com/openbsd/src/blob/master/include/spawn.h
3134 DragonFlyBSD: https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/include/spawn.h
3135
3136 Solaris: https://github.com/illumos/illumos-gate/blob/master/usr/src/head/spawn.h
3137+
3138+Hurd: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD
3139 */
3140
3141 version (OSX) // macOS and iOS only as this API is prohibited on WatchOS and TVOS
3142@@ -370,5 +372,45 @@ else version (Solaris)
3143 int posix_spawnattr_setsigignore_np(posix_spawnattr_t* attr, const sigset_t* sigignore);
3144 }
3145 }
3146+else version (Hurd)
3147+{
3148+ // Source: https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/spawn.h;hb=HEAD
3149+ enum
3150+ {
3151+ POSIX_SPAWN_RESETIDS = 0x01,
3152+ POSIX_SPAWN_SETPGROUP = 0x02,
3153+ POSIX_SPAWN_SETSIGDEF = 0x04,
3154+ POSIX_SPAWN_SETSIGMASK = 0x08,
3155+ POSIX_SPAWN_SETSCHEDPARAM = 0x10,
3156+ POSIX_SPAWN_SETSCHEDULER = 0x20,
3157+ }
3158+ import core.sys.posix.config : _GNU_SOURCE;
3159+ static if (_GNU_SOURCE)
3160+ {
3161+ enum
3162+ {
3163+ POSIX_SPAWN_USEVFORK = 0x40,
3164+ POSIX_SPAWN_SETSID = 0x80
3165+ }
3166+ }
3167+ struct posix_spawnattr_t
3168+ {
3169+ short __flags;
3170+ pid_t __pgrp;
3171+ sigset_t __sd;
3172+ sigset_t __ss;
3173+ sched_param __sp;
3174+ int __policy;
3175+ int[16] __pad;
3176+ }
3177+ private struct __spawn_action;
3178+ struct posix_spawn_file_actions_t
3179+ {
3180+ int __allocated;
3181+ int __used;
3182+ __spawn_action* __actions;
3183+ int[16] __pad;
3184+ }
3185+}
3186 else
3187 static assert(0, "Unsupported OS");
3188diff --git a/druntime/src/core/sys/posix/sys/ioctl.d b/druntime/src/core/sys/posix/sys/ioctl.d
3189index 27584d357c..56bc87e252 100644
3190--- a/druntime/src/core/sys/posix/sys/ioctl.d
3191+++ b/druntime/src/core/sys/posix/sys/ioctl.d
3192@@ -400,6 +400,43 @@ else version (DragonFlyBSD)
3193 else version (Solaris)
3194 {
3195 }
3196+else version (Hurd)
3197+{
3198+ struct tchars
3199+ {
3200+ char t_intrc;
3201+ char t_quitc;
3202+ char t_startc;
3203+ char t_stopc;
3204+ char t_eofc;
3205+ char t_brkc;
3206+ }
3207+ struct ltchars
3208+ {
3209+ char t_suspc;
3210+ char t_dsuspc;
3211+ char t_rprntc;
3212+ char t_flushc;
3213+ char t_werasc;
3214+ char t_lnextc;
3215+ }
3216+ struct sgttyb
3217+ {
3218+ char sg_ispeed;
3219+ char sg_ospeed;
3220+ char sg_erase;
3221+ char sg_kill;
3222+ short sg_flags;
3223+ }
3224+
3225+ struct winsize
3226+ {
3227+ ushort ws_row;
3228+ ushort ws_col;
3229+ ushort ws_xpixel;
3230+ ushort ws_ypixel;
3231+ }
3232+}
3233 else
3234 {
3235 static assert(false, "Unsupported platform");
3236diff --git a/druntime/src/core/sys/posix/sys/ipc.d b/druntime/src/core/sys/posix/sys/ipc.d
3237index 32caba95a1..1d12841fff 100644
3238--- a/druntime/src/core/sys/posix/sys/ipc.d
3239+++ b/druntime/src/core/sys/posix/sys/ipc.d
3240@@ -246,6 +246,49 @@ else version (Solaris)
3241 enum IPC_SET = 11;
3242 enum IPC_STAT = 12;
3243 }
3244+else version (Hurd)
3245+{
3246+ version (X86)
3247+ {
3248+ struct ipc_perm
3249+ {
3250+ key_t __key;
3251+ ushort uid;
3252+ ushort gid;
3253+ ushort cuid;
3254+ ushort cgid;
3255+ ushort mode;
3256+ ushort __seq;
3257+ }
3258+ }
3259+ else version (X86_64)
3260+ {
3261+ struct ipc_perm
3262+ {
3263+ key_t __key;
3264+ uid_t uid;
3265+ gid_t gid;
3266+ uid_t cuid;
3267+ gid_t cgid;
3268+ mode_t mode;
3269+ ushort __seq;
3270+ }
3271+ }
3272+ else
3273+ {
3274+ static assert(false, "Unsupported platform");
3275+ }
3276+
3277+ enum IPC_CREAT = 0x0200; // 01000
3278+ enum IPC_EXCL = 0x0400; // 02000
3279+ enum IPC_NOWAIT = 0x0800; // 04000
3280+
3281+ enum key_t IPC_PRIVATE = 0;
3282+
3283+ enum IPC_RMID = 0;
3284+ enum IPC_SET = 1;
3285+ enum IPC_STAT = 2;
3286+}
3287 else
3288 {
3289 static assert(false, "Unsupported platform");
3290diff --git a/druntime/src/core/sys/posix/sys/mman.d b/druntime/src/core/sys/posix/sys/mman.d
3291index 42da553c40..538588dd3f 100644
3292--- a/druntime/src/core/sys/posix/sys/mman.d
3293+++ b/druntime/src/core/sys/posix/sys/mman.d
3294@@ -170,6 +170,14 @@ else version (DragonFlyBSD)
3295 else version (Solaris)
3296 {
3297 }
3298+else version (Hurd)
3299+{
3300+ enum POSIX_MADV_NORMAL = 0;
3301+ enum POSIX_MADV_RANDOM = 1;
3302+ enum POSIX_MADV_SEQUENTIAL = 2;
3303+ enum POSIX_MADV_WILLNEED = 3;
3304+ enum POSIX_MADV_DONTNEED = 4;
3305+}
3306 else
3307 {
3308 static assert(false, "Unsupported platform");
3309@@ -234,6 +242,13 @@ else version (Solaris)
3310 enum PROT_WRITE = 0x02;
3311 enum PROT_EXEC = 0x04;
3312 }
3313+else version (Hurd)
3314+{
3315+ enum PROT_NONE = 0x00;
3316+ enum PROT_READ = 0x04;
3317+ enum PROT_WRITE = 0x02;
3318+ enum PROT_EXEC = 0x01;
3319+}
3320 else
3321 {
3322 static assert(false, "Unsupported platform");
3323@@ -474,6 +489,19 @@ else version (Solaris)
3324 enum MS_SYNC = 0x0004;
3325 enum MS_ASYNC = 0x0001;
3326 enum MS_INVALIDATE = 0x0002;
3327+}
3328+ else version (Hurd)
3329+{
3330+ enum MAP_SHARED = 0x0010;
3331+ enum MAP_PRIVATE = 0x0000;
3332+ enum MAP_FIXED = 0x0100;
3333+ enum MAP_ANON = 0x0002;
3334+
3335+ enum MAP_FAILED = cast(void*)-1;
3336+
3337+ enum MS_ASYNC = 1;
3338+ enum MS_INVALIDATE = 0;
3339+ enum MS_SYNC = 2;
3340 }
3341 else
3342 {
3343@@ -591,6 +619,11 @@ else version (Solaris)
3344 enum MCL_CURRENT = 0x0001;
3345 enum MCL_FUTURE = 0x0002;
3346 }
3347+else version (Hurd)
3348+{
3349+ enum MCL_CURRENT = 0x0001;
3350+ enum MCL_FUTURE = 0x0002;
3351+}
3352 else
3353 {
3354 static assert(false, "Unsupported platform");
3355diff --git a/druntime/src/core/sys/posix/sys/msg.d b/druntime/src/core/sys/posix/sys/msg.d
3356index 19e07bd646..f6b353bf56 100644
3357--- a/druntime/src/core/sys/posix/sys/msg.d
3358+++ b/druntime/src/core/sys/posix/sys/msg.d
3359@@ -173,6 +173,50 @@ version (linux)
3360 }
3361 }
3362 }
3363+else version (Hurd)
3364+{
3365+ import core.sys.hurd.sys.types;
3366+ enum MSG_STAT = 11;
3367+ enum MSG_INFO = 12;
3368+
3369+ enum MSG_NOERROR = 1 << 12; // octal!10000
3370+ enum MSG_EXCEPT = 2 << 12; // octal!20000
3371+
3372+ struct msginfo
3373+ {
3374+ int msgpool;
3375+ int msgmap;
3376+ int msgmax;
3377+ int msgmnb;
3378+ int msgmni;
3379+ int msgssz;
3380+ int msgtql;
3381+ ushort msgseg;
3382+ }
3383+
3384+ alias ushort msgqnum_t;
3385+ alias ushort msglen_t;
3386+
3387+ private struct msg;
3388+ private struct __wait_queue;
3389+
3390+ struct msqid_ds
3391+ {
3392+ ipc_perm msg_perm;
3393+ msg *__msg_first;
3394+ msg *__msg_last;
3395+ time_t msg_stime;
3396+ time_t msg_rtime;
3397+ time_t msg_ctime;
3398+ __wait_queue *__wwait;
3399+ __wait_queue *__rwait;
3400+ ushort __msg_cbytes;
3401+ msgqnum_t msg_qnum;
3402+ msglen_t msg_qbytes;
3403+ ipc_pid_t msg_lspid;
3404+ ipc_pid_t msg_lrpid;
3405+ }
3406+}
3407 else
3408 {
3409 // https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/msq.h
3410diff --git a/druntime/src/core/sys/posix/sys/resource.d b/druntime/src/core/sys/posix/sys/resource.d
3411index b75c794e92..a5cb7f5a3c 100644
3412--- a/druntime/src/core/sys/posix/sys/resource.d
3413+++ b/druntime/src/core/sys/posix/sys/resource.d
3414@@ -477,6 +477,64 @@ else version (Solaris)
3415 RLIMIT_AS = 6,
3416 }
3417 }
3418+else version (Hurd)
3419+{
3420+ enum
3421+ {
3422+ PRIO_PROCESS = 0,
3423+ PRIO_PGRP = 1,
3424+ PRIO_USER = 2,
3425+ }
3426+
3427+ static if (__USE_FILE_OFFSET64)
3428+ alias ulong rlim_t;
3429+ else
3430+ alias c_ulong rlim_t;
3431+
3432+ static if (__USE_FILE_OFFSET64)
3433+ enum RLIM_INFINITY = 0xffffffffffffffffUL;
3434+ else
3435+ enum RLIM_INFINITY = cast(c_ulong)(~0UL);
3436+
3437+ enum RLIM_SAVED_MAX = RLIM_INFINITY;
3438+ enum RLIM_SAVED_CUR = RLIM_INFINITY;
3439+
3440+ enum
3441+ {
3442+ RUSAGE_SELF = 0,
3443+ RUSAGE_CHILDREN = -1,
3444+ }
3445+
3446+ struct rusage
3447+ {
3448+ timeval ru_utime;
3449+ timeval ru_stime;
3450+ c_long ru_maxrss;
3451+ c_long ru_ixrss;
3452+ c_long ru_idrss;
3453+ c_long ru_isrss;
3454+ c_long ru_minflt;
3455+ c_long ru_majflt;
3456+ c_long ru_nswap;
3457+ c_long ru_inblock;
3458+ c_long ru_oublock;
3459+ c_long ru_msgsnd;
3460+ c_long ru_msgrcv;
3461+ c_long ru_nsignals;
3462+ c_long ru_nvcsw;
3463+ c_long ru_nivcsw;
3464+ }
3465+ enum
3466+ {
3467+ RLIMIT_CORE = 4,
3468+ RLIMIT_CPU = 0,
3469+ RLIMIT_DATA = 2,
3470+ RLIMIT_FSIZE = 1,
3471+ RLIMIT_NOFILE = 8,
3472+ RLIMIT_STACK = 3,
3473+ RLIMIT_AS = 10,
3474+ }
3475+}
3476 else
3477 static assert (false, "Unsupported platform");
3478
3479diff --git a/druntime/src/core/sys/posix/sys/shm.d b/druntime/src/core/sys/posix/sys/shm.d
3480index 7481d8cc60..25accfa715 100644
3481--- a/druntime/src/core/sys/posix/sys/shm.d
3482+++ b/druntime/src/core/sys/posix/sys/shm.d
3483@@ -180,6 +180,32 @@ else version (Darwin)
3484 else version (Solaris)
3485 {
3486
3487+}
3488+else version (Hurd)
3489+{
3490+ import core.sys.hurd.sys.types;
3491+ enum SHM_RDONLY = 0x01000; // 010000
3492+ enum SHM_RND = 0x02000; // 020000
3493+ enum SHM_REMAP = 0x4000; // 040000
3494+
3495+ alias short shmatt_t;
3496+
3497+ private struct __vm_area_struct;
3498+
3499+ struct shmid_ds
3500+ {
3501+ ipc_perm shm_perm;
3502+ size_t shm_segsz;
3503+ time_t shm_atime;
3504+ time_t shm_dtime;
3505+ time_t shm_ctime;
3506+ ipc_pid_t shm_cpid;
3507+ ipc_pid_t shm_lpid;
3508+ shmatt_t shm_nattch;
3509+ private ushort __shm_npages;
3510+ private c_ulong* __shm_pages;
3511+ private __vm_area_struct* __attaches;
3512+ }
3513 }
3514 else
3515 {
3516diff --git a/druntime/src/core/sys/posix/sys/socket.d b/druntime/src/core/sys/posix/sys/socket.d
3517index 5bdc22294c..00b99e71eb 100644
3518--- a/druntime/src/core/sys/posix/sys/socket.d
3519+++ b/druntime/src/core/sys/posix/sys/socket.d
3520@@ -1598,6 +1598,153 @@ else version (Solaris)
3521 SHUT_RDWR
3522 }
3523 }
3524+else version (Hurd)
3525+{
3526+ alias uint socklen_t;
3527+ alias ubyte sa_family_t;
3528+
3529+ struct sockaddr
3530+ {
3531+ ubyte ss_len;
3532+ sa_family_t sa_family;
3533+ byte[14] sa_data;
3534+ }
3535+
3536+ private enum : size_t
3537+ {
3538+ _SS_SIZE = 128,
3539+ _SS_PADSIZE = _SS_SIZE - c_ulong.sizeof - sa_family_t.sizeof - ubyte.sizeof,
3540+ }
3541+
3542+ struct sockaddr_storage
3543+ {
3544+ ubyte ss_len;
3545+ sa_family_t ss_family;
3546+ byte[_SS_PADSIZE] __ss_padding;
3547+ c_ulong __ss_align;
3548+ }
3549+ struct msghdr
3550+ {
3551+ void* msg_name;
3552+ socklen_t msg_namelen;
3553+ iovec* msg_iov;
3554+ int msg_iovlen;
3555+ void* msg_control;
3556+ socklen_t msg_controllen;
3557+ int msg_flags;
3558+ }
3559+
3560+ struct cmsghdr
3561+ {
3562+ socklen_t cmsg_len;
3563+ int cmsg_level;
3564+ int cmsg_type;
3565+ }
3566+ enum : uint
3567+ {
3568+ SCM_RIGHTS = 0x01
3569+ }
3570+
3571+ extern (D) inout(ubyte)* CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
3572+ private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;
3573+ extern (D) inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc
3574+ {
3575+ return __cmsg_nxthdr(msg, cmsg);
3576+ }
3577+
3578+ extern (D) inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc
3579+ {
3580+ return ( cast(size_t)mhdr.msg_controllen >= cmsghdr.sizeof
3581+ ? cast(inout(cmsghdr)*) mhdr.msg_control
3582+ : cast(inout(cmsghdr)*) null );
3583+ }
3584+
3585+ extern (D)
3586+ {
3587+ size_t CMSG_ALIGN( size_t len ) pure nothrow @nogc
3588+ {
3589+ return (len + size_t.sizeof - 1) & cast(size_t) (~(size_t.sizeof - 1));
3590+ }
3591+
3592+ size_t CMSG_LEN( size_t len ) pure nothrow @nogc
3593+ {
3594+ return CMSG_ALIGN(cmsghdr.sizeof) + len;
3595+ }
3596+ }
3597+
3598+ extern (D) size_t CMSG_SPACE(size_t len) pure nothrow @nogc
3599+ {
3600+ return CMSG_ALIGN(len) + CMSG_ALIGN(cmsghdr.sizeof);
3601+ }
3602+ struct linger
3603+ {
3604+ int l_onoff;
3605+ int l_linger;
3606+ }
3607+
3608+ enum
3609+ {
3610+ SOCK_DGRAM = 2,
3611+ SOCK_RDM = 4,
3612+ SOCK_SEQPACKET = 5,
3613+ SOCK_STREAM = 1,
3614+ }
3615+ enum
3616+ {
3617+ SOL_SOCKET = 0xffff
3618+ }
3619+ enum
3620+ {
3621+ SO_ACCEPTCONN = 0x0002,
3622+ SO_BROADCAST = 0x0020,
3623+ SO_DEBUG = 0x0001,
3624+ SO_DONTROUTE = 0x0010,
3625+ SO_ERROR = 0x1007,
3626+ SO_KEEPALIVE = 0x0008,
3627+ SO_LINGER = 0x0080,
3628+ SO_OOBINLINE = 0x0100,
3629+ SO_RCVBUF = 0x1002,
3630+ SO_RCVLOWAT = 0x1004,
3631+ SO_RCVTIMEO = 0x1006,
3632+ SO_REUSEADDR = 0x0004,
3633+ SO_REUSEPORT = 0x0200,
3634+ SO_SNDBUF = 0x1002,
3635+ SO_SNDLOWAT = 0x1003,
3636+ SO_SNDTIMEO = 0x1005,
3637+ SO_TYPE = 0x1008
3638+ }
3639+ enum
3640+ {
3641+ SOMAXCONN = 128
3642+ }
3643+ enum : uint
3644+ {
3645+ MSG_CTRUNC = 0x20,
3646+ MSG_DONTROUTE = 0x04,
3647+ MSG_EOR = 0x08,
3648+ MSG_OOB = 0x01,
3649+ MSG_PEEK = 0x02,
3650+ MSG_TRUNC = 0x10,
3651+ MSG_WAITALL = 0x40,
3652+ MSG_NOSIGNAL = 0x0400
3653+ }
3654+
3655+ enum
3656+ {
3657+ AF_INET = 2,
3658+ AF_LOCAL = 1,
3659+ AF_UNIX = AF_LOCAL,
3660+ AF_UNSPEC = 0,
3661+ AF_APPLETALK = 16,
3662+ AF_IPX = 23
3663+ }
3664+ enum
3665+ {
3666+ SHUT_RD = 0,
3667+ SHUT_WR = 1,
3668+ SHUT_RDWR = 2
3669+ }
3670+}
3671 else
3672 {
3673 static assert(false, "Unsupported platform");
3674@@ -1899,6 +2046,13 @@ else version (Solaris)
3675 AF_INET6 = 26,
3676 }
3677 }
3678+else version (Hurd)
3679+{
3680+ enum
3681+ {
3682+ AF_INET6 = 26,
3683+ }
3684+}
3685 else
3686 {
3687 static assert(false, "Unsupported platform");
3688@@ -1960,6 +2114,13 @@ else version (Solaris)
3689 SOCK_RAW = 4,
3690 }
3691 }
3692+else version (Hurd)
3693+{
3694+ enum
3695+ {
3696+ SOCK_RAW = 3,
3697+ }
3698+}
3699 else
3700 {
3701 static assert(false, "Unsupported platform");
3702diff --git a/druntime/src/core/sys/posix/sys/stat.d b/druntime/src/core/sys/posix/sys/stat.d
3703index 762d6fcc76..5cd2c27914 100644
3704--- a/druntime/src/core/sys/posix/sys/stat.d
3705+++ b/druntime/src/core/sys/posix/sys/stat.d
3706@@ -1538,6 +1538,64 @@ else version (Solaris)
3707 enum S_ISGID = 0x400;
3708 enum S_ISVTX = 0x200;
3709 }
3710+else version (Hurd)
3711+{
3712+ import core.sys.hurd.sys.types;
3713+ static if (__USE_FILE_OFFSET64)
3714+ private enum SPARE_SIZE = 8;
3715+ else
3716+ private enum SPARE_SIZE = 11;
3717+
3718+ struct stat_t
3719+ {
3720+ int st_fstype; /* File system type. */
3721+ fsid_t st_fsid; /* File system ID. */
3722+ alias st_dev = st_fsid;
3723+ ino_t st_ino; /* File number. */
3724+ uint st_gen;
3725+ dev_t st_rdev;
3726+ mode_t st_mode;
3727+ nlink_t st_nlink;
3728+ uid_t st_uid;
3729+ gid_t st_gid;
3730+ off_t st_size;
3731+
3732+ static if (_DEFAULT_SOURCE || _XOPEN_SOURCE >= 700)
3733+ {
3734+ timespec st_atim;
3735+ timespec st_mtim;
3736+ timespec st_ctim;
3737+ extern(D) @safe @property inout pure nothrow
3738+ {
3739+ ref inout(time_t) st_atime() return { return st_atim.tv_sec; }
3740+ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; }
3741+ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; }
3742+ }
3743+ }
3744+ else
3745+ {
3746+ time_t st_atime;
3747+ c_ulong st_atimensec;
3748+ time_t st_mtime;
3749+ c_ulong st_mtimensec;
3750+ time_t st_ctime;
3751+ c_ulong st_ctimensec;
3752+ }
3753+
3754+ blksize_t st_blksize;
3755+ blkcnt_t st_blocks;
3756+
3757+ uid_t st_author;
3758+ uint st_flags;
3759+ int[SPARE_SIZE] st_spare;
3760+ }
3761+ version (X86) static assert(stat_t.sizeof == 128);
3762+ version (X86_64) static assert(stat_t.sizeof == 176);
3763+
3764+ enum S_ISUID = 0x800; // octal 0004000
3765+ enum S_ISGID = 0x400; // octal 0002000
3766+ enum S_ISVTX = 0x200; // octal 0001000
3767+}
3768 else
3769 {
3770 static assert(false, "Unsupported platform");
3771@@ -2207,6 +2265,11 @@ else version (Solaris)
3772 enum UTIME_NOW = -1;
3773 enum UTIME_OMIT = -2;
3774 }
3775+else version (Hurd)
3776+{
3777+ enum UTIME_NOW = -1;
3778+ enum UTIME_OMIT = -2;
3779+}
3780 else
3781 {
3782 static assert(false, "Unsupported platform");
3783@@ -2313,6 +2376,17 @@ else version (Solaris)
3784 enum S_IFDOOR = 0xD000;
3785 enum S_IFPORT = 0xE000;
3786 }
3787+else version (Hurd)
3788+{
3789+ enum S_IFMT = 0xF000; // octal 0170000
3790+ enum S_IFBLK = 0x6000; // octal 0060000
3791+ enum S_IFCHR = 0x2000; // octal 0020000
3792+ enum S_IFIFO = 0x1000; // octal 0010000
3793+ enum S_IFREG = 0x8000; // octal 0100000
3794+ enum S_IFDIR = 0x4000; // octal 0040000
3795+ enum S_IFLNK = 0xA000; // octal 0120000
3796+ enum S_IFSOCK = 0xC000; // octal 0140000
3797+}
3798 else
3799 {
3800 static assert(false, "Unsupported platform");
3801diff --git a/druntime/src/core/sys/posix/sys/statvfs.d b/druntime/src/core/sys/posix/sys/statvfs.d
3802index ede7866bae..bb50750f91 100644
3803--- a/druntime/src/core/sys/posix/sys/statvfs.d
3804+++ b/druntime/src/core/sys/posix/sys/statvfs.d
3805@@ -18,71 +18,117 @@ nothrow:
3806 @nogc:
3807
3808 version (CRuntime_Glibc) {
3809- static if (__WORDSIZE == 32)
3810+ version (linux)
3811 {
3812- version=_STATVFSBUF_F_UNUSED;
3813- }
3814- struct statvfs_t
3815- {
3816- c_ulong f_bsize;
3817- c_ulong f_frsize;
3818- fsblkcnt_t f_blocks;
3819- fsblkcnt_t f_bfree;
3820- fsblkcnt_t f_bavail;
3821- fsfilcnt_t f_files;
3822- fsfilcnt_t f_ffree;
3823- fsfilcnt_t f_favail;
3824- c_ulong f_fsid;
3825- version (_STATVFSBUF_F_UNUSED)
3826+ static if (__WORDSIZE == 32)
3827 {
3828- int __f_unused;
3829+ version=_STATVFSBUF_F_UNUSED;
3830+ }
3831+ struct statvfs_t
3832+ {
3833+ c_ulong f_bsize;
3834+ c_ulong f_frsize;
3835+ fsblkcnt_t f_blocks;
3836+ fsblkcnt_t f_bfree;
3837+ fsblkcnt_t f_bavail;
3838+ fsfilcnt_t f_files;
3839+ fsfilcnt_t f_ffree;
3840+ fsfilcnt_t f_favail;
3841+ c_ulong f_fsid;
3842+ version (_STATVFSBUF_F_UNUSED)
3843+ {
3844+ int __f_unused;
3845+ }
3846+ c_ulong f_flag;
3847+ c_ulong f_namemax;
3848+ int[6] __f_spare;
3849+ }
3850+ /* Definitions for the flag in `f_flag'. These definitions should be
3851+ kept in sync with the definitions in <sys/mount.h>. */
3852+ static if (_GNU_SOURCE)
3853+ {
3854+ enum FFlag
3855+ {
3856+ ST_RDONLY = 1, /* Mount read-only. */
3857+ ST_NOSUID = 2,
3858+ ST_NODEV = 4, /* Disallow access to device special files. */
3859+ ST_NOEXEC = 8, /* Disallow program execution. */
3860+ ST_SYNCHRONOUS = 16, /* Writes are synced at once. */
3861+ ST_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
3862+ ST_WRITE = 128, /* Write on file/directory/symlink. */
3863+ ST_APPEND = 256, /* Append-only file. */
3864+ ST_IMMUTABLE = 512, /* Immutable file. */
3865+ ST_NOATIME = 1024, /* Do not update access times. */
3866+ ST_NODIRATIME = 2048, /* Do not update directory access times. */
3867+ ST_RELATIME = 4096 /* Update atime relative to mtime/ctime. */
3868+
3869+ }
3870+ } /* Use GNU. */
3871+ else
3872+ { // Posix defined:
3873+ enum FFlag
3874+ {
3875+ ST_RDONLY = 1, /* Mount read-only. */
3876+ ST_NOSUID = 2
3877+ }
3878+ }
3879+ static if ( __USE_FILE_OFFSET64 )
3880+ {
3881+ int statvfs64 (const char * file, statvfs_t* buf);
3882+ alias statvfs = statvfs64;
3883+
3884+ int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;
3885+ alias fstatvfs = fstatvfs64;
3886+ }
3887+ else
3888+ {
3889+ int statvfs (const char * file, statvfs_t* buf);
3890+ int fstatvfs (int fildes, statvfs_t *buf);
3891 }
3892- c_ulong f_flag;
3893- c_ulong f_namemax;
3894- int[6] __f_spare;
3895 }
3896- /* Definitions for the flag in `f_flag'. These definitions should be
3897- kept in sync with the definitions in <sys/mount.h>. */
3898- static if (_GNU_SOURCE)
3899+ else version (Hurd)
3900 {
3901- enum FFlag
3902+ import core.sys.hurd.sys.types;
3903+ struct statvfs_t
3904 {
3905- ST_RDONLY = 1, /* Mount read-only. */
3906- ST_NOSUID = 2,
3907- ST_NODEV = 4, /* Disallow access to device special files. */
3908- ST_NOEXEC = 8, /* Disallow program execution. */
3909- ST_SYNCHRONOUS = 16, /* Writes are synced at once. */
3910- ST_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
3911- ST_WRITE = 128, /* Write on file/directory/symlink. */
3912- ST_APPEND = 256, /* Append-only file. */
3913- ST_IMMUTABLE = 512, /* Immutable file. */
3914- ST_NOATIME = 1024, /* Do not update access times. */
3915- ST_NODIRATIME = 2048, /* Do not update directory access times. */
3916- ST_RELATIME = 4096 /* Update atime relative to mtime/ctime. */
3917-
3918+ uint f_type;
3919+ c_ulong f_bsize;
3920+ fsblkcnt_t f_blocks;
3921+ fsblkcnt_t f_bfree;
3922+ fsblkcnt_t f_bavail;
3923+ fsfilcnt_t f_files;
3924+ fsfilcnt_t f_ffree;
3925+ fsid_t f_fsid;
3926+ c_ulong f_namelen;
3927+ fsfilcnt_t f_favail;
3928+ c_ulong f_frsize;
3929+ c_ulong f_flag;
3930+ uint[3] f_spare;
3931 }
3932- } /* Use GNU. */
3933- else
3934- { // Posix defined:
3935+
3936 enum FFlag
3937 {
3938- ST_RDONLY = 1, /* Mount read-only. */
3939- ST_NOSUID = 2
3940+ ST_RDONLY = 1,
3941+ ST_NOSUID = 2,
3942+ ST_NOEXEC = 8,
3943+ ST_SYNCHRONOUS = 16,
3944+ ST_NOATIME = 32,
3945+ ST_RELATIME = 64,
3946 }
3947- }
3948
3949- static if ( __USE_FILE_OFFSET64 )
3950- {
3951- int statvfs64 (const char * file, statvfs_t* buf);
3952- alias statvfs64 statvfs;
3953+ static if ( __USE_FILE_OFFSET64 )
3954+ {
3955+ int statvfs64 (const char * file, statvfs_t* buf);
3956+ alias statvfs = statvfs64;
3957
3958- int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;
3959- alias fstatvfs64 fstatvfs;
3960- }
3961- else
3962- {
3963- int statvfs (const char * file, statvfs_t* buf);
3964- int fstatvfs (int fildes, statvfs_t *buf);
3965+ int fstatvfs64 (int fildes, statvfs_t *buf) @trusted;
3966+ alias fstatvfs = fstatvfs64;
3967+ }
3968+ else
3969+ {
3970+ int statvfs (const char * file, statvfs_t* buf);
3971+ int fstatvfs (int fildes, statvfs_t *buf);
3972+ }
3973 }
3974 }
3975 else version (CRuntime_Musl)
3976diff --git a/druntime/src/core/sys/posix/sys/types.d b/druntime/src/core/sys/posix/sys/types.d
3977index 859c4ea0d2..fd5e5a9ebd 100644
3978--- a/druntime/src/core/sys/posix/sys/types.d
3979+++ b/druntime/src/core/sys/posix/sys/types.d
3980@@ -293,6 +293,32 @@ else version (Solaris)
3981 alias c_long time_t;
3982 alias uint uid_t;
3983 }
3984+else version (Hurd)
3985+{
3986+ static if ( __USE_FILE_OFFSET64 )
3987+ {
3988+ alias long blkcnt_t;
3989+ alias ulong ino_t;
3990+ alias long off_t;
3991+ }
3992+ else
3993+ {
3994+ alias slong_t blkcnt_t;
3995+ alias ulong_t ino_t;
3996+ alias slong_t off_t;
3997+ }
3998+ alias slong_t blksize_t;
3999+ alias ulong_t dev_t;
4000+ alias uint gid_t;
4001+ alias uint mode_t;
4002+ alias ulong_t nlink_t;
4003+ alias int pid_t;
4004+ //size_t (defined in core.stdc.stddef)
4005+ alias c_long ssize_t;
4006+ alias uint uid_t;
4007+
4008+ alias slong_t time_t;
4009+}
4010 else
4011 {
4012 static assert(false, "Unsupported platform");
4013@@ -404,6 +430,24 @@ else version (Solaris)
4014 alias id_t zoneid_t;
4015 alias id_t ctid_t;
4016 }
4017+else version (Hurd)
4018+{
4019+ static if ( __USE_FILE_OFFSET64 )
4020+ {
4021+ alias ulong fsblkcnt_t;
4022+ alias ulong fsfilcnt_t;
4023+ }
4024+ else
4025+ {
4026+ alias ulong_t fsblkcnt_t;
4027+ alias ulong_t fsfilcnt_t;
4028+ }
4029+ alias slong_t clock_t;
4030+ alias uint id_t;
4031+ alias int key_t;
4032+ alias slong_t suseconds_t;
4033+ alias uint useconds_t;
4034+}
4035 else
4036 {
4037 static assert(false, "Unsupported platform");
4038@@ -427,21 +471,84 @@ pthread_t
4039
4040 version (CRuntime_Glibc)
4041 {
4042- version (X86)
4043+ version (linux)
4044 {
4045- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4046- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4047- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4048- enum __SIZEOF_PTHREAD_COND_T = 48;
4049- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4050- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4051- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4052- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4053- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4054- }
4055- else version (X86_64)
4056- {
4057- static if (__WORDSIZE == 64)
4058+ version (X86)
4059+ {
4060+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4061+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4062+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4063+ enum __SIZEOF_PTHREAD_COND_T = 48;
4064+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4065+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4066+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4067+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4068+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4069+ }
4070+ else version (X86_64)
4071+ {
4072+ static if (__WORDSIZE == 64)
4073+ {
4074+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4075+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4076+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4077+ enum __SIZEOF_PTHREAD_COND_T = 48;
4078+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4079+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4080+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4081+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4082+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4083+ }
4084+ else
4085+ {
4086+ enum __SIZEOF_PTHREAD_ATTR_T = 32;
4087+ enum __SIZEOF_PTHREAD_MUTEX_T = 32;
4088+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4089+ enum __SIZEOF_PTHREAD_COND_T = 48;
4090+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4091+ enum __SIZEOF_PTHREAD_RWLOCK_T = 44;
4092+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4093+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4094+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4095+ }
4096+ }
4097+ else version (AArch64)
4098+ {
4099+ enum __SIZEOF_PTHREAD_ATTR_T = 64;
4100+ enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4101+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 8;
4102+ enum __SIZEOF_PTHREAD_COND_T = 48;
4103+ enum __SIZEOF_PTHREAD_CONDATTR_T = 8;
4104+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4105+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4106+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4107+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 8;
4108+ }
4109+ else version (ARM)
4110+ {
4111+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4112+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4113+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4114+ enum __SIZEOF_PTHREAD_COND_T = 48;
4115+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4116+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4117+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4118+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4119+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4120+ }
4121+ else version (HPPA)
4122+ {
4123+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4124+ enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4125+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4126+ enum __SIZEOF_PTHREAD_COND_T = 48;
4127+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4128+ enum __SIZEOF_PTHREAD_RWLOCK_T = 64;
4129+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4130+ enum __SIZEOF_PTHREAD_BARRIER_T = 48;
4131+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4132+ }
4133+ else version (IA64)
4134 {
4135 enum __SIZEOF_PTHREAD_ATTR_T = 56;
4136 enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4137@@ -453,262 +560,290 @@ version (CRuntime_Glibc)
4138 enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4139 enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4140 }
4141- else
4142+ else version (MIPS32)
4143 {
4144- enum __SIZEOF_PTHREAD_ATTR_T = 32;
4145- enum __SIZEOF_PTHREAD_MUTEX_T = 32;
4146+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4147+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4148 enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4149 enum __SIZEOF_PTHREAD_COND_T = 48;
4150 enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4151- enum __SIZEOF_PTHREAD_RWLOCK_T = 44;
4152+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4153 enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4154 enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4155 enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4156 }
4157+ else version (MIPS64)
4158+ {
4159+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4160+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4161+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4162+ enum __SIZEOF_PTHREAD_COND_T = 48;
4163+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4164+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4165+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4166+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4167+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4168+ }
4169+ else version (PPC)
4170+ {
4171+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4172+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4173+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4174+ enum __SIZEOF_PTHREAD_COND_T = 48;
4175+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4176+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4177+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4178+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4179+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4180+ }
4181+ else version (PPC64)
4182+ {
4183+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4184+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4185+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4186+ enum __SIZEOF_PTHREAD_COND_T = 48;
4187+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4188+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4189+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4190+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4191+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4192+ }
4193+ else version (RISCV32)
4194+ {
4195+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4196+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4197+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4198+ enum __SIZEOF_PTHREAD_COND_T = 48;
4199+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4200+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4201+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4202+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4203+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4204+ }
4205+ else version (RISCV64)
4206+ {
4207+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4208+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4209+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4210+ enum __SIZEOF_PTHREAD_COND_T = 48;
4211+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4212+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4213+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4214+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4215+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4216+ }
4217+ else version (SPARC)
4218+ {
4219+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4220+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4221+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4222+ enum __SIZEOF_PTHREAD_COND_T = 48;
4223+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4224+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4225+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4226+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4227+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4228+ }
4229+ else version (SPARC64)
4230+ {
4231+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4232+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4233+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4234+ enum __SIZEOF_PTHREAD_COND_T = 48;
4235+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4236+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4237+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4238+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4239+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4240+ }
4241+ else version (S390)
4242+ {
4243+ enum __SIZEOF_PTHREAD_ATTR_T = 36;
4244+ enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4245+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4246+ enum __SIZEOF_PTHREAD_COND_T = 48;
4247+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4248+ enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4249+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4250+ enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4251+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4252+ }
4253+ else version (SystemZ)
4254+ {
4255+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4256+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4257+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4258+ enum __SIZEOF_PTHREAD_COND_T = 48;
4259+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4260+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4261+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4262+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4263+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4264+ }
4265+ else version (LoongArch64)
4266+ {
4267+ enum __SIZEOF_PTHREAD_ATTR_T = 56;
4268+ enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4269+ enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4270+ enum __SIZEOF_PTHREAD_COND_T = 48;
4271+ enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4272+ enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4273+ enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4274+ enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4275+ enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4276+ }
4277+ else
4278+ {
4279+ static assert (false, "Unsupported platform");
4280+ }
4281+
4282+ union pthread_attr_t
4283+ {
4284+ byte[__SIZEOF_PTHREAD_ATTR_T] __size;
4285+ c_long __align;
4286+ }
4287+
4288+ private alias int __atomic_lock_t;
4289+
4290+ private struct _pthread_fastlock
4291+ {
4292+ c_long __status;
4293+ __atomic_lock_t __spinlock;
4294+ }
4295+
4296+ private alias void* _pthread_descr;
4297+
4298+ union pthread_cond_t
4299+ {
4300+ byte[__SIZEOF_PTHREAD_COND_T] __size;
4301+ long __align;
4302+ }
4303+
4304+ union pthread_condattr_t
4305+ {
4306+ byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;
4307+ int __align;
4308+ }
4309+
4310+ alias uint pthread_key_t;
4311+
4312+ union pthread_mutex_t
4313+ {
4314+ byte[__SIZEOF_PTHREAD_MUTEX_T] __size;
4315+ c_long __align;
4316+ }
4317+
4318+ union pthread_mutexattr_t
4319+ {
4320+ byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;
4321+ int __align;
4322+ }
4323+
4324+ alias int pthread_once_t;
4325+
4326+ struct pthread_rwlock_t
4327+ {
4328+ byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;
4329+ c_long __align;
4330+ }
4331+
4332+ struct pthread_rwlockattr_t
4333+ {
4334+ byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;
4335+ c_long __align;
4336+ }
4337+
4338+ alias c_ulong pthread_t;
4339 }
4340- else version (AArch64)
4341- {
4342- enum __SIZEOF_PTHREAD_ATTR_T = 64;
4343- enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4344- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 8;
4345- enum __SIZEOF_PTHREAD_COND_T = 48;
4346- enum __SIZEOF_PTHREAD_CONDATTR_T = 8;
4347- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4348- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4349- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4350- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 8;
4351- }
4352- else version (ARM)
4353- {
4354- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4355- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4356- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4357- enum __SIZEOF_PTHREAD_COND_T = 48;
4358- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4359- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4360- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4361- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4362- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4363- }
4364- else version (HPPA)
4365- {
4366- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4367- enum __SIZEOF_PTHREAD_MUTEX_T = 48;
4368- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4369- enum __SIZEOF_PTHREAD_COND_T = 48;
4370- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4371- enum __SIZEOF_PTHREAD_RWLOCK_T = 64;
4372- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4373- enum __SIZEOF_PTHREAD_BARRIER_T = 48;
4374- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4375- }
4376- else version (IA64)
4377- {
4378- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4379- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4380- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4381- enum __SIZEOF_PTHREAD_COND_T = 48;
4382- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4383- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4384- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4385- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4386- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4387- }
4388- else version (MIPS32)
4389- {
4390- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4391- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4392- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4393- enum __SIZEOF_PTHREAD_COND_T = 48;
4394- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4395- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4396- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4397- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4398- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4399- }
4400- else version (MIPS64)
4401- {
4402- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4403- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4404- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4405- enum __SIZEOF_PTHREAD_COND_T = 48;
4406- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4407- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4408- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4409- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4410- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4411- }
4412- else version (PPC)
4413- {
4414- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4415- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4416- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4417- enum __SIZEOF_PTHREAD_COND_T = 48;
4418- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4419- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4420- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4421- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4422- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4423- }
4424- else version (PPC64)
4425- {
4426- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4427- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4428- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4429- enum __SIZEOF_PTHREAD_COND_T = 48;
4430- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4431- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4432- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4433- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4434- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4435- }
4436- else version (RISCV32)
4437- {
4438- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4439- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4440- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4441- enum __SIZEOF_PTHREAD_COND_T = 48;
4442- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4443- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4444- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4445- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4446- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4447- }
4448- else version (RISCV64)
4449- {
4450- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4451- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4452- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4453- enum __SIZEOF_PTHREAD_COND_T = 48;
4454- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4455- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4456- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4457- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4458- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4459- }
4460- else version (SPARC)
4461- {
4462- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4463- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4464- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4465- enum __SIZEOF_PTHREAD_COND_T = 48;
4466- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4467- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4468- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4469- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4470- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4471- }
4472- else version (SPARC64)
4473- {
4474- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4475- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4476- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4477- enum __SIZEOF_PTHREAD_COND_T = 48;
4478- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4479- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4480- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4481- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4482- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4483- }
4484- else version (S390)
4485- {
4486- enum __SIZEOF_PTHREAD_ATTR_T = 36;
4487- enum __SIZEOF_PTHREAD_MUTEX_T = 24;
4488- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4489- enum __SIZEOF_PTHREAD_COND_T = 48;
4490- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4491- enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
4492- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4493- enum __SIZEOF_PTHREAD_BARRIER_T = 20;
4494- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4495- }
4496- else version (SystemZ)
4497- {
4498- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4499- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4500- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4501- enum __SIZEOF_PTHREAD_COND_T = 48;
4502- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4503- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4504- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4505- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4506- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4507- }
4508- else version (LoongArch64)
4509- {
4510- enum __SIZEOF_PTHREAD_ATTR_T = 56;
4511- enum __SIZEOF_PTHREAD_MUTEX_T = 40;
4512- enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
4513- enum __SIZEOF_PTHREAD_COND_T = 48;
4514- enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
4515- enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
4516- enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
4517- enum __SIZEOF_PTHREAD_BARRIER_T = 32;
4518- enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
4519- }
4520- else
4521+ else version (Hurd)
4522 {
4523- static assert (false, "Unsupported platform");
4524- }
4525+ import core.sys.hurd.sys.types;
4526+ import core.sys.posix.time: clockid_t;
4527
4528- union pthread_attr_t
4529- {
4530- byte[__SIZEOF_PTHREAD_ATTR_T] __size;
4531- c_long __align;
4532- }
4533+ private struct __sched_param
4534+ {
4535+ int __sched_priority;
4536+ }
4537
4538- private alias int __atomic_lock_t;
4539+ private struct __pthread;
4540
4541- private struct _pthread_fastlock
4542- {
4543- c_long __status;
4544- __atomic_lock_t __spinlock;
4545- }
4546+ struct pthread_attr_t
4547+ {
4548+ __sched_param schedparam;
4549+ void* stackaddr;
4550+ size_t __stacksize;
4551+ size_t __guardsize;
4552+ int __detachstate;
4553+ int __inheritsched;
4554+ int __contentionscope;
4555+ int __schedpolicy;
4556+ }
4557
4558- private alias void* _pthread_descr;
4559+ struct pthread_cond_t
4560+ {
4561+ pthread_spinlock_t __lock;
4562+ __pthread *__queue;
4563+ pthread_condattr_t *__attr;
4564+ uint __wrefs;
4565+ void *__data;
4566+ }
4567
4568- union pthread_cond_t
4569- {
4570- byte[__SIZEOF_PTHREAD_COND_T] __size;
4571- long __align;
4572- }
4573+ struct pthread_condattr_t
4574+ {
4575+ int __pshared;
4576+ clockid_t __clock;
4577+ }
4578
4579- union pthread_condattr_t
4580- {
4581- byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;
4582- int __align;
4583- }
4584+ alias int pthread_key_t;
4585
4586- alias uint pthread_key_t;
4587+ struct pthread_mutex_t
4588+ {
4589+ uint __lock;
4590+ uint __owner_id;
4591+ uint __cnt;
4592+ int __shpid;
4593+ int __type;
4594+ int __flags;
4595+ union
4596+ {
4597+ uint[2] __reserved;
4598+ void *__pointer_aligned;
4599+ }
4600+ }
4601
4602- union pthread_mutex_t
4603- {
4604- byte[__SIZEOF_PTHREAD_MUTEX_T] __size;
4605- c_long __align;
4606- }
4607+ struct pthread_mutexattr_t
4608+ {
4609+ int __prioceiling;
4610+ int __protocol;
4611+ int __pshared;
4612+ int __mutex_type;
4613+ }
4614
4615- union pthread_mutexattr_t
4616- {
4617- byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;
4618- int __align;
4619- }
4620+ struct pthread_once_t
4621+ {
4622+ int __run;
4623+ pthread_spinlock_t __lock;
4624+ }
4625
4626- alias int pthread_once_t;
4627+ struct pthread_rwlock_t
4628+ {
4629+ pthread_spinlock_t __held;
4630+ pthread_spinlock_t __lock;
4631+ int __readers;
4632+ __pthread *__readerqueue;
4633+ __pthread *__writerqueue;
4634+ pthread_rwlockattr_t *__attr;
4635+ void *__data;
4636+ }
4637
4638- struct pthread_rwlock_t
4639- {
4640- byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;
4641- c_long __align;
4642- }
4643+ struct pthread_rwlockattr_t
4644+ {
4645+ int __pshared;
4646+ }
4647
4648- struct pthread_rwlockattr_t
4649- {
4650- byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;
4651- c_long __align;
4652+ alias c_long pthread_t;
4653 }
4654-
4655- alias c_ulong pthread_t;
4656-}
4657+ }
4658 else version (CRuntime_Musl)
4659 {
4660 version (D_LP64)
4661@@ -1315,17 +1450,37 @@ pthread_barrierattr_t
4662
4663 version (CRuntime_Glibc)
4664 {
4665- struct pthread_barrier_t
4666- {
4667- byte[__SIZEOF_PTHREAD_BARRIER_T] __size;
4668- c_long __align;
4669- }
4670+ version (linux)
4671+ {
4672+ struct pthread_barrier_t
4673+ {
4674+ byte[__SIZEOF_PTHREAD_BARRIER_T] __size;
4675+ c_long __align;
4676+ }
4677
4678- struct pthread_barrierattr_t
4679- {
4680- byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;
4681- int __align;
4682- }
4683+ struct pthread_barrierattr_t
4684+ {
4685+ byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;
4686+ int __align;
4687+ }
4688+ }
4689+ else version (Hurd)
4690+ {
4691+ struct pthread_barrier_t
4692+ {
4693+ pthread_spinlock_t __lock;
4694+ __pthread *__queue;
4695+ uint __pending;
4696+ uint __count;
4697+ pthread_barrierattr_t *__attr;
4698+ void *__data;
4699+ }
4700+
4701+ struct pthread_barrierattr_t
4702+ {
4703+ int __pshared;
4704+ }
4705+ }
4706 }
4707 else version (FreeBSD)
4708 {
4709diff --git a/druntime/src/core/sys/posix/sys/un.d b/druntime/src/core/sys/posix/sys/un.d
4710index 11e98a72ab..0d4746ee36 100644
4711--- a/druntime/src/core/sys/posix/sys/un.d
4712+++ b/druntime/src/core/sys/posix/sys/un.d
4713@@ -104,3 +104,12 @@ else version (Solaris)
4714 byte[108] sun_path;
4715 }
4716 }
4717+else version (Hurd)
4718+{
4719+ struct sockaddr_un
4720+ {
4721+ ubyte sun_len;
4722+ sa_family_t sun_family;
4723+ byte[108] sun_path;
4724+ }
4725+}
4726diff --git a/druntime/src/core/sys/posix/sys/utsname.d b/druntime/src/core/sys/posix/sys/utsname.d
4727index 5de50aca46..507113b6fb 100644
4728--- a/druntime/src/core/sys/posix/sys/utsname.d
4729+++ b/druntime/src/core/sys/posix/sys/utsname.d
4730@@ -19,19 +19,36 @@ nothrow:
4731
4732 version (CRuntime_Glibc)
4733 {
4734- private enum utsNameLength = 65;
4735-
4736- struct utsname
4737+ version(linux)
4738 {
4739- char[utsNameLength] sysname = 0;
4740- char[utsNameLength] nodename = 0;
4741- char[utsNameLength] release = 0;
4742- char[utsNameLength] version_ = 0;
4743- // TODO Deprecate after version_ has been in an official release.
4744- alias update = version_;
4745- char[utsNameLength] machine = 0;
4746+ private enum utsNameLength = 65;
4747+ struct utsname
4748+ {
4749+ char[utsNameLength] sysname = 0;
4750+ char[utsNameLength] nodename = 0;
4751+ char[utsNameLength] release = 0;
4752+ char[utsNameLength] version_ = 0;
4753+ // TODO Deprecate after version_ has been in an official release.
4754+ alias update = version_;
4755+ char[utsNameLength] machine = 0;
4756+
4757+ char[utsNameLength] __domainname = 0;
4758+ }
4759+ }
4760
4761- char[utsNameLength] __domainname = 0;
4762+ else version(Hurd)
4763+ {
4764+ private enum utsNameLength = 1024;
4765+ struct utsname
4766+ {
4767+ char[utsNameLength] sysname = 0;
4768+ char[utsNameLength] nodename = 0;
4769+ char[utsNameLength] release = 0;
4770+ char[utsNameLength] version_ = 0;
4771+ // TODO Deprecate after version_ has been in an official release.
4772+ alias update = version_;
4773+ char[utsNameLength] machine = 0;
4774+ }
4775 }
4776
4777 int uname(utsname* __name);
4778diff --git a/druntime/src/core/sys/posix/sys/wait.d b/druntime/src/core/sys/posix/sys/wait.d
4779index 131a9400dc..91fe9020a1 100644
4780--- a/druntime/src/core/sys/posix/sys/wait.d
4781+++ b/druntime/src/core/sys/posix/sys/wait.d
4782@@ -106,6 +106,15 @@ else version (Solaris)
4783 enum WNOHANG = 64;
4784 enum WUNTRACED = 4;
4785 }
4786+else version (Hurd)
4787+{
4788+ enum WNOHANG = 1;
4789+ enum WUNTRACED = 2;
4790+ private
4791+ {
4792+ enum __W_CONTINUED = 0xFFFF;
4793+ }
4794+}
4795 else
4796 {
4797 static assert(false, "Unsupported platform");
4798@@ -430,6 +439,20 @@ else version (Solaris)
4799 P_CPUID, /* CPU identifier. */
4800 P_PSETID, /* Processor set identifier */
4801 }
4802+}
4803+ else version (Hurd)
4804+{
4805+ enum WEXITED = 16;
4806+ enum WSTOPPED = WUNTRACED;
4807+ enum WCONTINUED = 4;
4808+ enum WNOWAIT = 8;
4809+
4810+ enum idtype_t
4811+ {
4812+ P_ALL,
4813+ P_PID,
4814+ P_PGID
4815+ }
4816 }
4817 else
4818 {
4819diff --git a/druntime/src/core/sys/posix/termios.d b/druntime/src/core/sys/posix/termios.d
4820index e4a99e6865..ecc7367151 100644
4821--- a/druntime/src/core/sys/posix/termios.d
4822+++ b/druntime/src/core/sys/posix/termios.d
4823@@ -831,6 +831,103 @@ else version (Solaris)
4824 enum B460800 = 22;
4825 enum B921600 = 23;
4826 }
4827+else version (Hurd)
4828+{
4829+ alias ubyte cc_t;
4830+ alias uint speed_t;
4831+ alias uint tcflag_t;
4832+
4833+ enum NCCS = 20;
4834+
4835+ struct termios
4836+ {
4837+ tcflag_t c_iflag;
4838+ tcflag_t c_oflag;
4839+ tcflag_t c_cflag;
4840+ tcflag_t c_lflag;
4841+ cc_t[NCCS] c_cc;
4842+ speed_t c_ispeed;
4843+ speed_t c_ospeed;
4844+ }
4845+
4846+ enum VEOF = 0;
4847+ enum VEOL = 1;
4848+ enum VERASE = 3;
4849+ enum VINTR = 8;
4850+ enum VKILL = 5;
4851+ enum VMIN = 16;
4852+ enum VQUIT = 9;
4853+ enum VSTART = 12;
4854+ enum VSTOP = 13;
4855+ enum VSUSP = 10;
4856+ enum VTIME = 17;
4857+
4858+ enum BRKINT = 0x0000002;
4859+ enum ICRNL = 0x0000100;
4860+ enum IGNBRK = 0x0000001;
4861+ enum IGNCR = 0x0000080;
4862+ enum IGNPAR = 0x0000004;
4863+ enum INLCR = 0x0000040;
4864+ enum INPCK = 0x0000010;
4865+ enum ISTRIP = 0x0000020;
4866+ enum IXOFF = 0x0000400;
4867+ enum IXON = 0x0000200;
4868+ enum PARMRK = 0x0000008;
4869+
4870+ enum OPOST = 0x0000001;
4871+
4872+ enum B0 = 0;
4873+ enum B50 = 50;
4874+ enum B75 = 75;
4875+ enum B110 = 110;
4876+ enum B134 = 134;
4877+ enum B150 = 150;
4878+ enum B200 = 200;
4879+ enum B300 = 300;
4880+ enum B600 = 600;
4881+ enum B1200 = 1200;
4882+ enum B1800 = 1800;
4883+ enum B2400 = 2400;
4884+ enum B4800 = 4800;
4885+ enum B9600 = 9600;
4886+ enum B19200 = 19200;
4887+ enum B38400 = 38400;
4888+
4889+ enum CSIZE = 0x0000300;
4890+ enum CS5 = 0x0000000;
4891+ enum CS6 = 0x0000100;
4892+ enum CS7 = 0x0000200;
4893+ enum CS8 = 0x0000300;
4894+ enum CSTOPB = 0x0000400;
4895+ enum CREAD = 0x0000800;
4896+ enum PARENB = 0x0001000;
4897+ enum PARODD = 0x0002000;
4898+ enum HUPCL = 0x0004000;
4899+ enum CLOCAL = 0x0008000;
4900+
4901+ enum ECHO = 0x00000008;
4902+ enum ECHOE = 0x00000002;
4903+ enum ECHOK = 0x00000004;
4904+ enum ECHONL = 0x00000010;
4905+ enum ICANON = 0x00000100;
4906+ enum IEXTEN = 0x00000400;
4907+ enum ISIG = 0x00000080;
4908+ enum NOFLSH = 0x80000000;
4909+ enum TOSTOP = 0x00400000;
4910+
4911+ enum TCSANOW = 0;
4912+ enum TCSADRAIN = 1;
4913+ enum TCSAFLUSH = 2;
4914+
4915+ enum TCIFLUSH = 0;
4916+ enum TCOFLUSH = 1;
4917+ enum TCIOFLUSH = 2;
4918+
4919+ enum TCIOFF = 3;
4920+ enum TCION = 4;
4921+ enum TCOOFF = 1;
4922+ enum TCOON = 2;
4923+}
4924
4925 /*
4926 speed_t cfgetispeed(const scope termios*);
4927diff --git a/druntime/src/core/sys/posix/time.d b/druntime/src/core/sys/posix/time.d
4928index fdd6b0a888..37234579ba 100644
4929--- a/druntime/src/core/sys/posix/time.d
4930+++ b/druntime/src/core/sys/posix/time.d
4931@@ -156,6 +156,10 @@ else version (Solaris)
4932 {
4933 enum CLOCK_MONOTONIC = 4;
4934 }
4935+else version (Hurd)
4936+{
4937+ enum CLOCK_MONOTONIC = 1;
4938+}
4939 else
4940 {
4941 static assert(0);
4942@@ -259,6 +263,14 @@ else version (Solaris)
4943
4944 alias timespec timestruc_t;
4945 }
4946+else version (Hurd)
4947+{
4948+ struct timespec
4949+ {
4950+ time_t tv_sec;
4951+ c_long tv_nsec;
4952+ }
4953+}
4954 else
4955 {
4956 static assert(false, "Unsupported platform");
4957diff --git a/druntime/src/core/thread/fiber/switch_context_asm.S b/druntime/src/core/thread/fiber/switch_context_asm.S
4958index cef64f65f0..ca44874262 100644
4959--- a/druntime/src/core/thread/fiber/switch_context_asm.S
4960+++ b/druntime/src/core/thread/fiber/switch_context_asm.S
4961@@ -13,7 +13,7 @@
4962 * http://www.boost.org/LICENSE_1_0.txt)
4963 */
4964
4965-#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__) && __ELF__
4966+#if (__linux__ || __FreeBSD__ || __NetBSD__ || __OpenBSD__ || __DragonFly__ | __GNU__) && __ELF__
4967 /*
4968 * Mark the resulting object file as not requiring execution permissions on
4969 * stack memory. The absence of this section would mark the whole resulting
4970diff --git a/druntime/src/core/thread/osthread.d b/druntime/src/core/thread/osthread.d
4971index ff82283a83..4dd22c7764 100644
4972--- a/druntime/src/core/thread/osthread.d
4973+++ b/druntime/src/core/thread/osthread.d
4974@@ -2252,6 +2252,14 @@ extern (C) void thread_init() @nogc nothrow
4975 enum SIGRTMIN = SIGUSR1;
4976 enum SIGRTMAX = 32;
4977 }
4978+ else version (Hurd)
4979+ {
4980+ // Hurd does not support SIGRTMIN or SIGRTMAX
4981+ // Use SIGUSR1 for SIGRTMIN, SIGUSR2 for SIGRTMIN + 1
4982+ // And use 32 for SIGRTMAX (32 is the max signal number on Hurd)
4983+ enum SIGRTMIN = SIGUSR1;
4984+ enum SIGRTMAX = 32;
4985+ }
4986 else
4987 {
4988 import core.sys.posix.signal : SIGRTMAX, SIGRTMIN;
4989diff --git a/druntime/src/core/time.d b/druntime/src/core/time.d
4990index 8189e67f8a..920094d832 100644
4991--- a/druntime/src/core/time.d
4992+++ b/druntime/src/core/time.d
4993@@ -337,6 +337,17 @@ else version (Solaris) enum ClockType
4994 second = 6,
4995 threadCPUTime = 7,
4996 }
4997+else version (Hurd) enum ClockType
4998+{
4999+ normal = 0,
5000+ coarse = 2,
5001+ precise = 3,
5002+ // processCPUTime = 4,
5003+ raw = 5,
5004+ second = 6,
5005+ // threadCPUTime = 7,
5006+
5007+}
5008 else
5009 {
5010 // It needs to be decided (and implemented in an appropriate version branch
5011@@ -436,6 +447,20 @@ version (Posix)
5012 case second: assert(0);
5013 }
5014 }
5015+ else version (Hurd)
5016+ {
5017+ import core.sys.hurd.time;
5018+ with(ClockType) final switch (clockType)
5019+ {
5020+ case coarse: return CLOCK_MONOTONIC_COARSE;
5021+ case normal: return CLOCK_MONOTONIC;
5022+ case precise: return CLOCK_MONOTONIC;
5023+ // case processCPUTime: return CLOCK_PROCESS_CPUTIME_ID;
5024+ case raw: return CLOCK_MONOTONIC_RAW;
5025+ // case threadCPUTime: return CLOCK_THREAD_CPUTIME_ID;
5026+ case second: assert(0);
5027+ }
5028+ }
5029 else
5030 // It needs to be decided (and implemented in an appropriate
5031 // version branch here) which clock types new platforms are going
5032diff --git a/druntime/src/importc.h b/druntime/src/importc.h
5033index b97d33807b..e93d1b1a7e 100644
5034--- a/druntime/src/importc.h
5035+++ b/druntime/src/importc.h
5036@@ -172,7 +172,7 @@ typedef unsigned long long __uint64_t;
5037 #endif
5038
5039 #define _Float16 float
5040-#ifdef __linux__ // Microsoft won't allow the following macro
5041+#if defined(__linux__) || defined(__GNU__) // Microsoft won't allow the following macro
5042 // Ubuntu's assert.h uses this
5043 #define __PRETTY_FUNCTION__ __func__
5044
5045@@ -195,7 +195,7 @@ typedef struct {} __SVFloat32_t;
5046 typedef struct {} __SVFloat64_t;
5047 #endif
5048
5049-#endif // __linux__
5050+#endif // __linux__ || __GNU__
5051
5052 #if __APPLE__
5053 #undef __SIZEOF_INT128__
5054diff --git a/druntime/src/rt/sections_elf_shared.d b/druntime/src/rt/sections_elf_shared.d
5055index 2061d3caeb..e899696a06 100644
5056--- a/druntime/src/rt/sections_elf_shared.d
5057+++ b/druntime/src/rt/sections_elf_shared.d
5058@@ -64,6 +64,12 @@ else version (DragonFlyBSD)
5059 import core.sys.dragonflybsd.sys.elf : DT_AUXILIARY, DT_FILTER, DT_NEEDED, DT_STRTAB, PF_W, PF_X, PT_DYNAMIC, PT_LOAD, PT_TLS;
5060 import core.sys.dragonflybsd.sys.link_elf : ElfW, link_map;
5061 }
5062+else version (Hurd)
5063+{
5064+ import core.sys.hurd.dlfcn : Dl_info, dladdr, dlclose, dlinfo, dlopen, RTLD_DI_LINKMAP, RTLD_LAZY, RTLD_NOLOAD;
5065+ import core.sys.hurd.elf : DT_AUXILIARY, DT_FILTER, DT_NEEDED, DT_STRTAB, PF_W, PF_X, PT_DYNAMIC, PT_LOAD, PT_TLS;
5066+ import core.sys.hurd.link : ElfW, link_map;
5067+}
5068 else
5069 {
5070 static assert(0, "unimplemented");
5071@@ -744,6 +750,8 @@ version (Shared)
5072 enum relocate = true;
5073 else version (DragonFlyBSD)
5074 enum relocate = true;
5075+ else version (Hurd)
5076+ enum relocate = false;
5077 else
5078 static assert(0, "unimplemented");
5079
5080diff --git a/druntime/test/importc_compare/src/importc_compare.d b/druntime/test/importc_compare/src/importc_compare.d
5081index 54081a23f1..d48ffefe2e 100644
5082--- a/druntime/test/importc_compare/src/importc_compare.d
5083+++ b/druntime/test/importc_compare/src/importc_compare.d
5084@@ -35,10 +35,14 @@ immutable ErrorFilter[] knownProblems = [
5085 ErrorFilter("core.stdc.locale.lconv", "", "Windows", 0, "https://issues.dlang.org/show_bug.cgi?id=24652"),
5086 ErrorFilter("core.stdc.math.double_t", "", "linux", 0, ""),
5087 ErrorFilter("core.stdc.math.float_t", "", "linux", 0, ""),
5088+ ErrorFilter("core.stdc.math.double_t", "", "Hurd", 0, ""),
5089+ ErrorFilter("core.stdc.math.float_t", "", "Hurd", 0, ""),
5090 ErrorFilter("core.stdc.signal.sig_atomic_t", "", "FreeBSD", 0, ""),
5091 ErrorFilter("core.stdc.stdio.FILE", "", "FreeBSD", 0, ""),
5092 ErrorFilter("core.stdc.stdio.FILE", "", "linux", 0, ""),
5093 ErrorFilter("core.stdc.stdio._IO_FILE", "", "linux", 0, ""),
5094+ ErrorFilter("core.stdc.stdio.FILE", "", "Hurd", 0, ""),
5095+ ErrorFilter("core.stdc.stdio._IO_FILE", "", "Hurd", 0, ""),
5096 ErrorFilter("core.stdc.stdio.__sFILE", "", "FreeBSD", 0, ""),
5097 ErrorFilter("core.stdc.wchar_.mbstate_t", "", "Apple", 0, ""),
5098 ErrorFilter("core.stdc.wchar_.mbstate_t", "", "Windows", 0, ""),
5099diff --git a/druntime/test/profile/myprofilegc.log.hurd.32.exp b/druntime/test/profile/myprofilegc.log.hurd.32.exp
5100new file mode 100644
5101index 0000000000..bdf8dd0a9b
5102--- /dev/null
5103+++ b/druntime/test/profile/myprofilegc.log.hurd.32.exp
5104@@ -0,0 +1,18 @@
5105+bytes allocated, allocations, type, function, file:line
5106+ 128 1 float profilegc.main src/profilegc.d:18
5107+ 128 1 int profilegc.main src/profilegc.d:15
5108+ 64 1 double[] profilegc.main src/profilegc.d:56
5109+ 48 1 float[] profilegc.main src/profilegc.d:42
5110+ 48 1 int[] profilegc.main src/profilegc.d:41
5111+ 32 1 void[] profilegc.main src/profilegc.d:55
5112+ 16 1 C profilegc.main src/profilegc.d:12
5113+ 16 1 char[] profilegc.main src/profilegc.d:34
5114+ 16 1 char[] profilegc.main src/profilegc.d:36
5115+ 16 1 closure profilegc.main.foo src/profilegc.d:45
5116+ 16 1 float profilegc.main src/profilegc.d:16
5117+ 16 1 float profilegc.main src/profilegc.d:17
5118+ 16 1 int profilegc.main src/profilegc.d:13
5119+ 16 1 int profilegc.main src/profilegc.d:14
5120+ 16 1 int[] profilegc.main src/profilegc.d:22
5121+ 16 1 int[] profilegc.main src/profilegc.d:37
5122+ 16 1 wchar[] profilegc.main src/profilegc.d:35
5123diff --git a/druntime/test/profile/myprofilegc.log.hurd.64.exp b/druntime/test/profile/myprofilegc.log.hurd.64.exp
5124new file mode 100644
5125index 0000000000..0a882256c9
5126--- /dev/null
5127+++ b/druntime/test/profile/myprofilegc.log.hurd.64.exp
5128@@ -0,0 +1,18 @@
5129+bytes allocated, allocations, type, function, file:line
5130+ 160 1 float profilegc.main src/profilegc.d:18
5131+ 160 1 int profilegc.main src/profilegc.d:15
5132+ 64 1 double[] profilegc.main src/profilegc.d:56
5133+ 48 1 float[] profilegc.main src/profilegc.d:42
5134+ 48 1 int[] profilegc.main src/profilegc.d:41
5135+ 32 1 C profilegc.main src/profilegc.d:12
5136+ 32 1 void[] profilegc.main src/profilegc.d:55
5137+ 16 1 char[] profilegc.main src/profilegc.d:34
5138+ 16 1 char[] profilegc.main src/profilegc.d:36
5139+ 16 1 closure profilegc.main.foo src/profilegc.d:45
5140+ 16 1 float profilegc.main src/profilegc.d:16
5141+ 16 1 float profilegc.main src/profilegc.d:17
5142+ 16 1 int profilegc.main src/profilegc.d:13
5143+ 16 1 int profilegc.main src/profilegc.d:14
5144+ 16 1 int[] profilegc.main src/profilegc.d:22
5145+ 16 1 int[] profilegc.main src/profilegc.d:37
5146+ 16 1 wchar[] profilegc.main src/profilegc.d:35
5147diff --git a/druntime/test/shared/src/load.d b/druntime/test/shared/src/load.d
5148index a36fcffefc..61d50f8e37 100644
5149--- a/druntime/test/shared/src/load.d
5150+++ b/druntime/test/shared/src/load.d
5151@@ -8,6 +8,7 @@ version (linux) import core.sys.linux.dlfcn : RTLD_NOLOAD;
5152 version (NetBSD) import core.sys.netbsd.dlfcn : RTLD_NOLOAD;
5153 version (OSX) import core.sys.darwin.dlfcn : RTLD_NOLOAD;
5154 version (Solaris) import core.sys.solaris.dlfcn : RTLD_NOLOAD;
5155+version (Hurd) import core.sys.hurd.dlfcn : RTLD_NOLOAD;
5156
5157 void* openLib(string s)
5158 {
5159--
51602.52.0
5161
diff --git a/gnu/packages/patches/phobos-hurd.patch b/gnu/packages/patches/phobos-hurd.patch
new file mode 100644
index 00000000000..c8b5523ea03
--- /dev/null
+++ b/gnu/packages/patches/phobos-hurd.patch
@@ -0,0 +1,64 @@
1From e2d65597896089a8bd06992a4b83e3d14176b02c Mon Sep 17 00:00:00 2001
2From: Yelninei <yelninei@tutamail.com>
3Date: Tue, 24 Mar 2026 19:46:30 +0000
4Subject: [PATCH] phobos: Fixes for GNU/Hurd.
5
6---
7 Makefile | 2 +-
8 std/datetime/timezone.d | 1 +
9 std/math/algebraic.d | 1 +
10 std/process.d | 2 ++
11 4 files changed, 5 insertions(+), 1 deletion(-)
12
13diff --git a/Makefile b/Makefile
14index 4fa51299e..a9d4789f6 100644
15--- a/Makefile
16+++ b/Makefile
17@@ -305,7 +305,7 @@ else
18 endif
19
20 # build with shared library support (defaults to true on supported platforms)
21-SHARED=$(if $(findstring $(OS),linux freebsd),1,)
22+SHARED=$(if $(findstring $(OS),linux freebsd hurd),1,)
23
24 TESTS_EXTRACTOR=$(ROOT)/tests_extractor$(DOTEXE)
25 PUBLICTESTS_DIR=$(ROOT)/publictests
26diff --git a/std/datetime/timezone.d b/std/datetime/timezone.d
27index 7461fcaa3..05c2999d3 100644
28--- a/std/datetime/timezone.d
29+++ b/std/datetime/timezone.d
30@@ -338,6 +338,7 @@ public:
31 else version (linux) enum utcZone = "UTC";
32 else version (Darwin) enum utcZone = "UTC";
33 else version (Solaris) enum utcZone = "UTC";
34+ else version (Hurd) enum utcZone = "UTC";
35 else static assert(0, "The location of the UTC timezone file on this Posix platform must be set.");
36
37 auto tzs = [testTZ("America/Los_Angeles", "PST", "PDT", dur!"hours"(-8), dur!"hours"(1)),
38diff --git a/std/math/algebraic.d b/std/math/algebraic.d
39index f96f24f15..05bf08b9c 100644
40--- a/std/math/algebraic.d
41+++ b/std/math/algebraic.d
42@@ -631,6 +631,7 @@ else version (FreeBSD) version = GenericPosixVersion;
43 else version (OpenBSD) version = GenericPosixVersion;
44 else version (Solaris) version = GenericPosixVersion;
45 else version (DragonFlyBSD) version = GenericPosixVersion;
46+else version (Hurd) version = GenericPosixVersion;
47
48 private real polyImpl(real x, in real[] A) @trusted pure nothrow @nogc
49 {
50diff --git a/std/process.d b/std/process.d
51index d359ca0ba..dc981c5e5 100644
52--- a/std/process.d
53+++ b/std/process.d
54@@ -1031,6 +1031,8 @@ private Pid spawnProcessPosix(scope const(char[])[] args,
55 import core.sys.freebsd.unistd : closefrom;
56 else version (OpenBSD)
57 import core.sys.openbsd.unistd : closefrom;
58+ else version (Hurd)
59+ import core.sys.hurd.unistd : closefrom;
60
61 static if (!__traits(compiles, closefrom))
62 {
63--
642.52.0