aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2023-03-10 10:29:38 -0500
committerThan McIntosh <thanm@google.com>2023-03-14 13:17:46 +0000
commit035db07d7c5f1b90ebc9bae03cab694685acebb8 (patch)
tree2adb1f902e46d03873654b503451fe3cf9e29e9b /src/cmd/link
parentb37c0602cdc9b7f13b3d539663e68b12f10b44b1 (diff)
downloadgo-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')
-rw-r--r--src/cmd/link/internal/ld/config.go6
-rw-r--r--src/cmd/link/internal/ld/lib.go13
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