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)

Commits related to this issue

Most upvoted comments

The mimalloc segfault is fixed by da3f5dd as well, thanks!

da3f5dd

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

docker run -it aabacchus/test sh
cc test.c
./a.out

to reproduce.