diff options
| author | Than McIntosh <thanm@google.com> | 2023-03-10 10:29:38 -0500 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2023-03-14 13:17:46 +0000 |
| commit | 035db07d7c5f1b90ebc9bae03cab694685acebb8 (patch) | |
| tree | 2adb1f902e46d03873654b503451fe3cf9e29e9b /src/cmd/link/internal | |
| parent | b37c0602cdc9b7f13b3d539663e68b12f10b44b1 (diff) | |
| download | go-035db07d7c5f1b90ebc9bae03cab694685acebb8.tar.xz | |
cmd/go,cmd/link: prefer external linking when strange cgo flags seen
This patch changes the Go command to examine the set of compiler
flags feeding into the C compiler when packages that use cgo are built.
If any of a specific set of strange/dangerous flags are in use,
then the Go command generates a token file ("preferlinkext") and
embeds it into the compiled package's archive.
When the Go linker reads the archives of the packages feeding into the
link and detects a "preferlinkext" token, it will then use external
linking for the program by default (although this default can be
overridden with an explicit "-linkmode" flag).
The intent here is to avoid having to teach the Go linker's host object
reader to grok/understand the various odd symbols/sections/types that
can result from boutique flag use, but rather to just boot the objects
in question over to the C linker instead.
Updates #58619.
Updates #58620.
Updates #58848.
Change-Id: I56382dd305de8dac3841a7a7e664277826061eaa
Reviewed-on: https://go-review.googlesource.com/c/go/+/475375
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/link/internal')
| -rw-r--r-- | src/cmd/link/internal/ld/config.go | 6 | ||||
| -rw-r--r-- | src/cmd/link/internal/ld/lib.go | 13 |
2 files changed, 18 insertions, 1 deletions
diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go index 7cce28dac5..c0484d6c39 100644 --- a/src/cmd/link/internal/ld/config.go +++ b/src/cmd/link/internal/ld/config.go @@ -198,7 +198,11 @@ func determineLinkMode(ctxt *Link) { ctxt.LinkMode = LinkExternal via = "via GO_EXTLINK_ENABLED " default: - if extNeeded || (iscgo && externalobj) { + preferExternal := len(preferlinkext) != 0 + if preferExternal && ctxt.Debugvlog > 0 { + ctxt.Logf("external linking prefer list is %v\n", preferlinkext) + } + if extNeeded || (iscgo && (externalobj || preferExternal)) { ctxt.LinkMode = LinkExternal } else { ctxt.LinkMode = LinkInternal diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index b64176e35d..02c6908407 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -341,6 +341,12 @@ var ( // any of these objects, we must link externally. Issue 52863. dynimportfail []string + // preferlinkext is a list of packages for which the Go command + // noticed use of peculiar C flags. If we see any of these, + // default to linking externally unless overridden by the + // user. See issues #58619, #58620, and #58848. + preferlinkext []string + // unknownObjFormat is set to true if we see an object whose // format we don't recognize. unknownObjFormat = false @@ -1086,6 +1092,13 @@ func loadobjfile(ctxt *Link, lib *sym.Library) { if arhdr.name == "dynimportfail" { dynimportfail = append(dynimportfail, lib.Pkg) } + if arhdr.name == "preferlinkext" { + // Ignore this directive if -linkmode has been + // set explicitly. + if ctxt.LinkMode == LinkAuto { + preferlinkext = append(preferlinkext, lib.Pkg) + } + } // Skip other special (non-object-file) sections that // build tools may have added. Such sections must have |
