From: Michael Hudson-Doyle Date: Tue, 5 Jan 2021 23:18:24 +0000 (+1300) Subject: [PATCH] cmd/link: check CGO_CFLAGS for non -g/-I/-O options before internal linking X-Git-Tag: archive/raspbian/1.15.8-3+rpi1^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a5a7b09fb8be678733e27932fa1218ce3e10254b;p=golang-1.15.git [PATCH] cmd/link: check CGO_CFLAGS for non -g/-I/-O options before internal linking On Debian and Ubuntu we are investigating enabling link-time optimization by default, which means the default CFLAGS will contain arguments that cause gcc to generate object files cmd/link/internal/loadelf cannot process. Rather than failing in this situation, scan CGO_CFLAGS in mustLinkExternal and do not link internally if there is a flag that does not start with -g, -I, or -O. CFLAGS can also be injected via #cgo CFLAGS: directives but as use of any non-standard library cgo modules disables internal linking anyway, we don't have to worry about that here. Fixes #43505 Change-Id: Ib083f6daf22617e2e5df67e95d3bc178942328cd Gbp-Pq: Name 0007-cmd-link-check-CGO_CFLAGS-for-non-g-I-O-options-befo.patch --- diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go index 2373b500..18fc5d2c 100644 --- a/src/cmd/link/internal/ld/config.go +++ b/src/cmd/link/internal/ld/config.go @@ -9,6 +9,8 @@ import ( "cmd/internal/sys" "fmt" "log" + "os" + "strings" ) // A BuildMode indicates the sort of object we are building. @@ -164,6 +166,15 @@ func (mode *LinkMode) String() string { return fmt.Sprintf("LinkMode(%d)", uint8(*mode)) } +// Some arguments in CGO_CFLAGS can cause the host compiler to +// generate object files that loadelf cannot handle but arguments +// starting with any of these values are OK. +var internalOKCflagPrefixes = []string{ + "-O", + "-g", + "-I", +} + // mustLinkExternal reports whether the program being linked requires // the external linker be used to complete the link. func mustLinkExternal(ctxt *Link) (res bool, reason string) { @@ -223,6 +234,16 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) { return true, "dynamically linking with a shared library" } +outer: + for _, flag := range strings.Fields(os.Getenv("CGO_CFLAGS")) { + for _, okPrefix := range internalOKCflagPrefixes { + if strings.HasPrefix(flag, okPrefix) { + continue outer + } + } + return true, "CGO_CFLAGS contains flag that may inhibit internal linking: " + flag + } + return false, "" }