Skip to content

Commit

Permalink
all: enable c-shared/c-archive support for freebsd/amd64
Browse files Browse the repository at this point in the history
Fixes golang#14327
Much of the code is based on the linux/amd64 code that implements these
build modes, and code is shared where possible.

Change-Id: Ia510f2023768c0edbc863aebc585929ec593b332
Reviewed-on: https://go-review.googlesource.com/93875
Run-TryBot: Ian Lance Taylor <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
tenortim authored and ianlancetaylor committed Mar 21, 2018
1 parent ff5cf43 commit 88129f0
Show file tree
Hide file tree
Showing 21 changed files with 356 additions and 52 deletions.
5 changes: 4 additions & 1 deletion misc/cgo/testcarchive/carchive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ func TestSignalForwarding(t *testing.T) {
}

func TestSignalForwardingExternal(t *testing.T) {
if GOOS == "freebsd" {
t.Skipf("skipping on %s/%s; signal always goes to the Go runtime", GOOS, GOARCH)
}
checkSignalForwardingTest(t)

defer func() {
Expand Down Expand Up @@ -433,7 +436,7 @@ func TestSigaltstack(t *testing.T) {
}

const testar = `#!/usr/bin/env bash
while expr $1 : '[-]' >/dev/null; do
while [[ $1 == -* ]] >/dev/null; do
shift
done
echo "testar" > $1
Expand Down
2 changes: 2 additions & 0 deletions misc/cgo/testcarchive/main5.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ int main(int argc, char** argv) {
printf("write(2) unexpectedly succeeded\n");
return 0;
}
printf("did not receieve SIGPIPE\n");
return 0;
}
default:
printf("Unknown test: %d\n", test);
Expand Down
12 changes: 10 additions & 2 deletions misc/cgo/testcshared/cshared_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,11 @@ func TestExportedSymbolsWithDynamicLoad(t *testing.T) {

createHeadersOnce(t)

runCC(t, "-o", cmd, "main1.c", "-ldl")
if GOOS != "freebsd" {
runCC(t, "-o", cmd, "main1.c", "-ldl")
} else {
runCC(t, "-o", cmd, "main1.c")
}
adbPush(t, cmd)

defer os.Remove(bin)
Expand Down Expand Up @@ -411,7 +415,11 @@ func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) {
"-o", libname, pkgname,
)
adbPush(t, libname)
runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
if GOOS != "freebsd" {
runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
} else {
runCC(t, "-pthread", "-o", cmd, cfile)
}
adbPush(t, cmd)

bin := cmdToRun(cmd)
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/dist/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ func (t *tester) supportedBuildmode(mode string) bool {
switch pair {
case "darwin-386", "darwin-amd64", "darwin-arm", "darwin-arm64",
"linux-amd64", "linux-386", "linux-ppc64le", "linux-s390x",
"freebsd-amd64",
"windows-amd64", "windows-386":
return true
}
Expand All @@ -920,6 +921,7 @@ func (t *tester) supportedBuildmode(mode string) bool {
switch pair {
case "linux-386", "linux-amd64", "linux-arm", "linux-arm64", "linux-ppc64le", "linux-s390x",
"darwin-amd64", "darwin-386",
"freebsd-amd64",
"android-arm", "android-arm64", "android-386",
"windows-amd64", "windows-386":
return true
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/go/internal/work/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ func buildModeInit() {
} else {
switch platform {
case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le", "linux/s390x",
"android/amd64", "android/arm", "android/arm64", "android/386":
"android/amd64", "android/arm", "android/arm64", "android/386",
"freebsd/amd64":
codegenArg = "-shared"
case "darwin/amd64", "darwin/386":
case "windows/amd64", "windows/386":
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/internal/obj/x86/asm6.go
Original file line number Diff line number Diff line change
Expand Up @@ -4615,7 +4615,7 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
log.Fatalf("unknown TLS base location for %v", ctxt.Headtype)

case objabi.Hlinux,
objabi.Hnacl:
objabi.Hnacl, objabi.Hfreebsd:
if ctxt.Flag_shared {
// Note that this is not generating the same insns as the other cases.
// MOV TLS, dst
Expand Down Expand Up @@ -4687,9 +4687,9 @@ func (asmbuf *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
default:
log.Fatalf("unknown TLS base location for %v", ctxt.Headtype)

case objabi.Hlinux:
case objabi.Hlinux, objabi.Hfreebsd:
if !ctxt.Flag_shared {
log.Fatalf("unknown TLS base location for linux without -shared")
log.Fatalf("unknown TLS base location for linux/freebsd without -shared")
}
// Note that this is not generating the same insn as the other cases.
// MOV TLS, R_to
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/internal/obj/x86/obj6.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func CanUse1InsnTLS(ctxt *obj.Link) bool {
switch ctxt.Headtype {
case objabi.Hplan9, objabi.Hwindows:
return false
case objabi.Hlinux:
case objabi.Hlinux, objabi.Hfreebsd:
return !ctxt.Flag_shared
}

Expand Down
6 changes: 6 additions & 0 deletions src/cmd/link/internal/ld/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ func (mode *BuildMode) Set(s string) error {
case "c-archive":
switch objabi.GOOS {
case "darwin", "linux":
case "freebsd":
switch objabi.GOARCH {
case "amd64":
default:
return badmode()
}
case "windows":
switch objabi.GOARCH {
case "amd64", "386":
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/cgo/gcc_fatalf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !android,linux
// +build !android,linux freebsd

#include <stdarg.h>
#include <stdio.h>
Expand Down
22 changes: 15 additions & 7 deletions src/runtime/cgo/gcc_freebsd_amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.

#include <sys/types.h>
#include <errno.h>
#include <sys/signalvar.h>
#include <pthread.h>
#include <signal.h>
Expand All @@ -16,14 +17,21 @@ static void (*setg_gcc)(void*);
void
x_cgo_init(G *g, void (*setg)(void*))
{
pthread_attr_t attr;
pthread_attr_t *attr;
size_t size;

// Deal with memory sanitizer/clang interaction.
// See gcc_linux_amd64.c for details.
setg_gcc = setg;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
attr = (pthread_attr_t*)malloc(sizeof *attr);
if (attr == NULL) {
fatalf("malloc failed: %s", strerror(errno));
}
pthread_attr_init(attr);
pthread_attr_getstacksize(attr, &size);
g->stacklo = (uintptr)&attr - size + 4096;
pthread_attr_destroy(&attr);
pthread_attr_destroy(attr);
free(attr);
}

void
Expand All @@ -40,16 +48,14 @@ _cgo_sys_thread_start(ThreadStart *ts)

pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);

// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
ts->g->stackhi = size;
err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);

pthread_sigmask(SIG_SETMASK, &oset, nil);

if (err != 0) {
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
abort();
fatalf("pthread_create failed: %s", strerror(err));
}
}

Expand All @@ -59,7 +65,9 @@ threadentry(void *v)
ThreadStart ts;

ts = *(ThreadStart*)v;
_cgo_tsan_acquire();
free(v);
_cgo_tsan_release();

/*
* Set specific keys.
Expand Down
80 changes: 80 additions & 0 deletions src/runtime/cgo/gcc_freebsd_sigaction.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2018 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.

// +build freebsd,amd64

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>

#include "libcgo.h"

// go_sigaction_t is a C version of the sigactiont struct from
// os_freebsd.go. This definition — and its conversion to and from struct
// sigaction — are specific to freebsd/amd64.
typedef struct {
uint32_t __bits[_SIG_WORDS];
} go_sigset_t;
typedef struct {
uintptr_t handler;
int32_t flags;
go_sigset_t mask;
} go_sigaction_t;

int32_t
x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *oldgoact) {
int32_t ret;
struct sigaction act;
struct sigaction oldact;
int i;

_cgo_tsan_acquire();

memset(&act, 0, sizeof act);
memset(&oldact, 0, sizeof oldact);

if (goact) {
if (goact->flags & SA_SIGINFO) {
act.sa_sigaction = (void(*)(int, siginfo_t*, void*))(goact->handler);
} else {
act.sa_handler = (void(*)(int))(goact->handler);
}
sigemptyset(&act.sa_mask);
for (i = 0; i < 8 * sizeof(goact->mask); i++) {
if (goact->mask.__bits[i/32] & ((uint32_t)(1)<<(i&31))) {
sigaddset(&act.sa_mask, i+1);
}
}
act.sa_flags = goact->flags;
}

ret = sigaction(signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
if (ret == -1) {
// runtime.sigaction expects _cgo_sigaction to return errno on error.
_cgo_tsan_release();
return errno;
}

if (oldgoact) {
if (oldact.sa_flags & SA_SIGINFO) {
oldgoact->handler = (uintptr_t)(oldact.sa_sigaction);
} else {
oldgoact->handler = (uintptr_t)(oldact.sa_handler);
}
for (i = 0 ; i < _SIG_WORDS; i++) {
oldgoact->mask.__bits[i] = 0;
}
for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) {
if (sigismember(&oldact.sa_mask, i+1) == 1) {
oldgoact->mask.__bits[i/32] |= (uint32_t)(1)<<(i&31);
}
}
oldgoact->flags = oldact.sa_flags;
}

_cgo_tsan_release();
return ret;
}
2 changes: 1 addition & 1 deletion src/runtime/cgo/sigaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build linux,amd64
// +build linux,amd64 freebsd,amd64

package cgo

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/cgo_sigaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// Support for memory sanitizer. See runtime/cgo/sigaction.go.

// +build linux,amd64
// +build linux,amd64 freebsd,amd64

package runtime

Expand Down
Loading

0 comments on commit 88129f0

Please sign in to comment.