]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj: reject too large symbols
authorCherry Zhang <cherryyz@google.com>
Mon, 19 Oct 2020 14:40:24 +0000 (10:40 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 20 Oct 2020 18:51:03 +0000 (18:51 +0000)
We never supported symbol larger than 2GB (issue #9862), so the
object file uses 32-bit for symbol sizes. Check and reject too
large symbol before truncating its size.

Fixes #42054.

Change-Id: I0d1d585ebdba9556f2fd3a97043bd4296d5cc9e4
Reviewed-on: https://go-review.googlesource.com/c/go/+/263641
Trust: Cherry Zhang <cherryyz@google.com>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/objfile_test.go
test/fixedbugs/issue4348.go

index a08de891d31821b22c782eb5652b264a6fb9f00b..a24a7b878f99a6c2eff16c5b2b14a4e972356adf 100644 (file)
@@ -261,6 +261,10 @@ func (w *writer) StringTable() {
        }
 }
 
+// cutoff is the maximum data section size permitted by the linker
+// (see issue #9862).
+const cutoff = int64(2e9) // 2 GB (or so; looks better in errors than 2^31)
+
 func (w *writer) Sym(s *LSym) {
        abi := uint16(s.ABI())
        if s.Static() {
@@ -325,6 +329,9 @@ func (w *writer) Sym(s *LSym) {
                        // don't bother setting align to 1.
                }
        }
+       if s.Size > cutoff {
+               w.ctxt.Diag("%s: symbol too large (%d bytes > %d bytes)", s.Name, s.Size, cutoff)
+       }
        var o goobj.Sym
        o.SetName(name, w.Writer)
        o.SetABI(abi)
index 155701fa4e06a4690e79594b1712f2e2045c698f..146627b62b9ff0e889a5fe0eda5dc94df33db974 100644 (file)
@@ -5,9 +5,16 @@
 package obj
 
 import (
+       "bytes"
        "cmd/internal/goobj"
        "cmd/internal/sys"
+       "internal/testenv"
+       "io/ioutil"
+       "os"
+       "os/exec"
+       "path/filepath"
        "testing"
+       "unsafe"
 )
 
 var dummyArch = LinkArch{Arch: sys.ArchAMD64}
@@ -85,3 +92,32 @@ func TestContentHash(t *testing.T) {
                }
        }
 }
+
+func TestSymbolTooLarge(t *testing.T) { // Issue 42054
+       testenv.MustHaveGoBuild(t)
+       if unsafe.Sizeof(uintptr(0)) < 8 {
+               t.Skip("skip on 32-bit architectures")
+       }
+
+       tmpdir, err := ioutil.TempDir("", "TestSymbolTooLarge")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer os.RemoveAll(tmpdir)
+
+       src := filepath.Join(tmpdir, "p.go")
+       err = ioutil.WriteFile(src, []byte("package p; var x [1<<32]byte"), 0666)
+       if err != nil {
+               t.Fatalf("failed to write source file: %v\n", err)
+       }
+       obj := filepath.Join(tmpdir, "p.o")
+       cmd := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", obj, src)
+       out, err := cmd.CombinedOutput()
+       if err == nil {
+               t.Fatalf("did not fail\noutput: %s", out)
+       }
+       const want = "symbol too large"
+       if !bytes.Contains(out, []byte(want)) {
+               t.Errorf("unexpected error message: want: %q, got: %s", want, out)
+       }
+}
index c59b6b8caab22b90ceef34107f592dc6cdde4cb6..8b1a56c1d5116a55e76a7b5ab370138482c060a7 100644 (file)
@@ -1,4 +1,4 @@
-// compile
+// skip
 
 // Copyright 2012 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -7,6 +7,8 @@
 // Issue 4348. After switch to 64-bit ints the compiler generates
 // illegal instructions when using large array bounds or indexes.
 
+// Skip. We reject symbols larger that 2GB (Issue #9862).
+
 package main
 
 // 1<<32 on a 64-bit machine, 1 otherwise.