Skip to content

WIP: Port dmd and druntime to GNU/Hurd#22829

Open
yelninei wants to merge 3 commits intodlang:masterfrom
yelninei:dmd-hurd
Open

WIP: Port dmd and druntime to GNU/Hurd#22829
yelninei wants to merge 3 commits intodlang:masterfrom
yelninei:dmd-hurd

Conversation

@yelninei
Copy link
Copy Markdown
Contributor

@yelninei yelninei commented Mar 27, 2026

Hi,

As announced on https://forum.dlang.org/thread/agrrykgbdsjlbsgjtatq@forum.dlang.org here is my WIP PR for porting druntime and dmd to GNU Hurd.

To be able to build also #22787 is needed.

Things that I know are still a bit of a mess:

  • Indentation
  • How to add version(linux) where CRuntime_Glibc is used to mean linux + glibc.
  • Mix of new and old alias syntax. Some of the parts were originally against gcc-11 to be able to bootrap and I have not revised the patches yet.

I am currently quite happy with the dmd part as all tests pass on 32bit and 64bit except

  • dmd/compiler/test/dshell/sameenv.d : checks that 2 executables have the same environment variables but they expectedly differ in LD_ORIGIN_PATH
  • dmd/compiler/test/runnable_cxx/cppa.d : A warning coming from non _GLIBCXX_USE_CXX98_ABI version

For the runtime some tests still crash in pthread_join, I am not entirely sure why as the same test outside of libdruntime_ut works fine.
On x86_64 the test runner gets killed after a while with the gc suspend signal, I dont know yet why the runtime does not handle it.

I am not erntirely sure about the format for the dmd triplet as it differs from both the gnu config and llvm triplet.

I have asked people on the bug-hurd mailing list for help as well
https://lists.gnu.org/archive/html/bug-hurd/2026-03/msg00274.html
https://lists.gnu.org/archive/html/bug-hurd/2026-03/msg00275.html

There are some more things needed to bring this back into gdc,

@dlang-bot
Copy link
Copy Markdown
Contributor

Thanks for your pull request and interest in making D better, @yelninei! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#22829"

@yelninei
Copy link
Copy Markdown
Contributor Author

The error from the circleci is

ERROR: Newly generated header file (/home/circleci/dmd/generated/linux/release/64/frontend.h) doesn't match with the reference header file (/home/circleci/dmd/compiler/src/dmd/frontend.h)

DETAILS:

diff --git a/home/circleci/dmd/compiler/src/dmd/frontend.h b/home/circleci/dmd/generated/linux/release/64/frontend.h
index 8e8e2fe76..479667814 100644
--- a/home/circleci/dmd/compiler/src/dmd/frontend.h
+++ b/home/circleci/dmd/generated/linux/release/64/frontend.h
@@ -7363,8 +7363,9 @@ struct Target final
         FreeBSD = 16u,
         Solaris = 32u,
         DragonFlyBSD = 64u,
-        all = 127u,
-        Posix = 125u,
+        Hurd = 128u,
+        all = 255u,
+        Posix = 253u,
     };
 
     OS os;

===============
The file `src/dmd/frontend.h` seems to be out of sync. This is likely because
changes were made which affect the C++ interface used by GDC and LDC.

I guess this is expected, is there a way to regenerate the header?

@pbackus
Copy link
Copy Markdown
Contributor

pbackus commented Mar 27, 2026

Re: regenerating the headers, if you read a few more lines down in that error message, you will see this:

To read more about frontend.h and its usage, see src/README.md#cxx-headers-test

Which refers to https://github.com/dlang/dmd/tree/master/compiler/src#cxx-headers-test

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Mar 27, 2026

I am not erntirely sure about the format for the dmd triplet as it differs from both the gnu config and llvm triplet.

I thought dmd triplet (tuples?) matched ldc.

Historically, I guess gnu/hurd would be i*86-gnu or x86_64-gnu.

Comment thread compiler/src/dmd/backend/arm/cod1.d
Comment thread druntime/src/core/internal/elf/dl.d Outdated
Comment thread druntime/src/core/internal/elf/dl.d Outdated
Comment thread druntime/src/core/internal/elf/io.d Outdated
Comment thread druntime/src/core/stdc/config.d Outdated
Comment thread druntime/src/core/stdc/config.d Outdated
Comment thread druntime/src/core/sys/hurd/dlfcn.d Outdated
Comment thread druntime/src/core/sys/hurd/dlfcn.d Outdated
Comment thread druntime/src/core/sys/hurd/elf.d Outdated
Comment thread druntime/src/core/sys/hurd/execinfo.d Outdated
Comment thread druntime/src/core/sys/hurd/execinfo.d Outdated
Comment thread druntime/src/core/sys/hurd/unistd.d
Comment thread druntime/src/core/sys/linux/stdio.d Outdated
Comment thread druntime/src/core/sys/posix/sys/ioctl.d Outdated
Comment thread druntime/src/core/sys/posix/sys/socket.d Outdated
Comment thread druntime/src/core/sys/posix/sys/socket.d Outdated
Comment thread druntime/src/core/sys/posix/sys/socket.d Outdated
Comment thread druntime/src/core/sys/posix/sys/socket.d Outdated
Comment thread druntime/src/core/sys/posix/sys/socket.d
Comment thread druntime/src/core/sys/posix/pthread.d Outdated
Comment thread druntime/src/core/sys/posix/pthread.d Outdated
Comment thread druntime/src/rt/sections_elf_shared.d Outdated
Comment thread druntime/src/core/time.d Outdated
@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Apr 16, 2026

Does hurd need fixups for entries in the dl phdr? Some other archs/platforms do.

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Apr 17, 2026

FAOD, there is no GC involved in the dso registry/section support code.

v-- DSO loaded
#15 0x000000000000765e in call_init () from /gnu/store/cgjm6xbk68rpnl6gl326vfw5alg8ip9i-glibc-2.41/lib/ld-x86-64.so.1
v-- CRT in the DSO
#14 0x000000000b8c6182 in gdc.dso_ctor () at /tmp/guix-build-gdc-14.3.0.drv-0/build/x86_64-unknown-gnu/libphobos/src/<no_file>:1
v-- Register self into D runtime, find dl_phdr_info
#13 0x000000000bb033a5 in _d_dso_registry (data=data@entry=0x1e5eb30) at ../../../../gcc-14.3.0/libphobos/libdruntime/gcc/sections/elf.d:466
v-- Scans the found dl_phdr (.dynamic section, string table)
#12 0x000000000bb02b8e in gcc.sections.elf.getDependencies(ref const(core.sys.hurd.link.dl_phdr_info), ref core.internal.container.array.Array!(gcc.sections.elf.DSO*).Array) (info=..., deps=...) at ../../../../gcc-14.3.0/libphobos/libdruntime/gcc/sections/elf.d:806
v-- Get handle of library ref found in .dynamic
    handle name is computed from phdr_info strtab + dyn val
#11 0x000000000bb0113b in gcc.sections.elf.handleForName(const(char*)) (name=<optimized out>)
    at ../../../../gcc-14.3.0/libphobos/libdruntime/gcc/sections/elf.d:826
v-- Open handle to name at strtab + dyn val.
#10 0x000000000bfa5291 in dlopen@@GLIBC_2.38 () from /gnu/store/cgjm6xbk68rpnl6gl326vfw5alg8ip9i-glibc-2.41/lib/libc.so.0.3
v-- The rest just looks like dlopen failed because library not found
    the computed name is a pointer to garbage.
#9  0x000000000bfa4d77 in _dlerror_run () from /gnu/store/cgjm6xbk68rpnl6gl326vfw5alg8ip9i-glibc-2.41/lib/libc.so.0.3
#8  0x00000000000045bf in _dl_catch_error () from /gnu/store/cgjm6xbk68rpnl6gl326vfw5alg8ip9i-glibc-2.41/lib/ld-x86-64.so.1
...
#1  0x000000000000ee25 in dl_open_worker_begin () from /gnu/store/cgjm6xbk68rpnl6gl326vfw5alg8ip9i-glibc-2.41/lib/ld-x86-64.so.1
#0  0x000000000002996f in strchr () from /gnu/store/cgjm6xbk68rpnl6gl326vfw5alg8ip9i-glibc-2.41/lib/ld-x86-64.so.1

Most likely cause is the computed name being wrong:
https://forge.sourceware.org/gcc/gcc-TEST/src/commit/26e88fe809de0f1a1812c99e2e0106afb03257b3/libphobos/libdruntime/gcc/sections/elf.d#L791-L792

@yelninei
Copy link
Copy Markdown
Contributor Author

yelninei commented Apr 17, 2026

I think i found the issue.

in dmd i set relocate = falsein sections_elf_shared.d

In my gdc elf.d I just copied the code for BSD/Solaris that does relocation.

Give me a few hours to rebuild and verify.

my machine is currently busy rebuilding llvm to set the correct default target.

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Apr 17, 2026

I think i found the issue.

in dmd i set relocate = falsein sections_elf_shared.d

In my gdc elf.d I just copied the code for BSD/Solaris that does relocation.

That would certainly make the program segfault if you got that wrong.

@yelninei
Copy link
Copy Markdown
Contributor Author

That fixed gdc. Sorry for the noise.

@yelninei
Copy link
Copy Markdown
Contributor Author

Fixed termios constants. I als owent through all constants again to find bad copy pastes (i wish this would be less manual).

I think this is now ready so I am removing the WIP part. THere are still some smaller issues in some tests but these can be fixed as well.

for gdc I put the extra changes there already and it works well for my gdc-14 backport.

I have also been working on making ldc work as well which only needs some minimal additional changes to let it know of the new target and overcoming issues with llvm itself.
Ill open a similar PR there soon but the progress is that I am able to build a ldc with either dmd or gdc that is able to recompile itself again (have not looked at tests)

@yelninei yelninei marked this pull request as ready for review April 18, 2026 10:50
@yelninei
Copy link
Copy Markdown
Contributor Author

Whats the difference between target.h and frontend.h wrt the Target enum.

ldc seems to use a variable from target.h which is not updated with the new Os.

@thewilsonator
Copy link
Copy Markdown
Contributor

target.h is a manually maintained and translated C++ header mirror of target.d.

frontend.h is an automatically generated C++ header of every frontend *.d file that is required to be updated by PRs to ensure they don't break the synchronisation of the other headers.
It is desired to eventually move to frontend.h so we can stop needing to manually update headers, but that will be quite some time away because frontend.h does not compile and even once that is fixed, we would need to wait until such a fixed version becomes a bootstrap version.

@yelninei
Copy link
Copy Markdown
Contributor Author

target.h is a manually maintained and translated C++ header mirror of target.d.

Thanks I added the new enum member there as well then.

Copy link
Copy Markdown
Contributor

@thewilsonator thewilsonator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash all the druntime commits together and all of the DMD commits together.

@yelninei yelninei force-pushed the dmd-hurd branch 5 times, most recently from 004c5cb to 01b4f6d Compare April 20, 2026 13:57
@yelninei
Copy link
Copy Markdown
Contributor Author

@thewilsonator I needed the commit of druntime without the alias change to make backporting to gdc-11 a bit easier. I need this to be able to bootstrap without an initial cross compiler.

In gdc-11 this is a lot more of a mess because druntime used CRuntime_Glibc for linux+glibc and naively following the static asserts leads to a broken gdc e.g. because struct stat is different. thankfully ibuclaw mostly untangled this in https://bugzilla-archive.dlang.org/bugs/22689/

Comment thread druntime/src/core/sys/linux/stdio.d
@thewilsonator
Copy link
Copy Markdown
Contributor

Noted, do what you need to do. Can you squash the last two commits together?

Also do you plan on adding CI for Hurd?

@yelninei
Copy link
Copy Markdown
Contributor Author

Also do you plan on adding CI for Hurd?

Note tat a few tests still fail, either because it is not supported in libc (e.g. rename (NULL, "") crashes in std/file, something in std/socket failing with ENOPROTOOPT) and some of druntime tests still crash for unknown reason.

The best experience is with debian/hurd but I dont know if there is a convenient way to set that up with github actions.

You'd still need to get an initial D compiler from somewhere, I am not sure how D is bootstrapped in debian.

@yelninei
Copy link
Copy Markdown
Contributor Author

I have resolved a merge conflict in x86/cod1.d

@yelninei
Copy link
Copy Markdown
Contributor Author

I had another look at some of the failing tests

runnable_cxx/cppa.d

is failing

==============================
Test 'runnable_cxx/cppa.d' failed: 
expected:
----

----
actual:
----
libstdc++ std::__cxx11::basic_string is not yet supported; the struct contains an interior pointer which breaks D move semantics!
----
diff:
----
-
+libstdc++ std::__cxx11::basic_string is not yet supported; the struct contains an interior pointer which breaks D move semantics!
----

This comes from a pragma in the non _GLIBCXX_USE_CXX98_ABI version in core/stdcpp/string.d.

I found test/stdcpp/GNUmakefile.posx but there is a bit to much gnu make magic there to find out what is happening.

I thing id need to enable _GLIBCXX_USE_CXX98_ABI but I am not sure how to do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants