}
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))
}
}
}
+ 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
}
--- /dev/null
+// 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")
+ }
+}