From 5ac29058f01502c407a7b77ec57a08c96941f796 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 9 Nov 2017 21:56:59 +0000 Subject: [PATCH] sync/atomic, runtime/internal/atomic: don't assume reads from 0 fail For a misaligned address force a panic rather than assuming that reading from the address 0 will cause one. Reviewed-on: https://go-review.googlesource.com/69850 From-SVN: r254610 --- gcc/go/gofrontend/MERGE | 2 +- libgo/go/runtime/internal/atomic/atomic.c | 14 +++++++------- libgo/go/runtime/panic.go | 1 + libgo/go/sync/atomic/atomic.c | 12 ++++++------ libgo/runtime/runtime.h | 2 ++ 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 7be00931af7..0e5a718c92b 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -7fd845bd9414c348bfa30bd24aa0bb8e4eebf83a +b03c5dc36d6d0c0d3bef434936e8b924d253595b The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/go/runtime/internal/atomic/atomic.c b/libgo/go/runtime/internal/atomic/atomic.c index b584656f817..24820f22a42 100644 --- a/libgo/go/runtime/internal/atomic/atomic.c +++ b/libgo/go/runtime/internal/atomic/atomic.c @@ -34,7 +34,7 @@ uint64_t Load64 (uint64_t *ptr) { if (((uintptr_t) ptr & 7) != 0) - ptr = NULL; + panicmem (); return __atomic_load_n (ptr, __ATOMIC_ACQUIRE); } @@ -66,7 +66,7 @@ int64_t Loadint64 (int64_t *ptr) { if (((uintptr_t) ptr & 7) != 0) - ptr = NULL; + panicmem (); return __atomic_load_n (ptr, __ATOMIC_ACQUIRE); } @@ -88,7 +88,7 @@ uint64_t Xadd64 (uint64_t *ptr, int64_t delta) { if (((uintptr_t) ptr & 7) != 0) - ptr = NULL; + panicmem (); return __atomic_add_fetch (ptr, (uint64_t) delta, __ATOMIC_SEQ_CST); } @@ -110,7 +110,7 @@ int64_t Xaddint64 (int64_t *ptr, int64_t delta) { if (((uintptr_t) ptr & 7) != 0) - ptr = NULL; + panicmem (); return __atomic_add_fetch (ptr, delta, __ATOMIC_SEQ_CST); } @@ -132,7 +132,7 @@ uint64_t Xchg64 (uint64_t *ptr, uint64_t new) { if (((uintptr_t) ptr & 7) != 0) - ptr = NULL; + panicmem (); return __atomic_exchange_n (ptr, new, __ATOMIC_SEQ_CST); } @@ -184,7 +184,7 @@ _Bool Cas64 (uint64_t *ptr, uint64_t old, uint64_t new) { if (((uintptr_t) ptr & 7) != 0) - ptr = NULL; + panicmem (); return __atomic_compare_exchange_n (ptr, &old, new, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); } @@ -226,7 +226,7 @@ void Store64 (uint64_t *ptr, uint64_t val) { if (((uintptr_t) ptr & 7) != 0) - ptr = NULL; + panicmem (); __atomic_store_n (ptr, val, __ATOMIC_SEQ_CST); } diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go index 2f656038a9e..c39a58d0c4b 100644 --- a/libgo/go/runtime/panic.go +++ b/libgo/go/runtime/panic.go @@ -22,6 +22,7 @@ import ( //go:linkname makefuncreturning runtime.makefuncreturning //go:linkname gorecover runtime.gorecover //go:linkname deferredrecover runtime.deferredrecover +//go:linkname panicmem runtime.panicmem // Temporary for C code to call: //go:linkname throw runtime.throw diff --git a/libgo/go/sync/atomic/atomic.c b/libgo/go/sync/atomic/atomic.c index 7e04027c3f1..32cbf03c5cf 100644 --- a/libgo/go/sync/atomic/atomic.c +++ b/libgo/go/sync/atomic/atomic.c @@ -26,7 +26,7 @@ int64_t SwapInt64 (int64_t *addr, int64_t new) { if (((uintptr_t) addr & 7) != 0) - addr = NULL; + panicmem (); return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST); } @@ -48,7 +48,7 @@ uint64_t SwapUint64 (uint64_t *addr, uint64_t new) { if (((uintptr_t) addr & 7) != 0) - addr = NULL; + panicmem (); return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST); } @@ -215,7 +215,7 @@ LoadInt64 (int64_t *addr) int64_t v; if (((uintptr_t) addr & 7) != 0) - addr = NULL; + panicmem (); v = *addr; while (! __sync_bool_compare_and_swap (addr, v, v)) v = *addr; @@ -247,7 +247,7 @@ LoadUint64 (uint64_t *addr) uint64_t v; if (((uintptr_t) addr & 7) != 0) - addr = NULL; + panicmem (); v = *addr; while (! __sync_bool_compare_and_swap (addr, v, v)) v = *addr; @@ -308,7 +308,7 @@ StoreInt64 (int64_t *addr, int64_t val) int64_t v; if (((uintptr_t) addr & 7) != 0) - addr = NULL; + panicmem (); v = *addr; while (! __sync_bool_compare_and_swap (addr, v, val)) v = *addr; @@ -338,7 +338,7 @@ StoreUint64 (uint64_t *addr, uint64_t val) uint64_t v; if (((uintptr_t) addr & 7) != 0) - addr = NULL; + panicmem (); v = *addr; while (! __sync_bool_compare_and_swap (addr, v, val)) v = *addr; diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index dd5a958888f..39b5ef883bd 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -211,6 +211,8 @@ extern uint32 runtime_panicking(void) extern bool runtime_isstarted; extern bool runtime_isarchive; +extern void panicmem(void) __asm__ (GOSYM_PREFIX "runtime.panicmem"); + /* * common functions and data */ -- 2.30.2