This libgo patch fixes the channel code to work correctly on big-endian systems. The older version of the code did this right, but I forgot to handle it in the new version. This patch also fixes the memory structure built for the select statement to work correctly on strict alignment systems. The code was putting a uint16_t array before a pointer array, which would of course cause a SIGBUS on a strict alignment system. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Bootstrapped and ran channel tests on sparc-sun-solaris2.11; the Go testsuite on that system still has some failures but they appear to be due to other problems, such as PR 52205 which I just filed. Committed to mainline.
Ian
diff -r 93764d4d4aca libgo/runtime/chan.c --- a/libgo/runtime/chan.c Fri Feb 10 07:53:37 2012 -0800 +++ b/libgo/runtime/chan.c Fri Feb 10 15:54:46 2012 -0800 @@ -409,11 +409,20 @@ void __go_send_small(ChanType *t, Hchan* c, uint64 val) { - byte b[sizeof(uint64)]; + union + { + byte b[sizeof(uint64)]; + uint64 v; + } u; + byte *p; - runtime_memclr(b, sizeof(uint64)); - __builtin_memcpy(b, &val, t->__element_type->__size); - runtime_chansend(t, c, b, nil); + u.v = val; +#ifndef WORDS_BIGENDIAN + p = u.b; +#else + p = u.b + sizeof(uint64) - t->__element_type->__size; +#endif + runtime_chansend(t, c, p, nil); } // The compiler generates a call to __go_send_big to send a value @@ -433,9 +442,15 @@ byte b[sizeof(uint64)]; uint64 v; } u; + byte *p; u.v = 0; - runtime_chanrecv(t, c, u.b, nil, nil); +#ifndef WORDS_BIGENDIAN + p = u.b; +#else + p = u.b + sizeof(uint64) - t->__element_type->__size; +#endif + runtime_chanrecv(t, c, p, nil, nil); return u.v; } @@ -654,8 +669,8 @@ sel->tcase = size; sel->ncase = 0; - sel->pollorder = (void*)(sel->scase + size); - sel->lockorder = (void*)(sel->pollorder + size); + sel->lockorder = (void*)(sel->scase + size); + sel->pollorder = (void*)(sel->lockorder + size); *selp = sel; if(debug)