From f5194c3579c10f112e9706fd3c1a787defc753eb Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Wed, 23 Oct 2024 23:00:13 +0000 Subject: [PATCH 1/3] openbsd.openbsdSetupHook: Fix bsd.prog.mk bsd.prog.mk makes sure libc is built before programs that use it by making all programs depend on core files. We handle this dependency by referencing libc in cc-wrapper, but that isn't sufficient to tell bsd.prog.mk that e.g. crtbegin.o exists. Clear libc-related variables to fix OpenBSD program build --- .../bsd/openbsd/pkgs/openbsdSetupHook/setup-hook.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/openbsdSetupHook/setup-hook.sh b/pkgs/os-specific/bsd/openbsd/pkgs/openbsdSetupHook/setup-hook.sh index e06dbda37c40..dbd016fcb59c 100644 --- a/pkgs/os-specific/bsd/openbsd/pkgs/openbsdSetupHook/setup-hook.sh +++ b/pkgs/os-specific/bsd/openbsd/pkgs/openbsdSetupHook/setup-hook.sh @@ -1,6 +1,11 @@ addOpenBSDMakeFlags() { prependToVar makeFlags "INCSDIR=${!outputDev}/include" prependToVar makeFlags "MANDIR=${!outputMan}/share/man" + # Variables are used to declare dependencies, but we handle them with cc-wrapper + prependToVar makeFlags "CRTBEGIN=" + prependToVar makeFlags "CRTEND=" + prependToVar makeFlags "LIBCRT0=" + prependToVar makeFlags "LIBC=" } fixOpenBSDInstallDirs() { From fcd62ad08216260152221622eba2f6119b8eb5f4 Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Wed, 23 Oct 2024 23:09:45 +0000 Subject: [PATCH 2/3] openbsd.rtld: init rtld contains ld.so, the dynamic linker on OpenBSD. This package does not include related scripts (ldd and ldconfig), because they would create a dependency loop. rtld (run-time ld) is an os-agnostic term for dynamic linker. For simplicity, also link this into the libc symlinkJoin package --- pkgs/os-specific/bsd/openbsd/pkgs/libc.nix | 19 ++++--- .../openbsd/pkgs/rtld/ldso-fix-makefile.patch | 57 +++++++++++++++++++ .../bsd/openbsd/pkgs/rtld/package.nix | 31 ++++++++++ 3 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 pkgs/os-specific/bsd/openbsd/pkgs/rtld/ldso-fix-makefile.patch create mode 100644 pkgs/os-specific/bsd/openbsd/pkgs/rtld/package.nix diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/libc.nix b/pkgs/os-specific/bsd/openbsd/pkgs/libc.nix index 895b82ed5307..db49e28ec7e3 100644 --- a/pkgs/os-specific/bsd/openbsd/pkgs/libc.nix +++ b/pkgs/os-specific/bsd/openbsd/pkgs/libc.nix @@ -1,11 +1,13 @@ { lib, + stdenvNoLibc, symlinkJoin, libcMinimal, librthread, libm, librpcsvc, libutil, + rtld, version, }: @@ -27,13 +29,16 @@ symlinkJoin rec { (lib.getLib p) (lib.getMan p) ]) - [ - libcMinimal - libm - librthread - librpcsvc - libutil - ]; + ( + [ + libcMinimal + libm + librthread + librpcsvc + libutil + ] + ++ (lib.optional (!stdenvNoLibc.hostPlatform.isStatic) rtld) + ); postBuild = '' rm -r "$out/nix-support" diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/rtld/ldso-fix-makefile.patch b/pkgs/os-specific/bsd/openbsd/pkgs/rtld/ldso-fix-makefile.patch new file mode 100644 index 000000000000..b6155539e84c --- /dev/null +++ b/pkgs/os-specific/bsd/openbsd/pkgs/rtld/ldso-fix-makefile.patch @@ -0,0 +1,57 @@ +diff --git a/libexec/ld.so/Makefile b/libexec/ld.so/Makefile +index 7f8f6ef2961..469c34bb6de 100644 +--- a/libexec/ld.so/Makefile ++++ b/libexec/ld.so/Makefile +@@ -1,6 +1,5 @@ + # $OpenBSD: Makefile,v 1.88 2024/04/05 13:51:47 deraadt Exp $ + +-SUBDIR=ldconfig ldd + MAN= ld.so.1 + + .include +@@ -70,21 +69,15 @@ ELF_LDFLAGS+=--shared -Bsymbolic --no-undefined + + .ifdef RELATIVE_RELOC + CHECK_LDSO=c() { \ +- ! readelf -Wr $$1 | \ ++ ! $(READELF) -Wr $$1 | \ + egrep -qv '^($$|[ R])| (${RELATIVE_RELOC}) '; \ + }; c + .endif + +-test_prog= test-$(PROG) +-CLEANFILES+= test-$(PROG) + candidate= $(PROG).test + CLEANFILES+= ${candidate} + +-$(test_prog): +- printf '#include \n#include \nint main(int argc, char **argv){ pthread_attr_t attr; printf("%%s: ", argv[0]); pthread_attr_init(&attr); printf("%%s!\\n", argv[1] ? argv[1] : "foo"); }\n' | \ +- $(CC) -P -x c - -Wl,-dynamic-linker,./$(candidate) -o $@ -lpthread +- +-$(PROG): $(test_prog) ${VERSION_SCRIPT} $(OBJS) ${LD_SCRIPT} ++$(PROG): ${VERSION_SCRIPT} $(OBJS) ${LD_SCRIPT} + .if defined(SYSPATCH_PATH) + $(LD) -e _dl_start $(ELF_LDFLAGS) -o $(candidate) \ + `readelf -Ws ${SYSPATCH_PATH}/usr/libexec/${.TARGET} | \ +@@ -96,9 +89,6 @@ $(PROG): $(test_prog) ${VERSION_SCRIPT} $(OBJS) ${LD_SCRIPT} + .endif + .ifdef CHECK_LDSO + ${CHECK_LDSO} $(candidate) +-.endif +-.ifndef CROSSDIR +- ulimit -c 0; [ "`${.OBJDIR}/$(test_prog) ok`" = "${.OBJDIR}/$(test_prog): ok!" ] + .endif + cp $(candidate) $@ + .endif +@@ -113,10 +103,4 @@ CLEANFILES+= ld.so.a + all: ld.so.a + + ld.so.a: ${OBJS} ${.CURDIR}/Symbols.map ${test_prog} ${LD_SCRIPT} +- ar cqD $@ $? +- +-afterinstall: ld.so.a +- install -d -o root -g wheel -m 755 \ +- ${DESTDIR}/usr/share/relink/usr/libexec +- install -o ${BINOWN} -g ${BINGRP} -m ${NONBINMODE} \ +- ld.so.a ${DESTDIR}/usr/share/relink/usr/libexec/ld.so.a ++ $(AR) cqD $@ $? diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/rtld/package.nix b/pkgs/os-specific/bsd/openbsd/pkgs/rtld/package.nix new file mode 100644 index 000000000000..58fd1fd8ebd4 --- /dev/null +++ b/pkgs/os-specific/bsd/openbsd/pkgs/rtld/package.nix @@ -0,0 +1,31 @@ +{ + lib, + mkDerivation, +}: + +mkDerivation { + path = "libexec/ld.so"; + extraPaths = [ + "lib/libc/string" + "lib/csu/os-note-elf.h" + ]; + patches = [ + ./ldso-fix-makefile.patch + ]; + + libcMinimal = true; + + NIX_CFLAGS_COMPILE = "-Wno-error"; + + # DESTDIR is overridden in bsdSetupHook, just fixup afterwards + postInstall = '' + mv $out/bin $out/libexec + ''; + + outputs = [ + "out" + "man" + ]; + + meta.platforms = lib.platforms.openbsd; +} From 6da0a87109da2ea84a076c34dd66a7e596952438 Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Thu, 24 Oct 2024 00:15:36 +0000 Subject: [PATCH 3/3] bintools-wrapper: Set dynamic-linker on OpenBSD Now that ld.so is symlinked into the libc derivation, we can use it as a dynamic linker. In my testing, OpenBSD does not have any issues with executing from a symlinked ld.so. --- pkgs/build-support/bintools-wrapper/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index b4736bc960fa..6d8b9a0a7593 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -134,6 +134,7 @@ let else if targetPlatform.isLoongArch64 then "${sharedLibraryLoader}/lib/ld-linux-loongarch*.so.1" else if targetPlatform.isDarwin then "/usr/lib/dyld" else if targetPlatform.isFreeBSD then "${sharedLibraryLoader}/libexec/ld-elf.so.1" + else if targetPlatform.isOpenBSD then "${sharedLibraryLoader}/libexec/ld.so" else if hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" else "";