Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/link: determine GO_LDSO on Linux at link time instead of baking in make.bash #54197

rsc opened this issue Aug 2, 2022 · 2 comments
compiler/runtime NeedsInvestigation


Copy link

@rsc rsc commented Aug 2, 2022

#54196 identifies a general problem with our baked-in variables and a general fix of making them per-GOOS/GOARCH. But GO_LDSO is not really even per-GOOS/GOARCH: there are different settings needed on different linux/amd64 systems.

The computation during make.bash of a default GO_LDSO added in CL 301989 is particularly problematic for cross-compilation, since the GO_LDSO is only right for the current machine. CL 343010 fixed the problem for cross-compiling from one machine to another, but it does not fix the problem when the cross-compilation is used to build a bootstrap toolchain that is copied to a new machine. Then the GOOS and GOARCH tests flip back to true and the bootstrap toolchain uses the GO_LDSO setting from the original machine. This makes it impossible today to use bootstrap.bash to build an OpenBSD toolchain from Linux: when the toolchain is run on OpenBSD, it uses a GO_LDSO setting that is only appropriate on Linux. We should at the least make GO_LDSO per-GOOS/GOARCH and probably only bake in GO_LDSO_${GOOS}_${GOARCH} implicitly in make.bash. But I also wonder about baking it in at all. The default baking makes non-cross-compilation subtly different from cross compilation, which will keep coming back to bite us. And essentially all systems have a hard-coded ldso path.

CL 301989 was done to deal with the confusion of having two different on Linux systems, but then we end up with toolchains that still only work on one system or the other. Any bake-in is going to have that property. It seems like a better fix would be to not bake anything in by default and instead have the linker stat the two possible paths and use the one it finds. Then the same linker binary will produce working binaries on glibc- and musl-based systems.

/cc @ianlancetaylor and @cherrymui for thoughts. I am happy to write the CL adding the stat call in cmd/link and removing the GO_LDSO baking in make.bash.

Copy link

@gopherbot gopherbot commented Aug 2, 2022

Change mentions this issue: cmd/link: detect glibc vs musl ldso at link time

Copy link

@ianlancetaylor ianlancetaylor commented Aug 2, 2022

As far as I know this confusion about dynamic linkers is specific to Linux.

For GCC you pick a target when you build GCC. That sets the default dynamic linker. Then you can override that default with the options -mglibc, -muclibc, -mmusl, -mbionic. The -mbionic option corresponds to our GOOS == "android". uclibc always uses /lib/ or /lib/ musl unfortunately varies by GOARCH.

Trying to detect the default at run time is reasonable though we will sometimes get it wrong. And we will need a table of values for musl.

This is what I pulled out of the GCC sources for the musl dynamic linker:

arm64 /lib/ld-musl-aarch64[_be][_ilp32].so.1
arm /lib/ld-musl-arm[eb][hf][-fdpic].so.1
386 /lib/
amd64 /lib/
loongarch64 /lib64/ld-musl-loongarch-{,lp64d,lp64f,lp64s}.so.1
mips /lib/ld-musl-mips[el][-sf].so.1
mips64 /lib/ld-musl-mips64[el][-sf].so.1
risv64 /lib/
powerp64 /lib/ld-musl-powerpc[le][sf].so.1
s390x /lib/

@dmitshur dmitshur added the NeedsInvestigation label Aug 3, 2022
@dmitshur dmitshur added this to the Backlog milestone Aug 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
compiler/runtime NeedsInvestigation
Status: Done

No branches or pull requests

4 participants