Commit 0489a260 authored by Devon H. O'Dell's avatar Devon H. O'Dell Committed by Russ Cox

FreeBSD-specific porting work.

cgo/libmach remain unimplemented. However, compilers, runtime,
and packages are 100%. I still need to go through and implement
missing syscalls (at least make sure they're all listed), but
for all shipped functionality, this is done. Ship! ;)

R=rsc, VenkateshSrinivas
https://golang.org/cl/152142
parent 30b1b9a3
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# license that can be found in the LICENSE file. # license that can be found in the LICENSE file.
set -e set -e
make hello fib chain gomake hello fib chain
echo '*' hello >run.out echo '*' hello >run.out
./hello >>run.out ./hello >>run.out
echo '*' fib >>run.out echo '*' fib >>run.out
...@@ -12,4 +12,4 @@ echo '*' fib >>run.out ...@@ -12,4 +12,4 @@ echo '*' fib >>run.out
echo '*' chain >>run.out echo '*' chain >>run.out
./chain >>run.out ./chain >>run.out
diff run.out golden.out diff run.out golden.out
make clean gomake clean
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#define PADDR(a) ((uint32)(a) & ~0x80000000) #define PADDR(a) ((uint32)(a) & ~0x80000000)
char linuxdynld[] = "/lib64/ld-linux-x86-64.so.2"; char linuxdynld[] = "/lib64/ld-linux-x86-64.so.2";
char freebsddynld[] = "/libexec/ld-elf.so.1";
char zeroes[32]; char zeroes[32];
...@@ -284,7 +285,7 @@ doelf(void) ...@@ -284,7 +285,7 @@ doelf(void)
Sym *s, *shstrtab, *dynamic, *dynstr, *d; Sym *s, *shstrtab, *dynamic, *dynstr, *d;
int h, nsym, t; int h, nsym, t;
if(HEADTYPE != 7) if(HEADTYPE != 7 && HEADTYPE != 9)
return; return;
/* predefine strings we need for section headers */ /* predefine strings we need for section headers */
...@@ -317,7 +318,14 @@ doelf(void) ...@@ -317,7 +318,14 @@ doelf(void)
s = lookup(".interp", 0); s = lookup(".interp", 0);
s->reachable = 1; s->reachable = 1;
s->type = SDATA; // TODO: rodata s->type = SDATA; // TODO: rodata
switch(HEADTYPE) {
case 7:
addstring(lookup(".interp", 0), linuxdynld); addstring(lookup(".interp", 0), linuxdynld);
break;
case 9:
addstring(lookup(".interp", 0), freebsddynld);
break;
}
/* /*
* hash table. * hash table.
...@@ -512,6 +520,7 @@ asmb(void) ...@@ -512,6 +520,7 @@ asmb(void)
break; break;
case 7: case 7:
case 9:
debug['8'] = 1; /* 64-bit addresses */ debug['8'] = 1; /* 64-bit addresses */
v = rnd(HEADR+textsize, INITRND); v = rnd(HEADR+textsize, INITRND);
seek(cout, v, 0); seek(cout, v, 0);
...@@ -565,6 +574,7 @@ asmb(void) ...@@ -565,6 +574,7 @@ asmb(void)
symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND)+machlink; symo = rnd(HEADR+textsize, INITRND)+rnd(datsize, INITRND)+machlink;
break; break;
case 7: case 7:
case 9:
symo = rnd(HEADR+textsize, INITRND)+datsize; symo = rnd(HEADR+textsize, INITRND)+datsize;
symo = rnd(symo, INITRND); symo = rnd(symo, INITRND);
break; break;
...@@ -649,6 +659,7 @@ asmb(void) ...@@ -649,6 +659,7 @@ asmb(void)
asmbmacho(symdatva, symo); asmbmacho(symdatva, symo);
break; break;
case 7: case 7:
case 9:
/* elf amd-64 */ /* elf amd-64 */
eh = getElfEhdr(); eh = getElfEhdr();
...@@ -871,6 +882,8 @@ asmb(void) ...@@ -871,6 +882,8 @@ asmb(void)
eh->ident[EI_MAG1] = 'E'; eh->ident[EI_MAG1] = 'E';
eh->ident[EI_MAG2] = 'L'; eh->ident[EI_MAG2] = 'L';
eh->ident[EI_MAG3] = 'F'; eh->ident[EI_MAG3] = 'F';
if(HEADTYPE == 9)
eh->ident[EI_OSABI] = 9;
eh->ident[EI_CLASS] = ELFCLASS64; eh->ident[EI_CLASS] = ELFCLASS64;
eh->ident[EI_DATA] = ELFDATA2LSB; eh->ident[EI_DATA] = ELFDATA2LSB;
eh->ident[EI_VERSION] = EV_CURRENT; eh->ident[EI_VERSION] = EV_CURRENT;
......
...@@ -46,6 +46,7 @@ char* paramspace = "FP"; ...@@ -46,6 +46,7 @@ char* paramspace = "FP";
* -H5 -T0x80110000 -R4096 is ELF32 * -H5 -T0x80110000 -R4096 is ELF32
* -H6 -Tx -Rx is apple MH-exec * -H6 -Tx -Rx is apple MH-exec
* -H7 -Tx -Rx is linux elf-exec * -H7 -Tx -Rx is linux elf-exec
* -H9 -Tx -Rx is FreeBSD elf-exec
* *
* options used: 189BLQSWabcjlnpsvz * options used: 189BLQSWabcjlnpsvz
*/ */
...@@ -149,6 +150,10 @@ main(int argc, char *argv[]) ...@@ -149,6 +150,10 @@ main(int argc, char *argv[])
if(strcmp(goos, "darwin") == 0) if(strcmp(goos, "darwin") == 0)
HEADTYPE = 6; HEADTYPE = 6;
else else
if(strcmp(goos, "freebsd") == 0) {
debug['d'] = 1; /* no dynamic syms for now */
HEADTYPE = 9;
} else
print("goos is not known: %s\n", goos); print("goos is not known: %s\n", goos);
} }
...@@ -194,6 +199,7 @@ main(int argc, char *argv[]) ...@@ -194,6 +199,7 @@ main(int argc, char *argv[])
INITDAT = 0; INITDAT = 0;
break; break;
case 7: /* elf64 executable */ case 7: /* elf64 executable */
case 9: /* freebsd */
elfinit(); elfinit();
HEADR = ELFRESERVE; HEADR = ELFRESERVE;
if(INITTEXT == -1) if(INITTEXT == -1)
......
...@@ -24,6 +24,7 @@ clean: ...@@ -24,6 +24,7 @@ clean:
install: install-$(shell uname | tr A-Z a-z) install: install-$(shell uname | tr A-Z a-z)
install-linux: install-default install-linux: install-default
install-freebsd: install-default
# on Darwin, have to install and setgid; see $GOROOT/src/sudo.bash # on Darwin, have to install and setgid; see $GOROOT/src/sudo.bash
install-darwin: $(TARG) install-darwin: $(TARG)
......
...@@ -24,6 +24,7 @@ clean: ...@@ -24,6 +24,7 @@ clean:
install: install-$(shell uname | tr A-Z a-z) install: install-$(shell uname | tr A-Z a-z)
install-linux: install-default install-linux: install-default
install-freebsd: install-default
# on Darwin, have to install and setgid; see $GOROOT/src/sudo.bash # on Darwin, have to install and setgid; see $GOROOT/src/sudo.bash
install-darwin: $(TARG) install-darwin: $(TARG)
......
...@@ -16,6 +16,7 @@ CFLAGS_amd64=-m64 ...@@ -16,6 +16,7 @@ CFLAGS_amd64=-m64
LDFLAGS_linux=-shared -lpthread -lm LDFLAGS_linux=-shared -lpthread -lm
LDFLAGS_darwin=-dynamiclib -Wl,-undefined,dynamic_lookup /usr/lib/libpthread.dylib LDFLAGS_darwin=-dynamiclib -Wl,-undefined,dynamic_lookup /usr/lib/libpthread.dylib
LDFLAGS_freebsd=-pthread -shared -lm
%.o: %.c %.o: %.c
gcc $(CFLAGS_$(GOARCH)) -O2 -fPIC -o $@ -c $*.c gcc $(CFLAGS_$(GOARCH)) -O2 -fPIC -o $@ -c $*.c
......
// Copyright 2009 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 <pthread.h>
#include "libcgo.h"
static void* threadentry(void*);
void
initcgo(void)
{
}
void
libcgo_sys_thread_start(ThreadStart *ts)
{
pthread_attr_t attr;
pthread_t p;
size_t size;
pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &size);
ts->g->stackguard = size;
pthread_create(&p, &attr, threadentry, ts);
}
static void*
threadentry(void *v)
{
ThreadStart ts;
ts = *(ThreadStart*)v;
free(v);
ts.g->stackbase = (uintptr)&ts;
/*
* libcgo_sys_thread_start set stackguard to stack size;
* change to actual guard pointer.
*/
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
crosscall_amd64(ts.m, ts.g, ts.fn);
return nil;
}
// This is stubbed out for the moment. Will revisit when the time comes.
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
int
ctlproc(int pid, char *msg)
{
sysfatal("ctlproc unimplemented in FreeBSD");
}
char*
proctextfile(int pid)
{
sysfatal("proctextfile unimplemented in FreeBSD");
}
char*
procstatus(int pid)
{
sysfatal("procstatus unimplemented in FreeBSD");
}
Map*
attachproc(int pid, Fhdr *fp)
{
sysfatal("attachproc unimplemented in FreeBSD");
}
void
detachproc(Map *m)
{
sysfatal("detachproc unimplemented in FreeBSD");
}
int
procthreadpids(int pid, int *p, int np)
{
sysfatal("procthreadpids unimplemented in FreeBSD");
}
// Copyright 2009 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 proc
import "os"
// Process tracing is not supported on FreeBSD yet.
func Attach(pid int) (Process, os.Error) {
return nil, os.NewError("debug/proc not implemented on FreeBSD")
}
func ForkExec(argv0 string, argv []string, envv []string, dir string, fd []*os.File) (Process, os.Error) {
return Attach(0)
}
// Copyright 2009 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 proc
// Copyright 2009 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.
// Waiting for FDs via kqueue/kevent.
package net
import (
"os";
"syscall";
)
type pollster struct {
kq int;
eventbuf [10]syscall.Kevent_t;
events []syscall.Kevent_t;
}
func newpollster() (p *pollster, err os.Error) {
p = new(pollster);
var e int;
if p.kq, e = syscall.Kqueue(); e != 0 {
return nil, os.NewSyscallError("kqueue", e)
}
p.events = p.eventbuf[0:0];
return p, nil;
}
func (p *pollster) AddFD(fd int, mode int, repeat bool) os.Error {
var kmode int;
if mode == 'r' {
kmode = syscall.EVFILT_READ
} else {
kmode = syscall.EVFILT_WRITE
}
var events [1]syscall.Kevent_t;
ev := &events[0];
// EV_ADD - add event to kqueue list
// EV_ONESHOT - delete the event the first time it triggers
flags := syscall.EV_ADD;
if !repeat {
flags |= syscall.EV_ONESHOT
}
syscall.SetKevent(ev, fd, kmode, flags);
n, e := syscall.Kevent(p.kq, &events, nil, nil);
if e != 0 {
return os.NewSyscallError("kevent", e)
}
if n != 1 || (ev.Flags&syscall.EV_ERROR) == 0 || int(ev.Ident) != fd || int(ev.Filter) != kmode {
return os.NewSyscallError("kqueue phase error", e)
}
if ev.Data != 0 {
return os.Errno(int(ev.Data))
}
return nil;
}
func (p *pollster) DelFD(fd int, mode int) {
var kmode int;
if mode == 'r' {
kmode = syscall.EVFILT_READ
} else {
kmode = syscall.EVFILT_WRITE
}
var events [1]syscall.Kevent_t;
ev := &events[0];
// EV_DELETE - delete event from kqueue list
syscall.SetKevent(ev, fd, kmode, syscall.EV_DELETE);
syscall.Kevent(p.kq, &events, nil, nil);
}
func (p *pollster) WaitFD(nsec int64) (fd int, mode int, err os.Error) {
var t *syscall.Timespec;
for len(p.events) == 0 {
if nsec > 0 {
if t == nil {
t = new(syscall.Timespec)
}
*t = syscall.NsecToTimespec(nsec);
}
nn, e := syscall.Kevent(p.kq, nil, &p.eventbuf, t);
if e != 0 {
if e == syscall.EINTR {
continue
}
return -1, 0, os.NewSyscallError("kevent", e);
}
if nn == 0 {
return -1, 0, nil
}
p.events = p.eventbuf[0:nn];
}
ev := &p.events[0];
p.events = p.events[1:len(p.events)];
fd = int(ev.Ident);
if ev.Filter == syscall.EVFILT_READ {
mode = 'r'
} else {
mode = 'w'
}
return fd, mode, nil;
}
func (p *pollster) Close() os.Error { return os.NewSyscallError("close", syscall.Close(p.kq)) }
...@@ -18,6 +18,10 @@ import ( ...@@ -18,6 +18,10 @@ import (
// Unfortunately, we need to run on kernels built without IPv6 support too. // Unfortunately, we need to run on kernels built without IPv6 support too.
// So probe the kernel to figure it out. // So probe the kernel to figure it out.
func kernelSupportsIPv6() bool { func kernelSupportsIPv6() bool {
// FreeBSD does not support this sort of interface.
if syscall.OS == "freebsd" {
return false
}
fd, e := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP); fd, e := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP);
if fd >= 0 { if fd >= 0 {
syscall.Close(fd) syscall.Close(fd)
......
// Copyright 2009 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 os
import (
"syscall";
"unsafe";
)
const (
blockSize = 4096; // TODO(r): use statfs
)
func (file *File) Readdirnames(count int) (names []string, err Error) {
// If this file has no dirinfo, create one.
if file.dirinfo == nil {
file.dirinfo = new(dirInfo);
// The buffer must be at least a block long.
// TODO(r): use fstatfs to find fs block size.
file.dirinfo.buf = make([]byte, blockSize);
}
d := file.dirinfo;
size := count;
if size < 0 {
size = 100
}
names = make([]string, 0, size); // Empty with room to grow.
for count != 0 {
// Refill the buffer if necessary
if d.bufp >= d.nbuf {
var errno int;
d.bufp = 0;
// Final argument is (basep *uintptr) and the syscall doesn't take nil.
d.nbuf, errno = syscall.Getdirentries(file.fd, d.buf, new(uintptr));
if errno != 0 {
d.nbuf = 0;
return names, NewSyscallError("getdirentries", errno);
}
if d.nbuf <= 0 {
break // EOF
}
}
// Drain the buffer
for count != 0 && d.bufp < d.nbuf {
dirent := (*syscall.Dirent)(unsafe.Pointer(&d.buf[d.bufp]));
if dirent.Reclen == 0 {
d.bufp = d.nbuf;
break;
}
d.bufp += int(dirent.Reclen);
if dirent.Fileno == 0 { // File absent in directory.
continue
}
bytes := (*[len(dirent.Name)]byte)(unsafe.Pointer(&dirent.Name[0]));
var name = string(bytes[0:dirent.Namlen]);
if name == "." || name == ".." { // Useless names
continue
}
count--;
if len(names) == cap(names) {
nnames := make([]string, len(names), 2*len(names));
for i := 0; i < len(names); i++ {
nnames[i] = names[i]
}
names = nnames;
}
names = names[0 : len(names)+1];
names[len(names)-1] = name;
}
}
return names, nil;
}
// Copyright 2009 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 os
import "syscall"
func isSymlink(stat *syscall.Stat_t) bool {
return stat.Mode&syscall.S_IFMT == syscall.S_IFLNK
}
func dirFromStat(name string, dir *Dir, lstat, stat *syscall.Stat_t) *Dir {
dir.Dev = uint64(stat.Dev);
dir.Ino = uint64(stat.Ino);
dir.Nlink = uint64(stat.Nlink);
dir.Mode = uint32(stat.Mode);
dir.Uid = stat.Uid;
dir.Gid = stat.Gid;
dir.Rdev = uint64(stat.Rdev);
dir.Size = uint64(stat.Size);
dir.Blksize = uint64(stat.Blksize);
dir.Blocks = uint64(stat.Blocks);
dir.Atime_ns = uint64(syscall.TimespecToNsec(stat.Atimespec));
dir.Mtime_ns = uint64(syscall.TimespecToNsec(stat.Mtimespec));
dir.Ctime_ns = uint64(syscall.TimespecToNsec(stat.Ctimespec));
for i := len(name) - 1; i >= 0; i-- {
if name[i] == '/' {
name = name[i+1 : len(name)];
break;
}
}
dir.Name = name;
if isSymlink(lstat) && !isSymlink(stat) {
dir.FollowedSymlink = true
}
return dir;
}
// Copyright 2009 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 os
import "syscall"
func Hostname() (name string, err Error) {
var errno int;
name, errno = syscall.Sysctl("kern.hostname");
if errno != 0 {
return "", NewSyscallError("sysctl kern.hostname", errno)
}
return name, nil;
}
...@@ -5,10 +5,9 @@ ...@@ -5,10 +5,9 @@
#include "amd64/asm.h" #include "amd64/asm.h"
TEXT _rt0_amd64(SB),7,$-8 TEXT _rt0_amd64(SB),7,$-8
// copy arguments forward on an even stack // copy arguments forward on an even stack
MOVQ 0(SP), AX // argc MOVQ 0(DI), AX // argc
LEAQ 8(SP), BX // argv LEAQ 8(DI), BX // argv
SUBQ $(4*8+7), SP // 2args 2auto SUBQ $(4*8+7), SP // 2args 2auto
ANDQ $~7, SP ANDQ $~7, SP
MOVQ AX, 16(SP) MOVQ AX, 16(SP)
......
...@@ -6,4 +6,5 @@ ...@@ -6,4 +6,5 @@
TEXT _rt0_amd64_darwin(SB),7,$-8 TEXT _rt0_amd64_darwin(SB),7,$-8
MOVQ $_rt0_amd64(SB), AX MOVQ $_rt0_amd64(SB), AX
MOVQ SP, DI
JMP AX JMP AX
// godefs -f -m64 freebsd/defs.c
// MACHINE GENERATED - DO NOT EDIT.
// Constants
enum {
PROT_NONE = 0,
PROT_READ = 0x1,
PROT_WRITE = 0x2,
PROT_EXEC = 0x4,
MAP_ANON = 0x1000,
MAP_PRIVATE = 0x2,
SA_SIGINFO = 0x40,
SA_RESTART = 0x2,
SA_ONSTACK = 0x1,
UMTX_OP_WAIT = 0x2,
UMTX_OP_WAKE = 0x3,
EINTR = 0x4,
};
// Types
#pragma pack on
typedef struct Sigaltstack Sigaltstack;
struct Sigaltstack {
int8 *ss_sp;
uint64 ss_size;
int32 ss_flags;
byte pad0[4];
};
typedef struct Sigset Sigset;
struct Sigset {
uint32 __bits[4];
};
typedef union Sigval Sigval;
union Sigval {
int32 sival_int;
void *sival_ptr;
int32 sigval_int;
void *sigval_ptr;
};
typedef struct StackT StackT;
struct StackT {
int8 *ss_sp;
uint64 ss_size;
int32 ss_flags;
byte pad0[4];
};
typedef struct Siginfo Siginfo;
struct Siginfo {
int32 si_signo;
int32 si_errno;
int32 si_code;
int32 si_pid;
uint32 si_uid;
int32 si_status;
void *si_addr;
Sigval si_value;
byte _reason[40];
};
typedef struct Mcontext Mcontext;
struct Mcontext {
int64 mc_onstack;
int64 mc_rdi;
int64 mc_rsi;
int64 mc_rdx;
int64 mc_rcx;
int64 mc_r8;
int64 mc_r9;
int64 mc_rax;
int64 mc_rbx;
int64 mc_rbp;
int64 mc_r10;
int64 mc_r11;
int64 mc_r12;
int64 mc_r13;
int64 mc_r14;
int64 mc_r15;
uint32 mc_trapno;
uint16 mc_fs;
uint16 mc_gs;
int64 mc_addr;
uint32 mc_flags;
uint16 mc_es;
uint16 mc_ds;
int64 mc_err;
int64 mc_rip;
int64 mc_cs;
int64 mc_rflags;
int64 mc_rsp;
int64 mc_ss;
int64 mc_len;
int64 mc_fpformat;
int64 mc_ownedfp;
int64 mc_fpstate[64];
int64 mc_fsbase;
int64 mc_gsbase;
int64 mc_spare[6];
};
typedef struct Ucontext Ucontext;
struct Ucontext {
Sigset uc_sigmask;
Mcontext uc_mcontext;
Ucontext *uc_link;
StackT uc_stack;
int32 uc_flags;
int32 __spare__[4];
byte pad0[12];
};
typedef struct Sigcontext Sigcontext;
struct Sigcontext {
Sigset sc_mask;
int64 sc_onstack;
int64 sc_rdi;
int64 sc_rsi;
int64 sc_rdx;
int64 sc_rcx;
int64 sc_r8;
int64 sc_r9;
int64 sc_rax;
int64 sc_rbx;
int64 sc_rbp;
int64 sc_r10;
int64 sc_r11;
int64 sc_r12;
int64 sc_r13;
int64 sc_r14;
int64 sc_r15;
int32 sc_trapno;
int16 sc_fs;
int16 sc_gs;
int64 sc_addr;
int32 sc_flags;
int16 sc_es;
int16 sc_ds;
int64 sc_err;
int64 sc_rip;
int64 sc_cs;
int64 sc_rflags;
int64 sc_rsp;
int64 sc_ss;
int64 sc_len;
int64 sc_fpformat;
int64 sc_ownedfp;
int64 sc_fpstate[64];
int64 sc_fsbase;
int64 sc_gsbase;
int64 sc_spare[6];
};
#pragma pack off
// Copyright 2009 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.
// Darwin and Linux use the same linkage to main
TEXT _rt0_amd64_freebsd(SB),7,$-8
MOVQ $_rt0_amd64(SB), DX
JMP DX
#include "runtime.h"
#include "defs.h"
#include "signals.h"
#include "os.h"
extern void sigtramp(void);
typedef struct sigaction {
union {
void (*__sa_handler)(int32);
void (*__sa_sigaction)(int32, Siginfo*, void *);
} __sigaction_u; /* signal handler */
int32 sa_flags; /* see signal options below */
int64 sa_mask; /* signal mask to apply */
} Sigaction;
void
dumpregs(Sigcontext *r)
{
printf("rax %X\n", r->sc_rax);
printf("rbx %X\n", r->sc_rbx);
printf("rcx %X\n", r->sc_rcx);
printf("rdx %X\n", r->sc_rdx);
printf("rdi %X\n", r->sc_rdi);
printf("rsi %X\n", r->sc_rsi);
printf("rbp %X\n", r->sc_rbp);
printf("rsp %X\n", r->sc_rsp);
printf("r8 %X\n", r->sc_r8 );
printf("r9 %X\n", r->sc_r9 );
printf("r10 %X\n", r->sc_r10);
printf("r11 %X\n", r->sc_r11);
printf("r12 %X\n", r->sc_r12);
printf("r13 %X\n", r->sc_r13);
printf("r14 %X\n", r->sc_r14);
printf("r15 %X\n", r->sc_r15);
printf("rip %X\n", r->sc_rip);
printf("rflags %X\n", r->sc_flags);
printf("cs %X\n", (uint64)r->sc_cs);
printf("fs %X\n", (uint64)r->sc_fsbase);
printf("gs %X\n", (uint64)r->sc_gsbase);
}
void
sighandler(int32 sig, Siginfo* info, void* context)
{
Ucontext *uc;
Mcontext *mc;
Sigcontext *sc;
if(panicking) // traceback already printed
exit(2);
panicking = 1;
uc = context;
mc = &uc->uc_mcontext;
sc = (Sigcontext*)mc; // same layout, more conveient names
if(sig < 0 || sig >= NSIG)
printf("Signal %d\n", sig);
else
printf("%s\n", sigtab[sig].name);
printf("Faulting address: %p\n", info->si_addr);
printf("PC=%X\n", sc->sc_rip);
printf("\n");
if(gotraceback()){
traceback((void*)sc->sc_rip, (void*)sc->sc_rsp, (void*)sc->sc_r15);
tracebackothers((void*)sc->sc_r15);
dumpregs(sc);
}
breakpoint();
exit(2);
}
void
sigignore(void)
{
}
void
signalstack(byte *p, int32 n)
{
Sigaltstack st;
st.ss_sp = (int8*)p;
st.ss_size = n;
st.ss_flags = 0;
sigaltstack(&st, nil);
}
void
initsig(void)
{
static Sigaction sa;
int32 i;
sa.sa_flags |= SA_ONSTACK | SA_SIGINFO;
sa.sa_mask = ~0x0ull;
for(i = 0; i < NSIG; i++) {
if(sigtab[i].flags) {
if(sigtab[i].flags & SigCatch)
sa.__sigaction_u.__sa_handler = (void*) sigtramp;
else
sa.__sigaction_u.__sa_handler = (void*) sigignore;
if(sigtab[i].flags & SigRestart)
sa.sa_flags |= SA_RESTART;
else
sa.sa_flags &= ~SA_RESTART;
sigaction(i, &sa, nil);
}
}
}
// Copyright 2009 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.
//
// System calls and other sys.stuff for AMD64, FreeBSD
// /usr/src/sys/kern/syscalls.master for syscall numbers.
//
#include "amd64/asm.h"
TEXT sys_umtx_op(SB),7,$0
MOVQ 8(SP), DI
MOVL 16(SP), SI
MOVL 20(SP), DX
MOVQ 24(SP), R10
MOVQ 32(SP), R8
MOVL $454, AX
SYSCALL
RET
TEXT thr_new(SB),7,$0
MOVQ 8(SP), DI
MOVQ 16(SP), SI
MOVL $455, AX
SYSCALL
RET
TEXT thr_start(SB),7,$0
MOVQ DI, m
MOVQ m_g0(m), g
CALL mstart(SB)
MOVQ 0, AX // crash (not reached)
// Exit the entire program (like C exit)
TEXT exit(SB),7,$-8
MOVL 8(SP), DI // arg 1 exit status
MOVL $1, AX
SYSCALL
CALL notok(SB)
RET
TEXT exit1(SB),7,$-8
MOVQ 8(SP), DI // arg 1 exit status
MOVL $431, AX
SYSCALL
CALL notok(SB)
RET
TEXT write(SB),7,$-8
MOVL 8(SP), DI // arg 1 fd
MOVQ 16(SP), SI // arg 2 buf
MOVL 24(SP), DX // arg 3 count
MOVL $4, AX
SYSCALL
JCC 2(PC)
CALL notok(SB)
RET
TEXT sigaction(SB),7,$-8
MOVL 8(SP), DI // arg 1 sig
MOVQ 16(SP), SI // arg 2 act
MOVQ 24(SP), DX // arg 3 oact
MOVL $416, AX
SYSCALL
JCC 2(PC)
CALL notok(SB)
RET
TEXT sigtramp(SB),7,$24-16
MOVQ m_gsignal(m), g
MOVQ DI, 0(SP)
MOVQ SI, 8(SP)
MOVQ DX, 16(SP)
CALL sighandler(SB)
RET
TEXT runtime·mmap(SB),7,$-8
MOVQ 8(SP), DI // arg 1 addr
MOVL 16(SP), SI // arg 2 len
MOVL 20(SP), DX // arg 3 prot
MOVL 24(SP), R10 // arg 4 flags
MOVL 28(SP), R8 // arg 5 fid
MOVL 32(SP), R9 // arg 6 offset
MOVL $477, AX
SYSCALL
JCC 2(PC)
CALL notok(SB)
RET
TEXT notok(SB),7,$-8
MOVL $0xf1, BP
MOVQ BP, (BP)
RET
TEXT runtime·memclr(SB),7,$-8
MOVQ 8(SP), DI // arg 1 addr
MOVL 16(SP), CX // arg 2 count
ADDL $7, CX
SHRL $3, CX
MOVQ $0, AX
CLD
REP
STOSQ
RET
TEXT runtime·getcallerpc+0(SB),7,$0
MOVQ x+0(FP),AX // addr of first arg
MOVQ -8(AX),AX // get calling pc
RET
TEXT runtime·setcallerpc+0(SB),7,$0
MOVQ x+0(FP),AX // addr of first arg
MOVQ x+8(FP), BX
MOVQ BX, -8(AX) // set calling pc
RET
TEXT sigaltstack(SB),7,$-8
MOVQ new+8(SP), DI
MOVQ old+16(SP), SI
MOVQ $53, AX
SYSCALL
JCC 2(PC)
CALL notok(SB)
RET
// Copyright 2009 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.
/*
* Input to godefs.
*
godefs -f -m64 defs.c >amd64/defs.h
godefs defs.c >386/defs.h
*/
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/ucontext.h>
#include <sys/umtx.h>
#include <sys/_sigset.h>
enum {
$PROT_NONE = PROT_NONE,
$PROT_READ = PROT_READ,
$PROT_WRITE = PROT_WRITE,
$PROT_EXEC = PROT_EXEC,
$MAP_ANON = MAP_ANON,
$MAP_PRIVATE = MAP_PRIVATE,
$SA_SIGINFO = SA_SIGINFO,
$SA_RESTART = SA_RESTART,
$SA_ONSTACK = SA_ONSTACK,
$UMTX_OP_WAIT = UMTX_OP_WAIT,
$UMTX_OP_WAKE = UMTX_OP_WAKE,
$EINTR = EINTR,
};
typedef struct sigaltstack $Sigaltstack;
typedef struct __sigset $Sigset;
typedef union sigval $Sigval;
typedef stack_t $StackT;
typedef siginfo_t $Siginfo;
typedef mcontext_t $Mcontext;
typedef ucontext_t $Ucontext;
typedef struct sigcontext $Sigcontext;
// FreeBSD-specific system calls
int32 ksem_init(uint64 *, uint32);
int32 ksem_wait(uint32);
int32 ksem_destroy(uint32);
int32 ksem_post(uint32);
struct thr_param {
void (*start_func)(void *); /* thread entry function. */
void *arg; /* argument for entry function. */
byte *stack_base; /* stack base address. */
int64 stack_size; /* stack size. */
byte *tls_base; /* tls base address. */
int64 tls_size; /* tls size. */
int64 *child_tid; /* address to store new TID. */
int64 *parent_tid; /* parent accesses the new TID here. */
int32 flags; /* thread flags. */
void *spare[4]; /* TODO: cpu affinity mask etc. */
};
int32 thr_new(struct thr_param*, uint64);
// Copyright 2009 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.
#define C SigCatch
#define I SigIgnore
#define R SigRestart
static SigTab sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
/* 1 */ 0, "SIGHUP: terminal line hangup",
/* 2 */ 0, "SIGINT: interrupt",
/* 3 */ C, "SIGQUIT: quit",
/* 4 */ C, "SIGILL: illegal instruction",
/* 5 */ C, "SIGTRAP: trace trap",
/* 6 */ C, "SIGABRT: abort",
/* 7 */ C, "SIGEMT: EMT instruction",
/* 8 */ C, "SIGFPE: floating-point exception",
/* 9 */ 0, "SIGKILL: kill",
/* 10 */ C, "SIGBUS: bus error",
/* 11 */ C, "SIGSEGV: segmentation violation",
/* 12 */ C, "SIGSYS: bad system call",
/* 13 */ I, "SIGPIPE: write to broken pipe",
/* 14 */ 0, "SIGALRM: alarm clock",
/* 15 */ 0, "SIGTERM: termination",
/* 16 */ 0, "SIGURG: urgent condition on socket",
/* 17 */ 0, "SIGSTOP: stop, unblockable",
/* 18 */ 0, "SIGTSTP: stop from tty",
/* 19 */ 0, "SIGCONT: continue",
/* 20 */ I+R, "SIGCHLD: child status has changed",
/* 21 */ 0, "SIGTTIN: background read from tty",
/* 22 */ 0, "SIGTTOU: background write to tty",
/* 23 */ 0, "SIGIO: i/o now possible",
/* 24 */ 0, "SIGXCPU: cpu limit exceeded",
/* 25 */ 0, "SIGXFSZ: file size limit exceeded",
/* 26 */ 0, "SIGVTALRM: virtual alarm clock",
/* 27 */ 0, "SIGPROF: profiling alarm clock",
/* 28 */ I+R, "SIGWINCH: window size change",
/* 29 */ 0, "SIGINFO: information request",
/* 30 */ 0, "SIGUSR1: user-defined signal 1",
/* 31 */ 0, "SIGUSR2: user-defined signal 2",
/* 32 */ 0, "SIGTHR: reserved",
};
#undef C
#undef I
#undef R
#define NSIG 33
// Use of this source file is governed by a BSD-style
// license that can be found in the LICENSE file.`
#include "runtime.h"
#include "defs.h"
#include "signals.h"
#include "os.h"
// FreeBSD's umtx_op syscall is effectively the same as Linux's futex, and
// thus the code is largely similar. See linux/thread.c for comments.
static void
umtx_wait(uint32 *addr, uint32 val)
{
int32 ret;
ret = sys_umtx_op(addr, UMTX_OP_WAIT, val, nil, nil);
if(ret >= 0 || ret == -EINTR)
return;
printf("umtx_wait addr=%p val=%d ret=%d\n", addr, val, ret);
*(int32*)0x1005 = 0x1005;
}
static void
umtx_wake(uint32 *addr)
{
int32 ret;
ret = sys_umtx_op(addr, UMTX_OP_WAKE, 1, nil, nil);
if(ret >= 0)
return;
printf("umtx_wake addr=%p ret=%d\n", addr, ret);
*(int32*)0x1006 = 0x1006;
}
// See linux/thread.c for comments about the algorithm.
static void
umtx_lock(Lock *l)
{
uint32 v;
again:
v = l->key;
if((v&1) == 0){
if(cas(&l->key, v, v|1))
return;
goto again;
}
if(!cas(&l->key, v, v+2))
goto again;
umtx_wait(&l->key, v+2);
for(;;){
v = l->key;
if(v < 2)
throw("bad lock key");
if(cas(&l->key, v, v-2))
break;
}
goto again;
}
static void
umtx_unlock(Lock *l)
{
uint32 v;
again:
v = l->key;
if((v&1) == 0)
throw("unlock of unlocked lock");
if(!cas(&l->key, v, v&~1))
goto again;
if(v&~1)
umtx_wake(&l->key);
}
void
lock(Lock *l)
{
if(m->locks < 0)
throw("lock count");
m->locks++;
umtx_lock(l);
}
void
unlock(Lock *l)
{
m->locks--;
if(m->locks < 0)
throw("lock count");
umtx_unlock(l);
}
// Event notifications.
void
noteclear(Note *n)
{
n->lock.key = 0;
umtx_lock(&n->lock);
}
void
notesleep(Note *n)
{
umtx_lock(&n->lock);
umtx_unlock(&n->lock);
}
void
notewakeup(Note *n)
{
umtx_unlock(&n->lock);
}
void thr_start(void*);
void
newosproc(M *m, G *g, void *stk, void (*fn)(void))
{
struct thr_param param;
USED(fn); // thr_start assumes fn == mstart
USED(g); // thr_start assumes g == m->g0
if(0){
printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n",
stk, m, g, fn, m->id, m->tls[0], &m);
}
runtime_memclr((byte*)&param, sizeof param);
param.start_func = thr_start;
param.arg = m;
param.stack_base = stk;
param.stack_size = g->stackbase - g->stackguard + 256;
param.child_tid = (int64*)&m->procid;
param.parent_tid = nil;
thr_new(&param, sizeof param);
}
void
osinit(void)
{
}
// Called to initialize a new m (including the bootstrap m).
void
minit(void)
{
// Initialize signal handling
m->gsignal = malg(32*1024);
signalstack(m->gsignal->stackguard, 32*1024);
}
...@@ -11,6 +11,7 @@ TEXT _rt0_amd64_linux(SB),7,$-8 ...@@ -11,6 +11,7 @@ TEXT _rt0_amd64_linux(SB),7,$-8
CALL AX CALL AX
MOVQ $_rt0_amd64(SB), AX MOVQ $_rt0_amd64(SB), AX
MOVQ SP, DI
JMP AX JMP AX
GLOBL initcgo(SB), $8 GLOBL initcgo(SB), $8
// Copyright 2009 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.
//
// System call support for AMD64, FreeBSD
//
// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
// Trap # in AX, args in DI SI DX, return in AX DX
TEXT syscall·Syscall(SB),7,$0
CALL runtime·entersyscall(SB)
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ $0, R10
MOVQ $0, R8
MOVQ $0, R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
JCC ok
MOVQ $-1, 40(SP) // r1
MOVQ $0, 48(SP) // r2
MOVQ AX, 56(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok:
MOVQ AX, 40(SP) // r1
MOVQ DX, 48(SP) // r2
MOVQ $0, 56(SP) // errno
CALL runtime·exitsyscall(SB)
RET
TEXT syscall·Syscall6(SB),7,$0
CALL runtime·entersyscall(SB)
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ 40(SP), R10
MOVQ 48(SP), R8
MOVQ 56(SP), R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
JCC ok6
MOVQ $-1, 64(SP) // r1
MOVQ $0, 72(SP) // r2
MOVQ AX, 80(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok6:
MOVQ AX, 64(SP) // r1
MOVQ DX, 72(SP) // r2
MOVQ $0, 80(SP) // errno
CALL runtime·exitsyscall(SB)
RET
TEXT syscall·RawSyscall(SB),7,$0
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ $0, R10
MOVQ $0, R8
MOVQ $0, R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
JCC ok1
MOVQ $-1, 40(SP) // r1
MOVQ $0, 48(SP) // r2
MOVQ AX, 56(SP) // errno
RET
ok1:
MOVQ AX, 40(SP) // r1
MOVQ DX, 48(SP) // r2
MOVQ $0, 56(SP) // errno
RET
#!/usr/bin/perl
# Copyright 2009 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.
#
# Generate system call table for FreeBSD from master list
# (for example, /usr/src/sys/kern/syscalls.master).
my $command = "mksysnum_freebsd.sh " . join(' ', @ARGV);
print <<EOF;
// $command
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
package syscall
const (
EOF
while(<>){
if(/^([0-9]+)\s+\S+\s+STD\s+({ \S+\s+(\w+).*)$/){
my $num = $1;
my $proto = $2;
my $name = "SYS_$3";
$name =~ y/a-z/A-Z/;
# There are multiple entries for enosys and nosys, so comment them out.
if($name =~ /^SYS_E?NOSYS$/){
$name = "// $name";
}
if($name eq 'SYS_SYS_EXIT'){
$name = 'SYS_EXIT';
}
print " $name = $num; // $proto\n";
}
}
print <<EOF;
)
EOF
This diff is collapsed.
// Copyright 2009 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 syscall
func Getpagesize() int { return 4096 }
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
func NsecToTimespec(nsec int64) (ts Timespec) {
ts.Sec = nsec / 1e9;
ts.Nsec = nsec % 1e9;
return;
}
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
func NsecToTimeval(nsec int64) (tv Timeval) {
nsec += 999; // round up to microsecond
tv.Usec = nsec % 1e9 / 1e3;
tv.Sec = int64(nsec / 1e9);
return;
}
func SetKevent(k *Kevent_t, fd, mode, flags int) {
k.Ident = uint64(fd);
k.Filter = int16(mode);
k.Flags = uint16(flags);
}
// Copyright 2009 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.
/*
Input to godefs. See also mkerrors.sh and mkall.sh
*/
#define KERNEL
#include <sys/cdefs.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <stdio.h>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/ptrace.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <unistd.h>
// Machine characteristics; for internal use.
enum
{
$sizeofPtr = sizeof(void*),
$sizeofShort = sizeof(short),
$sizeofInt = sizeof(int),
$sizeofLong = sizeof(long),
$sizeofLongLong = sizeof(long long),
};
// Basic types
typedef short $_C_short;
typedef int $_C_int;
typedef long $_C_long;
typedef long long $_C_long_long;
// Time
typedef struct timespec $Timespec;
typedef struct timeval $Timeval;
// Processes
typedef struct rusage $Rusage;
typedef struct rlimit $Rlimit;
typedef gid_t $_Gid_t;
// Files
enum
{
$O_CLOEXEC = 0, // not supported
};
enum
{ // Directory mode bits
$S_IFMT = S_IFMT,
$S_IFIFO = S_IFIFO,
$S_IFCHR = S_IFCHR,
$S_IFDIR = S_IFDIR,
$S_IFBLK = S_IFBLK,
$S_IFREG = S_IFREG,
$S_IFLNK = S_IFLNK,
$S_IFSOCK = S_IFSOCK,
$S_ISUID = S_ISUID,
$S_ISGID = S_ISGID,
$S_ISVTX = S_ISVTX,
$S_IRUSR = S_IRUSR,
$S_IWUSR = S_IWUSR,
$S_IXUSR = S_IXUSR,
};
typedef struct stat $Stat_t;
typedef struct statfs $Statfs_t;
typedef struct flock $Flock_t;
typedef struct dirent $Dirent;
// Wait status.
// Sockets
union sockaddr_all {
struct sockaddr s1; // this one gets used for fields
struct sockaddr_in s2; // these pad it out
struct sockaddr_in6 s3;
struct sockaddr_un s4;
};
struct sockaddr_any {
struct sockaddr addr;
char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)];
};
typedef struct sockaddr_in $RawSockaddrInet4;
typedef struct sockaddr_in6 $RawSockaddrInet6;
typedef struct sockaddr_un $RawSockaddrUnix;
typedef struct sockaddr $RawSockaddr;
typedef struct sockaddr_any $RawSockaddrAny;
typedef socklen_t $_Socklen;
typedef struct linger $Linger;
typedef struct iovec $Iovec;
typedef struct msghdr $Msghdr;
typedef struct cmsghdr $Cmsghdr;
enum {
$SizeofSockaddrInet4 = sizeof(struct sockaddr_in),
$SizeofSockaddrInet6 = sizeof(struct sockaddr_in6),
$SizeofSockaddrAny = sizeof(struct sockaddr_any),
$SizeofSockaddrUnix = sizeof(struct sockaddr_un),
$SizeofLinger = sizeof(struct linger),
$SizeofMsghdr = sizeof(struct msghdr),
$SizeofCmsghdr = sizeof(struct cmsghdr),
};
// Ptrace requests
enum {
$PTRACE_TRACEME = PT_TRACE_ME,
$PTRACE_CONT = PT_CONTINUE,
$PTRACE_KILL = PT_KILL,
};
// Events (kqueue, kevent)
typedef struct kevent $Kevent_t;
// Select
typedef fd_set $FdSet;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// godefs -gsyscall -f-m64 types_freebsd.c
// MACHINE GENERATED - DO NOT EDIT.
package syscall
// Constants
const (
sizeofPtr = 0x8;
sizeofShort = 0x2;
sizeofInt = 0x4;
sizeofLong = 0x8;
sizeofLongLong = 0x8;
O_CLOEXEC = 0;
S_IFMT = 0xf000;
S_IFIFO = 0x1000;
S_IFCHR = 0x2000;
S_IFDIR = 0x4000;
S_IFBLK = 0x6000;
S_IFREG = 0x8000;
S_IFLNK = 0xa000;
S_IFSOCK = 0xc000;
S_ISUID = 0x800;
S_ISGID = 0x400;
S_ISVTX = 0x200;
S_IRUSR = 0x100;
S_IWUSR = 0x80;
S_IXUSR = 0x40;
SizeofSockaddrInet4 = 0x10;
SizeofSockaddrInet6 = 0x1c;
SizeofSockaddrAny = 0x6c;
SizeofSockaddrUnix = 0x6a;
SizeofLinger = 0x8;
SizeofMsghdr = 0x30;
SizeofCmsghdr = 0xc;
PTRACE_TRACEME = 0;
PTRACE_CONT = 0x7;
PTRACE_KILL = 0x8;
)
// Types
type _C_short int16
type _C_int int32
type _C_long int64
type _C_long_long int64
type Timespec struct {
Sec int64;
Nsec int64;
}
type Timeval struct {
Sec int64;
Usec int64;
}
type Rusage struct {
Utime Timeval;
Stime Timeval;
Maxrss int64;
Ixrss int64;
Idrss int64;
Isrss int64;
Minflt int64;
Majflt int64;
Nswap int64;
Inblock int64;
Oublock int64;
Msgsnd int64;
Msgrcv int64;
Nsignals int64;
Nvcsw int64;
Nivcsw int64;
}
type Rlimit struct {
Cur int64;
Max int64;
}
type _Gid_t uint32
type Stat_t struct {
Dev uint32;
Ino uint32;
Mode uint16;
Nlink uint16;
Uid uint32;
Gid uint32;
Rdev uint32;
Atimespec Timespec;
Mtimespec Timespec;
Ctimespec Timespec;
Size int64;
Blocks int64;
Blksize uint32;
Flags uint32;
Gen uint32;
Lspare int32;
Birthtimespec Timespec;
Pad0 uint8;
Pad1 uint8;
}
type Statfs_t struct {
Version uint32;
Type uint32;
Flags uint64;
Bsize uint64;
Iosize uint64;
Blocks uint64;
Bfree uint64;
Bavail int64;
Files uint64;
Ffree int64;
Syncwrites uint64;
Asyncwrites uint64;
Syncreads uint64;
Asyncreads uint64;
Spare [10]uint64;
Namemax uint32;
Owner uint32;
Fsid [8]byte; /* fsid */
Charspare [80]int8;
Fstypename [16]int8;
Mntfromname [88]int8;
Mntonname [88]int8;
}
type Flock_t struct {
Start int64;
Len int64;
Pid int32;
Type int16;
Whence int16;
Sysid int32;
Pad0 [4]byte;
}
type Dirent struct {
Fileno uint32;
Reclen uint16;
Type uint8;
Namlen uint8;
Name [256]int8;
}
type RawSockaddrInet4 struct {
Len uint8;
Family uint8;
Port uint16;
Addr [4]byte; /* in_addr */
Zero [8]int8;
}
type RawSockaddrInet6 struct {
Len uint8;
Family uint8;
Port uint16;
Flowinfo uint32;
Addr [16]byte; /* in6_addr */
Scope_id uint32;
}
type RawSockaddrUnix struct {
Len uint8;
Family uint8;
Path [104]int8;
}
type RawSockaddr struct {
Len uint8;
Family uint8;
Data [14]int8;
}
type RawSockaddrAny struct {
Addr RawSockaddr;
Pad [92]int8;
}
type _Socklen uint32
type Linger struct {
Onoff int32;
Linger int32;
}
type Iovec struct {
Base *byte;
Len uint64;
}
type Msghdr struct {
Name *byte;
Namelen uint32;
Pad0 [4]byte;
Iov *Iovec;
Iovlen int32;
Pad1 [4]byte;
Control *byte;
Controllen uint32;
Flags int32;
}
type Cmsghdr struct {
Len uint32;
Level int32;
Type int32;
}
type Kevent_t struct {
Ident uint64;
Filter int16;
Flags uint16;
Fflags uint32;
Data int64;
Udata *byte;
}
type FdSet struct {
X__fds_bits [16]uint64;
}
...@@ -14,7 +14,7 @@ func init() { ...@@ -14,7 +14,7 @@ func init() {
// Force US Pacific time for daylight-savings // Force US Pacific time for daylight-savings
// tests below (localtests). Needs to be set // tests below (localtests). Needs to be set
// before the first call into the time library. // before the first call into the time library.
os.Setenv("TZ", "US/Pacific") os.Setenv("TZ", "America/Los_Angeles")
} }
type TimeTest struct { type TimeTest struct {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment