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/ld: -linkmode=external doesn't always use the external linker? #5238

Closed
agoode opened this issue Apr 8, 2013 · 15 comments
Closed

cmd/ld: -linkmode=external doesn't always use the external linker? #5238

agoode opened this issue Apr 8, 2013 · 15 comments
Milestone

Comments

@agoode
Copy link

agoode commented Apr 8, 2013

What steps will reproduce the problem?
If possible, include a link to a program on play.golang.org.
1. Compile a pure-go (no C files) binary with -linkmode=external
2. Run readelf -n on the binary, looking for a system-ld generated build-id section


What is the expected output?
A build-id section (.note.gnu.build-id) in the ELF file, which implies that the system
linker was run.


What do you see instead?
No such section.

Which compiler are you using (5g, 6g, 8g, gccgo)?
6g

Which operating system are you using?
Linux

Which version are you using?  (run 'go version')
go version devel +267bb9854177 Wed Apr 03 18:23:43 2013 -0700 linux/amd64

Please provide any additional information below.
This does seem to work for binaries where cgo is involved. go and gofmt have these
sections, but gofmt does not.
@bradfitz
Copy link
Contributor

bradfitz commented Apr 8, 2013

Comment 1:

Owner changed to @ianlancetaylor.

Status changed to Accepted.

@minux
Copy link
Member

minux commented Apr 8, 2013

Comment 2:

why link pure-Go programs with the system linker?

@agoode
Copy link
Author

agoode commented Apr 8, 2013

Comment 3:

At least on Fedora, the 2 main reasons I see for linking with the system linker are:
 build-id support: http://fedoraproject.org/wiki/Releases/FeatureBuildId
 GNU_HASH support: http://www.sourceware.org/ml/binutils/2006-06/msg00418.html
Both of these could be added to 6l (and indeed 6l has partial build-id support), but
until then it would be nice if the external linker was an option. Plus, this allows for
future system-dependent features to be added to the system linker without needing
special support in 6l.

@ianlancetaylor
Copy link
Contributor

Comment 4:

Putting this on the Go 1.1 list to decide what to do; this is not a promise that it will
be fixed for Go 1.1.

Labels changed: added go1.1.

@ianlancetaylor
Copy link
Contributor

Comment 5:

https://golang.org/cl/8716044

Status changed to Started.

@ianlancetaylor
Copy link
Contributor

Comment 6:

This issue was closed by revision 6969012.

Status changed to Fixed.

@agoode
Copy link
Author

agoode commented Apr 13, 2013

Comment 7:

This seems to break building of go with GO_LDFLAGS="-linkmode external".
It is now refusing to build runtime/cgo.a, I get many messages during the build
"warning: unable to find runtime/cgo.a". When I try to run cgo itself, I get a segfault,
which makes some sense because I guess it is missing its own runtime code?

@minux
Copy link
Member

minux commented Apr 13, 2013

Comment 8:

i think we really shouldn't build non-cgo Go programs with
-linkmode external, because it's not free, as it makes
the program depending on runtime/cgo it has many consequences.
(for one, the Go command will fail to see its pseudo dependency
on runtime/cgo, for another, it will lose the static linking
feature enjoyed by normal non-cgo programs)
I suggest we revert rev 54957b8906eb for Go 1.1 and reconsider
this issue after Go 1.1 is released (for one, i think external
linking a non-cgo program should still produce a static binary).

@ianlancetaylor
Copy link
Contributor

Comment 9:

I don't see why we should support building Go itself with GO_LDFLAGS="-linkmode
external".  That seems designed for failure.
This bug has a real use case for using -linkmode external.  If you want to use -linkmode
external and get a statically linked binary, it's easy enough to use -extldflags -static.
The dependency on runtime/cgo is a fair point but I don't think it is a major one for
most people.

@minux
Copy link
Member

minux commented Apr 15, 2013

Comment 10:

ah, sorry, i don't know that external link can produce static binary
with -extldflags -static now.

@agoode
Copy link
Author

agoode commented Apr 15, 2013

Comment 11:

Building Go with linkmode external is my main motivation for this bug, to enable the
various linker-provided features available in Fedora.
Why is Go itself special in this regard?

@minux
Copy link
Member

minux commented Apr 15, 2013

Comment 12:

currently, building Go code with external linking mode means
to force it to use cgo and switch to use pthread to create
threads (instead of calling clone(2) directly), so every OS
thread incurs a bigger thread stack penalty (as we need to
accommodate pthread's requirement).
using cgo means every program needs runtime/cgo, but there
is circular dependency:
runtime/cgo needs cmd/cgo to build,
but when building in external linking mode, cmd/cgo needs
runtime/cgo.
To fix this, we must first build a internal linked copy of
cmd/cgo to bootstrap the whole process. This is doable,
but not at this stage.

@agoode
Copy link
Author

agoode commented Apr 15, 2013

Comment 13:

Aha, I did not realize the extent of the changes. The pthreads requirement seems
especially invasive. Thanks for the explanation.
So it seems that at this point, a better approach would be to extend the Go linker to
support the features needed directly. I'll perhaps file some feature request bugs for
tracking this separately.

@ianlancetaylor
Copy link
Contributor

Comment 14:

Can you explain why you want to do this?  Do you specifically want a
linker build ID in the Go binaries themselves?

@agoode
Copy link
Author

agoode commented Apr 15, 2013

Comment 15:

Yes, the Go binaries should have a build-id in them on Fedora. This helps because Fedora
extracts the debug symbols during build and packages them separately. The build-id
allows the system to correctly find (and download) the correct debuginfo package for any
given binary.
http://sourceware.org/binutils/docs-2.23.1/ld/Options.html#index-g_t_002d_002dbuild_002did-271
Go's linker has the build-id support, but does not currently implement the exact sha1
hashing that the system linker does.
Actually, perhaps the best way forward is to figure out how to put build-id information
into an arbitrary existing binary. This would solve the issue in a general way without
anything special from Go.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015
@rsc rsc removed the go1.1 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants