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>
This commit is contained in:
Than McIntosh 2023-03-10 10:29:38 -05:00
parent b37c0602cd
commit 035db07d7c
8 changed files with 294 additions and 15 deletions

View file

@ -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