From b0147ac2e62c3ed744d55fc5d009c4ef7a8ef651 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 23 Jan 2017 18:15:22 +0000 Subject: re PR go/79037 (gccgo: Binaries crash with parforsetup: pos is not aligned on m68k) PR go/79037 compiler, runtime: align gc data for m68k The current GC requires that the gc data be aligned to at least a 4 byte boundary, because it uses the lower two bits of the address for flags (see LOOP and PRECISE in runtime/mgc0.c). As the gc data is stored as a [...]uintptr, that is normally always true. However, on m68k, that only guarantees 2 byte alignment. Fix it by forcing the alignment. The parfor code used by the current GC requires that the parfor data be aligned to at least an 8 byte boundary. The code in parfor.c verifies this. This is normally true, as the data uses uint64_t values, but, again, this must be enforced explicitly on m68k. Fixes GCC PR 79037. Reviewed-on: https://go-review.googlesource.com/35478 From-SVN: r244824 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/types.cc | 17 ++++++++++++++++- libgo/runtime/go-unsafe-pointer.c | 3 ++- libgo/runtime/parfor.c | 2 +- libgo/runtime/runtime.h | 2 +- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 004e51b..0358626 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6d8ef03e760ff737ff2c613642142290b0f02e0e +0655e25d8e4acfac50c6b1422dc32eca3e30803a The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 296e8e5..9423ef6 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -2468,13 +2468,28 @@ Type::make_gc_symbol_var(Gogo* gogo) is_common = true; } + // The current garbage collector requires that the GC symbol be + // aligned to at least a four byte boundary. See the use of PRECISE + // and LOOP in libgo/runtime/mgc0.c. + int64_t align; + if (!sym_init->type()->backend_type_align(gogo, &align)) + go_assert(saw_errors()); + if (align < 4) + align = 4; + else + { + // Use default alignment. + align = 0; + } + // Since we are building the GC symbol in this package, we must create the // variable before converting the initializer to its backend representation // because the initializer may refer to the GC symbol for this type. std::string asm_name(go_selectively_encode_id(sym_name)); this->gc_symbol_var_ = gogo->backend()->implicit_variable(sym_name, asm_name, - sym_btype, false, true, is_common, 0); + sym_btype, false, true, is_common, + align); if (phash != NULL) *phash = this->gc_symbol_var_; diff --git a/libgo/runtime/go-unsafe-pointer.c b/libgo/runtime/go-unsafe-pointer.c index b980683..cce2e95 100644 --- a/libgo/runtime/go-unsafe-pointer.c +++ b/libgo/runtime/go-unsafe-pointer.c @@ -36,7 +36,8 @@ static const String reflection_string = sizeof REFLECTION - 1 }; -const uintptr unsafe_Pointer_gc[] = {sizeof(void*), GC_APTR, 0, GC_END}; +const uintptr unsafe_Pointer_gc[] __attribute__((aligned(4))) = + {sizeof(void*), GC_APTR, 0, GC_END}; extern const FuncVal runtime_pointerhash_descriptor __asm__ (GOSYM_PREFIX "runtime.pointerhash$descriptor"); diff --git a/libgo/runtime/parfor.c b/libgo/runtime/parfor.c index b49826f..d64d74c 100644 --- a/libgo/runtime/parfor.c +++ b/libgo/runtime/parfor.c @@ -11,7 +11,7 @@ struct ParForThread { // the thread's iteration space [32lsb, 32msb) - uint64 pos; + uint64 pos __attribute__((aligned(8))); // stats uint64 nsteal; uint64 nstealcnt; diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index 5fd1155..644fe92 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -191,7 +191,7 @@ struct ParFor // otherwise parfor may return while other threads are still working ParForThread *thr; // array of thread descriptors // stats - uint64 nsteal; + uint64 nsteal __attribute__((aligned(8))); // force alignment for m68k uint64 nstealcnt; uint64 nprocyield; uint64 nosyield; -- cgit v1.1