Skip to content

Commit

Permalink
add support for FreeBSD / aarch64
Browse files Browse the repository at this point in the history
  • Loading branch information
miki committed May 6, 2019
1 parent 8e28cd1 commit b46aa4e
Show file tree
Hide file tree
Showing 21 changed files with 5,405 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/cmd/api/goapi.go
Expand Up @@ -71,6 +71,8 @@ var contexts = []*build.Context{
{GOOS: "freebsd", GOARCH: "amd64"},
{GOOS: "freebsd", GOARCH: "arm", CgoEnabled: true},
{GOOS: "freebsd", GOARCH: "arm"},
{GOOS: "freebsd", GOARCH: "arm64", CgoEnabled: true},
{GOOS: "freebsd", GOARCH: "arm64"},
{GOOS: "netbsd", GOARCH: "386", CgoEnabled: true},
{GOOS: "netbsd", GOARCH: "386"},
{GOOS: "netbsd", GOARCH: "amd64", CgoEnabled: true},
Expand Down
1 change: 1 addition & 0 deletions src/cmd/dist/build.go
Expand Up @@ -1486,6 +1486,7 @@ var cgoEnabled = map[string]bool{
"freebsd/386": true,
"freebsd/amd64": true,
"freebsd/arm": true,
"freebsd/arm64": true,
"linux/386": true,
"linux/amd64": true,
"linux/arm": true,
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/link/internal/arm64/obj.go
Expand Up @@ -86,7 +86,8 @@ func archinit(ctxt *ld.Link) {

case objabi.Hlinux, /* arm64 elf */
objabi.Hnetbsd,
objabi.Hopenbsd:
objabi.Hopenbsd,
objabi.Hfreebsd:
ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE
if *ld.FlagTextAddr == -1 {
Expand Down
68 changes: 68 additions & 0 deletions src/runtime/cgo/gcc_freebsd_arm64.c
@@ -0,0 +1,68 @@
// Copyright 2019 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 <sys/types.h>
#include <errno.h>
#include <sys/signalvar.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include "libcgo.h"
#include "libcgo_unix.h"

static void* threadentry(void*);
static void (*setg_gcc)(void*);

void
x_cgo_init(G *g, void (*setg)(void*))
{
pthread_attr_t attr;
size_t size;

setg_gcc = setg;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
g->stacklo = (uintptr)&attr - size + 4096;
pthread_attr_destroy(&attr);
}

void
_cgo_sys_thread_start(ThreadStart *ts)
{
pthread_attr_t attr;
sigset_t ign, oset;
pthread_t p;
size_t size;
int err;

SIGFILLSET(ign);
pthread_sigmask(SIG_SETMASK, &ign, &oset);

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();
}
}

extern void crosscall1(void (*fn)(void), void (*setg_gcc)(void*), void *g);

static void*
threadentry(void *v)
{
ThreadStart ts;

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

crosscall1(ts.fn, setg_gcc, (void*)ts.g);
return nil;
}
252 changes: 252 additions & 0 deletions src/runtime/defs_freebsd_arm64.go
@@ -0,0 +1,252 @@
// created by cgo -cdefs and then converted to Go
// cgo -cdefs defs_freebsd.go

package runtime

import "unsafe"

const (
_NBBY = 0x8
_CTL_MAXNAME = 0x18
_CPU_LEVEL_WHICH = 0x3
_CPU_WHICH_PID = 0x2
)

const (
_EINTR = 0x4
_EFAULT = 0xe

_PROT_NONE = 0x0
_PROT_READ = 0x1
_PROT_WRITE = 0x2
_PROT_EXEC = 0x4

_MAP_ANON = 0x1000
_MAP_SHARED = 0x1
_MAP_PRIVATE = 0x2
_MAP_FIXED = 0x10

_MADV_FREE = 0x5

_SA_SIGINFO = 0x40
_SA_RESTART = 0x2
_SA_ONSTACK = 0x1

_CLOCK_MONOTONIC = 0x4
_CLOCK_REALTIME = 0x0

_UMTX_OP_WAIT_UINT = 0xb
_UMTX_OP_WAIT_UINT_PRIVATE = 0xf
_UMTX_OP_WAKE = 0x3
_UMTX_OP_WAKE_PRIVATE = 0x10

_SIGHUP = 0x1
_SIGINT = 0x2
_SIGQUIT = 0x3
_SIGILL = 0x4
_SIGTRAP = 0x5
_SIGABRT = 0x6
_SIGEMT = 0x7
_SIGFPE = 0x8
_SIGKILL = 0x9
_SIGBUS = 0xa
_SIGSEGV = 0xb
_SIGSYS = 0xc
_SIGPIPE = 0xd
_SIGALRM = 0xe
_SIGTERM = 0xf
_SIGURG = 0x10
_SIGSTOP = 0x11
_SIGTSTP = 0x12
_SIGCONT = 0x13
_SIGCHLD = 0x14
_SIGTTIN = 0x15
_SIGTTOU = 0x16
_SIGIO = 0x17
_SIGXCPU = 0x18
_SIGXFSZ = 0x19
_SIGVTALRM = 0x1a
_SIGPROF = 0x1b
_SIGWINCH = 0x1c
_SIGINFO = 0x1d
_SIGUSR1 = 0x1e
_SIGUSR2 = 0x1f

_FPE_INTDIV = 0x2
_FPE_INTOVF = 0x1
_FPE_FLTDIV = 0x3
_FPE_FLTOVF = 0x4
_FPE_FLTUND = 0x5
_FPE_FLTRES = 0x6
_FPE_FLTINV = 0x7
_FPE_FLTSUB = 0x8

_BUS_ADRALN = 0x1
_BUS_ADRERR = 0x2
_BUS_OBJERR = 0x3

_SEGV_MAPERR = 0x1
_SEGV_ACCERR = 0x2

_ITIMER_REAL = 0x0
_ITIMER_VIRTUAL = 0x1
_ITIMER_PROF = 0x2

_EV_ADD = 0x1
_EV_DELETE = 0x2
_EV_CLEAR = 0x20
_EV_RECEIPT = 0x40
_EV_ERROR = 0x4000
_EV_EOF = 0x8000
_EVFILT_READ = -0x1
_EVFILT_WRITE = -0x2
)

type rtprio struct {
_type uint16
prio uint16
}

type thrparam struct {
start_func uintptr
arg unsafe.Pointer
stack_base uintptr
stack_size uintptr
tls_base unsafe.Pointer
tls_size uintptr
child_tid unsafe.Pointer // *int64
parent_tid *int64
flags int32
pad_cgo_0 [4]byte
rtp *rtprio
spare [3]uintptr
}

type sigset struct {
__bits [4]uint32
}

type stackt struct {
ss_sp uintptr
ss_size uintptr
ss_flags int32
pad_cgo_0 [4]byte
}

type siginfo struct {
si_signo int32
si_errno int32
si_code int32
si_pid int32
si_uid uint32
si_status int32
si_addr uint64
si_value [8]byte
_reason [40]byte
}

type gpregs struct {
gp_x [30]uint64
gp_lr uint64
gp_sp uint64
gp_elr uint64
gp_spsr uint32
gp_pad int32
}

type fpregs struct {
fp_q [64]uint64 // actually [32]uint128
fp_sr uint32
fp_cr uint32
fp_flags int32
fp_pad int32
}

type mcontext struct {
mc_gpregs gpregs
mc_fpregs fpregs
mc_flags int32
mc_pad int32
mc_spare [8]uint64
}

type ucontext struct {
uc_sigmask sigset
uc_mcontext mcontext
uc_link *ucontext
uc_stack stackt
uc_flags int32
__spare__ [4]int32
pad_cgo_0 [12]byte
}

type timespec struct {
tv_sec int64
tv_nsec int64
}

//go:nosplit
func (ts *timespec) setNsec(ns int64) {
ts.tv_sec = ns / 1e9
ts.tv_nsec = ns % 1e9
}

type timeval struct {
tv_sec int64
tv_usec int64
}

func (tv *timeval) set_usec(x int32) {
tv.tv_usec = int64(x)
}

type itimerval struct {
it_interval timeval
it_value timeval
}

type umtx_time struct {
_timeout timespec
_flags uint32
_clockid uint32
}

type keventt struct {
ident uint64
filter int16
flags uint16
fflags uint32
data int64
udata *byte
}

type bintime struct {
sec int64
frac uint64
}

type vdsoTimehands struct {
algo uint32
gen uint32
scale uint64
offset_count uint32
counter_mask uint32
offset bintime
boottime bintime
physical uint32
res [7]uint32
}

type vdsoTimekeep struct {
ver uint32
enabled uint32
current uint32
pad_cgo_0 [4]byte
}

const (
_VDSO_TK_VER_CURR = 0x1

vdsoTimehandsSize = 0x58
vdsoTimekeepSize = 0x10
)
1 change: 1 addition & 0 deletions src/runtime/os_freebsd2.go
Expand Up @@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.

// +build freebsd,!amd64
// +build freebsd,!arm64

package runtime

Expand Down

0 comments on commit b46aa4e

Please sign in to comment.