$ORIGIN is not what it appears
Summary
A ton of tests broke on OpenBSD on aa3a262d.
Steps to reproduce
Commit aa3a262d merged in !9767 (closed) is detrimental on OpenBSD. The first symptom is a ton of tests are failing with the likes of:
Wrong exit code for CountDepsParser()(expected 0 , actual 2 )
Stderr ( CountDepsParser ):
ld.so: count-deps: can't load library 'libHSunix-2.8.0.0-ghc9.7.20230221.so'
The binaries are weirdly broken now, they work fine from stage1 but they fail when invoked from a sym-linked location, i.e. test/bin. E.g.
% ldd ./_validatebuild/test/bin/check-exact
./_validatebuild/test/bin/check-exact:
ld.so: check-exact: can't load library 'libHStime-1.12.2-ghc9.7.20230221.so'
./_validatebuild/test/bin/check-exact: signal 9
% ./_validatebuild/test/bin/check-exact
ld.so: check-exact: can't load library 'libHSexceptions-0.10.7-ghc9.7.20230221.so'
[1] 28192 killed ./_validatebuild/test/bin/check-exact
% ./_validatebuild/stage1/bin/check-exact
Missing file: /home/alanz/mysrc/git.haskell.org/worktree/master/_build/stage1/lib/settings
% readelf --dynamic ./_validatebuild/stage1/bin/check-exact | grep RUNPATH
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/../lib/x86_64-openbsd-ghc-9.7.20230221:$ORIGIN/../../../lib/x86_64-openbsd-ghc-9.7.20230221]
% ls -l ./_validatebuild/test/bin/check-exact
lrwxr-xr-x 1 greg greg 61 Feb 20 20:01 ./_validatebuild/test/bin/check-exact -> /home/greg/s/ghc-broken/_validatebuild/stage1/bin/check-exact
% ls -l ./_validatebuild/test/lib
ls: ./_validatebuild/test/lib: No such file or directory
When I build at the commit before this change I get a much more verbose RUNPATH which works fine when the binary is symlinked into test/bin.
% readelf --dynamic ghc/_validatebuild/test/bin/check-exact | grep RUNP
0x000000000000001d (RUNPATH) Library runpath: [/home/greg/s/ghc/_validatebuild/stage1/inplace/../compiler/build:...
The semantics of $ORIGIN is not covered by any standard I know of. If I read the Linux manual page literally, the behavior of OpenBSD ld.so is not errant:
$ORIGIN (or equivalently ${ORIGIN}) This expands to the directory containing the program or shared object. Thus, an application located in somedir/app could be compiled with
gcc -Wl,-rpath,'$ORIGIN/../lib'
so that it finds an associated shared object in somedir/lib no matter where somedir is located in the directory hierarchy. This facilitates the creation of "turn-key" applications that do not need to be installed into special directories, but can instead be unpacked into any directory and still find their own shared objects.
The symlinked test/bin
location does NOT have a corresponding
test/lib
where $ORIGIN
points at. Apparently other implementations
resolve $ORIGIN
relative to the symlink pointee.
Environment
- GHC version used: aa3a262d
Optional:
- Operating System: OpenBSD
- System Architecture: amd64
FYI @PHO