re PR go/79037 (gccgo: Binaries crash with parforsetup: pos is not aligned on m68k)
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 23 Jan 2017 18:15:22 +0000 (18:15 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 23 Jan 2017 18:15:22 +0000 (18:15 +0000)
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
gcc/go/gofrontend/types.cc
libgo/runtime/go-unsafe-pointer.c
libgo/runtime/parfor.c
libgo/runtime/runtime.h

index 004e51bb08ada61f937497bcb6c04bec26c051f1..03586265b45d73d4fb8cf1b68e74da1aecefcf19 100644 (file)
@@ -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.
index 296e8e51ee0f9c6cadec6ec037c6eefc153f72e4..9423ef6327689653ffc7072059ab16f922938c0e 100644 (file)
@@ -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_;
 
index b98068365e143692bc4662bfd0cec26b0f9f6a9f..cce2e95ac289307dcf78366f6aa960e976cd5473 100644 (file)
@@ -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");
index b49826fe568a6be317a25600c05ebdec17aa19ce..d64d74ccd3600e7732a18ff7cb470012f83750e1 100644 (file)
@@ -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;
index 5fd115589a7c13bfab003e4d59b3b6d11e326d3a..644fe9286541ca15b36347e001da49edef4fbfb2 100644 (file)
@@ -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;