aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQuim Muntal <quimmuntal@gmail.com>2020-10-22 22:32:20 +0200
committerDmitri Shuralyov <dmitshur@golang.org>2021-03-31 21:39:47 +0000
commit82f9c6cac1bcc6bc80f17d1415ac3f62c0afa6c5 (patch)
tree085a8f22ae2d11d1feb6c5c495b41786fccbaa1d /src
parent5055314a5749664ab66a24beed8158552e276959 (diff)
downloadgo-82f9c6cac1bcc6bc80f17d1415ac3f62c0afa6c5.tar.gz
go-82f9c6cac1bcc6bc80f17d1415ac3f62c0afa6c5.zip
[release-branch.go1.15] cmd/link: avoid exporting all symbols on windows buildmode=pie
Marking one functions with __declspec(dllexport) forces mingw to create .reloc section without having to export all symbols. See https://insights.sei.cmu.edu/cert/2018/08/when-aslr-is-not-really-aslr---the-case-of-incorrect-assumptions-and-bad-defaults.html for more info. This change cuts 73kb of a "hello world" pie binary. Updates #6853. Updates #40795. Fixes #43592. Change-Id: I3cc57c3b64f61187550bc8751dfa085f106c8475 Reviewed-on: https://go-review.googlesource.com/c/go/+/264459 Trust: Alex Brainman <alex.brainman@gmail.com> Run-TryBot: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Reviewed-by: Austin Clements <austin@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/300692 Trust: Dmitri Shuralyov <dmitshur@golang.org> Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/go/go_test.go33
-rw-r--r--src/cmd/link/internal/ld/lib.go3
-rw-r--r--src/runtime/cgo/gcc_windows_386.c1
-rw-r--r--src/runtime/cgo/gcc_windows_amd64.c1
-rw-r--r--src/runtime/cgo/libcgo_windows.h12
5 files changed, 47 insertions, 3 deletions
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 021930a8a81..3f790cdeabc 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -9,6 +9,7 @@ import (
"debug/elf"
"debug/macho"
"debug/pe"
+ "encoding/binary"
"flag"
"fmt"
"go/format"
@@ -2166,6 +2167,38 @@ func testBuildmodePIE(t *testing.T, useCgo, setBuildmodeToPIE bool) {
if (dc & pe.IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) == 0 {
t.Error("IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE flag is not set")
}
+ if useCgo {
+ // Test that only one symbol is exported (#40795).
+ // PIE binaries don´t require .edata section but unfortunately
+ // binutils doesn´t generate a .reloc section unless there is
+ // at least one symbol exported.
+ // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
+ section := f.Section(".edata")
+ if section == nil {
+ t.Fatalf(".edata section is not present")
+ }
+ // TODO: deduplicate this struct from cmd/link/internal/ld/pe.go
+ type IMAGE_EXPORT_DIRECTORY struct {
+ _ [2]uint32
+ _ [2]uint16
+ _ [2]uint32
+ NumberOfFunctions uint32
+ NumberOfNames uint32
+ _ [3]uint32
+ }
+ var e IMAGE_EXPORT_DIRECTORY
+ if err := binary.Read(section.Open(), binary.LittleEndian, &e); err != nil {
+ t.Fatalf("binary.Read failed: %v", err)
+ }
+
+ // Only _cgo_dummy_export should be exported
+ if e.NumberOfFunctions != 1 {
+ t.Fatalf("got %d exported functions; want 1", e.NumberOfFunctions)
+ }
+ if e.NumberOfNames != 1 {
+ t.Fatalf("got %d exported names; want 1", e.NumberOfNames)
+ }
+ }
default:
panic("unreachable")
}
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index fc897599970..d03fb6cf91b 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1423,9 +1423,6 @@ func (ctxt *Link) hostlink() {
if ctxt.Arch.PtrSize >= 8 {
argv = append(argv, "-Wl,--high-entropy-va")
}
- // Work around binutils limitation that strips relocation table for dynamicbase.
- // See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
- argv = append(argv, "-Wl,--export-all-symbols")
default:
// ELF.
if ctxt.UseRelro() {
diff --git a/src/runtime/cgo/gcc_windows_386.c b/src/runtime/cgo/gcc_windows_386.c
index 9184b91393f..60cb011bf24 100644
--- a/src/runtime/cgo/gcc_windows_386.c
+++ b/src/runtime/cgo/gcc_windows_386.c
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <errno.h>
#include "libcgo.h"
+#include "libcgo_windows.h"
static void threadentry(void*);
diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c
index 7192a246315..0f8c817f0e4 100644
--- a/src/runtime/cgo/gcc_windows_amd64.c
+++ b/src/runtime/cgo/gcc_windows_amd64.c
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <errno.h>
#include "libcgo.h"
+#include "libcgo_windows.h"
static void threadentry(void*);
diff --git a/src/runtime/cgo/libcgo_windows.h b/src/runtime/cgo/libcgo_windows.h
new file mode 100644
index 00000000000..0013f06baeb
--- /dev/null
+++ b/src/runtime/cgo/libcgo_windows.h
@@ -0,0 +1,12 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure there's one symbol marked __declspec(dllexport).
+// If there are no exported symbols, the unfortunate behavior of
+// the binutils linker is to also strip the relocations table,
+// resulting in non-PIE binary. The other option is the
+// --export-all-symbols flag, but we don't need to export all symbols
+// and this may overflow the export table (#40795).
+// See https://sourceware.org/bugzilla/show_bug.cgi?id=19011
+__declspec(dllexport) int _cgo_dummy_export;