Package: libgo11
Version: 7.2.0-17
Tags: upstream fixed-upstream patch
User: debian-sp...@lists.debian.org
Usertags: sparc64
X-Debbugs-Cc: debian-sp...@lists.debian.org

Hi,
For a while, libgo11 on sparc64 has been broken, with executables
crashing with messages like:

> runtime: lfstackpush invalid packing: node=0xfff8000102424000 cnt=1 
> packed=283958541549569 -> node=0x102424000

whenever runtime_gc is called. This is because lfstack_64bit.go has
incorrect assumptions about the virtual address space, and so clobbers
the node address when packing. Please apply the attached debdiff, which
is a backport of the upstream fix (the change to gcc/go/gofrontend/MERGE
has been dropped as it's needless noise that is likely to just cause
conflicts). In my testing it completely fixes that error with no traces
of it in the build log.

Regards,
James
diff -u gcc-7-7.2.0/debian/rules.patch gcc-7-7.2.0/debian/rules.patch
--- gcc-7-7.2.0/debian/rules.patch
+++ gcc-7-7.2.0/debian/rules.patch
@@ -75,6 +75,7 @@
        pr77631 \
        pr67165 \
        cuda-float128 \
+       libgo-sparc64 \
        libgo-ia64 \
        pr82880 \
        libcc1-compiler-name \
only in patch2:
unchanged:
--- gcc-7-7.2.0.orig/debian/patches/libgo-sparc64.diff
+++ gcc-7-7.2.0/debian/patches/libgo-sparc64.diff
@@ -0,0 +1,99 @@
+From c536feb42f56afd6397697f9ee9e5d8d918bef1b Mon Sep 17 00:00:00 2001
+From: ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Wed, 31 May 2017 21:36:42 +0000
+Subject: [PATCH]     libgo: support for sparc64 GNU/Linux
+
+    Fix lfstack code to work with sparc64 GNU/Linux address map.
+
+    Force alignment of epollevent.  To make this work reliably, pass
+    GOARCH explicitly to mkrsysinfo.sh.
+
+    Patch by Vladimir Mezentsev.
+
+    Reviewed-on: https://go-review.googlesource.com/44494
+
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@248765 
138bc75d-0d04-0410-961f-82ee72b054a4
+---
+[gcc/go/gofrontend/MERGE           |  2 +-]
+ libgo/Makefile.am                 |  2 +-
+ libgo/Makefile.in                 |  2 +-
+ libgo/go/runtime/lfstack_64bit.go | 12 ++++++++++++
+ libgo/mkrsysinfo.sh               |  6 +++++-
+ 5 files changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/src/libgo/Makefile.am b/src/libgo/Makefile.am
+index 8bbd43771447..0f9881ffaa4e 100644
+--- a/src/libgo/Makefile.am
++++ b/src/libgo/Makefile.am
+@@ -531,7 +531,7 @@ s-version: Makefile
+ 
+ runtime_sysinfo.go: s-runtime_sysinfo; @true
+ s-runtime_sysinfo: $(srcdir)/mkrsysinfo.sh gen-sysinfo.go
+-      $(SHELL) $(srcdir)/mkrsysinfo.sh
++      GOARCH=$(GOARCH) GOOS=$(GOOS) $(SHELL) $(srcdir)/mkrsysinfo.sh
+       $(SHELL) $(srcdir)/mvifdiff.sh tmp-runtime_sysinfo.go runtime_sysinfo.go
+       $(STAMP) $@
+ 
+diff --git a/src/libgo/Makefile.in b/src/libgo/Makefile.in
+index cbdd37998369..2452f967252b 100644
+--- a/src/libgo/Makefile.in
++++ b/src/libgo/Makefile.in
+@@ -3081,7 +3081,7 @@ s-version: Makefile
+ 
+ runtime_sysinfo.go: s-runtime_sysinfo; @true
+ s-runtime_sysinfo: $(srcdir)/mkrsysinfo.sh gen-sysinfo.go
+-      $(SHELL) $(srcdir)/mkrsysinfo.sh
++      GOARCH=$(GOARCH) GOOS=$(GOOS) $(SHELL) $(srcdir)/mkrsysinfo.sh
+       $(SHELL) $(srcdir)/mvifdiff.sh tmp-runtime_sysinfo.go runtime_sysinfo.go
+       $(STAMP) $@
+ 
+diff --git a/src/libgo/go/runtime/lfstack_64bit.go 
b/src/libgo/go/runtime/lfstack_64bit.go
+index 213efb107068..b314a3ba2169 100644
+--- a/src/libgo/go/runtime/lfstack_64bit.go
++++ b/src/libgo/go/runtime/lfstack_64bit.go
+@@ -32,9 +32,18 @@ const (
+       // bottom, because node must be pointer-aligned, giving a total of 19 
bits
+       // of count.
+       cntBits = 64 - addrBits + 3
++
++      // On sparc64-linux, user addresses are 52-bit numbers sign extended to 
64.
++      // We shift the address left 12 to eliminate the sign extended part and 
make
++      // room in the bottom for the count.
++      sparcLinuxAddrBits = 52
++      sparcLinuxCntBits  = 64 - sparcLinuxAddrBits + 3
+ )
+ 
+ func lfstackPack(node *lfnode, cnt uintptr) uint64 {
++      if GOARCH == "sparc64" && GOOS == "linux" {
++              return 
uint64(uintptr(unsafe.Pointer(node)))<<(64-sparcLinuxAddrBits) | 
uint64(cnt&(1<<sparcLinuxCntBits-1))
++      }
+       return uint64(uintptr(unsafe.Pointer(node)))<<(64-addrBits) | 
uint64(cnt&(1<<cntBits-1))
+ }
+ 
+@@ -44,5 +53,8 @@ func lfstackUnpack(val uint64) *lfnode {
+               // val before unpacking.
+               return (*lfnode)(unsafe.Pointer(uintptr(int64(val) >> cntBits 
<< 3)))
+       }
++      if GOARCH == "sparc64" && GOOS == "linux" {
++              return (*lfnode)(unsafe.Pointer(uintptr(int64(val) >> 
sparcLinuxCntBits << 3)))
++      }
+       return (*lfnode)(unsafe.Pointer(uintptr(val >> cntBits << 3)))
+ }
+diff --git a/src/libgo/mkrsysinfo.sh b/src/libgo/mkrsysinfo.sh
+index a86e9143bf46..6ab80e625d93 100755
+--- a/src/libgo/mkrsysinfo.sh
++++ b/src/libgo/mkrsysinfo.sh
+@@ -83,7 +83,11 @@ if grep '^const _epoll_data_offset ' ${OUT} >/dev/null 
2>&1; then
+   if test "$val" = "4"; then
+       echo 'type epollevent struct { events uint32; data [8]byte }' >> ${OUT}
+   elif test "$val" = "8"; then
+-      echo 'type epollevent struct { events uint32; pad [4]byte; data [8]byte 
}' >> ${OUT}
++      if test "$GOARCH" = "sparc64" -a "$GOOS" = "linux"; then
++          echo 'type epollevent struct { events uint32; pad [4]byte; data 
[8]byte; _align [0]int64 }' >> ${OUT}
++      else
++          echo 'type epollevent struct { events uint32; pad [4]byte; data 
[8]byte }' >> ${OUT}
++      fi
+   else
+       echo 1>&2 "unknown epoll data offset value ${val}"
+       exit 1

Reply via email to