]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/link: put zero-sized data symbols at same address as runtime.zerobase
authorCherry Mui <cherryyz@google.com>
Fri, 28 Apr 2023 17:46:38 +0000 (13:46 -0400)
committerCherry Mui <cherryyz@google.com>
Fri, 28 Apr 2023 18:35:43 +0000 (18:35 +0000)
Put zero-sized data symbols at same address as runtime.zerobase,
so zero-sized global variables have the same address as zero-sized
allocations.

Change-Id: Ib3145dc1b663a9794dfabc0e6abd2384960f2c49
Reviewed-on: https://go-review.googlesource.com/c/go/+/490435
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/link/internal/ld/data.go
test/zerosize.go [new file with mode: 0644]

index 7c135ae7e610c0cfc716056de68919b98c2ccd89..d0efcdc05203a47cd7e53936bbd052d1dac4c1c6 100644 (file)
@@ -2156,7 +2156,7 @@ type symNameSize struct {
 }
 
 func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) {
-       var head, tail loader.Sym
+       var head, tail, zerobase loader.Sym
        ldr := ctxt.loader
        sl := make([]symNameSize, len(syms))
 
@@ -2196,20 +2196,26 @@ func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader
                        }
                }
        }
+       zerobase = ldr.Lookup("runtime.zerobase", 0)
 
        // Perform the sort.
        if symn != sym.SPCLNTAB {
                sort.Slice(sl, func(i, j int) bool {
                        si, sj := sl[i].sym, sl[j].sym
+                       isz, jsz := sl[i].sz, sl[j].sz
                        switch {
                        case si == head, sj == tail:
                                return true
                        case sj == head, si == tail:
                                return false
+                       // put zerobase right after all the zero-sized symbols,
+                       // so zero-sized symbols have the same address as zerobase.
+                       case si == zerobase:
+                               return jsz != 0 // zerobase < nonzero-sized
+                       case sj == zerobase:
+                               return isz == 0 // 0-sized < zerobase
                        }
                        if checkSize {
-                               isz := sl[i].sz
-                               jsz := sl[j].sz
                                if isz != jsz {
                                        return isz < jsz
                                }
diff --git a/test/zerosize.go b/test/zerosize.go
new file mode 100644 (file)
index 0000000..53a29f7
--- /dev/null
@@ -0,0 +1,33 @@
+// run
+
+// Copyright 2023 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.
+
+// Test that zero-sized variables get same address as
+// runtime.zerobase.
+
+package main
+
+var x, y [0]int
+var p, q = new([0]int), new([0]int) // should get &runtime.zerobase
+
+func main() {
+       if &x != &y {
+               // Failing for now. x and y are at same address, but compiler optimizes &x==&y to false. Skip.
+               // print("&x=", &x, " &y=", &y, " &x==&y = ", &x==&y, "\n")
+               // panic("FAIL")
+       }
+       if p != q {
+               print("p=", p, " q=", q, " p==q = ", p==q, "\n")
+               panic("FAIL")
+       }
+       if &x != p {
+               print("&x=", &x, " p=", p, " &x==p = ", &x==p, "\n")
+               panic("FAIL")
+       }
+       if &y != p {
+               print("&y=", &y, " p=", p, " &y==p = ", &y==p, "\n")
+               panic("FAIL")
+       }
+}