misc/cgo/testcarchive: fix test to work for gccgo

This test is not yet run, but it will be soon.

Change-Id: I7ed81a0c8da7c3e34a25ef8aa58bca164611ba16
Reviewed-on: https://go-review.googlesource.com/47038
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/libgo/misc/cgo/testcarchive/carchive_test.go b/libgo/misc/cgo/testcarchive/carchive_test.go
index 4999929..a2ad9c5 100644
--- a/libgo/misc/cgo/testcarchive/carchive_test.go
+++ b/libgo/misc/cgo/testcarchive/carchive_test.go
@@ -12,6 +12,7 @@
 	"os"
 	"os/exec"
 	"path/filepath"
+	"runtime"
 	"strings"
 	"syscall"
 	"testing"
@@ -81,13 +82,17 @@
 		cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
 	}
 	libgodir = GOOS + "_" + GOARCH
-	switch GOOS {
-	case "darwin":
-		if GOARCH == "arm" || GOARCH == "arm64" {
+	if runtime.Compiler == "gccgo" {
+		libgodir = "gccgo_" + libgodir + "_fPIC"
+	} else {
+		switch GOOS {
+		case "darwin":
+			if GOARCH == "arm" || GOARCH == "arm64" {
+				libgodir += "_shared"
+			}
+		case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
 			libgodir += "_shared"
 		}
-	case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
-		libgodir += "_shared"
 	}
 	cc = append(cc, "-I", filepath.Join("pkg", libgodir))
 
@@ -149,6 +154,9 @@
 	} else {
 		ccArgs = append(ccArgs, "main_unix.c", libgoa)
 	}
+	if runtime.Compiler == "gccgo" {
+		ccArgs = append(ccArgs, "-lgo")
+	}
 	t.Log(ccArgs)
 	if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
@@ -157,7 +165,11 @@
 	defer os.Remove(exe)
 
 	binArgs := append(cmdToRun(exe), "arg1", "arg2")
-	if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
+	cmd = exec.Command(binArgs[0], binArgs[1:]...)
+	if runtime.Compiler == "gccgo" {
+		cmd.Env = append(os.Environ(), "GCCGO=1")
+	}
+	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
 	}
@@ -166,8 +178,13 @@
 func TestInstall(t *testing.T) {
 	defer os.RemoveAll("pkg")
 
+	libgoa := "libgo.a"
+	if runtime.Compiler == "gccgo" {
+		libgoa = "liblibgo.a"
+	}
+
 	testInstall(t, "./testp1"+exeSuffix,
-		filepath.Join("pkg", libgodir, "libgo.a"),
+		filepath.Join("pkg", libgodir, libgoa),
 		filepath.Join("pkg", libgodir, "libgo.h"),
 		"go", "install", "-buildmode=c-archive", "libgo")
 
@@ -206,6 +223,9 @@
 	}
 
 	ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
+	if runtime.Compiler == "gccgo" {
+		ccArgs = append(ccArgs, "-lgo")
+	}
 	if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
@@ -243,6 +263,9 @@
 	}
 
 	ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
+	if runtime.Compiler == "gccgo" {
+		ccArgs = append(ccArgs, "-lgo")
+	}
 	if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
@@ -293,6 +316,9 @@
 	}
 
 	ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
+	if runtime.Compiler == "gccgo" {
+		ccArgs = append(ccArgs, "-lgo")
+	}
 	if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
@@ -380,6 +406,9 @@
 	}
 
 	ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
+	if runtime.Compiler == "gccgo" {
+		ccArgs = append(ccArgs, "-lgo")
+	}
 	if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
@@ -412,6 +441,9 @@
 	}
 
 	ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
+	if runtime.Compiler == "gccgo" {
+		ccArgs = append(ccArgs, "-lgo")
+	}
 	if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
@@ -436,6 +468,9 @@
 	case "windows":
 		t.Skip("skipping signal test on Windows")
 	}
+	if runtime.Compiler == "gccgo" {
+		t.Skip("skipping -extar test when using gccgo")
+	}
 
 	defer func() {
 		os.Remove("libgo4.a")
@@ -489,14 +524,26 @@
 		t.Fatal(err)
 	}
 
-	ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join("pkg", libgodir, "libgo.a"))
+	libgoa := "libgo.a"
+	if runtime.Compiler == "gccgo" {
+		libgoa = "liblibgo.a"
+	}
+
+	ccArgs := append(cc, "-fPIE", "-pie", "-o", "testp"+exeSuffix, "main.c", "main_unix.c", filepath.Join("pkg", libgodir, libgoa))
+	if runtime.Compiler == "gccgo" {
+		ccArgs = append(ccArgs, "-lgo")
+	}
 	if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
 	}
 
 	binArgs := append(bin, "arg1", "arg2")
-	if out, err := exec.Command(binArgs[0], binArgs[1:]...).CombinedOutput(); err != nil {
+	cmd = exec.Command(binArgs[0], binArgs[1:]...)
+	if runtime.Compiler == "gccgo" {
+		cmd.Env = append(os.Environ(), "GCCGO=1")
+	}
+	if out, err := cmd.CombinedOutput(); err != nil {
 		t.Logf("%s", out)
 		t.Fatal(err)
 	}
diff --git a/libgo/misc/cgo/testcarchive/main_unix.c b/libgo/misc/cgo/testcarchive/main_unix.c
index 4d9d16f..b23ac1c 100644
--- a/libgo/misc/cgo/testcarchive/main_unix.c
+++ b/libgo/misc/cgo/testcarchive/main_unix.c
@@ -5,6 +5,7 @@
 #include <signal.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 struct sigaction sa;
@@ -30,7 +31,12 @@
 		perror("sigaction");
 		return 2;
 	}
-	if (osa.sa_handler == SIG_DFL || (osa.sa_flags&SA_ONSTACK) == 0) {
+	if (osa.sa_handler == SIG_DFL) {
+		fprintf(stderr, "Go runtime did not install signal handler\n");
+		return 2;
+	}
+	// gccgo does not set SA_ONSTACK for SIGSEGV.
+	if (getenv("GCCGO") == "" && (osa.sa_flags&SA_ONSTACK) == 0) {
 		fprintf(stderr, "Go runtime did not install signal handler\n");
 		return 2;
 	}