Extend linker-script workaround to work with musl libc
authorSamuel Holland <samuel@sholland.org>
Mon, 21 Jan 2019 02:20:16 +0000 (20:20 -0600)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Mon, 21 Jan 2019 23:28:38 +0000 (18:28 -0500)
GHC has code to handle unsuffixed .so files that are linker scripts
pointing to the real shared library. The detection is done by parsing
the result of `dlerror()` after calling `dlopen()` and looking for
certain error strings. On musl libc, the error message is "Exec format
error", which happens to be `strerror(ENOEXEC)`:

```
$ cat tmp.c
#include <dlfcn.h>
#include <stdio.h>

int main(void) {
        dlopen("libz.so", RTLD_NOW | RTLD_GLOBAL);
        puts(dlerror());
        return 0;
}
$ gcc -o tmp tmp.c
$ ./tmp
Error loading shared library libz.so: Exec format error
$
```

This change fixes the workaround to also work on musl libc.

Link: https://phabricator.haskell.org/D5474
rts/Linker.c

index 5b10b79..ac030af 100644 (file)
@@ -483,7 +483,7 @@ initLinker_ (int retain_cafs)
 #   endif /* RTLD_DEFAULT */
 
     compileResult = regcomp(&re_invalid,
-           "(([^ \t()])+\\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)",
+           "(([^ \t()])+\\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format|Exec format error)",
            REG_EXTENDED);
     if (compileResult != 0) {
         barf("Compiling re_invalid failed");