mold: Linking musl with mold causes issues with global variables from libc
mold version: 2.0.0 musl version: 1.2.4
I recently rebuilt musl and used mold to link it, and subsequently experienced segfaults and bugs in a lot of random programs. After some digging, I found that the problems were all from globals from musl (program_invocation_short_name and optind in particular). Using a different linker to link musl fixed the problems.
Interestingly, programs built with clang didn’t have these problems. Consider this C program:
#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
int
main(void) {
puts(program_invocation_short_name);
return 0;
}
This program, built with GCC against musl linked with mold, segfaults when puts tries to dereference a NULL pointer.
The difference between clang and GCC is how the global is accessed. GCC does this:
movq program_invocation_short_name(%rip), %rdi
call puts@PLT
but clang does this:
movq program_invocation_short_name@GOTPCREL(%rip), %rax
movq (%rax), %rdi
call puts@PLT
I have confirmed that the use of @GOTPCREL fixes the GCC program.
The first version always gets NULL, the second gets the correct value initialised by musl.
Similarly with optind, in GCC programs, optind is always 1 even after calling getopt, but clang programs can read the updated value.
Now, this is quickly approaching the limits of my understanding. Please let me know if I can help with more testing.
This happened to me once before a few months ago, but since then I had forgotten how I fixed it.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 20 (12 by maintainers)
The mimalloc segfault is fixed by da3f5dd as well, thanks!
It seems to be fixed, thank you!
@rui314 I made a docker image with the above commands run, so that it contains the buggy musl. Just
to reproduce.