-
Notifications
You must be signed in to change notification settings - Fork 18k
runtime, liblink, cmd/ld: externally linked binaries without cgo crash immediately on amd64 #9913
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
Labels
Milestone
Comments
mwhudson
added a commit
to mwhudson/go
that referenced
this issue
Feb 18, 2015
The runtime assumes that it knows the offset from the TLS base to g, but in the external linking case it is actually the host linker that decides. This changes the runtime (on linux/amd64 only) to use a global variable with a magic name that the linker recognizes and generates the appropriate relocation to overwrite it with the offset. Fixes golang#9913 Change-Id: I75050866dbb7f0f5a952ffaa9c4caca6e5212ee7
The reason external linked programs require runtime/cgo is that on certain
OSes
(notably Darwin), once the system libc runs, we can no longer create
threads using
syscalls due to conflicts (bsdthread_register).
|
Ah, so my evil plan to delete that code completely can't work. Shame. Maybe we can update the comment though? |
Sure.
|
mwhudson
added a commit
to mwhudson/go
that referenced
this issue
Mar 16, 2015
For OSes that use elf on intel, 2*Ptrsize bytes are reserved for TLS. But only one pointer (g) has been stored in the TLS for a while now. So we can set it to just Ptrsize, which happily matches what happens when externally linking. Fixes golang#9913 Change-Id: Ic816369d3a55a8cdcc23be349b1a1791d53f5f81
mwhudson
added a commit
to mwhudson/go
that referenced
this issue
Mar 16, 2015
The runtime assumes that it knows the offset from the TLS base to g, but in the external linking case it is actually the host linker that decides. This changes the runtime (on linux/amd64 only) to use a global variable with a magic name that the linker recognizes and generates the appropriate relocation to overwrite it with the offset. Fixes golang#9913 Change-Id: I75050866dbb7f0f5a952ffaa9c4caca6e5212ee7
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
If you externally link a binary and runtime/cgo.a cannot be found (maybe by saying CGO_ENABLED=0 ./make.bash) you get a warning, and a binary that crashes during startup:
The reason turns out to be a disagreement over the TLS offset for g. Presumably because both g and m used to be stored in TLS, the runtime and internal linking assumes it to be 16 but as g is now the only pointer stored in TLS, binutils ld sets it to 8, causing the tls consistency check on startup to fail.
I see two ways to fix this: one would be to just change the runtime and internal linker to assume the offset is 8 bytes and the other would be use a special relocation to get the linker (either internal or external) to tell us what the symbol is. In the latter case I don't think there would really be any need to do the magic import of runtime/cgo in an externally linked program (the comment justifying it is already a bit wrong, unless I am very confused).
The text was updated successfully, but these errors were encountered: