From 19fd96512c4ff96415cd4dacb5fac1854422e1fa Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Fri, 28 Apr 2023 13:46:38 -0400 Subject: [PATCH] cmd/link: put zero-sized data symbols at same address as runtime.zerobase 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 TryBot-Result: Gopher Robot Reviewed-by: Russ Cox --- src/cmd/link/internal/ld/data.go | 12 +++++++++--- test/zerosize.go | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 test/zerosize.go diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 7c135ae7e6..d0efcdc052 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -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 index 0000000000..53a29f7927 --- /dev/null +++ b/test/zerosize.go @@ -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") + } +}