]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/ld: handle a special case of scattered relocation 2/1 on Darwin/386
authorShenghou Ma <minux.ma@gmail.com>
Wed, 29 Aug 2012 15:42:05 +0000 (23:42 +0800)
committerShenghou Ma <minux.ma@gmail.com>
Wed, 29 Aug 2012 15:42:05 +0000 (23:42 +0800)
        Fixes #1635.

R=golang-dev, dave, r
CC=golang-dev
https://golang.org/cl/6496043

misc/cgo/test/cgo_test.go
misc/cgo/test/issue1635.go [new file with mode: 0644]
src/cmd/ld/ldmacho.c

index 9c3c1163453ceeaea80c80ed27c680f1d15e3dfa..1aa21cb65bccc0a423829b88d2e331929e8f6954 100644 (file)
@@ -28,5 +28,6 @@ func TestParallelSleep(t *testing.T)       { testParallelSleep(t) }
 func TestSetEnv(t *testing.T)              { testSetEnv(t) }
 func TestHelpers(t *testing.T)             { testHelpers(t) }
 func TestLibgcc(t *testing.T)              { testLibgcc(t) }
+func Test1635(t *testing.T)                { test1635(t) }
 
 func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/issue1635.go b/misc/cgo/test/issue1635.go
new file mode 100644 (file)
index 0000000..6bfe110
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2012 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.
+
+package cgotest
+
+/*
+// Mac OS X's gcc will generate scattered relocation 2/1 for
+// this function on Darwin/386, and 8l couldn't handle it.
+// this example is in issue 1635
+#include <stdio.h>
+void scatter() {
+       void *p = scatter;
+       printf("scatter = %p\n", p);
+}
+
+// this example is in issue 3253
+int hola = 0;
+int testHola() { return hola; }
+*/
+import "C"
+
+import "testing"
+
+func test1635(t *testing.T) {
+       C.scatter()
+       if v := C.hola; v != 0 {
+               t.Fatalf("C.hola is %d, should be 0", v)
+       }
+       if v := C.testHola(); v != 0 {
+               t.Fatalf("C.testHola() is %d, should be 0", v)
+       }
+}
index 3888487673f291e7ac21f879721c96a372b2c7fb..54126d586210ab6a5cce54bec8df88934cfff895 100644 (file)
@@ -680,19 +680,28 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
                                int k;
                                MachoSect *ks;
 
-                               if(thechar != '8')
+                               if(thechar != '8') {
+                                       // mach-o only uses scattered relocation on 32-bit platforms
                                        diag("unexpected scattered relocation");
+                                       continue;
+                               }
 
-                               // on 386, rewrite scattered 4/1 relocation into
-                               // the pseudo-pc-relative reference that it is.
+                               // on 386, rewrite scattered 4/1 relocation and some
+                               // scattered 2/1 relocation into the pseudo-pc-relative
+                               // reference that it is.
                                // assume that the second in the pair is in this section
                                // and use that as the pc-relative base.
-                               if(thechar != '8' || rel->type != 4 || j+1 >= sect->nreloc ||
-                                               !(rel+1)->scattered || (rel+1)->type != 1 ||
-                                               (rel+1)->value < sect->addr || (rel+1)->value >= sect->addr+sect->size) {
+                               if(j+1 >= sect->nreloc) {
+                                       werrstr("unsupported scattered relocation %d", (int)rel->type);
+                                       goto bad;
+                               }
+                               if(!(rel+1)->scattered || (rel+1)->type != 1 ||
+                                  (rel->type != 4 && rel->type != 2) ||
+                                  (rel+1)->value < sect->addr || (rel+1)->value >= sect->addr+sect->size) {
                                        werrstr("unsupported scattered relocation %d/%d", (int)rel->type, (int)(rel+1)->type);
                                        goto bad;
                                }
+
                                rp->siz = rel->length;
                                rp->off = rel->addr;