Skip to content

Commit

Permalink
cmd/link: detect glibc vs musl ldso at link time
Browse files Browse the repository at this point in the history
Doing the test at link time lets us distribute one Linux toolchain
that works on both glibc-based and musl-based Linux systems.
The old way built a toolchain that only ran on one or the other.

Fixes #54197.

Change-Id: Iaae8c274c78e1091eee828a720b49646be9bfffe
Reviewed-on: https://go-review.googlesource.com/c/go/+/420774
Auto-Submit: Russ Cox <[email protected]>
Reviewed-by: Cherry Mui <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Run-TryBot: Russ Cox <[email protected]>
  • Loading branch information
rsc authored and gopherbot committed Aug 8, 2022
1 parent 52dfdc5 commit 3315066
Show file tree
Hide file tree
Showing 12 changed files with 37 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/cmd/link/internal/amd64/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func Init() (*sys.Arch, ld.Arch) {
TLSIEtoLE: tlsIEtoLE,

Linuxdynld: "/lib64/ld-linux-x86-64.so.2",
LinuxdynldMusl: "/lib/ld-musl-x84_64.so.1",
Freebsddynld: "/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "/libexec/ld.elf_so",
Expand Down
1 change: 1 addition & 0 deletions src/cmd/link/internal/arm/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ func Init() (*sys.Arch, ld.Arch) {
PEreloc1: pereloc1,

Linuxdynld: "/lib/ld-linux.so.3", // 2 for OABI, 3 for EABI
LinuxdynldMusl: "/lib/ld-musl-arm.so.1",
Freebsddynld: "/usr/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "/libexec/ld.elf_so",
Expand Down
5 changes: 3 additions & 2 deletions src/cmd/link/internal/arm64/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ func Init() (*sys.Arch, ld.Arch) {
PEreloc1: pereloc1,
Trampoline: trampoline,

Androiddynld: "/system/bin/linker64",
Linuxdynld: "/lib/ld-linux-aarch64.so.1",
Androiddynld: "/system/bin/linker64",
Linuxdynld: "/lib/ld-linux-aarch64.so.1",
LinuxdynldMusl: "/lib/ld-musl-aarch64.so.1",

Freebsddynld: "/usr/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Expand Down
11 changes: 11 additions & 0 deletions src/cmd/link/internal/ld/elf.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"encoding/hex"
"fmt"
"internal/buildcfg"
"os"
"path/filepath"
"runtime"
"sort"
Expand Down Expand Up @@ -1782,6 +1783,16 @@ func asmbElf(ctxt *Link) {
}
} else {
interpreter = thearch.Linuxdynld
// If interpreter does not exist, try musl instead.
// This lets the same cmd/link binary work on
// both glibc-based and musl-based systems.
if _, err := os.Stat(interpreter); err != nil {
if musl := thearch.LinuxdynldMusl; musl != "" {
if _, err := os.Stat(musl); err == nil {
interpreter = musl
}
}
}
}

case objabi.Hfreebsd:
Expand Down
1 change: 1 addition & 0 deletions src/cmd/link/internal/ld/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ type Arch struct {

Androiddynld string
Linuxdynld string
LinuxdynldMusl string
Freebsddynld string
Netbsddynld string
Openbsddynld string
Expand Down
1 change: 1 addition & 0 deletions src/cmd/link/internal/loong64/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func Init() (*sys.Arch, ld.Arch) {
Gentext: gentext,

Linuxdynld: "/lib64/ld.so.1",
LinuxdynldMusl: "/lib64/ld-musl-loongarch.so.1",
Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Expand Down
5 changes: 4 additions & 1 deletion src/cmd/link/internal/mips/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ import (

func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchMIPS
musl := "/lib/ld-musl-mips.so.1"
if buildcfg.GOARCH == "mipsle" {
arch = sys.ArchMIPSLE
musl = "/lib/ld-musl-mipsel.so.1"
}

theArch := ld.Arch{
Expand All @@ -60,7 +62,8 @@ func Init() (*sys.Arch, ld.Arch) {
Gentext: gentext,
Machoreloc1: machoreloc1,

Linuxdynld: "/lib/ld.so.1",
Linuxdynld: "/lib/ld.so.1",
LinuxdynldMusl: musl,

Freebsddynld: "XXX",
Openbsddynld: "XXX",
Expand Down
3 changes: 3 additions & 0 deletions src/cmd/link/internal/mips64/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ import (

func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchMIPS64
musl := "/lib/ld-musl-mips64.so.1"
if buildcfg.GOARCH == "mips64le" {
arch = sys.ArchMIPS64LE
musl = "/lib/ld-musl-mips64el.so.1"
}

theArch := ld.Arch{
Expand All @@ -60,6 +62,7 @@ func Init() (*sys.Arch, ld.Arch) {
Machoreloc1: machoreloc1,

Linuxdynld: "/lib64/ld64.so.1",
LinuxdynldMusl: musl,
Freebsddynld: "XXX",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "XXX",
Expand Down
4 changes: 4 additions & 0 deletions src/cmd/link/internal/ppc64/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ import (
func Init() (*sys.Arch, ld.Arch) {
arch := sys.ArchPPC64LE
dynld := "/lib64/ld64.so.2"
musl := "/lib/ld-musl-powerpc64le.so.1"

if buildcfg.GOARCH == "ppc64" {
arch = sys.ArchPPC64
dynld = "/lib64/ld64.so.1"
musl = "/lib/ld-musl-powerpc64.so.1"
}

theArch := ld.Arch{
Expand All @@ -68,6 +70,8 @@ func Init() (*sys.Arch, ld.Arch) {
Xcoffreloc1: xcoffreloc1,

Linuxdynld: dynld,
LinuxdynldMusl: musl,

Freebsddynld: "XXX",
Openbsddynld: "XXX",
Netbsddynld: "XXX",
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/link/internal/s390x/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ func Init() (*sys.Arch, ld.Arch) {
Gentext: gentext,
Machoreloc1: machoreloc1,

Linuxdynld: "/lib64/ld64.so.1",
Linuxdynld: "/lib64/ld64.so.1",
LinuxdynldMusl: "/lib/ld-musl-s390x.so.1",

// not relevant for s390x
Freebsddynld: "XXX",
Expand Down
11 changes: 6 additions & 5 deletions src/cmd/link/internal/x86/obj.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ func Init() (*sys.Arch, ld.Arch) {
Machoreloc1: machoreloc1,
PEreloc1: pereloc1,

Linuxdynld: "/lib/ld-linux.so.2",
Freebsddynld: "/usr/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "/usr/libexec/ld.elf_so",
Solarisdynld: "/lib/ld.so.1",
Linuxdynld: "/lib/ld-linux.so.2",
LinuxdynldMusl: "/lib/ld-musl-i386.so.1",
Freebsddynld: "/usr/libexec/ld-elf.so.1",
Openbsddynld: "/usr/libexec/ld.so",
Netbsddynld: "/usr/libexec/ld.elf_so",
Solarisdynld: "/lib/ld.so.1",
}

return arch, theArch
Expand Down
9 changes: 0 additions & 9 deletions src/make.bash
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,6 @@ if [ "$(uname -s)" = "GNU/kFreeBSD" ]; then
export CGO_ENABLED=0
fi

# Test which linker/loader our system is using, if GO_LDSO is not set.
if [ -z "$GO_LDSO" ] && type readelf >/dev/null 2>&1; then
if echo "int main() { return 0; }" | ${CC:-cc} -o ./test-musl-ldso -x c - >/dev/null 2>&1; then
LDSO=$(readelf -l ./test-musl-ldso | grep 'interpreter:' | sed -e 's/^.*interpreter: \(.*\)[]]/\1/') >/dev/null 2>&1
[ -z "$LDSO" ] || export GO_LDSO="$LDSO"
rm -f ./test-musl-ldso
fi
fi

# Clean old generated file that will cause problems in the build.
rm -f ./runtime/runtime_defs.go

Expand Down

0 comments on commit 3315066

Please sign in to comment.