]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.r58] runtime/cgo: fix for OS X 10.7
authorRuss Cox <rsc@golang.org>
Tue, 12 Jul 2011 03:38:02 +0000 (23:38 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 12 Jul 2011 03:38:02 +0000 (23:38 -0400)
««« CL 4603057 / 0905a2ca94c6
runtime/cgo: fix for OS X 10.7

Correct a few error messages (libcgo -> runtime/cgo)
and delete old nacl_386.c file too.

Fixes #1657.

R=iant
CC=golang-dev
https://golang.org/cl/4603057
»»»

R=adg
CC=golang-dev
https://golang.org/cl/4698041

src/pkg/runtime/cgo/darwin_386.c
src/pkg/runtime/cgo/darwin_amd64.c
src/pkg/runtime/cgo/nacl_386.c [deleted file]
src/pkg/runtime/cgo/util.c

index 4fc7eb4e0a5dafea200fa56933c362388080d3d2..13184f3217c45b8c2d0163dd32d7d331cedebb44 100644 (file)
@@ -8,11 +8,13 @@
 static void* threadentry(void*);
 static pthread_key_t k1, k2;
 
+#define magic1 (0x23581321U)
+
 static void
 inittls(void)
 {
        uint32 x, y;
-       pthread_key_t tofree[16], k;
+       pthread_key_t tofree[128], k;
        int i, ntofree;
        int havek1, havek2;
 
@@ -35,9 +37,8 @@ inittls(void)
         * 0x48+4*0x108 = 0x468 and 0x48+4*0x109 = 0x46c.
         *
         * The linker and runtime hard-code these constant offsets
-        * from %gs where we expect to find m and g.  The code
-        * below verifies that the constants are correct once it has
-        * obtained the keys.  Known to ../cmd/8l/obj.c:/468
+        * from %gs where we expect to find m and g.
+        * Known to ../cmd/8l/obj.c:/468
         * and to ../pkg/runtime/darwin/386/sys.s:/468
         *
         * This is truly disgusting and a bit fragile, but taking care
@@ -48,55 +49,54 @@ inittls(void)
         * require an extra instruction and memory reference in
         * every stack growth prolog and would also require
         * rewriting the code that 8c generates for extern registers.
+        *
+        * Things get more disgusting on OS X 10.7 Lion.
+        * The 0x48 base mentioned above is the offset of the tsd
+        * array within the per-thread structure on Leopard and Snow Leopard.
+        * On Lion, the base moved a little, so while the math above
+        * still applies, the base is different.  Thus, we cannot
+        * look for specific key values if we want to build binaries
+        * that run on both systems.  Instead, forget about the
+        * specific key values and just allocate and initialize per-thread
+        * storage until we find a key that writes to the memory location
+        * we want.  Then keep that key.
         */
        havek1 = 0;
        havek2 = 0;
        ntofree = 0;
        while(!havek1 || !havek2) {
                if(pthread_key_create(&k, nil) < 0) {
-                       fprintf(stderr, "libcgo: pthread_key_create failed\n");
+                       fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
                        abort();
                }
-               if(k == 0x108) {
+               pthread_setspecific(k, (void*)magic1);
+               asm volatile("movl %%gs:0x468, %0" : "=r"(x));
+               asm volatile("movl %%gs:0x46c, %0" : "=r"(y));
+               if(x == magic1) {
                        havek1 = 1;
                        k1 = k;
-                       continue;
-               }
-               if(k == 0x109) {
+               } else if(y == magic1) {
                        havek2 = 1;
                        k2 = k;
-                       continue;
+               } else {
+                       if(ntofree >= nelem(tofree)) {
+                               fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
+                               fprintf(stderr, "\ttried");
+                               for(i=0; i<ntofree; i++)
+                                       fprintf(stderr, " %#x", (unsigned)tofree[i]);
+                               fprintf(stderr, "\n");
+                               abort();
+                       }
+                       tofree[ntofree++] = k;
                }
-               if(ntofree >= nelem(tofree)) {
-                       fprintf(stderr, "libcgo: could not obtain pthread_keys\n");
-                       fprintf(stderr, "\twanted 0x108 and 0x109\n");
-                       fprintf(stderr, "\tgot");
-                       for(i=0; i<ntofree; i++)
-                               fprintf(stderr, " %#lx", tofree[i]);
-                       fprintf(stderr, "\n");
-                       abort();
-               }
-               tofree[ntofree++] = k;
+               pthread_setspecific(k, 0);
        }
 
-       for(i=0; i<ntofree; i++)
-               pthread_key_delete(tofree[i]);
-
        /*
-        * We got the keys we wanted.  Make sure that we observe
-        * updates to k1 at 0x468, to verify that the TLS array
-        * offset from %gs hasn't changed.
+        * We got the keys we wanted.  Free the others.
         */
-       pthread_setspecific(k1, (void*)0x12345678);
-       asm volatile("movl %%gs:0x468, %0" : "=r"(x));
-
-       pthread_setspecific(k1, (void*)0x87654321);
-       asm volatile("movl %%gs:0x468, %0" : "=r"(y));
-
-       if(x != 0x12345678 || y != 0x87654321) {
-               printf("libcgo: thread-local storage %#lx not at %%gs:0x468 - x=%#x y=%#x\n", k1, x, y);
-               abort();
-       }
+       for(i=0; i<ntofree; i++)
+               pthread_key_delete(tofree[i]);
 }
 
 static void
index 253a1b252c9ff59874307e62c903e09ce25d95b2..38cd80a6f93374da2213250b7db3aa490e35f28e 100644 (file)
@@ -8,24 +8,25 @@
 static void* threadentry(void*);
 static pthread_key_t k1, k2;
 
+#define magic1 (0x23581321345589ULL)
+
 static void
 inittls(void)
 {
        uint64 x, y;
-       pthread_key_t tofree[16], k;
+       pthread_key_t tofree[128], k;
        int i, ntofree;
        int havek1, havek2;
 
        /*
         * Same logic, code as darwin_386.c:/inittls, except that words
-        * are 8 bytes long now, and the thread-local storage starts at 0x60.
-        * So the offsets are
+        * are 8 bytes long now, and the thread-local storage starts
+        * at 0x60 on Leopard / Snow Leopard. So the offsets are
         * 0x60+8*0x108 = 0x8a0 and 0x60+8*0x109 = 0x8a8.
         *
         * The linker and runtime hard-code these constant offsets
-        * from %gs where we expect to find m and g.  The code
-        * below verifies that the constants are correct once it has
-        * obtained the keys.  Known to ../cmd/6l/obj.c:/8a0
+        * from %gs where we expect to find m and g.
+        * Known to ../cmd/6l/obj.c:/8a0
         * and to ../pkg/runtime/darwin/amd64/sys.s:/8a0
         *
         * As disgusting as on the 386; same justification.
@@ -35,49 +36,37 @@ inittls(void)
        ntofree = 0;
        while(!havek1 || !havek2) {
                if(pthread_key_create(&k, nil) < 0) {
-                       fprintf(stderr, "libcgo: pthread_key_create failed\n");
+                       fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
                        abort();
                }
-               if(k == 0x108) {
+               pthread_setspecific(k, (void*)magic1);
+               asm volatile("movq %%gs:0x8a0, %0" : "=r"(x));
+               asm volatile("movq %%gs:0x8a8, %0" : "=r"(y));
+               if(x == magic1) {
                        havek1 = 1;
                        k1 = k;
-                       continue;
-               }
-               if(k == 0x109) {
+               } else if(y == magic1) {
                        havek2 = 1;
                        k2 = k;
-                       continue;
-               }
-               if(ntofree >= nelem(tofree)) {
-                       fprintf(stderr, "libcgo: could not obtain pthread_keys\n");
-                       fprintf(stderr, "\twanted 0x108 and 0x109\n");
-                       fprintf(stderr, "\tgot");
-                       for(i=0; i<ntofree; i++)
-                               fprintf(stderr, " %#x", (unsigned)tofree[i]);
-                       fprintf(stderr, "\n");
-                       abort();
+               } else {
+                       if(ntofree >= nelem(tofree)) {
+                               fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
+                               fprintf(stderr, "\ttried");
+                               for(i=0; i<ntofree; i++)
+                                       fprintf(stderr, " %#x", (unsigned)tofree[i]);
+                               fprintf(stderr, "\n");
+                               abort();
+                       }
+                       tofree[ntofree++] = k;
                }
-               tofree[ntofree++] = k;
+               pthread_setspecific(k, 0);
        }
 
-       for(i=0; i<ntofree; i++)
-               pthread_key_delete(tofree[i]);
-
        /*
-        * We got the keys we wanted.  Make sure that we observe
-        * updates to k1 at 0x8a0, to verify that the TLS array
-        * offset from %gs hasn't changed.
+        * We got the keys we wanted.  Free the others.
         */
-       pthread_setspecific(k1, (void*)0x123456789abcdef0ULL);
-       asm volatile("movq %%gs:0x8a0, %0" : "=r"(x));
-
-       pthread_setspecific(k2, (void*)0x0fedcba987654321);
-       asm volatile("movq %%gs:0x8a8, %0" : "=r"(y));
-
-       if(x != 0x123456789abcdef0ULL || y != 0x0fedcba987654321) {
-               printf("libcgo: thread-local storage %#x not at %%gs:0x8a0 - x=%#llx y=%#llx\n", (unsigned)k1, x, y);
-               abort();
-       }
+       for(i=0; i<ntofree; i++)
+               pthread_key_delete(tofree[i]);
 }
 
 void
diff --git a/src/pkg/runtime/cgo/nacl_386.c b/src/pkg/runtime/cgo/nacl_386.c
deleted file mode 100644 (file)
index e556c43..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "libcgo.h"
-
-static void
-xinitcgo(void)
-{
-}
-
-void (*initcgo)(void) = xinitcgo;
-
-void
-libcgo_sys_thread_start(ThreadStart *ts)
-{
-       // unimplemented
-       *(int*)0 = 0;
-}
index 0eff19aa6d5e99023a7013cc662d8065dc1870f2..9d96521f53ffceaa42af0503e1e1bcb4fc8b7357 100644 (file)
@@ -40,7 +40,7 @@ xlibcgo_thread_start(ThreadStart *arg)
        /* Make our own copy that can persist after we return. */
        ts = malloc(sizeof *ts);
        if(ts == nil) {
-               fprintf(stderr, "libcgo: out of memory in thread_start\n");
+               fprintf(stderr, "runtime/cgo: out of memory in thread_start\n");
                abort();
        }
        *ts = *arg;