diff --git a/dev-lang/golang/golang-1.4.3.recipe b/dev-lang/golang/golang-1.4.3.recipe new file mode 100644 index 000000000..aff380cb9 --- /dev/null +++ b/dev-lang/golang/golang-1.4.3.recipe @@ -0,0 +1,73 @@ +SUMMARY="The Go Programming Language" +DESCRIPTION="The Go Programming Language is an open source project to make \ +programmers more productive. + +Go is expressive, concise, clean, and efficient. Its concurrency \ +mechanisms make it easy to write programs that get the most out of multicore \ +and networked machines, while its novel type system enables flexible and \ +modular program construction. Go compiles quickly to machine code yet has the \ +convenience of garbage collection and the power of run-time reflection. It's a \ +fast, statically typed, compiled language that feels like a dynamically typed, \ +interpreted language." +HOMEPAGE="https://golang.org/go" +COPYRIGHT="2009-2018 The Go Authors" +LICENSE="BSD (3-clause)" +REVISION="1" +SOURCE_URI="https://dl.google.com/go/go$portVersion.src.tar.gz" +CHECKSUM_SHA256="9947fc705b0b841b5938c48b22dc33e9647ec0752bae66e50278df4f23f64959" +SOURCE_DIR="go" +PATCHES="golang-$portVersion.patchset" + +ARCHITECTURES="!x86_gcc2 !x86 ?x86_64" +SECONDARY_ARCHITECTURES="!x86" + +PROVIDES=" + golang$secondaryArchSuffix = $portVersion + cmd:go$secondaryArchSuffix = $portVersion + cmd:gofmt$secondaryArchSuffix = $portVersion + cmd:godoc$secondaryArchSuffix = $portVersion + " +if [ -n "$secondaryArchSuffix" ]; then +PROVIDES="$PROVIDES + cmd:go = $portVersion + cmd:gofmt = $portVersion + cmd:godoc = $portVersion + " +fi + +REQUIRES=" + haiku$secondaryArchSuffix + " +BUILD_REQUIRES=" + haiku${secondaryArchSuffix}_devel + " + +BUILD_PREREQUIRES=" + cmd:gcc$secondaryArchSuffix + cmd:git + " + +BUILD() +{ + echo "$portVersion" > VERSION + export GOROOT_FINAL=/system/$relativeDevelopLibDir/go + cd src + DISABLE_ASLR=1 ./make.bash + cd .. + export GOPATH=/tmp + export GOROOT="$sourceDir" +} + +INSTALL() +{ + mkdir -p $developLibDir/go/ + cp -r src pkg doc $developLibDir/go/ + mkdir -p $binDir + cp bin/* $binDir/ +} + +TEST() +{ + cd src + DISABLE_ASLR=1 ./all.bash +} diff --git a/dev-lang/golang/patches/golang-1.4.3.patchset b/dev-lang/golang/patches/golang-1.4.3.patchset new file mode 100644 index 000000000..8e9178694 --- /dev/null +++ b/dev-lang/golang/patches/golang-1.4.3.patchset @@ -0,0 +1,7777 @@ +From 709601cc4136cb49e4a6f3f1b2b90058b698d396 Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:55:04 +0100 +Subject: cmd/ld: Port cmd and ld to build on Haiku x86_64. + + +diff --git a/include/link.h b/include/link.h +index 05e117c..50c8120 100644 +--- a/include/link.h ++++ b/include/link.h +@@ -495,6 +495,7 @@ enum { + Hdragonfly, + Helf, + Hfreebsd, ++ Hhaiku, + Hlinux, + Hnacl, + Hnetbsd, +diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c +index 9c1c04e..7af74ea 100644 +--- a/src/cmd/5l/asm.c ++++ b/src/cmd/5l/asm.c +@@ -38,6 +38,7 @@ + + char linuxdynld[] = "/lib/ld-linux.so.3"; // 2 for OABI, 3 for EABI + char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; ++char haikudynld[] = "XXX"; + char openbsddynld[] = "XXX"; + char netbsddynld[] = "/libexec/ld.elf_so"; + char dragonflydynld[] = "XXX"; +diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c +index 18b5aa3..3936b83 100644 +--- a/src/cmd/6l/asm.c ++++ b/src/cmd/6l/asm.c +@@ -41,6 +41,7 @@ + + char linuxdynld[] = "/lib64/ld-linux-x86-64.so.2"; + char freebsddynld[] = "/libexec/ld-elf.so.1"; ++char haikudynld[] = "/system/runtime_loader"; + char openbsddynld[] = "/usr/libexec/ld.so"; + char netbsddynld[] = "/libexec/ld.elf_so"; + char dragonflydynld[] = "/usr/libexec/ld-elf.so.2"; +@@ -301,7 +302,15 @@ elfreloc1(Reloc *r, vlong sectoff) + + case R_PCREL: + if(r->siz == 4) { +- VPUT(R_X86_64_PC32 | (uint64)elfsym<<32); ++ // HACK to fix relocation issue with Haiku // ++ if(HEADTYPE == Hhaiku) { ++ if(r->xsym->type == SDYNIMPORT) ++ VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32); ++ else ++ VPUT(R_X86_64_PC32 | (uint64)elfsym<<32); ++ //// ++ } else ++ VPUT(R_X86_64_PC32 | (uint64)elfsym<<32); + } else + return -1; + break; +@@ -678,6 +687,7 @@ asmb(void) + case Hopenbsd: + case Hdragonfly: + case Hsolaris: ++ case Hhaiku: + debug['8'] = 1; /* 64-bit addresses */ + break; + case Hnacl: +@@ -710,6 +720,7 @@ asmb(void) + case Hdragonfly: + case Hsolaris: + case Hnacl: ++ case Hhaiku: + symo = segdata.fileoff+segdata.filelen; + symo = rnd(symo, INITRND); + break; +@@ -787,6 +798,7 @@ asmb(void) + break; + case Hlinux: + case Hfreebsd: ++ case Hhaiku: + case Hnetbsd: + case Hopenbsd: + case Hdragonfly: +diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c +index 3b8e8f4..9641f70 100644 +--- a/src/cmd/6l/obj.c ++++ b/src/cmd/6l/obj.c +@@ -72,6 +72,7 @@ archinit(void) + case Hdarwin: + case Hdragonfly: + case Hfreebsd: ++ case Hhaiku: + case Hlinux: + case Hnacl: + case Hnetbsd: +@@ -114,6 +115,7 @@ archinit(void) + break; + case Hlinux: /* elf64 executable */ + case Hfreebsd: /* freebsd */ ++ case Hhaiku: /* haiku */ + case Hnetbsd: /* netbsd */ + case Hopenbsd: /* openbsd */ + case Hdragonfly: /* dragonfly */ +diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c +index 98c0424..3282dbc 100644 +--- a/src/cmd/8l/asm.c ++++ b/src/cmd/8l/asm.c +@@ -39,6 +39,7 @@ + + char linuxdynld[] = "/lib/ld-linux.so.2"; + char freebsddynld[] = "/usr/libexec/ld-elf.so.1"; ++char haikudynld[] = "/system/runtime_loader"; + char openbsddynld[] = "/usr/libexec/ld.so"; + char netbsddynld[] = "/usr/libexec/ld.elf_so"; + char dragonflydynld[] = "/usr/libexec/ld-elf.so.2"; +diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c +index 7c9f718..4ae1422 100644 +--- a/src/cmd/cc/lex.c ++++ b/src/cmd/cc/lex.c +@@ -129,7 +129,7 @@ main(int argc, char *argv[]) + ewidth[TIND] = 4; + + nacl = strcmp(getgoos(), "nacl") == 0; +- if(nacl) ++ if(nacl || strcmp(getgoos(), "haiku") == 0) + flag_largemodel = 1; + + quotefmtinstall(); // before cinit, which overrides %Q +diff --git a/src/cmd/dist/build.c b/src/cmd/dist/build.c +index 8d82167..6319c00 100644 +--- a/src/cmd/dist/build.c ++++ b/src/cmd/dist/build.c +@@ -58,6 +58,7 @@ static char *okgoos[] = { + "android", + "solaris", + "freebsd", ++ "haiku", + "nacl", + "netbsd", + "openbsd", +@@ -1103,8 +1104,14 @@ install(char *dir) + if(!islib && !isgo) { + // C binaries need the libraries explicitly, and -lm. + vcopy(&link, lib.p, lib.len); +- if(!streq(gohostos, "plan9")) ++ if(!streq(gohostos, "plan9") && !streq(gohostos, "haiku")) + vadd(&link, "-lm"); ++ ++ // Haiku needs -lbsd for wait4(). ++ // TODO(bga): Revisit this as it is probably overkill to link against ++ // -lbsd just for wait4(). ++ if(streq(gohostos, "haiku")) ++ vadd(&link, "-lbsd"); + } + + // Remove target before writing it. +diff --git a/src/cmd/dist/unix.c b/src/cmd/dist/unix.c +index 4a78684..93b640e 100644 +--- a/src/cmd/dist/unix.c ++++ b/src/cmd/dist/unix.c +@@ -466,7 +466,11 @@ xworkdir(void) + + xgetenv(&b, "TMPDIR"); + if(b.len == 0) ++#if defined(__HAIKU__) ++ bwritestr(&b, "/tmp"); ++#else + bwritestr(&b, "/var/tmp"); ++#endif + if(b.p[b.len-1] != '/') + bwrite(&b, "/", 1); + bwritestr(&b, "go-cbuild-XXXXXX"); +@@ -695,6 +699,14 @@ main(int argc, char **argv) + gohostarch = "amd64"; + if(contains(bstr(&b), "i386")) + gohostarch = "386"; ++#elif defined(__HAIKU__) ++ gohostos = "haiku"; ++ // Under a Haiku PC, uname -m will always print BePC. ++ run(&b, nil, 0, "uname", "-p", nil); ++ if(contains(bstr(&b), "x86_64")) ++ gohostarch = "amd64"; ++ else if(contains(bstr(&b), "x86")) ++ gohostarch = "386"; + #else + fatal("unknown operating system"); + #endif +diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c +index 523ba37..bb954fc 100644 +--- a/src/cmd/gc/lex.c ++++ b/src/cmd/gc/lex.c +@@ -267,7 +267,7 @@ main(int argc, char *argv[]) + goos = getgoos(); + + nacl = strcmp(goos, "nacl") == 0; +- if(nacl) ++ if(nacl || strcmp(goos, "haiku") == 0) + flag_largemodel = 1; + + setexp(); +diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go +index 1dd4314..d13d0a7 100644 +--- a/src/cmd/go/build.go ++++ b/src/cmd/go/build.go +@@ -2118,6 +2118,10 @@ func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string { + a = append(a, "-fno-common") + } + ++ if goos == "haiku" { ++ a = append(a, "-Wl, -Bsymbolic") ++ } ++ + return a + } + +@@ -2381,6 +2385,8 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfi + switch goos { + case "android", "dragonfly", "linux", "netbsd": + ldflags = append(ldflags, "-Wl,--build-id=none") ++ case "haiku": ++ ldflags = append(ldflags, "-fPIC") + } + + if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil { +diff --git a/src/cmd/go/signal_unix.go b/src/cmd/go/signal_unix.go +index e86cd46..9e2fe0e 100644 +--- a/src/cmd/go/signal_unix.go ++++ b/src/cmd/go/signal_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package main + +diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c +index 6184754..d8168a3 100644 +--- a/src/cmd/ld/data.c ++++ b/src/cmd/ld/data.c +@@ -155,7 +155,7 @@ relocsym(LSym *s) + continue; + + // Solaris needs the ability to reference dynimport symbols. +- if(HEADTYPE != Hsolaris && r->sym != S && r->sym->type == SDYNIMPORT) ++ if(HEADTYPE != Hsolaris && HEADTYPE != Hhaiku && r->sym != S && r->sym->type == SDYNIMPORT) + diag("unhandled relocation for %s (type %d rtype %d)", r->sym->name, r->sym->type, r->type); + if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable) + diag("unreachable sym in relocation: %s %s", s->name, r->sym->name); +@@ -188,7 +188,7 @@ relocsym(LSym *s) + o = r->add; + break; + case R_TLS_LE: +- if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) { ++ if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd && HEADTYPE != Hhaiku) { + r->done = 0; + r->sym = ctxt->tlsg; + r->xsym = ctxt->tlsg; +@@ -202,7 +202,7 @@ relocsym(LSym *s) + break; + + case R_TLS_IE: +- if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) { ++ if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd && HEADTYPE != Hhaiku) { + r->done = 0; + r->sym = ctxt->tlsg; + r->xsym = ctxt->tlsg; +@@ -1088,7 +1088,7 @@ dodata(void) + diag("data or bss segment too large"); + } + +- if(iself && linkmode == LinkExternal && s != nil && s->type == STLSBSS && HEADTYPE != Hopenbsd) { ++ if(iself && linkmode == LinkExternal && s != nil && s->type == STLSBSS && HEADTYPE != Hopenbsd && HEADTYPE != Hhaiku) { + sect = addsection(&segdata, ".tbss", 06); + sect->align = PtrSize; + sect->vaddr = 0; +diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c +index 3196961..e4d1489 100644 +--- a/src/cmd/ld/elf.c ++++ b/src/cmd/ld/elf.c +@@ -911,7 +911,7 @@ doelf(void) + // for dynamic internal linker or external linking, so that various + // binutils could correctly calculate PT_TLS size. + // see http://golang.org/issue/5200. +- if(HEADTYPE != Hopenbsd) ++ if(HEADTYPE != Hopenbsd && HEADTYPE != Hhaiku) + if(!debug['d'] || linkmode == LinkExternal) + addstring(shstrtab, ".tbss"); + if(HEADTYPE == Hnetbsd) +@@ -1198,6 +1198,9 @@ asmbelf(vlong symo) + case Hfreebsd: + interpreter = freebsddynld; + break; ++ case Hhaiku: ++ interpreter = haikudynld; ++ break; + case Hnetbsd: + interpreter = netbsddynld; + break; +@@ -1387,7 +1390,7 @@ asmbelf(vlong symo) + // Do not emit PT_TLS for OpenBSD since ld.so(1) does + // not currently support it. This is handled + // appropriately in runtime/cgo. +- if(ctxt->tlsoffset != 0 && HEADTYPE != Hopenbsd) { ++ if(ctxt->tlsoffset != 0 && HEADTYPE != Hopenbsd && HEADTYPE != Hhaiku) { + ph = newElfPhdr(); + ph->type = PT_TLS; + ph->flags = PF_R; +@@ -1444,7 +1447,7 @@ elfobj: + + // generate .tbss section for dynamic internal linking (except for OpenBSD) + // external linking generates .tbss in data.c +- if(linkmode == LinkInternal && !debug['d'] && HEADTYPE != Hopenbsd) { ++ if(linkmode == LinkInternal && !debug['d'] && HEADTYPE != Hopenbsd && HEADTYPE != Hhaiku) { + sh = elfshname(".tbss"); + sh->type = SHT_NOBITS; + sh->addralign = RegSize; +@@ -1484,6 +1487,8 @@ elfobj: + eh->ident[EI_OSABI] = ELFOSABI_OPENBSD; + else if(HEADTYPE == Hdragonfly) + eh->ident[EI_OSABI] = ELFOSABI_NONE; ++ else if(HEADTYPE == Hhaiku) ++ eh->ident[EI_OSABI] = ELFOSABI_NONE; + if(elf64) + eh->ident[EI_CLASS] = ELFCLASS64; + else +diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h +index e84d996..3796967 100644 +--- a/src/cmd/ld/elf.h ++++ b/src/cmd/ld/elf.h +@@ -1007,6 +1007,7 @@ void asmbelf(vlong symo); + void asmbelfsetup(void); + extern char linuxdynld[]; + extern char freebsddynld[]; ++extern char haikudynld[]; + extern char netbsddynld[]; + extern char openbsddynld[]; + extern char dragonflydynld[]; +diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c +index f889aba..6e68e6d 100644 +--- a/src/cmd/ld/lib.c ++++ b/src/cmd/ld/lib.c +@@ -208,7 +208,9 @@ loadlib(void) + // The startup code uses an import of runtime/cgo to decide + // whether to initialize the TLS. So give it one. This could + // be handled differently but it's an unusual case. +- loadinternal("runtime/cgo"); ++ if(HEADTYPE != Hhaiku) ++ loadinternal("runtime/cgo"); ++ + if(i < ctxt->libraryp) + objfile(ctxt->library[i].file, ctxt->library[i].pkg); + +@@ -290,7 +292,7 @@ loadlib(void) + // binaries, so leave it enabled on OS X (Mach-O) binaries. + // Also leave it enabled on Solaris which doesn't support + // statically linked binaries. +- if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris) ++ if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris && HEADTYPE != Hhaiku) + debug['d'] = 1; + + importcycles(); +@@ -609,6 +611,9 @@ hostlink(void) + argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000"; + if(HEADTYPE == Hopenbsd) + argv[argc++] = "-Wl,-nopie"; ++ ++ if(HEADTYPE == Hhaiku) ++ argv[argc++] = "-fPIC"; + + if(iself && AssumeGoldLinker) + argv[argc++] = "-Wl,--rosegment"; +@@ -622,10 +627,13 @@ hostlink(void) + + if(rpath) + argv[argc++] = smprint("-Wl,-rpath,%s", rpath); ++ ++ if(iself && HEADTYPE != Hhaiku) ++ argv[argc++] = "-rdynamic"; + + // Force global symbols to be exported for dlopen, etc. + if(iself) +- argv[argc++] = "-rdynamic"; ++ // argv[argc++] = "-rdynamic"; + + if(strstr(argv[0], "clang") != nil) + argv[argc++] = "-Qunused-arguments"; +diff --git a/src/cmd/ld/pobj.c b/src/cmd/ld/pobj.c +index 63460df..4e8152e 100644 +--- a/src/cmd/ld/pobj.c ++++ b/src/cmd/ld/pobj.c +@@ -150,6 +150,8 @@ main(int argc, char *argv[]) + ctxt->headtype = HEADTYPE; + if(headstring == nil) + headstring = headstr(HEADTYPE); ++ if(HEADTYPE == Hhaiku) ++ linkmode = LinkExternal; + + archinit(); + ctxt->debugfloat = debug['F']; +diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c +index 156270c..53e9160 100644 +--- a/src/cmd/ld/symtab.c ++++ b/src/cmd/ld/symtab.c +@@ -197,7 +197,7 @@ asmelfsym(void) + elfbind = STB_LOCAL; + genasmsym(putelfsym); + +- if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) { ++ if(linkmode == LinkExternal && HEADTYPE != Hopenbsd && HEADTYPE != Hhaiku) { + s = linklookup(ctxt, "runtime.tlsg", 0); + if(s->sect == nil) { + ctxt->cursym = nil; +-- +2.19.0 + + +From 1aa9823a966a0e04513fe2293d55046e516a7d4a Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:55:40 +0100 +Subject: lib9/liblink: Add Haiku to the syslist and build lib9 and liblink. + + +diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go +index b74595e..61641e4 100644 +--- a/src/go/build/deps_test.go ++++ b/src/go/build/deps_test.go +@@ -361,7 +361,7 @@ func allowed(pkg string) map[string]bool { + } + + var bools = []bool{false, true} +-var geese = []string{"android", "darwin", "dragonfly", "freebsd", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows"} ++var geese = []string{"android", "darwin", "dragonfly", "freebsd", "haiku", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows"} + var goarches = []string{"386", "amd64", "arm"} + + type osPkg struct { +diff --git a/src/go/build/syslist.go b/src/go/build/syslist.go +index 965f873..4d5906f 100644 +--- a/src/go/build/syslist.go ++++ b/src/go/build/syslist.go +@@ -4,5 +4,5 @@ + + package build + +-const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows " ++const goosList = "android darwin dragonfly haiku freebsd linux nacl netbsd openbsd plan9 solaris windows " + const goarchList = "386 amd64 amd64p32 arm " +diff --git a/src/lib9/run_unix.c b/src/lib9/run_unix.c +index 1acaefe..6c32872 100644 +--- a/src/lib9/run_unix.c ++++ b/src/lib9/run_unix.c +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + #include + #include +diff --git a/src/lib9/tempdir_unix.c b/src/lib9/tempdir_unix.c +index 269d538..8fda14e 100644 +--- a/src/lib9/tempdir_unix.c ++++ b/src/lib9/tempdir_unix.c +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + #include + #include +@@ -17,7 +17,11 @@ mktempdir(void) + + tmp = getenv("TMPDIR"); + if(tmp == nil || strlen(tmp) == 0) +- tmp = "/var/tmp"; ++#ifdef __HAIKU__ ++ tmp = "/boot/system/cache/tmp"; ++#else ++ tmp = "/var/tmp"; ++#endif + p = smprint("%s/go-link-XXXXXX", tmp); + if(mkdtemp(p) == nil) + return nil; +diff --git a/src/liblink/asm6.c b/src/liblink/asm6.c +index 428eb94..44c0ec1 100644 +--- a/src/liblink/asm6.c ++++ b/src/liblink/asm6.c +@@ -1545,7 +1545,12 @@ isextern(LSym *s) + { + // All the Solaris dynamic imports from libc.so begin with "libc·", which + // the compiler rewrites to "libc." by the time liblink gets it. ++ // Haiku also uses this for dynamic imports but from libroot instead. ++#if defined(__HAIKU__) ++ return strncmp(s->name, "libroot.", 9) == 0; ++#else + return strncmp(s->name, "libc.", 5) == 0; ++#endif + } + + // single-instruction no-ops of various lengths. +@@ -3415,6 +3420,19 @@ mfound: + *ctxt->andptr++ = 0x8B; + asmand(ctxt, &pp.from, &p->to); + break; ++ ++ case Hhaiku: ++ // Haiku TLS base is 0(FS). ++ pp.from = p->from; ++ pp.from.type = D_INDIR+D_GS; ++ pp.from.offset = 0; ++ pp.from.index = D_NONE; ++ pp.from.scale = 0; ++ ctxt->rexflag |= Pw; ++ *ctxt->andptr++ = 0x64; // FS ++ *ctxt->andptr++ = 0x8B; ++ asmand(ctxt, &pp.from, &p->to); ++ break; + } + break; + } +diff --git a/src/liblink/obj6.c b/src/liblink/obj6.c +index 2acfd2f..2d699b7 100644 +--- a/src/liblink/obj6.c ++++ b/src/liblink/obj6.c +@@ -103,6 +103,7 @@ static int + canuselocaltls(Link *ctxt) + { + switch(ctxt->headtype) { ++ case Hhaiku: + case Hplan9: + case Hwindows: + return 0; +diff --git a/src/liblink/sym.c b/src/liblink/sym.c +index bd85518..6e9aead 100644 +--- a/src/liblink/sym.c ++++ b/src/liblink/sym.c +@@ -48,6 +48,7 @@ static struct { + {"darwin", Hdarwin}, + {"dragonfly", Hdragonfly}, + {"elf", Helf}, ++ {"haiku", Hhaiku}, + {"freebsd", Hfreebsd}, + {"linux", Hlinux}, + {"nacl", Hnacl}, +@@ -130,6 +131,13 @@ linknew(LinkArch *arch) + case Hplan9: + case Hwindows: + break; ++ case Hhaiku: ++ /* FIXME */ ++ // // on 64-bit we use the last two regular TLS slots ++ if(ctxt->arch->thechar == '6') { ++ ctxt->tlsoffset = (64 - 2) * 8; ++ } ++ break; + case Hlinux: + case Hfreebsd: + case Hnetbsd: +-- +2.19.0 + + +From 91c5e8374435ecf60f410d90688acaff69b29e93 Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:56:26 +0100 +Subject: runtime: Add early Haiku x86_64 support. Derived mostly from Solaris + port. + + +diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s +index 39d7c78..7e25985 100644 +--- a/src/runtime/asm_amd64.s ++++ b/src/runtime/asm_amd64.s +@@ -60,6 +60,9 @@ needtls: + // skip TLS setup on Solaris + CMPL runtime·issolaris(SB), $1 + JEQ ok ++ // skip TLS setup on Haiku ++ CMPL runtime·ishaiku(SB), $1 ++ JEQ ok + + LEAQ runtime·tls0(SB), DI + CALL runtime·settls(SB) +diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go +index 7fd9146..5e58db5 100644 +--- a/src/runtime/cgocall.go ++++ b/src/runtime/cgocall.go +@@ -89,7 +89,7 @@ func cgocall(fn, arg unsafe.Pointer) { + + //go:nosplit + func cgocall_errno(fn, arg unsafe.Pointer) int32 { +- if !iscgo && GOOS != "solaris" && GOOS != "windows" { ++ if !iscgo && GOOS != "solaris" && GOOS != "windows" && GOOS != "haiku" { + gothrow("cgocall unavailable") + } + +diff --git a/src/runtime/defs_haiku.go b/src/runtime/defs_haiku.go +new file mode 100644 +index 0000000..d0ea4fe +--- /dev/null ++++ b/src/runtime/defs_haiku.go +@@ -0,0 +1,160 @@ ++// 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. ++ ++// +build ignore ++ ++/* ++Input to cgo. ++ ++GOARCH=amd64 go tool cgo -cdefs defs_haiku.go >defs_haiku_amd64.h ++GOARCH=386 go tool cgo -cdefs defs_haiku.go >defs_haiku_386.h ++GOARCH=arm go tool cgo -cdefs defs_haiku.go >defs_haiku_arm.h ++*/ ++ ++package runtime ++ ++/* ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#ifdef __x86_64__ ++struct extended_regs { ++ // not used anywhere; just to make this file compile (stub of struct used in the 386 version) ++}; ++#else ++struct xmm_regs { ++ // not used anywhere, just to make this compile (stub of struct used in x86_64) ++} ++struct fpu_state { ++ // ditto ++} ++#endif ++*/ ++import "C" ++ ++const ( ++ EINTR = C.EINTR ++ EFAULT = C.EFAULT ++ EAGAIN = C.EAGAIN ++ ENOMEM = C.ENOMEM ++ ETIMEDOUT = C.ETIMEDOUT ++ EACCES = C.EACCES ++ ++ PROT_NONE = C.PROT_NONE ++ PROT_READ = C.PROT_READ ++ PROT_WRITE = C.PROT_WRITE ++ PROT_EXEC = C.PROT_EXEC ++ ++ MAP_ANON = C.MAP_ANON ++ MAP_PRIVATE = C.MAP_PRIVATE ++ MAP_FIXED = C.MAP_FIXED ++ ++ SA_SIGINFO = C.SA_SIGINFO ++ SA_RESTART = C.SA_RESTART ++ SA_ONSTACK = C.SA_ONSTACK ++ ++ SIGHUP = C.SIGHUP ++ SIGINT = C.SIGINT ++ SIGQUIT = C.SIGQUIT ++ SIGILL = C.SIGILL ++ SIGTRAP = C.SIGTRAP ++ SIGABRT = C.SIGABRT ++ SIGFPE = C.SIGFPE ++ SIGKILL = C.SIGKILL ++ SIGBUS = C.SIGBUS ++ SIGSEGV = C.SIGSEGV ++ SIGSYS = C.SIGSYS ++ SIGPIPE = C.SIGPIPE ++ SIGALRM = C.SIGALRM ++ SIGTERM = C.SIGTERM ++ SIGURG = C.SIGURG ++ SIGSTOP = C.SIGSTOP ++ SIGTSTP = C.SIGTSTP ++ SIGCONT = C.SIGCONT ++ SIGCHLD = C.SIGCHLD ++ SIGTTIN = C.SIGTTIN ++ SIGTTOU = C.SIGTTOU ++ SIGXCPU = C.SIGXCPU ++ SIGXFSZ = C.SIGXFSZ ++ SIGVTALRM = C.SIGVTALRM ++ SIGPROF = C.SIGPROF ++ SIGWINCH = C.SIGWINCH ++ SIGUSR1 = C.SIGUSR1 ++ SIGUSR2 = C.SIGUSR2 ++ ++ FPE_INTDIV = C.FPE_INTDIV ++ FPE_INTOVF = C.FPE_INTOVF ++ FPE_FLTDIV = C.FPE_FLTDIV ++ FPE_FLTOVF = C.FPE_FLTOVF ++ FPE_FLTUND = C.FPE_FLTUND ++ FPE_FLTRES = C.FPE_FLTRES ++ FPE_FLTINV = C.FPE_FLTINV ++ FPE_FLTSUB = C.FPE_FLTSUB ++ ++ BUS_ADRALN = C.BUS_ADRALN ++ BUS_ADRERR = C.BUS_ADRERR ++ BUS_OBJERR = C.BUS_OBJERR ++ ++ SEGV_MAPERR = C.SEGV_MAPERR ++ SEGV_ACCERR = C.SEGV_ACCERR ++ ++ ITIMER_REAL = C.ITIMER_REAL ++ ITIMER_VIRTUAL = C.ITIMER_VIRTUAL ++ ITIMER_PROF = C.ITIMER_PROF ++ ++ PTHREAD_CREATE_DETACHED = C.PTHREAD_CREATE_DETACHED ++ ++ HOST_NAME_MAX = C.HOST_NAME_MAX ++ ++ O_NONBLOCK = C.O_NONBLOCK ++ FD_CLOEXEC = C.FD_CLOEXEC ++ F_GETFL = C.F_GETFL ++ F_SETFL = C.F_SETFL ++ F_SETFD = C.F_SETFD ++ ++ _SC_NPROCESSORS_ONLN = C._SC_NPROCESSORS_ONLN ++ ++ _MAXHOSTNAMELEN = C.MAXHOSTNAMELEN ++ ++ B_PAGE_SIZE = C.B_PAGE_SIZE ++ ++ B_ERROR = C.B_ERROR ++) ++ ++type SemT C.sem_t ++ ++type Sigset C.sigset_t ++type StackT C.stack_t ++type SigaltstackT StackT ++ ++type Siginfo C.siginfo_t ++type Sigaction C.struct_sigaction ++ ++// needed by Mcontext ++// for 386 ++type ExtendedRegs C.struct_extended_regs ++ ++// for amd64 ++type XmmRegs C.struct_xmm_regs ++type FpuState C.struct_fpu_state ++ ++type Mcontext C.mcontext_t ++type Ucontext C.ucontext_t ++ ++type Timespec C.struct_timespec ++type Timeval C.struct_timeval ++type Itimerval C.struct_itimerval ++ ++type Pthread C.pthread_t ++type PthreadAttr C.pthread_attr_t ++ ++// depends on Timespec, must appear below ++type Stat C.struct_stat +diff --git a/src/runtime/defs_haiku_amd64.h b/src/runtime/defs_haiku_amd64.h +new file mode 100644 +index 0000000..fd4f2bf +--- /dev/null ++++ b/src/runtime/defs_haiku_amd64.h +@@ -0,0 +1,244 @@ ++// Created by cgo -cdefs - DO NOT EDIT ++// cgo -cdefs defs_haiku.go ++ ++ ++enum { ++ EINTR = -0x7ffffff6, ++ EFAULT = -0x7fffecff, ++ EAGAIN = -0x7ffffff5, ++ ENOMEM = -0x80000000, ++ ETIMEDOUT = -0x7ffffff7, ++ EACCES = -0x7ffffffe, ++ ++ PROT_NONE = 0x0, ++ PROT_READ = 0x1, ++ PROT_WRITE = 0x2, ++ PROT_EXEC = 0x4, ++ ++ MAP_ANON = 0x8, ++ MAP_PRIVATE = 0x2, ++ MAP_FIXED = 0x4, ++ ++ SA_SIGINFO = 0x40, ++ SA_RESTART = 0x10, ++ SA_ONSTACK = 0x20, ++ ++ SIGHUP = 0x1, ++ SIGINT = 0x2, ++ SIGQUIT = 0x3, ++ SIGILL = 0x4, ++ SIGTRAP = 0x16, ++ SIGABRT = 0x6, ++ SIGFPE = 0x8, ++ SIGKILL = 0x9, ++ SIGBUS = 0x1e, ++ SIGSEGV = 0xb, ++ SIGSYS = 0x19, ++ SIGPIPE = 0x7, ++ SIGALRM = 0xe, ++ SIGTERM = 0xf, ++ SIGURG = 0x1a, ++ SIGSTOP = 0xa, ++ SIGTSTP = 0xd, ++ SIGCONT = 0xc, ++ SIGCHLD = 0x5, ++ SIGTTIN = 0x10, ++ SIGTTOU = 0x11, ++ SIGXCPU = 0x1c, ++ SIGXFSZ = 0x1d, ++ SIGVTALRM = 0x1b, ++ SIGPROF = 0x18, ++ SIGWINCH = 0x14, ++ SIGUSR1 = 0x12, ++ SIGUSR2 = 0x13, ++ ++ FPE_INTDIV = 0x14, ++ FPE_INTOVF = 0x15, ++ FPE_FLTDIV = 0x16, ++ FPE_FLTOVF = 0x17, ++ FPE_FLTUND = 0x18, ++ FPE_FLTRES = 0x19, ++ FPE_FLTINV = 0x1a, ++ FPE_FLTSUB = 0x1b, ++ ++ BUS_ADRALN = 0x28, ++ BUS_ADRERR = 0x29, ++ BUS_OBJERR = 0x2a, ++ ++ SEGV_MAPERR = 0x1e, ++ SEGV_ACCERR = 0x1f, ++ ++ ITIMER_REAL = 0x1, ++ ITIMER_VIRTUAL = 0x2, ++ ITIMER_PROF = 0x3, ++ ++ PTHREAD_CREATE_DETACHED = 0x1, ++ ++ HOST_NAME_MAX = 0xff, ++ ++ O_NONBLOCK = 0x80, ++ FD_CLOEXEC = 0x1, ++ F_GETFL = 0x8, ++ F_SETFL = 0x10, ++ F_SETFD = 0x4, ++ ++ _SC_NPROCESSORS_ONLN = 0x23, ++ ++ _MAXHOSTNAMELEN = 0x100, ++ ++ B_PAGE_SIZE = 0x1000, ++ ++ B_ERROR = -0x1, ++}; ++ ++typedef struct SemT SemT; ++typedef struct StackT StackT; ++typedef struct Siginfo Siginfo; ++typedef struct SigactionT SigactionT; ++typedef struct ExtendedRegs ExtendedRegs; ++typedef struct XmmRegs XmmRegs; ++typedef struct FpuState FpuState; ++typedef struct Mcontext Mcontext; ++typedef struct Ucontext Ucontext; ++typedef struct Timespec Timespec; ++typedef struct Timeval Timeval; ++typedef struct Itimerval Itimerval; ++typedef struct Stat Stat; ++ ++#pragma pack on ++ ++struct SemT { ++ int32 id; ++ int32 _padding[3]; ++}; ++ ++typedef uint64 Sigset; ++struct StackT { ++ byte *ss_sp; ++ uint64 ss_size; ++ int32 ss_flags; ++ byte Pad_cgo_0[4]; ++}; ++typedef StackT SigaltstackT; ++ ++struct Siginfo { ++ int32 si_signo; ++ int32 si_code; ++ int32 si_errno; ++ int32 si_pid; ++ uint32 si_uid; ++ byte Pad_cgo_0[4]; ++ byte *si_addr; ++ int32 si_status; ++ byte Pad_cgo_1[4]; ++ int64 si_band; ++ byte si_value[8]; ++}; ++struct SigactionT { ++ byte anon0[8]; ++ uint64 sa_mask; ++ int32 sa_flags; ++ byte Pad_cgo_0[4]; ++ byte *sa_userdata; ++}; ++ ++ ++struct XmmRegs { ++ uint8 xmm0[16]; ++ uint8 xmm1[16]; ++ uint8 xmm2[16]; ++ uint8 xmm3[16]; ++ uint8 xmm4[16]; ++ uint8 xmm5[16]; ++ uint8 xmm6[16]; ++ uint8 xmm7[16]; ++ uint8 xmm8[16]; ++ uint8 xmm9[16]; ++ uint8 xmm10[16]; ++ uint8 xmm11[16]; ++ uint8 xmm12[16]; ++ uint8 xmm13[16]; ++ uint8 xmm14[16]; ++ uint8 xmm15[16]; ++}; ++struct FpuState { ++ uint16 control; ++ uint16 status; ++ uint16 tag; ++ uint16 opcode; ++ uint64 rip; ++ uint64 rdp; ++ uint32 mxcsr; ++ uint32 mscsr_mask; ++ byte anon0[128]; ++ XmmRegs xmm; ++ uint8 _reserved_416_511[96]; ++}; ++ ++struct Mcontext { ++ uint64 rax; ++ uint64 rbx; ++ uint64 rcx; ++ uint64 rdx; ++ uint64 rdi; ++ uint64 rsi; ++ uint64 rbp; ++ uint64 r8; ++ uint64 r9; ++ uint64 r10; ++ uint64 r11; ++ uint64 r12; ++ uint64 r13; ++ uint64 r14; ++ uint64 r15; ++ uint64 rsp; ++ uint64 rip; ++ uint64 rflags; ++ FpuState fpu; ++}; ++struct Ucontext { ++ Ucontext *uc_link; ++ uint64 uc_sigmask; ++ StackT uc_stack; ++ Mcontext uc_mcontext; ++}; ++ ++struct Timespec { ++ int32 tv_sec; ++ byte Pad_cgo_0[4]; ++ int64 tv_nsec; ++}; ++struct Timeval { ++ int32 tv_sec; ++ int32 tv_usec; ++}; ++struct Itimerval { ++ Timeval it_interval; ++ Timeval it_value; ++}; ++ ++typedef void *Pthread; ++typedef void *PthreadAttr; ++ ++struct Stat { ++ int32 st_dev; ++ byte Pad_cgo_0[4]; ++ int64 st_ino; ++ uint32 st_mode; ++ int32 st_nlink; ++ uint32 st_uid; ++ uint32 st_gid; ++ int64 st_size; ++ int32 st_rdev; ++ int32 st_blksize; ++ Timespec st_atim; ++ Timespec st_mtim; ++ Timespec st_ctim; ++ Timespec st_crtim; ++ uint32 st_type; ++ byte Pad_cgo_1[4]; ++ int64 st_blocks; ++}; ++ ++ ++#pragma pack off +diff --git a/src/runtime/env_posix.go b/src/runtime/env_posix.go +index dd57872..ef9c294 100644 +--- a/src/runtime/env_posix.go ++++ b/src/runtime/env_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package runtime + +diff --git a/src/runtime/lock_sema.go b/src/runtime/lock_sema.go +index d136b82..0604f13 100644 +--- a/src/runtime/lock_sema.go ++++ b/src/runtime/lock_sema.go +@@ -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 darwin nacl netbsd openbsd plan9 solaris windows ++// +build darwin haiku nacl netbsd openbsd plan9 solaris windows + + package runtime + +@@ -200,7 +200,9 @@ func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool { + for { + // Registered. Sleep. + gp.m.blocked = true +- if semasleep(ns) >= 0 { ++ // HACK for Haiku support. ++ if semasleep(deadline) >= 0 { ++ //if semasleep(ns) >= 0 { + gp.m.blocked = false + // Acquired semaphore, semawakeup unregistered us. + // Done. +diff --git a/src/runtime/mem_haiku.c b/src/runtime/mem_haiku.c +new file mode 100644 +index 0000000..0d59b5d +--- /dev/null ++++ b/src/runtime/mem_haiku.c +@@ -0,0 +1,160 @@ ++// Copyright 2010 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 "runtime.h" ++#include "arch_GOARCH.h" ++#include "defs_GOOS_GOARCH.h" ++#include "os_GOOS.h" ++#include "malloc.h" ++#include "textflag.h" ++ ++uintptr runtime·area_for(void* addr); ++ ++static int32 ++addrspace_free(void *v, uintptr n) ++{ ++ uintptr errval; ++ uintptr chunk; ++ uintptr off; ++ ++ for(off = 0; off < n; off += chunk) { ++ chunk = B_PAGE_SIZE; ++ if(chunk > (n - off)) ++ chunk = n - off; ++ errval = runtime·area_for((void*)((uintptr) v + off)); ++ // B_ERROR means unmapped, which is what we want. ++ // Anything else we assume means the pages are mapped. ++ if (errval != B_ERROR) ++ return 0; ++ } ++ return 1; ++} ++ ++static void * ++mmap_fixed(byte *v, uintptr n, int32 prot, int32 flags, int32 fd, uint32 offset) ++{ ++ void *p; ++ ++ p = runtime·mmap(v, n, prot, flags, fd, offset); ++ if(p != v && addrspace_free(v, n)) { ++ // On some systems, mmap ignores v without ++ // MAP_FIXED, so retry if the address space is free. ++ if(p > (void*)4096) ++ runtime·munmap(p, n); ++ p = runtime·mmap(v, n, prot, flags|MAP_FIXED, fd, offset); ++ } ++ return p; ++} ++ ++#pragma textflag NOSPLIT ++void* ++runtime·sysAlloc(uintptr n, uint64 *stat) ++{ ++ void *p; ++ ++ p = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); ++ if(p < (void*)4096) { ++ if(p == (void*)EACCES) { ++ runtime·printf("runtime: mmap: access denied\n"); ++ runtime·printf("if you're running SELinux, enable execmem for this process.\n"); ++ runtime·exit(2); ++ } ++ if(p == (void*)EAGAIN) { ++ runtime·printf("runtime: mmap: too much locked memory (check 'ulimit -l').\n"); ++ runtime·exit(2); ++ } ++ return nil; ++ } ++ runtime·xadd64(stat, n); ++ return p; ++} ++ ++void ++runtime·SysUnused(void *v, uintptr n) ++{ ++ /*runtime·madvise(v, n, MADV_DONTNEED);*/ ++} ++ ++void ++runtime·SysUsed(void *v, uintptr n) ++{ ++ USED(v); ++ USED(n); ++} ++ ++void ++runtime·SysFree(void *v, uintptr n, uint64 *stat) ++{ ++ runtime·xadd64(stat, -(uint64)n); ++ runtime·munmap(v, n); ++} ++ ++void ++runtime·SysFault(void *v, uintptr n) ++{ ++ runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0); ++} ++ ++int32 runtime·kern_reserve_address_range(void* v, int32 address_spec, uintptr n); ++ ++void* ++runtime·SysReserve(void *v, uintptr n, bool *reserved) ++{ ++ void *p; ++ ++ // On 64-bit, people with ulimit -v set complain if we reserve too ++ // much address space. Instead, assume that the reservation is okay ++ // if we can reserve at least 64K and check the assumption in SysMap. ++ // Only user-mode Linux (UML) rejects these requests. ++ if(sizeof(void*) == 8 && n > 1LL<<32) { ++ p = mmap_fixed(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); ++ if (p != v) { ++ if(p >= (void*)4096) ++ runtime·munmap(p, 64<<10); ++ return nil; ++ } ++ runtime·munmap(p, 64<<10); ++ *reserved = false; ++ return v; ++ } ++ ++ //int32 status = runtime·kern_reserve_address_range(&p, 0x7 /* B_RANDOMIZED_BASE_ADDRESS */, 64<<10); ++ *reserved = false; ++ p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); ++ //that doesn't work: PROT_NONE still reserves physical memory ++ //so immediately unmap it and mark it as unreserved ++ if((uintptr)p < 4096) ++ return nil; ++ //if (status) { ++ // return nil; ++ //} ++ runtime·munmap(p, n); ++ return p; ++} ++ ++void ++runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat) ++{ ++ void *p; ++ ++ runtime·xadd64(stat, n); ++ ++ // On 64-bit, we don't actually have v reserved, so tread carefully. ++ if(!reserved) { ++ p = mmap_fixed(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); ++ if(p == (void*)ENOMEM) ++ runtime·throw("runtime: out of memory"); ++ if(p != v) { ++ runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p); ++ runtime·throw("runtime: address space conflict"); ++ } ++ return; ++ } ++ ++ p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0); ++ if(p == (void*)ENOMEM) ++ runtime·throw("runtime: out of memory"); ++ if(p != v) ++ runtime·throw("runtime: cannot map pages in arena address space"); ++} +diff --git a/src/runtime/mheap.c b/src/runtime/mheap.c +index bb203d5..67de821 100644 +--- a/src/runtime/mheap.c ++++ b/src/runtime/mheap.c +@@ -608,6 +608,8 @@ scavengelist(MSpan *list, uint64 now, uint64 limit) + void + runtime·MHeap_Scavenge(int32 k, uint64 now, uint64 limit) + { ++ //HACK: Disable GC for Haiku ++ /* + uint32 i; + uintptr sumreleased; + MHeap *h; +@@ -629,6 +631,7 @@ runtime·MHeap_Scavenge(int32 k, uint64 now, uint64 limit) + k, mstats.heap_inuse>>20, mstats.heap_idle>>20, mstats.heap_sys>>20, + mstats.heap_released>>20, (mstats.heap_sys - mstats.heap_released)>>20); + } ++ */ + } + + void +diff --git a/src/runtime/netpoll.go b/src/runtime/netpoll.go +index 3456e02..1b69e8a 100644 +--- a/src/runtime/netpoll.go ++++ b/src/runtime/netpoll.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package runtime + +diff --git a/src/runtime/netpoll_haiku.go b/src/runtime/netpoll_haiku.go +new file mode 100644 +index 0000000..e003d8e +--- /dev/null ++++ b/src/runtime/netpoll_haiku.go +@@ -0,0 +1,23 @@ ++// Copyright 2013 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 runtime ++ ++func netpollinit() { ++} ++ ++func netpollopen(fd uintptr, pd *pollDesc) int32 { ++ return 0 ++} ++ ++func netpollclose(fd uintptr) int32 { ++ return 0 ++} ++ ++func netpollarm(pd *pollDesc, mode int) { ++} ++ ++func netpoll(block bool) *g { ++ return nil ++} +diff --git a/src/runtime/os_haiku.c b/src/runtime/os_haiku.c +new file mode 100644 +index 0000000..3180fa5 +--- /dev/null ++++ b/src/runtime/os_haiku.c +@@ -0,0 +1,595 @@ ++// Copyright 2011 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 "runtime.h" ++#include "defs_GOOS_GOARCH.h" ++#include "os_GOOS.h" ++#include "signal_unix.h" ++#include "stack.h" ++#include "textflag.h" ++ ++// dynimport is broken in 386: one needs the address instead of the value ++// contained in each imported variable ++#ifdef GOARCH_386 ++#define FUNC(a) ((uintptr) &a) ++#else ++#define FUNC(a) (a) ++#endif ++ ++#pragma dynexport runtime·end _end ++#pragma dynexport runtime·etext _etext ++#pragma dynexport runtime·edata _edata ++ ++#pragma dynimport libc·_errnop _errnop "libroot.so" ++#pragma dynimport libc·clock_gettime clock_gettime "libroot.so" ++#pragma dynimport libc·close close "libroot.so" ++#pragma dynimport libc·exit exit "libroot.so" ++#pragma dynimport libc·fstat fstat "libroot.so" ++#pragma dynimport libc·getcontext getcontext "libroot.so" ++#pragma dynimport libc·getrlimit getrlimit "libroot.so" ++#pragma dynimport libc·malloc malloc "libroot.so" ++#pragma dynimport libc·mmap mmap "libroot.so" ++#pragma dynimport libc·munmap munmap "libroot.so" ++#pragma dynimport libc·open open "libroot.so" ++#pragma dynimport libc·pthread_attr_destroy pthread_attr_destroy "libroot.so" ++#pragma dynimport libc·pthread_attr_getstacksize pthread_attr_getstacksize "libroot.so" ++#pragma dynimport libc·pthread_attr_init pthread_attr_init "libroot.so" ++#pragma dynimport libc·pthread_attr_setdetachstate pthread_attr_setdetachstate "libroot.so" ++#pragma dynimport libc·pthread_attr_setstack pthread_attr_setstack "libroot.so" ++#pragma dynimport libc·pthread_create pthread_create "libroot.so" ++#pragma dynimport libc·raise raise "libroot.so" ++#pragma dynimport libc·read read "libroot.so" ++#pragma dynimport libc·select select "libroot.so" ++#pragma dynimport libc·sched_yield sched_yield "libroot.so" ++#pragma dynimport libc·sem_init sem_init "libroot.so" ++#pragma dynimport libc·sem_post sem_post "libroot.so" ++#pragma dynimport libc·sem_timedwait sem_timedwait "libroot.so" ++#pragma dynimport libc·sem_wait sem_wait "libroot.so" ++#pragma dynimport libc·setitimer setitimer "libroot.so" ++#pragma dynimport libc·sigaction sigaction "libroot.so" ++#pragma dynimport libc·sigaltstack sigaltstack "libroot.so" ++#pragma dynimport libc·sigprocmask sigprocmask "libroot.so" ++#pragma dynimport libc·sysconf sysconf "libroot.so" ++#pragma dynimport libc·usleep usleep "libroot.so" ++#pragma dynimport libc·write write "libroot.so" ++#pragma dynimport libc·area_for area_for "libroot.so" ++ ++extern uintptr libc·_errnop; ++extern uintptr libc·clock_gettime; ++extern uintptr libc·close; ++extern uintptr libc·exit; ++extern uintptr libc·fstat; ++extern uintptr libc·getcontext; ++extern uintptr libc·getrlimit; ++extern uintptr libc·malloc; ++extern uintptr libc·mmap; ++extern uintptr libc·munmap; ++extern uintptr libc·open; ++extern uintptr libc·pthread_attr_destroy; ++extern uintptr libc·pthread_attr_getstacksize; ++extern uintptr libc·pthread_attr_init; ++extern uintptr libc·pthread_attr_setdetachstate; ++extern uintptr libc·pthread_attr_setstack; ++extern uintptr libc·pthread_create; ++extern uintptr libc·raise; ++extern uintptr libc·read; ++extern uintptr libc·sched_yield; ++extern uintptr libc·select; ++extern uintptr libc·sem_init; ++extern uintptr libc·sem_post; ++extern uintptr libc·sem_timedwait; ++extern uintptr libc·sem_wait; ++extern uintptr libc·setitimer; ++extern uintptr libc·sigaction; ++extern uintptr libc·sigaltstack; ++extern uintptr libc·sigprocmask; ++extern uintptr libc·sysconf; ++extern uintptr libc·usleep; ++extern uintptr libc·write; ++extern uintptr libc·area_for; ++ ++void runtime·getcontext(Ucontext *context); ++int32 runtime·pthread_attr_destroy(PthreadAttr* attr); ++int32 runtime·pthread_attr_init(PthreadAttr* attr); ++//TODO: uint32/uint64 problem needs to be solved ++int32 runtime·pthread_attr_getstacksize(PthreadAttr* attr, uintptr* size); ++int32 runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state); ++int32 runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint32 size); ++int32 runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg); ++uint32 runtime·tstart_sysvicall(M *newm); ++int32 runtime·sem_init(SemT* sem, int32 pshared, uint32 value); ++int32 runtime·sem_post(SemT* sem); ++//int32 runtime·sem_reltimedwait(SemT* sem, Timespec* timeout); ++int32 runtime·sem_wait(SemT* sem); ++int64 runtime·sysconf(int32 name); ++ ++extern SigTab runtime·sigtab[]; ++static Sigset sigset_none = 0; ++static Sigset sigset_all = 0; ++ ++static int32 ++getncpu(void) ++{ ++ int32 n; ++ ++ n = (int32)runtime·sysconf(_SC_NPROCESSORS_ONLN); ++ if(n < 1) ++ return 1; ++ return n; ++} ++ ++void ++runtime·osinit(void) ++{ ++ runtime·ncpu = getncpu(); ++} ++ ++void ++runtime·newosproc(M *mp, void *stk) ++{ ++ PthreadAttr attr; ++ Sigset oset; ++ Pthread tid; ++ int32 ret; ++ uint64 size; ++ ++ USED(stk); ++ if(runtime·pthread_attr_init(&attr) != 0) ++ runtime·throw("pthread_attr_init"); ++ //if(runtime·pthread_attr_setstack(&attr, 0, 0x200000) != 0) ++ // runtime·throw("pthread_attr_setstack"); ++ //if(runtime·pthread_attr_getstack(&attr, (void**)&mp->g0->stackbase, &mp->g0->stacksize) != 0) ++ // runtime·throw("pthread_attr_getstack"); ++ ++ if(runtime·pthread_attr_getstacksize(&attr, &mp->g0->stack.hi) != 0) ++ runtime·throw("pthread_attr_getstacksize"); ++ if(runtime·pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0) ++ runtime·throw("pthread_attr_setdetachstate"); ++ ++ // Disable signals during create, so that the new thread starts ++ // with signals disabled. It will enable them in minit. ++ runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset); ++ mp->g0->stack.hi = 0xdeadf00d; ++ ret = runtime·pthread_create(&tid, &attr, (void (*)(void))runtime·tstart_sysvicall, mp); ++ runtime·sigprocmask(SIG_SETMASK, &oset, nil); ++ if(ret != 0) { ++ runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), ret); ++ runtime·throw("runtime.newosproc"); ++ } ++} ++ ++#pragma textflag NOSPLIT ++void ++runtime·get_random_data(byte **rnd, int32 *rnd_len) ++{ ++ static byte urandom_data[HashRandomBytes]; ++ int32 fd; ++ fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0); ++ if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) { ++ *rnd = urandom_data; ++ *rnd_len = HashRandomBytes; ++ } else { ++ *rnd = nil; ++ *rnd_len = 0; ++ } ++ runtime·close(fd); ++} ++ ++void ++runtime·goenvs(void) ++{ ++ runtime·goenvs_unix(); ++} ++ ++// Called to initialize a new m (including the bootstrap m). ++// Called on the parent thread (main thread in case of bootstrap), can allocate memory. ++void ++runtime·mpreinit(M *mp) ++{ ++ mp->gsignal = runtime·malg(32*1024); ++ mp->gsignal->m = mp; ++} ++ ++// Called to initialize a new m (including the bootstrap m). ++// Called on the new thread, can not allocate memory. ++void ++runtime·minit(void) ++{ ++ runtime·asmcgocall(runtime·miniterrno, (void *) FUNC(libc·_errnop)); ++ // Initialize signal handling ++ runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024); ++ runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); ++} ++ ++// Called from dropm to undo the effect of an minit. ++void ++runtime·unminit(void) ++{ ++ runtime·signalstack(nil, 0); ++} ++ ++#pragma textflag NOSPLIT ++int8* ++runtime·signame(int32 sig) ++{ ++ return runtime·sigtab[sig].name; ++} ++ ++uintptr ++runtime·memlimit(void) ++{ ++ /*Rlimit rl; ++ extern byte runtime·text[], runtime·end[]; ++ uintptr used; ++ ++ if(runtime·getrlimit(RLIMIT_AS, &rl) != 0) ++ return 0; ++ if(rl.rlim_cur >= 0x7fffffff) ++ return 0; ++ ++ // Estimate our VM footprint excluding the heap. ++ // Not an exact science: use size of binary plus ++ // some room for thread stacks. ++ used = runtime·end - runtime·text + (64<<20); ++ if(used >= rl.rlim_cur) ++ return 0; ++ ++ // If there's not at least 16 MB left, we're probably ++ // not going to be able to do much. Treat as no limit. ++ rl.rlim_cur -= used; ++ if(rl.rlim_cur < (16<<20)) ++ return 0; ++ ++ return rl.rlim_cur - used; ++ */ ++ return 0; ++} ++ ++void ++runtime·setprof(bool on) ++{ ++ USED(on); ++} ++ ++extern void runtime·sigtramp(void); ++ ++void ++runtime·setsig(int32 i, GoSighandler *fn, bool restart) ++{ ++ SigactionT sa; ++ ++ runtime·memclr((byte*)&sa, sizeof sa); ++ sa.sa_flags = SA_SIGINFO|SA_ONSTACK; ++ if(restart) ++ sa.sa_flags |= SA_RESTART; ++ sa.sa_mask = ~(uint64)0; ++ if(fn == runtime·sighandler) ++ fn = (void*)runtime·sigtramp; ++ *((void**)&sa.anon0[0]) = (void*)fn; ++ runtime·sigaction(i, &sa, nil); ++} ++ ++GoSighandler* ++runtime·getsig(int32 i) ++{ ++ SigactionT sa; ++ ++ runtime·memclr((byte*)&sa, sizeof sa); ++ runtime·sigaction(i, nil, &sa); ++ if(*((void**)&sa.anon0[0]) == runtime·sigtramp) ++ return runtime·sighandler; ++ return *((void**)&sa.anon0[0]); ++} ++ ++void ++runtime·signalstack(byte *p, int32 n) ++{ ++ StackT st; ++ ++ st.ss_sp = (void*)p; ++ st.ss_size = n; ++ st.ss_flags = 0; ++ if(p == nil) ++ st.ss_flags = SS_DISABLE; ++ runtime·sigaltstack(&st, nil); ++} ++ ++void ++runtime·unblocksignals(void) ++{ ++ runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); ++} ++ ++#pragma textflag NOSPLIT ++uintptr ++runtime·semacreate(void) ++{ ++ SemT* sem; ++ ++ // Call libc's malloc rather than runtime·malloc. This will ++ // allocate space on the C heap. We can't call runtime·malloc ++ // here because it could cause a deadlock. ++ g->m->libcall.fn = (uintptr)(void*) FUNC(libc·malloc); ++ g->m->libcall.n = 1; ++ runtime·memclr((byte*)&g->m->scratch, sizeof(g->m->scratch)); ++ g->m->scratch.v[0] = (uintptr)sizeof(*sem); ++ g->m->libcall.args = (uintptr)(uintptr*)&g->m->scratch; ++ runtime·asmcgocall(runtime·asmsysvicall6, &g->m->libcall); ++ sem = (void*)g->m->libcall.r1; ++ if(runtime·sem_init(sem, 0, 0) != 0) ++ runtime·throw("sem_init"); ++ return (uintptr)sem; ++} ++ ++int32 _div64by32(int64 numerator, int32 denominator, int32* pointerToRemainder); ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·semasleep(int64 ns) ++{ ++ M *m; ++ ++ m = g->m; ++ ++ if(ns >= 0) { ++#ifdef GOARCH_amd64 ++ m->ts.tv_sec = ns / 1000000000LL; ++ m->ts.tv_nsec = ns % 1000000000LL; ++#else ++ // because 64-bit divide generates a call to a split stack method, which we can't call ++ m->ts.tv_sec = _div64by32(ns, 1000000000, &(m->ts.tv_nsec)); ++#endif ++ ++ m->libcall.fn = (uintptr)(void*) FUNC(libc·sem_timedwait); ++ m->libcall.n = 2; ++ runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); ++ m->scratch.v[0] = m->waitsema; ++ m->scratch.v[1] = (uintptr)&m->ts; ++ m->libcall.args = (uintptr)(uintptr*)&m->scratch; ++ runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); ++ if(*m->perrno != 0) { ++ if(*m->perrno == ETIMEDOUT || *m->perrno == EAGAIN || *m->perrno == EINTR) ++ return -1; ++ runtime·throw("sem_reltimedwait"); ++ } ++ return 0; ++ } ++ for(;;) { ++ m->libcall.fn = (uintptr)(void*) FUNC(libc·sem_wait); ++ m->libcall.n = 1; ++ runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); ++ m->scratch.v[0] = m->waitsema; ++ m->libcall.args = (uintptr)(uintptr*)&m->scratch; ++ runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); ++ if(m->libcall.r1 == 0) ++ break; ++ if(*m->perrno == EINTR) ++ continue; ++ runtime·throw("sem_wait"); ++ } ++ return 0; ++} ++ ++#pragma textflag NOSPLIT ++void ++runtime·semawakeup(M *mp) ++{ ++ SemT* sem = (SemT*)mp->waitsema; ++ if(runtime·sem_post(sem) != 0) ++ runtime·throw("sem_post"); ++} ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·close(int32 fd) ++{ ++ return runtime·sysvicall1(FUNC(libc·close), (uintptr)fd); ++} ++ ++#pragma textflag NOSPLIT ++void ++runtime·exit(int32 r) ++{ ++ runtime·sysvicall1(FUNC(libc·exit), (uintptr)r); ++} ++ ++#pragma textflag NOSPLIT ++/* int32 */ void ++runtime·getcontext(Ucontext* context) ++{ ++ runtime·sysvicall1(FUNC(libc·getcontext), (uintptr)context); ++} ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·getrlimit(int32 res, Rlimit* rlp) ++{ ++ return runtime·sysvicall2(FUNC(libc·getrlimit), (uintptr)res, (uintptr)rlp); ++} ++ ++#pragma textflag NOSPLIT ++uint8* ++runtime·mmap(byte* addr, uintptr len, int32 prot, int32 flags, int32 fildes, uint32 off) ++{ ++ return (uint8*)runtime·sysvicall6(FUNC(libc·mmap), (uintptr)addr, (uintptr)len, (uintptr)prot, (uintptr)flags, (uintptr)fildes, (uintptr)off); ++} ++ ++#pragma textflag NOSPLIT ++void ++runtime·munmap(byte* addr, uintptr len) ++{ ++ runtime·sysvicall2(FUNC(libc·munmap), (uintptr)addr, (uintptr)len); ++} ++ ++extern void runtime·nanotime1(void); ++#pragma textflag NOSPLIT ++int64 ++runtime·nanotime(void) ++{ ++ M *m; ++ ++ m = g->m; ++ ++ runtime·sysvicall0((uintptr)runtime·nanotime1); ++ if (sizeof(void*) == 8) { // on 64-bit the assembly wrapper does the multiplication ++ return m->libcall.r1; ++ } ++ return (m->libcall.r1 * 1000000000LL) + m->libcall.r2; ++} ++ ++// #pragma textflag NOSPLIT ++// void ++// time·now(int64 sec, int32 usec) ++// { ++// int64 ns; ++ ++// ns = runtime·nanotime(); ++// sec = ns / 1000000000LL; ++// usec = ns - sec * 1000000000LL; ++// FLUSH(&sec); ++// FLUSH(&usec); ++// } ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·open(int8* path, int32 oflag, int32 mode) ++{ ++ return runtime·sysvicall3(FUNC(libc·open), (uintptr)path, (uintptr)oflag, (uintptr)mode); ++} ++ ++int32 ++runtime·pthread_attr_destroy(PthreadAttr* attr) ++{ ++ return runtime·sysvicall1(FUNC(libc·pthread_attr_destroy), (uintptr)attr); ++} ++ ++int32 ++runtime·pthread_attr_getstacksize(PthreadAttr* attr, uintptr* size) ++{ ++ return runtime·sysvicall2(FUNC(libc·pthread_attr_getstacksize), (uintptr)attr, (uintptr)size); ++} ++ ++int32 ++runtime·pthread_attr_init(PthreadAttr* attr) ++{ ++ return runtime·sysvicall1(FUNC(libc·pthread_attr_init), (uintptr)attr); ++} ++ ++int32 ++runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state) ++{ ++ return runtime·sysvicall2(FUNC(libc·pthread_attr_setdetachstate), (uintptr)attr, (uintptr)state); ++} ++ ++int32 ++runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint32 size) ++{ ++ return runtime·sysvicall3(FUNC(libc·pthread_attr_setstack), (uintptr)attr, (uintptr)addr, (uintptr)size); ++} ++ ++int32 ++runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg) ++{ ++ return runtime·sysvicall4(FUNC(libc·pthread_create), (uintptr)thread, (uintptr)attr, (uintptr)fn, (uintptr)arg); ++} ++ ++/* int32 */ void ++runtime·raise(int32 sig) ++{ ++ runtime·sysvicall1(FUNC(libc·raise), (uintptr)sig); ++} ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·read(int32 fd, void* buf, int32 nbyte) ++{ ++ return runtime·sysvicall3(FUNC(libc·read), (uintptr)fd, (uintptr)buf, (uintptr)nbyte); ++} ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·sem_init(SemT* sem, int32 pshared, uint32 value) ++{ ++ return runtime·sysvicall3(FUNC(libc·sem_init), (uintptr)sem, (uintptr)pshared, (uintptr)value); ++} ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·sem_post(SemT* sem) ++{ ++ return runtime·sysvicall1(FUNC(libc·sem_post), (uintptr)sem); ++} ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·sem_wait(SemT* sem) ++{ ++ return runtime·sysvicall1(FUNC(libc·sem_wait), (uintptr)sem); ++} ++ ++/* int32 */ void ++runtime·setitimer(int32 which, Itimerval* value, Itimerval* ovalue) ++{ ++ runtime·sysvicall3(FUNC(libc·setitimer), (uintptr)which, (uintptr)value, (uintptr)ovalue); ++} ++ ++/* int32 */ void ++runtime·sigaction(int32 sig, struct SigactionT* act, struct SigactionT* oact) ++{ ++ runtime·sysvicall3(FUNC(libc·sigaction), (uintptr)sig, (uintptr)act, (uintptr)oact); ++} ++ ++/* int32 */ void ++runtime·sigaltstack(SigaltstackT* ss, SigaltstackT* oss) ++{ ++ runtime·sysvicall2(FUNC(libc·sigaltstack), (uintptr)ss, (uintptr)oss); ++} ++ ++/* int32 */ void ++runtime·sigprocmask(int32 how, Sigset* set, Sigset* oset) ++{ ++ runtime·sysvicall3(FUNC(libc·sigprocmask), (uintptr)how, (uintptr)set, (uintptr)oset); ++} ++ ++int64 ++runtime·sysconf(int32 name) ++{ ++ return runtime·sysvicall1(FUNC(libc·sysconf), (uintptr)name); ++} ++ ++#pragma textflag NOSPLIT ++void ++runtime·usleep(uint32 us) ++{ ++ runtime·sysvicall1(FUNC(libc·usleep), (uintptr)us); ++} ++ ++#pragma textflag NOSPLIT ++int32 ++runtime·write(uintptr fd, void* buf, int32 nbyte) ++{ ++ return runtime·sysvicall3(FUNC(libc·write), (uintptr)fd, (uintptr)buf, (uintptr)nbyte); ++} ++ ++#pragma textflag NOSPLIT ++void ++runtime·osyield(void) ++{ ++ runtime·sysvicall0(FUNC(libc·sched_yield)); ++} ++ ++uintptr ++runtime·area_for(void* addr) ++{ ++ return (uintptr)runtime·sysvicall1(FUNC(libc·area_for), (uintptr)addr); ++} ++ ++#ifndef GOARCH_amd64 ++// STUB ++void ++runtime·pipe1(void) ++{ ++ runtime·throw("Pipe not implemented"); ++} ++#endif +diff --git a/src/runtime/os_haiku.go b/src/runtime/os_haiku.go +new file mode 100644 +index 0000000..f843205 +--- /dev/null ++++ b/src/runtime/os_haiku.go +@@ -0,0 +1,102 @@ ++// Copyright 2014 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 runtime ++ ++import "unsafe" ++ ++func rt_sigaction(sig uintptr, new, old unsafe.Pointer, size uintptr) int32 ++ ++func sigaltstack(new, old unsafe.Pointer) ++func setitimer(mode int32, new, old unsafe.Pointer) ++func rtsigprocmask(sig int32, new, old unsafe.Pointer, size int32) ++func getrlimit(kind int32, limit unsafe.Pointer) int32 ++func raise(sig int32) ++func sched_getaffinity(pid, len uintptr, buf *uintptr) int32 ++ ++func sigaction(sig int32, new, old unsafe.Pointer) ++func sigprocmask(mode int32, new, old unsafe.Pointer) ++func miniterrno(fn unsafe.Pointer) ++ ++func getcontext(ctxt unsafe.Pointer) ++func tstart_sysvicall(mm unsafe.Pointer) uint32 ++func nanotime1() int64 ++func usleep1(usec uint32) ++func osyield1() ++ ++type libcFunc byte ++ ++var asmsysvicall6 libcFunc ++ ++//go:nosplit ++func sysvicall0(fn *libcFunc) uintptr { ++ libcall := &getg().m.libcall ++ libcall.fn = uintptr(unsafe.Pointer(fn)) ++ libcall.n = 0 ++ // TODO(rsc): Why is noescape necessary here and below? ++ libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) ++ return libcall.r1 ++} ++ ++//go:nosplit ++func sysvicall1(fn *libcFunc, a1 uintptr) uintptr { ++ libcall := &getg().m.libcall ++ libcall.fn = uintptr(unsafe.Pointer(fn)) ++ libcall.n = 1 ++ libcall.args = uintptr(noescape(unsafe.Pointer(&a1))) ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) ++ return libcall.r1 ++} ++ ++//go:nosplit ++func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr { ++ libcall := &getg().m.libcall ++ libcall.fn = uintptr(unsafe.Pointer(fn)) ++ libcall.n = 2 ++ libcall.args = uintptr(noescape(unsafe.Pointer(&a1))) ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) ++ return libcall.r1 ++} ++ ++//go:nosplit ++func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr { ++ libcall := &getg().m.libcall ++ libcall.fn = uintptr(unsafe.Pointer(fn)) ++ libcall.n = 3 ++ libcall.args = uintptr(noescape(unsafe.Pointer(&a1))) ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) ++ return libcall.r1 ++} ++ ++//go:nosplit ++func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr { ++ libcall := &getg().m.libcall ++ libcall.fn = uintptr(unsafe.Pointer(fn)) ++ libcall.n = 4 ++ libcall.args = uintptr(noescape(unsafe.Pointer(&a1))) ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) ++ return libcall.r1 ++} ++ ++//go:nosplit ++func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr { ++ libcall := &getg().m.libcall ++ libcall.fn = uintptr(unsafe.Pointer(fn)) ++ libcall.n = 5 ++ libcall.args = uintptr(noescape(unsafe.Pointer(&a1))) ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) ++ return libcall.r1 ++} ++ ++//go:nosplit ++func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr { ++ libcall := &getg().m.libcall ++ libcall.fn = uintptr(unsafe.Pointer(fn)) ++ libcall.n = 6 ++ libcall.args = uintptr(noescape(unsafe.Pointer(&a1))) ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall)) ++ return libcall.r1 ++} ++ +diff --git a/src/runtime/os_haiku.h b/src/runtime/os_haiku.h +new file mode 100644 +index 0000000..b611b13 +--- /dev/null ++++ b/src/runtime/os_haiku.h +@@ -0,0 +1,45 @@ ++// 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. ++ ++// Linux-specific system calls ++//int32 runtime·futex(uint32*, int32, uint32, Timespec*, uint32*, uint32); ++//int32 runtime·clone(int32, void*, M*, G*, void(*)(void)); ++ ++struct SigactionT; ++void runtime·sigaction(int32, struct SigactionT*, struct SigactionT*); ++ ++void runtime·sigaltstack(SigaltstackT*, SigaltstackT*); ++void runtime·sigpanic(void); ++void runtime·setitimer(int32, Itimerval*, Itimerval*); ++ ++enum { ++ SS_DISABLE = 2, ++ NSIG = 65, ++ SI_USER = 0, ++ SIG_SETMASK = 3, // Modified for Haiku support ++ RLIMIT_AS = 6, // Modified for Haiku support ++}; ++ ++void runtime·sigprocmask(int32, Sigset*, Sigset*); ++void runtime·unblocksignals(void); ++ ++typedef struct Rlimit Rlimit; ++struct Rlimit { ++ uintptr rlim_cur; ++ uintptr rlim_max; ++}; ++int32 runtime·getrlimit(int32, Rlimit*); ++ ++// Call an external library function described by {fn, a0, ..., an}, with ++// SysV conventions, switching to os stack during the call, if necessary. ++ ++uintptr runtime·sysvicall0(uintptr fn); ++uintptr runtime·sysvicall1(uintptr fn, uintptr a1); ++uintptr runtime·sysvicall2(uintptr fn, uintptr a1, uintptr a2); ++uintptr runtime·sysvicall3(uintptr fn, uintptr a1, uintptr a2, uintptr a3); ++uintptr runtime·sysvicall4(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4); ++uintptr runtime·sysvicall5(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5); ++uintptr runtime·sysvicall6(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6); ++void runtime·asmsysvicall6(void *c); ++void runtime·miniterrno(void *fn); +diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go +index 8677cb3..3da28f9 100644 +--- a/src/runtime/pprof/pprof_test.go ++++ b/src/runtime/pprof/pprof_test.go +@@ -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 !nacl ++// +build !haiku !nacl + + package pprof_test + +diff --git a/src/runtime/proc.c b/src/runtime/proc.c +index 8462c4b..d8377ac 100644 +--- a/src/runtime/proc.c ++++ b/src/runtime/proc.c +@@ -902,7 +902,7 @@ runtime·allocm(P *p) + + // In case of cgo or Solaris, pthread_create will make us a stack. + // Windows and Plan 9 will layout sched stack on OS stack. +- if(runtime·iscgo || Solaris || Windows || Plan9) ++ if(runtime·iscgo || Haiku || Solaris || Windows || Plan9) + mp->g0 = runtime·malg(-1); + else + mp->g0 = runtime·malg(8192); +diff --git a/src/runtime/rt0_haiku_amd64.s b/src/runtime/rt0_haiku_amd64.s +new file mode 100644 +index 0000000..4b604ef +--- /dev/null ++++ b/src/runtime/rt0_haiku_amd64.s +@@ -0,0 +1,18 @@ ++// 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 "textflag.h" ++ ++TEXT _rt0_amd64_haiku(SB),NOSPLIT,$-8 ++ LEAQ 8(SP), SI // argv ++ MOVQ 0(SP), DI // argc ++ MOVQ $main(SB), AX ++ JMP AX ++ ++TEXT main(SB),NOSPLIT,$-8 ++ MOVQ $runtime·rt0_go(SB), AX ++ JMP AX ++ ++DATA runtime·ishaiku(SB)/4, $1 ++GLOBL runtime·ishaiku(SB), NOPTR, $4 +diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c +index c823691..25408c3 100644 +--- a/src/runtime/runtime.c ++++ b/src/runtime/runtime.c +@@ -80,6 +80,7 @@ runtime·args(int32 c, uint8 **v) + runtime·sysargs(c, v); + } + ++int32 runtime·ishaiku; + int32 runtime·isplan9; + int32 runtime·issolaris; + int32 runtime·iswindows; +diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h +index 177a128..c24d5d9 100644 +--- a/src/runtime/runtime.h ++++ b/src/runtime/runtime.h +@@ -392,6 +392,19 @@ struct M + uintptr v[6]; + } scratch; + #endif ++#ifdef GOOS_haiku ++ int32* perrno; // pointer to TLS errno ++ // these are here because they are too large to be on the stack ++ // of low-level NOSPLIT functions. ++ LibCall libcall; ++ struct MTs { ++ int64 tv_sec; ++ int64 tv_nsec; ++ } ts; ++ struct MScratch { ++ uintptr v[6]; ++ } scratch; ++#endif + #ifdef GOOS_plan9 + int8* notesig; + byte* errstr; +@@ -559,6 +572,15 @@ enum { + Solaris = 0 + }; + #endif ++#ifdef GOOS_haiku ++enum { ++ Haiku = 1 ++}; ++#else ++enum { ++ Haiku = 0 ++}; ++#endif + #ifdef GOOS_plan9 + enum { + Plan9 = 1 +diff --git a/src/runtime/signal_amd64x.c b/src/runtime/signal_amd64x.c +index feb4afc..26d0680 100644 +--- a/src/runtime/signal_amd64x.c ++++ b/src/runtime/signal_amd64x.c +@@ -3,7 +3,7 @@ + // license that can be found in the LICENSE file. + + // +build amd64 amd64p32 +-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + #include "runtime.h" + #include "defs_GOOS_GOARCH.h" +diff --git a/src/runtime/signal_haiku_amd64.h b/src/runtime/signal_haiku_amd64.h +new file mode 100644 +index 0000000..b8c330a +--- /dev/null ++++ b/src/runtime/signal_haiku_amd64.h +@@ -0,0 +1,33 @@ ++// Copyright 2013 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 SIG_REGS(ctxt) (((Ucontext*)(ctxt))->uc_mcontext) ++ ++#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).rax) ++#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).rbx) ++#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).rcx) ++#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).rdx) ++#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).rdi) ++#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).rsi) ++#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).rbp) ++#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).rsp) ++#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8) ++#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9) ++#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10) ++#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).r11) ++#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).r12) ++#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).r13) ++#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).r14) ++#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).r15) ++#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).rip) ++#define SIG_RFLAGS(info, ctxt) ((uint64)SIG_REGS(ctxt).rflags) ++ ++// FIXME: haiku: cs, fs, gs ++#define SIG_CS(info, ctxt) (-1) ++#define SIG_FS(info, ctxt) (-1) ++#define SIG_GS(info, ctxt) (-1) ++ ++#define SIG_CODE0(info, ctxt) ((info)->si_code) ++#define SIG_CODE1(info, ctxt) (((uintptr*)(info))[2]) ++ +diff --git a/src/runtime/signal_unix.c b/src/runtime/signal_unix.c +index 0e33ece..55e9335 100644 +--- a/src/runtime/signal_unix.c ++++ b/src/runtime/signal_unix.c +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + #include "runtime.h" + #include "defs_GOOS_GOARCH.h" +diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go +index ba77b6e..f75eb92 100644 +--- a/src/runtime/signal_unix.go ++++ b/src/runtime/signal_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package runtime + +diff --git a/src/runtime/signals_haiku.h b/src/runtime/signals_haiku.h +new file mode 100644 +index 0000000..c7f29df +--- /dev/null ++++ b/src/runtime/signals_haiku.h +@@ -0,0 +1,86 @@ ++// 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 "textflag.h" ++ ++#define N SigNotify ++#define K SigKill ++#define T SigThrow ++#define P SigPanic ++#define D SigDefault ++ ++#pragma dataflag NOPTR ++SigTab runtime·sigtab[] = { ++ /* 0 */ 0, "SIGNONE: no trap", ++ /* 1 */ N+K, "SIGHUP: hangup", ++ /* 2 */ N+K, "SIGINT: interrupt", ++ /* 3 */ N+T, "SIGQUIT: quit", ++ /* 4 */ T, "SIGILL: illegal instruction", ++ /* 5 */ N, "SIGCHLD: child exited", ++ /* 6 */ N+T, "SIGABRT: abort", ++ /* 7 */ N, "SIGPIPE: broken pipe", ++ /* 8 */ P, "SIGFPE: floating point exception", ++ /* 9 */ 0, "SIGKILL: killed (by death)", ++ /* 10 */ 0, "SIGSTOP: stopped", ++ /* 11 */ P, "SIGSEGV: segmentation violation", ++ /* 12 */ 0, "SIGCONT: continued", ++ /* 13 */ N+D, "SIGTSTP: stopped (tty output)", ++ /* 14 */ N, "SIGALRM: alarm", ++ /* 15 */ N+K, "SIGTERM: termination requested", ++ /* 16 */ N+D, "SIGTTIN: stopped (tty input)", ++ /* 17 */ N+D, "SIGTTOU: stopped (tty output)", ++ /* 18 */ N, "SIGUSR1: user defined signal 1", ++ /* 19 */ N, "SIGUSR2: user defined signal 2", ++ /* 20 */ N, "SIGWINCH: window size changed", ++ /* 21 */ N+K, "SIGKILLTHR: kill Thread", ++ /* 22 */ T, "SIGTRAP: trace/breakpoint trap", ++ /* 23 */ N, "SIGPOLL: pollable event", ++ /* 24 */ N, "SIGPROF: profiling timer expired", ++ /* 25 */ N, "SIGSYS: bad system call", ++ /* 26 */ N, "SIGURG: high bandwidth data is available at socket", ++ /* 27 */ N, "SIGVTALRM: virtual timer expired", ++ /* 28 */ N, "SIGXCPU: CPU time limit exceeded", ++ /* 29 */ N, "SIGXFSZ: file size limit exceeded", ++ /* 30 */ P, "SIGBUS: bus error", ++ /* 31 */ N, "SIGRESERVED1: reserved signal 1", ++ /* 32 */ N, "SIGRESERVED2: reserved signal 2", ++ /* 33 */ N, "signal 33", ++ /* 34 */ N, "signal 34", ++ /* 35 */ N, "signal 35", ++ /* 36 */ N, "signal 36", ++ /* 37 */ N, "signal 37", ++ /* 38 */ N, "signal 38", ++ /* 39 */ N, "signal 39", ++ /* 40 */ N, "signal 40", ++ /* 41 */ N, "signal 41", ++ /* 42 */ N, "signal 42", ++ /* 43 */ N, "signal 43", ++ /* 44 */ N, "signal 44", ++ /* 45 */ N, "signal 45", ++ /* 46 */ N, "signal 46", ++ /* 47 */ N, "signal 47", ++ /* 48 */ N, "signal 48", ++ /* 49 */ N, "signal 49", ++ /* 50 */ N, "signal 50", ++ /* 51 */ N, "signal 51", ++ /* 52 */ N, "signal 52", ++ /* 53 */ N, "signal 53", ++ /* 54 */ N, "signal 54", ++ /* 55 */ N, "signal 55", ++ /* 56 */ N, "signal 56", ++ /* 57 */ N, "signal 57", ++ /* 58 */ N, "signal 58", ++ /* 59 */ N, "signal 59", ++ /* 60 */ N, "signal 60", ++ /* 61 */ N, "signal 61", ++ /* 62 */ N, "signal 62", ++ /* 63 */ N, "signal 63", ++ /* 64 */ N, "signal 64", ++}; ++ ++#undef N ++#undef K ++#undef T ++#undef P ++#undef D +diff --git a/src/runtime/sigpanic_unix.go b/src/runtime/sigpanic_unix.go +index 6807985..5cd9a2a 100644 +--- a/src/runtime/sigpanic_unix.go ++++ b/src/runtime/sigpanic_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package runtime + +diff --git a/src/runtime/sys_haiku_amd64.s b/src/runtime/sys_haiku_amd64.s +new file mode 100644 +index 0000000..95d874a +--- /dev/null ++++ b/src/runtime/sys_haiku_amd64.s +@@ -0,0 +1,352 @@ ++// Copyright 2014 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, SunOS ++// /usr/include/sys/syscall.h for syscall numbers. ++// ++ ++#include "zasm_GOOS_GOARCH.h" ++#include "textflag.h" ++ ++// This is needed by asm_amd64.s ++TEXT runtime·settls(SB),NOSPLIT,$8 ++ RET ++ ++// void libc·miniterrno(void *(*___errno)(void)); ++// ++// Set the TLS errno pointer in M. ++// ++// Called using runtime·asmcgocall from os_solaris.c:/minit. ++// NOT USING GO CALLING CONVENTION. ++TEXT runtime·miniterrno(SB),NOSPLIT,$0 ++ // asmcgocall will put first argument into DI. ++ CALL DI // SysV ABI so returns in AX ++ get_tls(CX) ++ MOVQ g(CX), BX ++ MOVQ g_m(BX), BX ++ MOVQ AX, m_perrno(BX) ++ RET ++ ++// int64 runtime·nanotime1(void); ++// ++// clock_gettime(3c) wrapper because Timespec is too large for ++// runtime·nanotime stack. ++// ++// Called using runtime·sysvicall6 from os_solaris.c:/nanotime. ++// NOT USING GO CALLING CONVENTION. ++TEXT runtime·nanotime1(SB),NOSPLIT,$0 ++ // need space for the timespec argument. ++ SUBQ $64, SP // 16 bytes will do, but who knows in the future? ++ MOVQ $0xffffffffffffffff, DI // CLOCK_REALTIME from ++ //MOVQ $3, DI // CLOCK_REALTIME from ++ MOVQ SP, SI ++ MOVQ libc·clock_gettime(SB), AX ++ CALL AX ++ MOVQ (SP), AX // tv_sec from struct timespec ++ IMULQ $1000000000, AX // multiply into nanoseconds ++ ADDQ 8(SP), AX // tv_nsec, offset should be stable. ++ ADDQ $64, SP ++ RET ++ ++// pipe(3c) wrapper that returns fds in AX, DX. ++// NOT USING GO CALLING CONVENTION. ++TEXT runtime·pipe1(SB),NOSPLIT,$0 ++ SUBQ $16, SP // 8 bytes will do, but stack has to be 16-byte alligned ++ MOVQ SP, DI ++ MOVQ libc·pipe(SB), AX ++ CALL AX ++ MOVL 0(SP), AX ++ MOVL 4(SP), DX ++ ADDQ $16, SP ++ RET ++ ++// Call a library function with SysV calling conventions. ++// The called function can take a maximum of 6 INTEGER class arguments, ++// see ++// Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell ++// System V Application Binary Interface ++// AMD64 Architecture Processor Supplement ++// section 3.2.3. ++// ++// Called by runtime·asmcgocall or runtime·cgocall. ++// NOT USING GO CALLING CONVENTION. ++TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0 ++ // asmcgocall will put first argument into DI. ++ PUSHQ DI // save for later ++ MOVQ libcall_fn(DI), AX ++ MOVQ libcall_args(DI), R11 ++ MOVQ libcall_n(DI), R10 ++ ++ get_tls(CX) ++ MOVQ g(CX), BX ++ MOVQ g_m(BX), BX ++ MOVQ m_perrno(BX), DX ++ CMPQ DX, $0 ++ JEQ skiperrno1 ++ MOVL $0, 0(DX) ++ ++skiperrno1: ++ CMPQ R11, $0 ++ JEQ skipargs ++ // Load 6 args into correspondent registers. ++ MOVQ 0(R11), DI ++ MOVQ 8(R11), SI ++ MOVQ 16(R11), DX ++ MOVQ 24(R11), CX ++ MOVQ 32(R11), R8 ++ MOVQ 40(R11), R9 ++skipargs: ++ ++ // Call SysV function ++ CALL AX ++ ++ // Return result ++ POPQ DI ++ MOVQ AX, libcall_r1(DI) ++ MOVQ DX, libcall_r2(DI) ++ ++ get_tls(CX) ++ MOVQ g(CX), BX ++ MOVQ g_m(BX), BX ++ MOVQ m_perrno(BX), AX ++ CMPQ AX, $0 ++ JEQ skiperrno2 ++ MOVL 0(AX), AX ++ MOVQ AX, libcall_err(DI) ++ ++skiperrno2: ++ RET ++ ++// uint32 tstart_sysvicall(M *newm); ++TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0 ++ // DI contains first arg newm ++ MOVQ m_g0(DI), DX // g ++ ++ // Make TLS entries point at g and m. ++ get_tls(BX) ++ MOVQ DX, g(BX) ++ MOVQ DI, g_m(DX) ++ ++ // Layout new m scheduler stack on os stack. ++ MOVQ SP, AX ++ MOVQ AX, (g_stack+stack_hi)(DX) ++ SUBQ $(0x100000), AX // stack size ++ MOVQ AX, (g_stack+stack_lo)(DX) ++ ADDQ $const_StackGuard, AX ++ MOVQ AX, g_stackguard0(DX) ++ MOVQ AX, g_stackguard1(DX) ++ ++ // Someday the convention will be D is always cleared. ++ CLD ++ ++ CALL runtime·stackcheck(SB) // clobbers AX,CX ++ CALL runtime·mstart(SB) ++ ++ XORL AX, AX // return 0 == success ++ MOVL AX, ret+8(FP) ++ RET ++ ++// Careful, this is called by __sighndlr, a libc function. We must preserve ++// registers as per AMD 64 ABI. ++TEXT runtime·sigtramp(SB),NOSPLIT,$0 ++ // Note that we are executing on altsigstack here, so we have ++ // more stack available than NOSPLIT would have us believe. ++ // To defeat the linker, we make our own stack frame with ++ // more space: ++ SUBQ $184, SP ++ ++ // save registers ++ MOVQ BX, 32(SP) ++ MOVQ BP, 40(SP) ++ MOVQ R12, 48(SP) ++ MOVQ R13, 56(SP) ++ MOVQ R14, 64(SP) ++ MOVQ R15, 72(SP) ++ ++ get_tls(BX) ++ // check that g exists ++ MOVQ g(BX), R10 ++ CMPQ R10, $0 ++ JNE allgood ++ MOVQ DI, 0(SP) ++ MOVQ $runtime·badsignal(SB), AX ++ CALL AX ++ JMP exit ++ ++allgood: ++ // save g ++ MOVQ R10, 80(SP) ++ ++ // Save m->libcall and m->scratch. We need to do this because we ++ // might get interrupted by a signal in runtime·asmcgocall. ++ ++ // save m->libcall ++ MOVQ g_m(R10), BP ++ LEAQ m_libcall(BP), R11 ++ MOVQ libcall_fn(R11), R10 ++ MOVQ R10, 88(SP) ++ MOVQ libcall_args(R11), R10 ++ MOVQ R10, 96(SP) ++ MOVQ libcall_n(R11), R10 ++ MOVQ R10, 104(SP) ++ MOVQ libcall_r1(R11), R10 ++ MOVQ R10, 168(SP) ++ MOVQ libcall_r2(R11), R10 ++ MOVQ R10, 176(SP) ++ ++ // save m->scratch ++ LEAQ m_scratch(BP), R11 ++ MOVQ 0(R11), R10 ++ MOVQ R10, 112(SP) ++ MOVQ 8(R11), R10 ++ MOVQ R10, 120(SP) ++ MOVQ 16(R11), R10 ++ MOVQ R10, 128(SP) ++ MOVQ 24(R11), R10 ++ MOVQ R10, 136(SP) ++ MOVQ 32(R11), R10 ++ MOVQ R10, 144(SP) ++ MOVQ 40(R11), R10 ++ MOVQ R10, 152(SP) ++ ++ // save errno, it might be EINTR; stuff we do here might reset it. ++ MOVQ m_perrno(BP), R10 ++ MOVL 0(R10), R10 ++ MOVQ R10, 160(SP) ++ ++ MOVQ g(BX), R10 ++ // g = m->gsignal ++ MOVQ m_gsignal(BP), BP ++ MOVQ BP, g(BX) ++ ++ // prepare call ++ MOVQ DI, 0(SP) ++ MOVQ SI, 8(SP) ++ MOVQ DX, 16(SP) ++ MOVQ R10, 24(SP) ++ CALL runtime·sighandler(SB) ++ ++ get_tls(BX) ++ MOVQ g(BX), BP ++ MOVQ g_m(BP), BP ++ // restore libcall ++ LEAQ m_libcall(BP), R11 ++ MOVQ 88(SP), R10 ++ MOVQ R10, libcall_fn(R11) ++ MOVQ 96(SP), R10 ++ MOVQ R10, libcall_args(R11) ++ MOVQ 104(SP), R10 ++ MOVQ R10, libcall_n(R11) ++ MOVQ 168(SP), R10 ++ MOVQ R10, libcall_r1(R11) ++ MOVQ 176(SP), R10 ++ MOVQ R10, libcall_r2(R11) ++ ++ // restore scratch ++ LEAQ m_scratch(BP), R11 ++ MOVQ 112(SP), R10 ++ MOVQ R10, 0(R11) ++ MOVQ 120(SP), R10 ++ MOVQ R10, 8(R11) ++ MOVQ 128(SP), R10 ++ MOVQ R10, 16(R11) ++ MOVQ 136(SP), R10 ++ MOVQ R10, 24(R11) ++ MOVQ 144(SP), R10 ++ MOVQ R10, 32(R11) ++ MOVQ 152(SP), R10 ++ MOVQ R10, 40(R11) ++ ++ // restore errno ++ MOVQ m_perrno(BP), R11 ++ MOVQ 160(SP), R10 ++ MOVL R10, 0(R11) ++ ++ // restore g ++ MOVQ 80(SP), R10 ++ MOVQ R10, g(BX) ++ ++exit: ++ // restore registers ++ MOVQ 32(SP), BX ++ MOVQ 40(SP), BP ++ MOVQ 48(SP), R12 ++ MOVQ 56(SP), R13 ++ MOVQ 64(SP), R14 ++ MOVQ 72(SP), R15 ++ ++ ADDQ $184, SP ++ RET ++ ++// Called from runtime·usleep (Go). Can be called on Go stack, on OS stack, ++// can also be called in cgo callback path without a g->m. ++TEXT runtime·usleep1(SB),NOSPLIT,$0 ++ MOVL usec+0(FP), DI ++ MOVQ $runtime·usleep2(SB), AX // to hide from 6l ++ ++ // Execute call on m->g0. ++ get_tls(R15) ++ CMPQ R15, $0 ++ JE usleep1_noswitch ++ ++ MOVQ g(R15), R13 ++ CMPQ R13, $0 ++ JE usleep1_noswitch ++ MOVQ g_m(R13), R13 ++ CMPQ R13, $0 ++ JE usleep1_noswitch ++ // TODO(aram): do something about the cpu profiler here. ++ ++ MOVQ m_g0(R13), R14 ++ CMPQ g(R15), R14 ++ JNE usleep1_switch ++ // executing on m->g0 already ++ CALL AX ++ RET ++ ++usleep1_switch: ++ // Switch to m->g0 stack and back. ++ MOVQ (g_sched+gobuf_sp)(R14), R14 ++ MOVQ SP, -8(R14) ++ LEAQ -8(R14), SP ++ CALL AX ++ MOVQ 0(SP), SP ++ RET ++ ++usleep1_noswitch: ++ // Not a Go-managed thread. Do not switch stack. ++ CALL AX ++ RET ++ ++// Runs on OS stack. duration (in µs units) is in DI. ++TEXT runtime·usleep2(SB),NOSPLIT,$0 ++ MOVQ libc·usleep(SB), AX ++ CALL AX ++ RET ++ ++// Runs on OS stack, called from runtime·osyield. ++TEXT runtime·osyield1(SB),NOSPLIT,$0 ++ MOVQ libc·sched_yield(SB), AX ++ CALL AX ++ RET ++ ++// func now() (sec int64, nsec int32) ++TEXT time·now(SB),NOSPLIT,$8-12 ++ CALL runtime·nanotime(SB) ++ MOVQ 0(SP), AX ++ ++ // generated code for ++ // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 } ++ // adapted to reduce duplication ++ MOVQ AX, CX ++ MOVQ $1360296554856532783, AX ++ MULQ CX ++ ADDQ CX, DX ++ RCRQ $1, DX ++ SHRQ $29, DX ++ MOVQ DX, sec+0(FP) ++ IMULQ $1000000000, DX ++ SUBQ DX, CX ++ MOVL CX, nsec+8(FP) ++ RET +diff --git a/src/runtime/syscall_haiku.c b/src/runtime/syscall_haiku.c +new file mode 100644 +index 0000000..1c56821 +--- /dev/null ++++ b/src/runtime/syscall_haiku.c +@@ -0,0 +1,26 @@ ++// Copyright 2014 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. ++ ++#pragma dynimport libc·chdir chdir "libroot.so" ++#pragma dynimport libc·chroot chroot "libroot.so" ++#pragma dynimport libc·close close "libroot.so" ++#pragma dynimport libc·dlclose dlclose "libroot.so" ++#pragma dynimport libc·dlopen dlopen "libroot.so" ++#pragma dynimport libc·dlsym dlsym "libroot.so" ++#pragma dynimport libc·dup2 dup2 "libroot.so" ++#pragma dynimport libc·execve execve "libroot.so" ++#pragma dynimport libc·fcntl fcntl "libroot.so" ++#pragma dynimport libc·gethostname gethostname "libroot.so" ++#pragma dynimport libc·ioctl ioctl "libroot.so" ++#pragma dynimport libc·mmap mmap "libroot.so" ++#pragma dynimport libc·pipe pipe "libroot.so" ++#pragma dynimport libc·setgid setgid "libroot.so" ++#pragma dynimport libc·setgroups setgroups "libroot.so" ++#pragma dynimport libc·setsid setsid "libroot.so" ++#pragma dynimport libc·setuid setuid "libroot.so" ++#pragma dynimport libc·setpgid setsid "libroot.so" ++#pragma dynimport libc·_kern_generic_syscall _kern_generic_syscall "libroot.so" ++#pragma dynimport libc·fork fork "libroot.so" ++//#pragma dynimport libc·waitpid waitpid "libroot.so" ++#pragma dynimport libc·wait4 wait4 "libbsd.so" +diff --git a/src/runtime/syscall_haiku.go b/src/runtime/syscall_haiku.go +new file mode 100644 +index 0000000..5a32f23 +--- /dev/null ++++ b/src/runtime/syscall_haiku.go +@@ -0,0 +1,351 @@ ++// Copyright 2014 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 runtime ++ ++import "unsafe" ++ ++var ( ++ libc_chdir, ++ libc_chroot, ++ libc_close, ++ libc_dlclose, ++ libc_dlopen, ++ libc_dlsym, ++ libc_dup2, ++ libc_execve, ++ libc_exit, ++ libc_fcntl, ++ libc_gethostname, ++ libc_ioctl, ++ libc_mmap, ++ libc_pipe, ++ libc_setgid, ++ libc_setgroups, ++ libc_setsid, ++ libc_setuid, ++ libc_setpgid, ++ libc__kern_generic_syscall, ++ libc_fork, ++ libc_waitpid, ++// libc_wait4, ++ libc_write, ++ pipe1 libcFunc ++) ++ ++//go:nosplit ++func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { ++ call := libcall{ ++ fn: fn, ++ n: nargs, ++ args: uintptr(unsafe.Pointer(&a1)), ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ return call.r1, call.r2, call.err ++} ++ ++// TODO(aram): Once we remove all instances of C calling sysvicallN, make ++// sysvicallN return errors and replace the body of the following functions ++// with calls to sysvicallN. ++ ++//go:nosplit ++func syscall_chdir(path uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_chdir)), ++ n: 1, ++ args: uintptr(unsafe.Pointer(&path)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++//go:nosplit ++func syscall_chroot(path uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_chroot)), ++ n: 1, ++ args: uintptr(unsafe.Pointer(&path)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++// like close, but must not split stack, for forkx. ++//go:nosplit ++func syscall_close(fd int32) int32 { ++ return int32(sysvicall1(&libc_close, uintptr(fd))) ++} ++ ++func syscall_dlopen(name *byte, mode uintptr) (handle uintptr, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_dlopen)), ++ n: 2, ++ args: uintptr(unsafe.Pointer(&name)), ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ if call.r1 == 0 { ++ return call.r1, call.err ++ } ++ return call.r1, 0 ++} ++ ++func syscall_dlclose(handle uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_dlclose)), ++ n: 1, ++ args: uintptr(unsafe.Pointer(&handle)), ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ return call.r1 ++} ++ ++func syscall_dlsym(handle uintptr, name *byte) (proc uintptr, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_dlsym)), ++ n: 2, ++ args: uintptr(unsafe.Pointer(&handle)), ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ if call.r1 == 0 { ++ return call.r1, call.err ++ } ++ return call.r1, 0 ++} ++ ++//go:nosplit ++func syscall_dup2(fd1 uintptr, fd2 uintptr) (val uintptr, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_dup2)), ++ n: 2, ++ args: uintptr(unsafe.Pointer(&fd1)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.r1, call.err ++} ++ ++//go:nosplit ++func syscall_execve(path, argv, envp uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_execve)), ++ n: 3, ++ args: uintptr(unsafe.Pointer(&path)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++// like exit, but must not split stack, for forkx. ++//go:nosplit ++func syscall_exit(code uintptr) { ++ sysvicall1(&libc_exit, code) ++} ++ ++//go:nosplit ++func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_fcntl)), ++ n: 3, ++ args: uintptr(unsafe.Pointer(&fd)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.r1, call.err ++} ++ ++//go:nosplit ++func syscall_fork(flags uintptr) (pid uintptr, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_fork)), ++ n: 0, ++ args: uintptr(unsafe.Pointer(nil)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.r1, call.err ++} ++ ++func syscall_gethostname() (name string, err uintptr) { ++ cname := new([_MAXHOSTNAMELEN]byte) ++ var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN} ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_gethostname)), ++ n: 2, ++ args: uintptr(unsafe.Pointer(&args[0])), ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ if call.r1 != 0 { ++ return "", call.err ++ } ++ cname[_MAXHOSTNAMELEN-1] = 0 ++ return gostringnocopy(&cname[0]), 0 ++} ++ ++//go:nosplit ++func syscall_ioctl(fd, req, arg uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_ioctl)), ++ n: 3, ++ args: uintptr(unsafe.Pointer(&fd)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++func syscall_pipe() (r, w, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&pipe1)), ++ n: 0, ++ args: uintptr(unsafe.Pointer(&pipe1)), // it's unused but must be non-nil, otherwise crashes ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ return call.r1, call.r2, call.err ++} ++ ++// FIXME: haiku: can we fix the auto generator so we won't have to handcode this? ++func syscall_mmap(addr, length, prot, flag, fd uintptr, pos int64) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_mmap)), ++ n: 7, ++ args: uintptr(unsafe.Pointer(&addr)), // it's unused but must be non-nil, otherwise crashes ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++//go:nosplit ++func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { ++ call := libcall{ ++ fn: fn, ++ n: nargs, ++ args: uintptr(unsafe.Pointer(&a1)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.r1, call.r2, call.err ++} ++ ++// This is syscall.RawSyscall, it exists to satisfy some build dependency, ++// but it doesn't work correctly. ++// ++// DO NOT USE! ++// ++// TODO(aram): make this panic once we stop calling fcntl(2) in net using it. ++func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc__kern_generic_syscall)), ++ n: 4, ++ args: uintptr(unsafe.Pointer(&trap)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.r1, call.r2, call.err ++} ++ ++//go:nosplit ++func syscall_setgid(gid uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_setgid)), ++ n: 1, ++ args: uintptr(unsafe.Pointer(&gid)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++//go:nosplit ++func syscall_setgroups(ngid, gid uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_setgroups)), ++ n: 2, ++ args: uintptr(unsafe.Pointer(&ngid)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++//go:nosplit ++func syscall_setsid() (pid, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_setsid)), ++ n: 0, ++ args: uintptr(unsafe.Pointer(&libc_setsid)), // it's unused but must be non-nil, otherwise crashes ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.r1, call.err ++} ++ ++//go:nosplit ++func syscall_setuid(uid uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_setuid)), ++ n: 1, ++ args: uintptr(unsafe.Pointer(&uid)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++//go:nosplit ++func syscall_setpgid(pid, pgid uintptr) (err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_setpgid)), ++ n: 2, ++ args: uintptr(unsafe.Pointer(&pid)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.err ++} ++ ++// This is syscall.Syscall, it exists to satisfy some build dependency, ++// but it doesn't work correctly. ++// ++// DO NOT USE! ++// ++// TODO(aram): make this panic once we stop calling fcntl(2) in net using it. ++func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { ++ ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc__kern_generic_syscall)), ++ n: 4, ++ args: uintptr(unsafe.Pointer(&trap)), ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ return call.r1, call.r2, call.err ++} ++ ++/* ++//go:nosplit ++func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr) (wpid int, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_waitpid)), ++ n: 3, ++ args: uintptr(unsafe.Pointer(&pid)), ++ } ++ entersyscallblock() ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ exitsyscall() ++ return int(call.r1), call.err ++} ++*/ ++ ++//go:nosplit ++func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) { ++ call := libcall{ ++ fn: uintptr(unsafe.Pointer(&libc_write)), ++ n: 3, ++ args: uintptr(unsafe.Pointer(&fd)), ++ } ++ asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call)) ++ return call.r1, call.err ++} +diff --git a/src/runtime/thunk_haiku_amd64.s b/src/runtime/thunk_haiku_amd64.s +new file mode 100644 +index 0000000..1eb12e9 +--- /dev/null ++++ b/src/runtime/thunk_haiku_amd64.s +@@ -0,0 +1,96 @@ ++// Copyright 2014 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. ++ ++// This file exposes various external library functions to Go code in the runtime. ++ ++#include "zasm_GOOS_GOARCH.h" ++#include "textflag.h" ++ ++TEXT runtime·libc_chdir(SB),NOSPLIT,$0 ++ MOVQ libc·chdir(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_chroot(SB),NOSPLIT,$0 ++ MOVQ libc·chroot(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_close(SB),NOSPLIT,$0 ++ MOVQ libc·close(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_dlopen(SB),NOSPLIT,$0 ++ MOVQ libc·dlopen(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_dlclose(SB),NOSPLIT,$0 ++ MOVQ libc·dlclose(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_dlsym(SB),NOSPLIT,$0 ++ MOVQ libc·dlsym(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_execve(SB),NOSPLIT,$0 ++ MOVQ libc·execve(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_exit(SB),NOSPLIT,$0 ++ MOVQ libc·exit(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_fcntl(SB),NOSPLIT,$0 ++ MOVQ libc·fcntl(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_fork(SB),NOSPLIT,$0 ++ MOVQ libc·fork(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_gethostname(SB),NOSPLIT,$0 ++ MOVQ libc·gethostname(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_ioctl(SB),NOSPLIT,$0 ++ MOVQ libc·ioctl(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_setgid(SB),NOSPLIT,$0 ++ MOVQ libc·setgid(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_setgroups(SB),NOSPLIT,$0 ++ MOVQ libc·setgroups(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_setsid(SB),NOSPLIT,$0 ++ MOVQ libc·setsid(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_setuid(SB),NOSPLIT,$0 ++ MOVQ libc·setuid(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_setpgid(SB),NOSPLIT,$0 ++ MOVQ libc·setpgid(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_syscall(SB),NOSPLIT,$0 ++ MOVQ libc·_kern_generic_syscall(SB), AX ++ JMP AX ++ ++//TEXT runtime·libc_wait4(SB),NOSPLIT,$0 ++// MOVQ libc·waitpid(SB), AX ++// JMP AX ++ ++TEXT runtime·libc_write(SB),NOSPLIT,$0 ++ MOVQ libc·write(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_mmap(SB),NOSPLIT,$0 ++ MOVQ libc·mmap(SB), AX ++ JMP AX ++ ++TEXT runtime·libc_dup2(SB),NOSPLIT,$0 ++ MOVQ libc·dup2(SB), AX ++ JMP AX +-- +2.19.0 + + +From 84b839ba63c02ca317a076bfc5142a72e08f17ce Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:57:06 +0100 +Subject: syscall: Add early Haiku x86_64 support for syscall package. + + +diff --git a/src/syscall/asm_haiku_amd64.s b/src/syscall/asm_haiku_amd64.s +new file mode 100644 +index 0000000..df7f8fb +--- /dev/null ++++ b/src/syscall/asm_haiku_amd64.s +@@ -0,0 +1,87 @@ ++// Copyright 2014 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 "textflag.h" ++ ++// ++// System calls for solaris/amd64 are implemented in ../runtime/syscall_haiku.go ++// ++ ++TEXT ·sysvicall6(SB),NOSPLIT,$0 ++ JMP runtime·syscall_sysvicall6(SB) ++ ++TEXT ·rawSysvicall6(SB),NOSPLIT,$0 ++ JMP runtime·syscall_rawsysvicall6(SB) ++ ++TEXT ·chdir(SB),NOSPLIT,$0 ++ JMP runtime·syscall_chdir(SB) ++ ++TEXT ·chroot1(SB),NOSPLIT,$0 ++ JMP runtime·syscall_chroot(SB) ++ ++TEXT ·close(SB),NOSPLIT,$0 ++ JMP runtime·syscall_close(SB) ++ ++TEXT ·dlopen(SB),NOSPLIT,$0 ++ JMP runtime·syscall_dlopen(SB) ++ ++TEXT ·dlclose(SB),NOSPLIT,$0 ++ JMP runtime·syscall_dlclose(SB) ++ ++TEXT ·dlsym(SB),NOSPLIT,$0 ++ JMP runtime·syscall_dlsym(SB) ++ ++TEXT ·execve(SB),NOSPLIT,$0 ++ JMP runtime·syscall_execve(SB) ++ ++TEXT ·exit(SB),NOSPLIT,$0 ++ JMP runtime·syscall_exit(SB) ++ ++TEXT ·fcntl1(SB),NOSPLIT,$0 ++ JMP runtime·syscall_fcntl(SB) ++ ++TEXT ·forkx(SB),NOSPLIT,$0 ++ JMP runtime·syscall_fork(SB) ++ ++TEXT ·gethostname(SB),NOSPLIT,$0 ++ JMP runtime·syscall_gethostname(SB) ++ ++TEXT ·ioctl(SB),NOSPLIT,$0 ++ JMP runtime·syscall_ioctl(SB) ++ ++TEXT ·pipe(SB),NOSPLIT,$0 ++ JMP runtime·syscall_pipe(SB) ++ ++TEXT ·mmap(SB),NOSPLIT,$0 ++ JMP runtime·syscall_mmap(SB) ++ ++TEXT ·RawSyscall(SB),NOSPLIT,$0 ++ JMP runtime·syscall_rawsyscall(SB) ++ ++TEXT ·setgid(SB),NOSPLIT,$0 ++ JMP runtime·syscall_setgid(SB) ++ ++TEXT ·setgroups1(SB),NOSPLIT,$0 ++ JMP runtime·syscall_setgroups(SB) ++ ++TEXT ·setsid(SB),NOSPLIT,$0 ++ JMP runtime·syscall_setsid(SB) ++ ++TEXT ·setuid(SB),NOSPLIT,$0 ++ JMP runtime·syscall_setuid(SB) ++ ++TEXT ·setpgid(SB),NOSPLIT,$0 ++ JMP runtime·syscall_setpgid(SB) ++ ++TEXT ·Syscall(SB),NOSPLIT,$0 ++ JMP runtime·syscall_syscall(SB) ++ ++//TEXT ·wait4(SB),NOSPLIT,$0 ++// JMP runtime·syscall_wait4(SB) ++ ++TEXT ·dup2(SB),NOSPLIT,$0 ++ JMP runtime·syscall_dup2(SB) ++ ++TEXT ·write1(SB),NOSPLIT,$0 ++ JMP runtime·syscall_write(SB) +diff --git a/src/syscall/env_unix.go b/src/syscall/env_unix.go +index b5ded9c..32a2d83 100644 +--- a/src/syscall/env_unix.go ++++ b/src/syscall/env_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + // Unix environment variables. + +diff --git a/src/syscall/exec_haiku.go b/src/syscall/exec_haiku.go +new file mode 100644 +index 0000000..0d92f3b +--- /dev/null ++++ b/src/syscall/exec_haiku.go +@@ -0,0 +1,245 @@ ++// Copyright 2011 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 ++ ++import ( ++ "unsafe" ++) ++ ++type SysProcAttr struct { ++ Chroot string // Chroot. ++ Credential *Credential // Credential. ++ Setsid bool // Create session. ++ Setpgid bool // Set process group ID to new pid (SYSV setpgrp) ++ Setctty bool // Set controlling terminal to fd 0 ++ Noctty bool // Detach fd 0 from controlling terminal ++} ++ ++// Implemented in runtime package. ++func runtime_BeforeFork() ++func runtime_AfterFork() ++ ++func chdir(path uintptr) (err Errno) ++func chroot1(path uintptr) (err Errno) ++func close(fd uintptr) (err Errno) ++func dup2(fd1 uintptr, fd2 uintptr) (val uintptr, err Errno) ++func execve(path uintptr, argv uintptr, envp uintptr) (err Errno) ++func exit(code uintptr) ++func fcntl1(fd uintptr, cmd uintptr, arg uintptr) (val uintptr, err Errno) ++func forkx(flags uintptr) (pid uintptr, err Errno) ++func ioctl(fd uintptr, req uintptr, arg uintptr) (err Errno) ++func setgid(gid uintptr) (err Errno) ++func setgroups1(ngid uintptr, gid uintptr) (err Errno) ++func setsid() (pid uintptr, err Errno) ++func setuid(uid uintptr) (err Errno) ++func setpgid(pid uintptr, pgid uintptr) (err Errno) ++func write1(fd uintptr, buf uintptr, nbyte uintptr) (n uintptr, err Errno) ++ ++// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child. ++// If a dup or exec fails, write the errno error to pipe. ++// (Pipe is close-on-exec so if exec succeeds, it will be closed.) ++// In the child, this function must not acquire any locks, because ++// they might have been locked at the time of the fork. This means ++// no rescheduling, no malloc calls, and no new stack segments. ++// ++// We call hand-crafted syscalls, implemented in ++// ../runtime/syscall_solaris.goc, rather than generated libc wrappers ++// because we need to avoid lazy-loading the functions (might malloc, ++// split the stack, or acquire mutexes). We can't call RawSyscall ++// because it's not safe even for BSD-subsystem calls. ++func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) { ++ // Declare all variables at top in case any ++ // declarations require heap allocation (e.g., err1). ++ var ( ++ r1 uintptr ++ err1 Errno ++ nextfd int ++ i int ++ ) ++ ++ // guard against side effects of shuffling fds below. ++ // Make sure that nextfd is beyond any currently open files so ++ // that we can't run the risk of overwriting any of them. ++ fd := make([]int, len(attr.Files)) ++ nextfd = len(attr.Files) ++ for i, ufd := range attr.Files { ++ if nextfd < int(ufd) { ++ nextfd = int(ufd) ++ } ++ fd[i] = int(ufd) ++ } ++ nextfd++ ++ ++ // About to call fork. ++ // No more allocation or calls of non-assembly functions. ++ runtime_BeforeFork() ++ r1, err1 = forkx(0x1) // FORK_NOSIGCHLD ++ if err1 != 0 { ++ runtime_AfterFork() ++ return 0, err1 ++ } ++ ++ if r1 != 0 { ++ // parent; return PID ++ runtime_AfterFork() ++ return int(r1), 0 ++ } ++ ++ // Fork succeeded, now in child. ++ ++ ++ // Session ID ++ if sys.Setsid { ++ _, err1 = setsid() ++ if err1 != 0 { ++ goto childerror ++ } ++ } ++ ++ // Set process group ++ if sys.Setpgid { ++ err1 = setpgid(0, 0) ++ if err1 != 0 { ++ goto childerror ++ } ++ } ++ ++ // Chroot ++ if chroot != nil { ++ err1 = chroot1(uintptr(unsafe.Pointer(chroot))) ++ if err1 != 0 { ++ goto childerror ++ } ++ } ++ ++ // User and groups ++ if cred := sys.Credential; cred != nil { ++ ngroups := uintptr(len(cred.Groups)) ++ groups := uintptr(0) ++ if ngroups > 0 { ++ groups = uintptr(unsafe.Pointer(&cred.Groups[0])) ++ } ++ err1 = setgroups1(ngroups, groups) ++ if err1 != 0 { ++ goto childerror ++ } ++ err1 = setgid(uintptr(cred.Gid)) ++ if err1 != 0 { ++ goto childerror ++ } ++ err1 = setuid(uintptr(cred.Uid)) ++ if err1 != 0 { ++ goto childerror ++ } ++ } ++ ++ // Chdir ++ if dir != nil { ++ err1 = chdir(uintptr(unsafe.Pointer(dir))) ++ if err1 != 0 { ++ goto childerror ++ } ++ } ++ ++ // Pass 1: look for fd[i] < i and move those up above len(fd) ++ // so that pass 2 won't stomp on an fd it needs later. ++ if pipe < nextfd { ++ _, err1 = dup2(uintptr(pipe), uintptr(nextfd)) ++ if err1 != 0 { ++ goto childerror ++ } ++ fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC) ++ pipe = nextfd ++ nextfd++ ++ } ++ for i = 0; i < len(fd); i++ { ++ if fd[i] >= 0 && fd[i] < int(i) { ++ _, err1 = dup2(uintptr(pipe), uintptr(nextfd)) ++ if err1 != 0 { ++ goto childerror ++ } ++ fcntl1(uintptr(nextfd), F_SETFD, FD_CLOEXEC) ++ fd[i] = nextfd ++ nextfd++ ++ if nextfd == pipe { // don't stomp on pipe ++ nextfd++ ++ } ++ } ++ } ++ ++ // Pass 2: dup fd[i] down onto i. ++ for i = 0; i < len(fd); i++ { ++ if fd[i] == -1 { ++ close(uintptr(i)) ++ continue ++ } ++ if fd[i] == int(i) { ++ // dup2(i, i) won't clear close-on-exec flag on Linux, ++ // probably not elsewhere either. ++ _, err1 = fcntl1(uintptr(fd[i]), F_SETFD, 0) ++ if err1 != 0 { ++ goto childerror ++ } ++ continue ++ } ++ // The new fd is created NOT close-on-exec, ++ // which is exactly what we want. ++ _, err1 = dup2(uintptr(fd[i]), uintptr(i)) ++ if err1 != 0 { ++ goto childerror ++ } ++ } ++ ++ // By convention, we don't close-on-exec the fds we are ++ // started with, so if len(fd) < 3, close 0, 1, 2 as needed. ++ // Programs that know they inherit fds >= 3 will need ++ // to set them close-on-exec. ++ for i = len(fd); i < 3; i++ { ++ close(uintptr(i)) ++ } ++ ++ /*// Detach fd 0 from tty ++ if sys.Noctty { ++ err1 = ioctl(0, uintptr(TIOCNOTTY), 0) ++ if err1 != 0 { ++ goto childerror ++ } ++ } ++ ++ // Make fd 0 the tty ++ if sys.Setctty { ++ err1 = ioctl(0, uintptr(TIOCSCTTY), 0) ++ if err1 != 0 { ++ goto childerror ++ } ++ }*/ ++ ++ // Time to exec. ++ err1 = execve( ++ uintptr(unsafe.Pointer(argv0)), ++ uintptr(unsafe.Pointer(&argv[0])), ++ uintptr(unsafe.Pointer(&envv[0]))) ++ ++childerror: ++ // send error code on pipe ++ write1(uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1)) ++ for { ++ exit(253) ++ } ++} ++ ++// Try to open a pipe with O_CLOEXEC set on both file descriptors. ++func forkExecPipe(p []int) error { ++ err := Pipe(p) ++ if err != nil { ++ return err ++ } ++ _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC) ++ if err != nil { ++ return err ++ } ++ _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC) ++ return err ++} +diff --git a/src/syscall/exec_unix.go b/src/syscall/exec_unix.go +index 890bfdc..e7e6420 100644 +--- a/src/syscall/exec_unix.go ++++ b/src/syscall/exec_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + // Fork, exec, wait, etc. + +@@ -94,6 +94,10 @@ func SlicePtrFromStrings(ss []string) ([]*byte, error) { + func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) } + + func SetNonblock(fd int, nonblocking bool) (err error) { ++ if runtime.GOOS == "haiku" { ++ // FIXME: Haiku does not have a working netpoller yet. ++ return nil ++ } + flag, err := fcntl(fd, F_GETFL, 0) + if err != nil { + return err +diff --git a/src/syscall/mksyscall_haiku.pl b/src/syscall/mksyscall_haiku.pl +new file mode 100644 +index 0000000..0647bdc +--- /dev/null ++++ b/src/syscall/mksyscall_haiku.pl +@@ -0,0 +1,290 @@ ++#!/usr/bin/env 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. ++ ++# This program reads a file containing function prototypes ++# (like syscall_haiku.go) and generates system call bodies. ++# The prototypes are marked by lines beginning with "//sys" ++# and read like func declarations if //sys is replaced by func, but: ++# * The parameter lists must give a name for each argument. ++# This includes return parameters. ++# * The parameter lists must give a type for each argument: ++# the (x, y, z int) shorthand is not allowed. ++# * If the return parameter is an error number, it must be named err. ++# * If go func name needs to be different than its libc name, ++# * or the function is not in libc, name could be specified ++# * at the end, after "=" sign, like ++# //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt ++ ++use strict; ++ ++my $cmdline = "mksyscall_haiku.pl " . join(' ', @ARGV); ++my $errors = 0; ++my $_32bit = ""; ++my $default_modname = "libc"; ++ ++binmode STDOUT; ++ ++if($ARGV[0] eq "-b32") { ++ $_32bit = "big-endian"; ++ shift; ++} elsif($ARGV[0] eq "-l32") { ++ $_32bit = "little-endian"; ++ shift; ++} ++ ++if ($ARGV[0] eq "-modname") { ++ $default_modname = "$ARGV[1]"; ++ shift; ++ shift; ++} ++ ++if($ARGV[0] =~ /^-/) { ++ print STDERR "usage: mksyscall_haiku.pl [-b32 | -l32] [file ...]\n"; ++ exit 1; ++} ++ ++sub parseparamlist($) { ++ my ($list) = @_; ++ $list =~ s/^\s*//; ++ $list =~ s/\s*$//; ++ if($list eq "") { ++ return (); ++ } ++ return split(/\s*,\s*/, $list); ++} ++ ++sub parseparam($) { ++ my ($p) = @_; ++ if($p !~ /^(\S*) (\S*)$/) { ++ print STDERR "$ARGV:$.: malformed parameter: $p\n"; ++ $errors = 1; ++ return ("xx", "int"); ++ } ++ return ($1, $2); ++} ++ ++my $package = ""; ++my $text = ""; ++my $vars = ""; ++my $mods = ""; ++my $modnames = ""; ++while(<>) { ++ chomp; ++ s/\s+/ /g; ++ s/^\s+//; ++ s/\s+$//; ++ $package = $1 if !$package && /^package (\S+)$/; ++ my $nonblock = /^\/\/sysnb /; ++ next if !/^\/\/sys / && !$nonblock; ++ ++ my $syscalldot = ""; ++ $syscalldot = "syscall." if $package ne "syscall"; ++ ++ # Line must be of the form ++ # func Open(path string, mode int, perm int) (fd int, err error) ++ # Split into name, in params, out params. ++ if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) { ++ print STDERR "$ARGV:$.: malformed //sys declaration\n"; ++ $errors = 1; ++ next; ++ } ++ my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6); ++ ++ # Split argument lists on comma. ++ my @in = parseparamlist($in); ++ my @out = parseparamlist($out); ++ ++ # So file name. ++ if($modname eq "") { ++ $modname = "$default_modname"; ++ } ++ my $modvname = "mod$modname"; ++ if($modnames !~ /$modname/) { ++ $modnames .= ".$modname"; ++ $mods .= "\t$modvname = ${syscalldot}newLazySO(\"$modname.so\")\n"; ++ } ++ ++ # System call name. ++ if($sysname eq "") { ++ $sysname = "$func"; ++ } ++ ++ # System call pointer variable name. ++ my $sysvarname = "proc$sysname"; ++ ++ my $strconvfunc = "BytePtrFromString"; ++ my $strconvtype = "*byte"; ++ ++ # Library proc address variable. ++ $sysname =~ y/A-Z/a-z/; # All libc functions are lowercase. ++ $vars .= "\t$sysvarname = $modvname.NewProc(\"$sysname\")\n"; ++ ++ # Go function header. ++ $out = join(', ', @out); ++ if($out ne "") { ++ $out = " ($out)"; ++ } ++ if($text ne "") { ++ $text .= "\n" ++ } ++ $text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out; ++ ++ # Check if err return available ++ my $errvar = ""; ++ foreach my $p (@out) { ++ my ($name, $type) = parseparam($p); ++ if($type eq "error") { ++ $errvar = $name; ++ last; ++ } ++ } ++ ++ # Prepare arguments to Syscall. ++ my @args = (); ++ my @uses = (); ++ my $n = 0; ++ foreach my $p (@in) { ++ my ($name, $type) = parseparam($p); ++ if($type =~ /^\*/) { ++ push @args, "uintptr(unsafe.Pointer($name))"; ++ } elsif($type eq "string" && $errvar ne "") { ++ $text .= "\tvar _p$n $strconvtype\n"; ++ $text .= "\t_p$n, $errvar = $strconvfunc($name)\n"; ++ $text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n"; ++ push @args, "uintptr(unsafe.Pointer(_p$n))"; ++ push @uses, "use(unsafe.Pointer(_p$n))"; ++ $n++; ++ } elsif($type eq "string") { ++ print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n"; ++ $text .= "\tvar _p$n $strconvtype\n"; ++ $text .= "\t_p$n, _ = $strconvfunc($name)\n"; ++ push @args, "uintptr(unsafe.Pointer(_p$n))"; ++ push @uses, "use(unsafe.Pointer(_p$n))"; ++ $n++; ++ } elsif($type =~ /^\[\](.*)/) { ++ # Convert slice into pointer, length. ++ # Have to be careful not to take address of &a[0] if len == 0: ++ # pass nil in that case. ++ $text .= "\tvar _p$n *$1\n"; ++ $text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n"; ++ push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))"; ++ $n++; ++ } elsif($type eq "int64" && $_32bit ne "") { ++ if($_32bit eq "big-endian") { ++ push @args, "uintptr($name >> 32)", "uintptr($name)"; ++ } else { ++ push @args, "uintptr($name)", "uintptr($name >> 32)"; ++ } ++ } elsif($type eq "bool") { ++ $text .= "\tvar _p$n uint32\n"; ++ $text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n"; ++ push @args, "uintptr(_p$n)"; ++ $n++; ++ } else { ++ push @args, "uintptr($name)"; ++ } ++ } ++ my $nargs = @args; ++ ++ # Determine which form to use; pad args with zeros. ++ my $asm = "${syscalldot}sysvicall6"; ++ if ($nonblock) { ++ $asm = "${syscalldot}rawSysvicall6"; ++ } ++ if(@args <= 6) { ++ while(@args < 6) { ++ push @args, "0"; ++ } ++ } else { ++ print STDERR "$ARGV:$.: too many arguments to system call\n"; ++ } ++ ++ # Actual call. ++ my $args = join(', ', @args); ++ my $call = "$asm($sysvarname.Addr(), $nargs, $args)"; ++ ++ # Assign return values. ++ my $body = ""; ++ my $failexpr = ""; ++ my @ret = ("_", "_", "_"); ++ my @pout= (); ++ my $do_errno = 0; ++ for(my $i=0; $i<@out; $i++) { ++ my $p = $out[$i]; ++ my ($name, $type) = parseparam($p); ++ my $reg = ""; ++ if($name eq "err") { ++ $reg = "e1"; ++ $ret[2] = $reg; ++ $do_errno = 1; ++ } else { ++ $reg = sprintf("r%d", $i); ++ $ret[$i] = $reg; ++ } ++ if($type eq "bool") { ++ $reg = "$reg != 0"; ++ } ++ if($type eq "int64" && $_32bit ne "") { ++ # 64-bit number in r1:r0 or r0:r1. ++ if($i+2 > @out) { ++ print STDERR "$ARGV:$.: not enough registers for int64 return\n"; ++ } ++ if($_32bit eq "big-endian") { ++ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1); ++ } else { ++ $reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i); ++ } ++ $ret[$i] = sprintf("r%d", $i); ++ $ret[$i+1] = sprintf("r%d", $i+1); ++ } ++ if($reg ne "e1") { ++ $body .= "\t$name = $type($reg)\n"; ++ } ++ } ++ if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") { ++ $text .= "\t$call\n"; ++ } else { ++ $text .= "\t$ret[0], $ret[1], $ret[2] := $call\n"; ++ } ++ foreach my $use (@uses) { ++ $text .= "\t$use\n"; ++ } ++ $text .= $body; ++ ++ if ($do_errno) { ++ $text .= "\tif e1 != 0 {\n"; ++ $text .= "\t\terr = e1\n"; ++ $text .= "\t}\n"; ++ } ++ $text .= "\treturn\n"; ++ $text .= "}\n"; ++} ++ ++if($errors) { ++ exit 1; ++} ++ ++print < 0 { ++ dirent := (*Dirent)(unsafe.Pointer(&buf[0])) ++ if dirent.Reclen == 0 { ++ buf = nil ++ break ++ } ++ buf = buf[dirent.Reclen:] ++ if dirent.Ino == 0 { // File absent in directory. ++ continue ++ } ++ bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) ++ var name = string(bytes[0:clen(bytes[:])]) ++ if name == "." || name == ".." { // Useless names ++ continue ++ } ++ max-- ++ count++ ++ names = append(names, name) ++ } ++ return origlen - len(buf), count, names ++} ++ ++func pipe() (r uintptr, w uintptr, err uintptr) ++ ++//sys pipe2(fds []int) (err error) = libroot.pipe ++ ++func Pipe(p []int) (err error) { ++ if len(p) != 2 { ++ return EINVAL ++ } ++ if runtime.GOARCH == "386" { ++ return pipe2(p) ++ } ++ r0, w0, e1 := pipe() ++ if e1 != 0 { ++ err = Errno(e1) ++ } ++ p[0], p[1] = int(r0), int(w0) ++ return ++} ++ ++func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) { ++ if sa.Port < 0 || sa.Port > 0xFFFF { ++ return nil, 0, EINVAL ++ } ++ sa.raw.Family = AF_INET ++ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) ++ p[0] = byte(sa.Port >> 8) ++ p[1] = byte(sa.Port) ++ for i := 0; i < len(sa.Addr); i++ { ++ sa.raw.Addr[i] = sa.Addr[i] ++ } ++ return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil ++} ++ ++func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) { ++ if sa.Port < 0 || sa.Port > 0xFFFF { ++ return nil, 0, EINVAL ++ } ++ sa.raw.Family = AF_INET6 ++ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port)) ++ p[0] = byte(sa.Port >> 8) ++ p[1] = byte(sa.Port) ++ sa.raw.Scope_id = sa.ZoneId ++ for i := 0; i < len(sa.Addr); i++ { ++ sa.raw.Addr[i] = sa.Addr[i] ++ } ++ return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil ++} ++ ++func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) { ++ name := sa.Name ++ n := len(name) ++ if n >= len(sa.raw.Path) { ++ return nil, 0, EINVAL ++ } ++ sa.raw.Family = AF_UNIX ++ for i := 0; i < n; i++ { ++ sa.raw.Path[i] = int8(name[i]) ++ } ++ // length is family (uint16), name, NUL. ++ sl := _Socklen(2) ++ if n > 0 { ++ sl += _Socklen(n) + 1 ++ } ++ if sa.raw.Path[0] == '@' { ++ sa.raw.Path[0] = 0 ++ // Don't count trailing NUL for abstract address. ++ sl-- ++ } ++ ++ return unsafe.Pointer(&sa.raw), sl, nil ++} ++ ++func Getsockname(fd int) (sa Sockaddr, err error) { ++ var rsa RawSockaddrAny ++ var len _Socklen = SizeofSockaddrAny ++ if err = getsockname(fd, &rsa, &len); err != nil { ++ return ++ } ++ return anyToSockaddr(&rsa) ++} ++ ++// The const provides a compile-time constant so clients ++// can adjust to whether there is a working Getwd and avoid ++// even linking this function into the binary. See ../os/getwd.go. ++const ImplementsGetwd = false ++ ++func Getwd() (string, error) { return "", ENOTSUP } ++ ++/* ++ * Wrapped ++ */ ++ ++//sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error) ++//sysnb setgroups(ngid int, gid *_Gid_t) (err error) ++ ++func Getgroups() (gids []int, err error) { ++ n, err := getgroups(0, nil) ++ if err != nil { ++ return nil, err ++ } ++ if n == 0 { ++ return nil, nil ++ } ++ ++ // Sanity check group count. Max is 16 on BSD. ++ if n < 0 || n > 1000 { ++ return nil, EINVAL ++ } ++ ++ a := make([]_Gid_t, n) ++ n, err = getgroups(n, &a[0]) ++ if err != nil { ++ return nil, err ++ } ++ gids = make([]int, n) ++ for i, v := range a[0:n] { ++ gids[i] = int(v) ++ } ++ return ++} ++ ++func Setgroups(gids []int) (err error) { ++ if len(gids) == 0 { ++ return setgroups(0, nil) ++ } ++ ++ a := make([]_Gid_t, len(gids)) ++ for i, v := range gids { ++ a[i] = _Gid_t(v) ++ } ++ return setgroups(len(a), &a[0]) ++} ++ ++func ReadDirent(fd int, buf []byte) (n int, err error) { ++ panic("Not implemented") ++} ++ ++// Wait status: 8 bits at the bottom is exit status ++// If all bits other than the 8 bottom are empty, then exited ++// next 8 bits are signal number that caused exit ++// next 8 bits are signal that caused stop ++// core is 0x10000 ++// continued is 0x20000 ++ ++type WaitStatus uint32 ++ ++const ( ++ mask = 0xFF ++ core = 0x10000 ++ continued = 0x20000 ++ shift = 8 ++ ++ exited = 0 ++) ++ ++func (w WaitStatus) Exited() bool { return w&^mask == exited } ++ ++func (w WaitStatus) ExitStatus() int { ++ if w&^mask != exited { ++ return -1 ++ } ++ return int(w & mask) ++} ++ ++func (w WaitStatus) Signaled() bool { return ((w >> 8) & mask) != 0 } ++ ++func (w WaitStatus) Signal() Signal { ++ sig := Signal((w >> 8) & mask) ++ if sig == 0 { ++ return -1 ++ } ++ return sig ++} ++ ++func (w WaitStatus) CoreDump() bool { return w&core != 0 } ++ ++func (w WaitStatus) Stopped() bool { return (w>>16)&mask != 0 } ++ ++func (w WaitStatus) Continued() bool { return w&continued != 0 } ++ ++func (w WaitStatus) StopSignal() Signal { ++ if !w.Stopped() { ++ return -1 ++ } ++ return Signal(w>>16) & mask ++} ++ ++func (w WaitStatus) TrapCause() int { return -1 } ++ ++// sys wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid int, err uintptr) = libroot.waitpid ++ ++func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) { ++ r0, _, e1 := sysvicall6(procwaitpid.Addr(), 3, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) ++ wpid = int(r0) ++ if e1 != 0 { ++ err = Errno(e1) ++ } ++ return wpid, err ++} ++ ++func gethostname() (name string, err uintptr) ++ ++func Gethostname() (name string, err error) { ++ name, e1 := gethostname() ++ if e1 != 0 { ++ err = Errno(e1) ++ } ++ return name, err ++} ++ ++func UtimesNano(path string, ts []Timespec) (err error) { ++ if len(ts) != 2 { ++ return EINVAL ++ } ++ var tv [2]Timeval ++ for i := 0; i < 2; i++ { ++ tv[i].Sec = ts[i].Sec ++ tv[i].Usec = int32(ts[i].Nsec / 1000) ++ } ++ return Utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0]))) ++} ++ ++//sys fcntl(fd int, cmd int, arg int) (val int, err error) ++ ++// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. ++func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { ++ _, _, e1 := sysvicall6(procfcntl.Addr(), 3, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(lk)), 0, 0, 0) ++ if e1 != 0 { ++ return e1 ++ } ++ return nil ++} ++ ++func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) { ++ switch rsa.Addr.Family { ++ case AF_UNIX: ++ pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa)) ++ sa := new(SockaddrUnix) ++ // Assume path ends at NUL. ++ // This is not technically the Solaris semantics for ++ // abstract Unix domain sockets -- they are supposed ++ // to be uninterpreted fixed-size binary blobs -- but ++ // everyone uses this convention. ++ n := 0 ++ for n < len(pp.Path) && pp.Path[n] != 0 { ++ n++ ++ } ++ bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] ++ sa.Name = string(bytes) ++ return sa, nil ++ ++ case AF_INET: ++ pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa)) ++ sa := new(SockaddrInet4) ++ p := (*[2]byte)(unsafe.Pointer(&pp.Port)) ++ sa.Port = int(p[0])<<8 + int(p[1]) ++ for i := 0; i < len(sa.Addr); i++ { ++ sa.Addr[i] = pp.Addr[i] ++ } ++ return sa, nil ++ ++ case AF_INET6: ++ pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa)) ++ sa := new(SockaddrInet6) ++ p := (*[2]byte)(unsafe.Pointer(&pp.Port)) ++ sa.Port = int(p[0])<<8 + int(p[1]) ++ sa.ZoneId = pp.Scope_id ++ for i := 0; i < len(sa.Addr); i++ { ++ sa.Addr[i] = pp.Addr[i] ++ } ++ return sa, nil ++ } ++ return nil, EAFNOSUPPORT ++} ++ ++//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = libnetwork.accept ++ ++func Accept(fd int) (nfd int, sa Sockaddr, err error) { ++ var rsa RawSockaddrAny ++ var len _Socklen = SizeofSockaddrAny ++ nfd, err = accept(fd, &rsa, &len) ++ if err != nil { ++ return ++ } ++ sa, err = anyToSockaddr(&rsa) ++ if err != nil { ++ Close(nfd) ++ nfd = 0 ++ } ++ return ++} ++ ++func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { ++ var msg Msghdr ++ var rsa RawSockaddrAny ++ msg.Name = (*byte)(unsafe.Pointer(&rsa)) ++ msg.Namelen = uint32(SizeofSockaddrAny) ++ var iov Iovec ++ if len(p) > 0 { ++ iov.Base = (*byte)(unsafe.Pointer(&p[0])) ++ iov.SetLen(len(p)) ++ } ++ var dummy byte ++ if len(oob) > 0 { ++ // receive at least one normal byte ++ if len(p) == 0 { ++ iov.Base = &dummy ++ iov.SetLen(1) ++ } ++ //msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) ++ } ++ msg.Iov = &iov ++ msg.Iovlen = 1 ++ if n, err = recvmsg(fd, &msg, flags); err != nil { ++ return ++ } ++ oobn = 0 //int(msg.Accrightslen) ++ // source address is only specified if the socket is unconnected ++ if rsa.Addr.Family != AF_UNSPEC { ++ from, err = anyToSockaddr(&rsa) ++ } ++ return ++} ++ ++func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { ++ _, err = SendmsgN(fd, p, oob, to, flags) ++ return ++} ++ ++//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = libnetwork.sendmsg ++ ++func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { ++ var ptr unsafe.Pointer ++ var salen _Socklen ++ if to != nil { ++ ptr, salen, err = to.sockaddr() ++ if err != nil { ++ return 0, err ++ } ++ } ++ var msg Msghdr ++ msg.Name = (*byte)(unsafe.Pointer(ptr)) ++ msg.Namelen = uint32(salen) ++ var iov Iovec ++ if len(p) > 0 { ++ iov.Base = (*byte)(unsafe.Pointer(&p[0])) ++ iov.SetLen(len(p)) ++ } ++ var dummy byte ++ if len(oob) > 0 { ++ // send at least one normal byte ++ if len(p) == 0 { ++ iov.Base = &dummy ++ iov.SetLen(1) ++ } ++ //msg.Accrights = (*int8)(unsafe.Pointer(&oob[0])) ++ } ++ msg.Iov = &iov ++ msg.Iovlen = 1 ++ if n, err = sendmsg(fd, &msg, flags); err != nil { ++ return 0, err ++ } ++ if len(oob) > 0 && len(p) == 0 { ++ n = 0 ++ } ++ return n, nil ++} ++ ++// FIXME: haiku: fix the auto generator so that it can deal with more than 6 params ++func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) ++ ++/* ++ * Exposed directly ++ */ ++//sys Access(path string, mode uint32) (err error) ++//sys Adjtime(delta *Timeval, olddelta *Timeval) (err error) ++//sys Chdir(path string) (err error) ++//sys Chmod(path string, mode uint32) (err error) ++//sys Chown(path string, uid int, gid int) (err error) ++//sys Chroot(path string) (err error) ++//sys Close(fd int) (err error) ++//sys Dup(fd int) (nfd int, err error) ++//sys Exit(code int) ++//sys Fchdir(fd int) (err error) ++//sys Fchmod(fd int, mode uint32) (err error) ++//sys Fchown(fd int, uid int, gid int) (err error) ++//sys Fpathconf(fd int, name int) (val int, err error) ++//sys Fstat(fd int, stat *Stat_t) (err error) ++//sysnb Getgid() (gid int) ++//sysnb Getpid() (pid int) ++//sys Geteuid() (euid int) ++//sys Getegid() (egid int) ++//sys Getppid() (ppid int) ++//sys Getpriority(which int, who int) (n int, err error) ++//sysnb Getrlimit(which int, lim *Rlimit) (err error) ++//sysnb Gettimeofday(tv *Timeval) (err error) ++//sysnb Getuid() (uid int) ++//sys Kill(pid int, signum Signal) (err error) ++//sys Lchown(path string, uid int, gid int) (err error) ++//sys Link(path string, link string) (err error) ++//sys Listen(s int, backlog int) (err error) = libnetwork.listen ++//sys Lstat(path string, stat *Stat_t) (err error) ++//sys Mkdir(path string, mode uint32) (err error) ++//sys Mknod(path string, mode uint32, dev int) (err error) ++//sys Nanosleep(time *Timespec, leftover *Timespec) (err error) ++//sys Open(path string, mode int, perm uint32) (fd int, err error) ++//sys Pathconf(path string, name int) (val int, err error) ++//sys Pread(fd int, p []byte, offset int64) (n int, err error) ++//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) ++//sys read(fd int, p []byte) (n int, err error) ++//sys Readlink(path string, buf []byte) (n int, err error) ++//sys Rename(from string, to string) (err error) ++//sys Rmdir(path string) (err error) ++//sys Seek(fd int, offset int64, whence int) (newoffset int64, err error) = lseek ++//sysnb Setegid(egid int) (err error) ++//sysnb Seteuid(euid int) (err error) ++//sysnb Setgid(gid int) (err error) ++//sysnb Setpgid(pid int, pgid int) (err error) ++//sys Setpriority(which int, who int, prio int) (err error) ++//sysnb Setregid(rgid int, egid int) (err error) ++//sysnb Setreuid(ruid int, euid int) (err error) ++//sysnb Setrlimit(which int, lim *Rlimit) (err error) ++//sysnb Setsid() (pid int, err error) ++//sysnb Setuid(uid int) (err error) ++//sys Shutdown(s int, how int) (err error) = libnetwork.shutdown ++//sys Stat(path string, stat *Stat_t) (err error) ++//sys Symlink(path string, link string) (err error) ++//sys Sync() (err error) ++//sys Truncate(path string, length int64) (err error) ++//sys Fsync(fd int) (err error) ++//sys Ftruncate(fd int, length int64) (err error) ++//sys Umask(newmask int) (oldmask int) ++//sys Unlink(path string) (err error) ++//sys Utimes(path string, times *[2]Timeval) (err error) ++//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libnetwork.bind ++//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) = libnetwork.connect ++/*//sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)*/ ++//sys munmap(addr uintptr, length uintptr) (err error) ++//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) = libnetwork.sendto ++//sys socket(domain int, typ int, proto int) (fd int, err error) = libnetwork.socket ++//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) = libnetwork.socketpair ++//sys write(fd int, p []byte) (n int, err error) ++//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) = libnetwork.getsockopt ++//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libnetwork.getpeername ++//sys getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) = libnetwork.getsockname ++//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libnetwork.setsockopt ++//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libnetwork.recvfrom ++//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = libnetwork.recvmsg ++ ++//sys Fdopendir(fd int) (dir unsafe.Pointer, err error) ++//sys Readdir_r(dir unsafe.Pointer, entry *Dirent, result **Dirent) (status int) ++//sys Closedir(dir unsafe.Pointer) (status int, err error) ++ ++func readlen(fd int, buf *byte, nbuf int) (n int, err error) { ++ r0, _, e1 := sysvicall6(procread.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func writelen(fd int, buf *byte, nbuf int) (n int, err error) { ++ r0, _, e1 := sysvicall6(procwrite.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++var mapper = &mmapper{ ++ active: make(map[*byte][]byte), ++ mmap: mmap, ++ munmap: munmap, ++} ++ ++func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { ++ return mapper.Mmap(fd, offset, length, prot, flags) ++} ++ ++func Munmap(b []byte) (err error) { ++ return mapper.Munmap(b) ++} +diff --git a/src/syscall/syscall_haiku_amd64.go b/src/syscall/syscall_haiku_amd64.go +new file mode 100644 +index 0000000..2c0cd69 +--- /dev/null ++++ b/src/syscall/syscall_haiku_amd64.go +@@ -0,0 +1,37 @@ ++// 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 = int32(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 = int32(nsec % 1e9 / 1e3) ++ tv.Sec = int32(nsec / 1e9) ++ return ++} ++ ++func (iov *Iovec) SetLen(length int) { ++ iov.Len = uint64(length) ++} ++ ++func (cmsg *Cmsghdr) SetLen(length int) { ++ cmsg.Len = uint32(length) ++} ++ ++func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { ++ // TODO(aram): implement this, see issue 5847. ++ panic("unimplemented") ++} +diff --git a/src/syscall/syscall_unix.go b/src/syscall/syscall_unix.go +index a06bd7d..0d5132e 100644 +--- a/src/syscall/syscall_unix.go ++++ b/src/syscall/syscall_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package syscall + +diff --git a/src/syscall/types_haiku.go b/src/syscall/types_haiku.go +new file mode 100644 +index 0000000..6873e5f +--- /dev/null ++++ b/src/syscall/types_haiku.go +@@ -0,0 +1,170 @@ ++// 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. ++ ++// +build ignore ++ ++/* ++Input to cgo -godefs. See also mkerrors.sh and mkall.sh ++*/ ++ ++// +godefs map struct_in_addr [4]byte /* in_addr */ ++// +godefs map struct_in6_addr [16]byte /* in6_addr */ ++ ++package syscall ++ ++/* ++#define KERNEL ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum { ++ sizeofPtr = sizeof(void*), ++}; ++ ++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_dl s5; ++}; ++ ++struct sockaddr_any { ++ struct sockaddr addr; ++ char pad[sizeof(union sockaddr_all) - sizeof(struct sockaddr)]; ++}; ++ ++*/ ++import "C" ++ ++// Machine characteristics; for internal use. ++ ++const ( ++ sizeofPtr = C.sizeofPtr ++ sizeofShort = C.sizeof_short ++ sizeofInt = C.sizeof_int ++ sizeofLong = C.sizeof_long ++ sizeofLongLong = C.sizeof_longlong ++) ++ ++// Basic types ++ ++type ( ++ _C_short C.short ++ _C_int C.int ++ _C_long C.long ++ _C_long_long C.longlong ++) ++ ++// Time ++ ++type Timespec C.struct_timespec ++ ++type Timeval C.struct_timeval ++ ++// Processes ++ ++type Rusage C.struct_rusage ++ ++type Rlimit C.struct_rlimit ++ ++type _Gid_t C.gid_t ++ ++// Files ++ ++type Stat_t C.struct_stat ++ ++type Flock_t C.struct_flock ++ ++// FIXME: haiku: Manual declaration because Dirent needs the padding ++type Dirent struct { ++ Dev int32 ++ Pdev int32 ++ Ino int64 ++ Pino int64 ++ Reclen uint16 ++ Name [1 + 256]int8 ++ Pad_cgo_0 [1]byte ++} ++ ++// Sockets ++ ++type RawSockaddrInet4 C.struct_sockaddr_in ++ ++type RawSockaddrInet6 C.struct_sockaddr_in6 ++ ++type RawSockaddrUnix C.struct_sockaddr_un ++ ++type RawSockaddrDatalink C.struct_sockaddr_dl ++ ++type RawSockaddr C.struct_sockaddr ++ ++type RawSockaddrAny C.struct_sockaddr_any ++ ++type _Socklen C.socklen_t ++ ++type Linger C.struct_linger ++ ++type Iovec C.struct_iovec ++ ++type IPMreq C.struct_ip_mreq ++ ++type IPv6Mreq C.struct_ipv6_mreq ++ ++type Msghdr C.struct_msghdr ++ ++type Cmsghdr C.struct_cmsghdr ++ ++type Inet6Pktinfo C.struct_in6_pktinfo ++ ++type ICMPv6Filter C.struct_icmp6_filter ++ ++const ( ++ SizeofSockaddrInet4 = C.sizeof_struct_sockaddr_in ++ SizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 ++ SizeofSockaddrAny = C.sizeof_struct_sockaddr_any ++ SizeofSockaddrUnix = C.sizeof_struct_sockaddr_un ++ SizeofSockaddrDatalink = C.sizeof_struct_sockaddr_dl ++ SizeofLinger = C.sizeof_struct_linger ++ SizeofIPMreq = C.sizeof_struct_ip_mreq ++ SizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq ++ SizeofMsghdr = C.sizeof_struct_msghdr ++ SizeofCmsghdr = C.sizeof_struct_cmsghdr ++ SizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo ++ SizeofICMPv6Filter = C.sizeof_struct_icmp6_filter ++) ++ ++// Select ++ ++type FdSet C.fd_set ++ ++// Terminal handling ++ ++type Termios C.struct_termios ++ ++// Fake constant needed by net package ++ ++const ( ++ F_DUPFD_CLOEXEC = 0x0200 ++) +diff --git a/src/syscall/zerrors_haiku_amd64.go b/src/syscall/zerrors_haiku_amd64.go +new file mode 100644 +index 0000000..6fd2ed2 +--- /dev/null ++++ b/src/syscall/zerrors_haiku_amd64.go +@@ -0,0 +1,640 @@ ++// mkerrors.sh -m64 ++// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT ++ ++// Created by cgo -godefs - DO NOT EDIT ++// cgo -godefs -- -m64 _const.go ++ ++package syscall ++ ++const ( ++ AF_APPLETALK = 0x2 ++ AF_BLUETOOTH = 0xa ++ AF_DLI = 0x6 ++ AF_INET = 0x1 ++ AF_INET6 = 0x5 ++ AF_IPX = 0x7 ++ AF_LINK = 0x4 ++ AF_LOCAL = 0x9 ++ AF_MAX = 0xb ++ AF_NOTIFY = 0x8 ++ AF_ROUTE = 0x3 ++ AF_UNIX = 0x9 ++ AF_UNSPEC = 0x0 ++ B0 = 0x0 ++ B110 = 0x3 ++ B115200 = 0x11 ++ B1200 = 0x9 ++ B134 = 0x4 ++ B150 = 0x5 ++ B1800 = 0xa ++ B19200 = 0xe ++ B200 = 0x6 ++ B230400 = 0x12 ++ B2400 = 0xb ++ B300 = 0x7 ++ B31250 = 0x13 ++ B38400 = 0xf ++ B4800 = 0xc ++ B50 = 0x1 ++ B57600 = 0x10 ++ B600 = 0x8 ++ B75 = 0x2 ++ B9600 = 0xd ++ BRKINT = 0x2 ++ CLOCAL = 0x800 ++ CREAD = 0x80 ++ CS5 = 0x0 ++ CS6 = 0x0 ++ CS7 = 0x0 ++ CS8 = 0x20 ++ CSIZE = 0x20 ++ CSTOPB = 0x40 ++ ECHO = 0x8 ++ ECHOCTL = 0x400 ++ ECHOE = 0x10 ++ ECHOK = 0x20 ++ ECHOKE = 0x1000 ++ ECHONL = 0x40 ++ ECHOPRT = 0x800 ++ EV_BREAK = 0x2 ++ EV_CARRIER = 0x4 ++ EV_CARRIERLOST = 0x8 ++ EV_RING = 0x1 ++ FD_CLOEXEC = 0x1 ++ FD_SETSIZE = 0x400 ++ FLUSHO = 0x2000 ++ F_DUPFD = 0x1 ++ F_GETFD = 0x2 ++ F_GETFL = 0x8 ++ F_GETLK = 0x20 ++ F_LOCK = 0x1 ++ F_OK = 0x0 ++ F_RDLCK = 0x40 ++ F_SETFD = 0x4 ++ F_SETFL = 0x10 ++ F_SETLK = 0x80 ++ F_SETLKW = 0x100 ++ F_TEST = 0x3 ++ F_TLOCK = 0x2 ++ F_ULOCK = 0x0 ++ F_UNLCK = 0x200 ++ F_WRLCK = 0x400 ++ HUPCL = 0x400 ++ ICANON = 0x2 ++ ICRNL = 0x100 ++ IEXTEN = 0x200 ++ IFF_ALLMULTI = 0x200 ++ IFF_AUTOUP = 0x80 ++ IFF_AUTO_CONFIGURED = 0x2000 ++ IFF_BROADCAST = 0x2 ++ IFF_CONFIGURING = 0x4000 ++ IFF_LINK = 0x1000 ++ IFF_LOOPBACK = 0x8 ++ IFF_MULTICAST = 0x8000 ++ IFF_NOARP = 0x40 ++ IFF_POINTOPOINT = 0x10 ++ IFF_PROMISC = 0x100 ++ IFF_SIMPLEX = 0x800 ++ IFF_UP = 0x1 ++ IFNAMSIZ = 0x20 ++ IGNBRK = 0x1 ++ IGNCR = 0x80 ++ IGNPAR = 0x4 ++ INLCR = 0x40 ++ INPCK = 0x10 ++ IN_CLASSA_HOST = 0xffffff ++ IN_CLASSA_MAX = 0x80 ++ IN_CLASSA_NET = 0xff000000 ++ IN_CLASSA_NSHIFT = 0x18 ++ IN_CLASSB_HOST = 0xffff ++ IN_CLASSB_MAX = 0x10000 ++ IN_CLASSB_NET = 0xffff0000 ++ IN_CLASSB_NSHIFT = 0x10 ++ IN_CLASSC_HOST = 0xff ++ IN_CLASSC_NET = 0xffffff00 ++ IN_CLASSC_NSHIFT = 0x8 ++ IN_CLASSD_HOST = 0xfffffff ++ IN_CLASSD_NET = 0xf0000000 ++ IN_CLASSD_NSHIFT = 0x1c ++ IN_LOOPBACKNET = 0x7f ++ IPPROTO_AH = 0x33 ++ IPPROTO_DSTOPTS = 0x3c ++ IPPROTO_ESP = 0x32 ++ IPPROTO_ETHERIP = 0x61 ++ IPPROTO_FRAGMENT = 0x2c ++ IPPROTO_HOPOPTS = 0x0 ++ IPPROTO_ICMP = 0x1 ++ IPPROTO_ICMPV6 = 0x3a ++ IPPROTO_IGMP = 0x2 ++ IPPROTO_IP = 0x0 ++ IPPROTO_IPV6 = 0x29 ++ IPPROTO_MAX = 0x100 ++ IPPROTO_NONE = 0x3b ++ IPPROTO_RAW = 0xff ++ IPPROTO_ROUTING = 0x2b ++ IPPROTO_TCP = 0x6 ++ IPPROTO_UDP = 0x11 ++ IPV6_DEFHLIM = 0x40 ++ IPV6_DSTOPTS = 0x24 ++ IPV6_FLOWINFO_MASK = 0xffffff0f ++ IPV6_FLOWLABEL_MASK = 0xffff0f00 ++ IPV6_FRAGTTL = 0x78 ++ IPV6_HLIMDEC = 0x1 ++ IPV6_HOPLIMIT = 0x21 ++ IPV6_HOPOPTS = 0x23 ++ IPV6_JOIN_GROUP = 0x1c ++ IPV6_LEAVE_GROUP = 0x1d ++ IPV6_MAXHLIM = 0xff ++ IPV6_MAXOPTHDR = 0x800 ++ IPV6_MAXPACKET = 0xffff ++ IPV6_MMTU = 0x500 ++ IPV6_MULTICAST_HOPS = 0x19 ++ IPV6_MULTICAST_IF = 0x18 ++ IPV6_MULTICAST_LOOP = 0x1a ++ IPV6_PKTINFO = 0x1f ++ IPV6_RECVHOPLIMIT = 0x22 ++ IPV6_RECVPKTINFO = 0x20 ++ IPV6_RTHDR = 0x25 ++ IPV6_UNICAST_HOPS = 0x1b ++ IPV6_V6ONLY = 0x1e ++ IPV6_VERSION = 0x60 ++ IPV6_VERSION_MASK = 0xf0 ++ IP_ADD_MEMBERSHIP = 0xc ++ IP_ADD_SOURCE_MEMBERSHIP = 0x10 ++ IP_BLOCK_SOURCE = 0xe ++ IP_DF = 0x4000 ++ IP_DROP_MEMBERSHIP = 0xd ++ IP_DROP_SOURCE_MEMBERSHIP = 0x11 ++ IP_HDRINCL = 0x2 ++ IP_MAXPACKET = 0xffff ++ IP_MAX_MEMBERSHIPS = 0x14 ++ IP_MF = 0x2000 ++ IP_MSS = 0x240 ++ IP_MULTICAST_IF = 0x9 ++ IP_MULTICAST_LOOP = 0xb ++ IP_MULTICAST_TTL = 0xa ++ IP_OFFMASK = 0x1fff ++ IP_OPTIONS = 0x1 ++ IP_RECVDSTADDR = 0x7 ++ IP_RECVOPTS = 0x5 ++ IP_RECVRETOPTS = 0x6 ++ IP_RETOPTS = 0x8 ++ IP_TOS = 0x3 ++ IP_TTL = 0x4 ++ IP_UNBLOCK_SOURCE = 0xf ++ ISIG = 0x1 ++ ISTRIP = 0x20 ++ IXANY = 0x800 ++ IXOFF = 0x1000 ++ IXON = 0x400 ++ LOCK_EX = 0x2 ++ LOCK_NB = 0x4 ++ LOCK_SH = 0x1 ++ LOCK_UN = 0x8 ++ MAP_ANON = 0x8 ++ MAP_ANONYMOUS = 0x8 ++ MAP_FIXED = 0x4 ++ MAP_PRIVATE = 0x2 ++ MAP_SHARED = 0x1 ++ MSG_BCAST = 0x100 ++ MSG_CTRUNC = 0x20 ++ MSG_DONTROUTE = 0x4 ++ MSG_DONTWAIT = 0x80 ++ MSG_EOF = 0x400 ++ MSG_EOR = 0x8 ++ MSG_MCAST = 0x200 ++ MSG_OOB = 0x1 ++ MSG_PEEK = 0x2 ++ MSG_TRUNC = 0x10 ++ MSG_WAITALL = 0x40 ++ MS_ASYNC = 0x1 ++ MS_INVALIDATE = 0x4 ++ MS_SYNC = 0x2 ++ NAME_MAX = 0x100 ++ NOFLSH = 0x80 ++ OCRNL = 0x8 ++ OFDEL = 0x80 ++ OFILL = 0x40 ++ ONLCR = 0x4 ++ ONLRET = 0x20 ++ ONOCR = 0x10 ++ OPOST = 0x1 ++ O_ACCMODE = 0x3 ++ O_APPEND = 0x800 ++ O_CLOEXEC = 0x40 ++ O_CREAT = 0x200 ++ O_DIRECT = 0x100000 ++ O_DIRECTORY = 0x200000 ++ O_DSYNC = 0x40000 ++ O_EXCL = 0x100 ++ O_NDELAY = 0x80 ++ O_NOCACHE = 0x100000 ++ O_NOCTTY = 0x1000 ++ O_NOFOLLOW = 0x80000 ++ O_NONBLOCK = 0x80 ++ O_NOTRAVERSE = 0x2000 ++ O_RDONLY = 0x0 ++ O_RDWR = 0x2 ++ O_RSYNC = 0x20000 ++ O_RWMASK = 0x3 ++ O_SYNC = 0x10000 ++ O_TRUNC = 0x400 ++ O_WRONLY = 0x1 ++ PARENB = 0x100 ++ PARMRK = 0x8 ++ PARODD = 0x200 ++ PENDIN = 0x4000 ++ PRIO_PGRP = 0x1 ++ PRIO_PROCESS = 0x0 ++ PRIO_USER = 0x2 ++ PROT_EXEC = 0x4 ++ PROT_NONE = 0x0 ++ PROT_READ = 0x1 ++ PROT_WRITE = 0x2 ++ RLIMIT_AS = 0x6 ++ RLIMIT_CORE = 0x0 ++ RLIMIT_CPU = 0x1 ++ RLIMIT_DATA = 0x2 ++ RLIMIT_FSIZE = 0x3 ++ RLIMIT_NOFILE = 0x4 ++ RLIMIT_STACK = 0x5 ++ RLIM_INFINITY = 0xffffffff ++ RTF_BLACKHOLE = 0x1000 ++ RTF_DEFAULT = 0x80 ++ RTF_DYNAMIC = 0x10 ++ RTF_GATEWAY = 0x2 ++ RTF_HOST = 0x4 ++ RTF_LOCAL = 0x200000 ++ RTF_MODIFIED = 0x20 ++ RTF_REJECT = 0x8 ++ RTF_STATIC = 0x800 ++ RTF_UP = 0x1 ++ RUSAGE_CHILDREN = -0x1 ++ RUSAGE_SELF = 0x0 ++ SCM_RIGHTS = 0x1 ++ SHUT_RD = 0x0 ++ SHUT_RDWR = 0x2 ++ SHUT_WR = 0x1 ++ SOCK_DGRAM = 0x2 ++ SOCK_MISC = 0xff ++ SOCK_RAW = 0x3 ++ SOCK_SEQPACKET = 0x5 ++ SOCK_STREAM = 0x1 ++ SOL_SOCKET = -0x1 ++ SOMAXCONN = 0x20 ++ SO_ACCEPTCONN = 0x1 ++ SO_BINDTODEVICE = 0x4000000a ++ SO_BROADCAST = 0x2 ++ SO_DEBUG = 0x4 ++ SO_DONTROUTE = 0x8 ++ SO_ERROR = 0x40000007 ++ SO_KEEPALIVE = 0x10 ++ SO_LINGER = 0x200 ++ SO_NONBLOCK = 0x40000009 ++ SO_OOBINLINE = 0x20 ++ SO_PEERCRED = 0x4000000b ++ SO_RCVBUF = 0x40000004 ++ SO_RCVLOWAT = 0x40000005 ++ SO_RCVTIMEO = 0x40000006 ++ SO_REUSEADDR = 0x40 ++ SO_REUSEPORT = 0x80 ++ SO_SNDBUF = 0x40000001 ++ SO_SNDLOWAT = 0x40000002 ++ SO_SNDTIMEO = 0x40000003 ++ SO_TYPE = 0x40000008 ++ SO_USELOOPBACK = 0x100 ++ S_ALLOW_DUPS = 0x80000 ++ S_ATTR = 0x10000000 ++ S_ATTR_DIR = 0x8000000 ++ S_DOUBLE_INDEX = 0x40000 ++ S_FLOAT_INDEX = 0x800000 ++ S_IEXEC = 0x40 ++ S_IFBLK = 0x6000 ++ S_IFCHR = 0x2000 ++ S_IFDIR = 0x4000 ++ S_IFIFO = 0x1000 ++ S_IFLNK = 0xa000 ++ S_IFMT = 0xf000 ++ S_IFREG = 0x8000 ++ S_IFSOCK = 0xc000 ++ S_INDEX_DIR = 0x20000000 ++ S_INT_INDEX = 0x2000000 ++ S_IREAD = 0x100 ++ S_IRGRP = 0x20 ++ S_IROTH = 0x4 ++ S_IRUSR = 0x100 ++ S_IRWXG = 0x38 ++ S_IRWXO = 0x7 ++ S_IRWXU = 0x1c0 ++ S_ISGID = 0x400 ++ S_ISUID = 0x800 ++ S_ISVTX = 0x200 ++ S_IUMSK = 0xfff ++ S_IWGRP = 0x10 ++ S_IWOTH = 0x2 ++ S_IWRITE = 0x80 ++ S_IWUSR = 0x80 ++ S_IXGRP = 0x8 ++ S_IXOTH = 0x1 ++ S_IXUSR = 0x40 ++ S_LINK_AUTO_DELETE = 0x80000 ++ S_LINK_SELF_HEALING = 0x40000 ++ S_LONG_LONG_INDEX = 0x200000 ++ S_STR_INDEX = 0x1000000 ++ S_UINT_INDEX = 0x4000000 ++ S_ULONG_LONG_INDEX = 0x400000 ++ TCFLSH = 0x8006 ++ TCIFLUSH = 0x1 ++ TCIOFLUSH = 0x3 ++ TCOFLUSH = 0x2 ++ TCP_MAXSEG = 0x2 ++ TCP_NODELAY = 0x1 ++ TCP_NOOPT = 0x8 ++ TCP_NOPUSH = 0x4 ++ TCSAFLUSH = 0x4 ++ TIOCCBRK = 0x8015 ++ TIOCGPGRP = 0x800f ++ TIOCGWINSZ = 0x800c ++ TIOCMGET = 0x8012 ++ TIOCMSET = 0x8013 ++ TIOCM_CD = 0x8 ++ TIOCM_CTS = 0x1 ++ TIOCM_DSR = 0x2 ++ TIOCM_DTR = 0x10 ++ TIOCM_RI = 0x4 ++ TIOCM_RTS = 0x20 ++ TIOCSBRK = 0x8014 ++ TIOCSCTTY = 0x8011 ++ TIOCSPGRP = 0x8010 ++ TIOCSWINSZ = 0x800d ++ TOSTOP = 0x100 ++ VEOF = 0x4 ++ VEOL = 0x5 ++ VEOL2 = 0x6 ++ VERASE = 0x2 ++ VINTR = 0x0 ++ VKILL = 0x3 ++ VMIN = 0x4 ++ VQUIT = 0x1 ++ VSTART = 0x8 ++ VSTOP = 0x9 ++ VSUSP = 0xa ++ VSWTCH = 0x7 ++ VT0 = 0x0 ++ VT1 = 0x4000 ++ VTDLY = 0x4000 ++ VTIME = 0x5 ++) ++ ++// Errors ++const ( ++ E2BIG = Errno(-0x7fff8fff & 0xffffffff) ++ EACCES = Errno(-0x7ffffffe & 0xffffffff) ++ EADDRINUSE = Errno(-0x7fff8fea & 0xffffffff) ++ EADDRNOTAVAIL = Errno(-0x7fff8fe9 & 0xffffffff) ++ EAFNOSUPPORT = Errno(-0x7fff8feb & 0xffffffff) ++ EAGAIN = Errno(-0x7ffffff5 & 0xffffffff) ++ EALREADY = Errno(-0x7fff8fdb & 0xffffffff) ++ EBADF = Errno(-0x7fffa000 & 0xffffffff) ++ EBADMSG = Errno(-0x7fff8fd2 & 0xffffffff) ++ EBUSY = Errno(-0x7ffffff2 & 0xffffffff) ++ ECANCELED = Errno(-0x7fff8fd1 & 0xffffffff) ++ ECHILD = Errno(-0x7fff8ffe & 0xffffffff) ++ ECONNABORTED = Errno(-0x7fff8fe5 & 0xffffffff) ++ ECONNREFUSED = Errno(-0x7fff8fe0 & 0xffffffff) ++ ECONNRESET = Errno(-0x7fff8fe4 & 0xffffffff) ++ EDEADLK = Errno(-0x7fff8ffd & 0xffffffff) ++ EDESTADDRREQ = Errno(-0x7fff8fd0 & 0xffffffff) ++ EDOM = Errno(-0x7fff8ff0 & 0xffffffff) ++ EDOOFUS = Errno(-0x7ffffffb & 0xffffffff) ++ EDQUOT = Errno(-0x7fff8fcf & 0xffffffff) ++ EEXIST = Errno(-0x7fff9ffe & 0xffffffff) ++ EFAULT = Errno(-0x7fffecff & 0xffffffff) ++ EFBIG = Errno(-0x7fff8ffc & 0xffffffff) ++ EFPOS = Errno(-0x7fff8ff2 & 0xffffffff) ++ EHOSTDOWN = Errno(-0x7fff8fd3 & 0xffffffff) ++ EHOSTUNREACH = Errno(-0x7fff8fdf & 0xffffffff) ++ EIDRM = Errno(-0x7fff8fce & 0xffffffff) ++ EILSEQ = Errno(-0x7fff8fda & 0xffffffff) ++ EINPROGRESS = Errno(-0x7fff8fdc & 0xffffffff) ++ EINTR = Errno(-0x7ffffff6 & 0xffffffff) ++ EINVAL = Errno(-0x7ffffffb & 0xffffffff) ++ EIO = Errno(-0x7fffffff & 0xffffffff) ++ EISCONN = Errno(-0x7fff8fe3 & 0xffffffff) ++ EISDIR = Errno(-0x7fff9ff7 & 0xffffffff) ++ ELOOP = Errno(-0x7fff9ff4 & 0xffffffff) ++ EMFILE = Errno(-0x7fff9ff6 & 0xffffffff) ++ EMLINK = Errno(-0x7fff8ffb & 0xffffffff) ++ EMSGSIZE = Errno(-0x7fff8fd6 & 0xffffffff) ++ EMULTIHOP = Errno(-0x7fff8fcd & 0xffffffff) ++ ENAMETOOLONG = Errno(-0x7fff9ffc & 0xffffffff) ++ ENETDOWN = Errno(-0x7fff8fe8 & 0xffffffff) ++ ENETRESET = Errno(-0x7fff8fe6 & 0xffffffff) ++ ENETUNREACH = Errno(-0x7fff8fe7 & 0xffffffff) ++ ENFILE = Errno(-0x7fff8ffa & 0xffffffff) ++ ENOATTR = Errno(-0x7fff8fc4 & 0xffffffff) ++ ENOBUFS = Errno(-0x7fff8fdd & 0xffffffff) ++ ENODATA = Errno(-0x7fff8fcc & 0xffffffff) ++ ENODEV = Errno(-0x7fff8ff9 & 0xffffffff) ++ ENOENT = Errno(-0x7fff9ffd & 0xffffffff) ++ ENOERR = Errno(0x0 & 0xffffffff) ++ ENOEXEC = Errno(-0x7fffecfe & 0xffffffff) ++ ENOLCK = Errno(-0x7fff8ff8 & 0xffffffff) ++ ENOLINK = Errno(-0x7fff8fcb & 0xffffffff) ++ ENOMEM = Errno(-0x80000000 & 0xffffffff) ++ ENOMSG = Errno(-0x7fff8fd9 & 0xffffffff) ++ ENOPROTOOPT = Errno(-0x7fff8fde & 0xffffffff) ++ ENOSPC = Errno(-0x7fff9ff9 & 0xffffffff) ++ ENOSR = Errno(-0x7fff8fca & 0xffffffff) ++ ENOSTR = Errno(-0x7fff8fc9 & 0xffffffff) ++ ENOSYS = Errno(-0x7fff8ff7 & 0xffffffff) ++ ENOTCONN = Errno(-0x7fff8fe2 & 0xffffffff) ++ ENOTDIR = Errno(-0x7fff9ffb & 0xffffffff) ++ ENOTEMPTY = Errno(-0x7fff9ffa & 0xffffffff) ++ ENOTSOCK = Errno(-0x7fff8fd4 & 0xffffffff) ++ ENOTSUP = Errno(-0x7fff8fc8 & 0xffffffff) ++ ENOTTY = Errno(-0x7fff8ff6 & 0xffffffff) ++ ENXIO = Errno(-0x7fff8ff5 & 0xffffffff) ++ EOK = Errno(0x0 & 0xffffffff) ++ EOPNOTSUPP = Errno(-0x7fff8fd5 & 0xffffffff) ++ EOVERFLOW = Errno(-0x7fff8fd7 & 0xffffffff) ++ EPERM = Errno(-0x7ffffff1 & 0xffffffff) ++ EPFNOSUPPORT = Errno(-0x7fff8fec & 0xffffffff) ++ EPIPE = Errno(-0x7fff9ff3 & 0xffffffff) ++ EPROTO = Errno(-0x7fff8fc7 & 0xffffffff) ++ EPROTONOSUPPORT = Errno(-0x7fff8fed & 0xffffffff) ++ EPROTOTYPE = Errno(-0x7fff8fee & 0xffffffff) ++ ERANGE = Errno(-0x7fff8fef & 0xffffffff) ++ EROFS = Errno(-0x7fff9ff8 & 0xffffffff) ++ ESHUTDOWN = Errno(-0x7fff8fe1 & 0xffffffff) ++ ESIGPARM = Errno(-0x7fff8ff1 & 0xffffffff) ++ ESPIPE = Errno(-0x7fff8ff4 & 0xffffffff) ++ ESRCH = Errno(-0x7fff8ff3 & 0xffffffff) ++ ESTALE = Errno(-0x7fff8fd8 & 0xffffffff) ++ ETIME = Errno(-0x7fff8fc6 & 0xffffffff) ++ ETIMEDOUT = Errno(-0x7ffffff7 & 0xffffffff) ++ ETXTBSY = Errno(-0x7fff8fc5 & 0xffffffff) ++ EWOULDBLOCK = Errno(-0x7ffffff5 & 0xffffffff) ++ EXDEV = Errno(-0x7fff9ff5 & 0xffffffff) ++) ++ ++// Signals ++const ( ++ SIGABRT = Signal(0x6) ++ SIGALRM = Signal(0xe) ++ SIGBUS = Signal(0x1e) ++ SIGCHLD = Signal(0x5) ++ SIGCONT = Signal(0xc) ++ SIGFPE = Signal(0x8) ++ SIGHUP = Signal(0x1) ++ SIGILL = Signal(0x4) ++ SIGINT = Signal(0x2) ++ SIGKILL = Signal(0x9) ++ SIGKILLTHR = Signal(0x15) ++ SIGPIPE = Signal(0x7) ++ SIGPOLL = Signal(0x17) ++ SIGPROF = Signal(0x18) ++ SIGQUIT = Signal(0x3) ++ SIGRESERVED1 = Signal(0x1f) ++ SIGRESERVED2 = Signal(0x20) ++ SIGSEGV = Signal(0xb) ++ SIGSTOP = Signal(0xa) ++ SIGSYS = Signal(0x19) ++ SIGTERM = Signal(0xf) ++ SIGTRAP = Signal(0x16) ++ SIGTSTP = Signal(0xd) ++ SIGTTIN = Signal(0x10) ++ SIGTTOU = Signal(0x11) ++ SIGURG = Signal(0x1a) ++ SIGUSR1 = Signal(0x12) ++ SIGUSR2 = Signal(0x13) ++ SIGVTALRM = Signal(0x1b) ++ SIGWINCH = Signal(0x14) ++ SIGXCPU = Signal(0x1c) ++ SIGXFSZ = Signal(0x1d) ++) ++ ++// Error table ++var errors = [...]string{ ++ 1: "out of memory", ++ 2: "I/O error", ++ 3: "permission denied", ++ 6: "invalid Argument", ++ 10: "operation timed out", ++ 11: "interrupted system call", ++ 12: "operation would block", ++ 15: "device/File/Resource busy", ++ 16: "operation not allowed", ++ 4866: "bad address", ++ 4867: "not an executable", ++ 24577: "bad file descriptor", ++ 24579: "file or Directory already exists", ++ 24580: "no such file or directory", ++ 24581: "file name too long", ++ 24582: "not a directory", ++ 24583: "directory not empty", ++ 24584: "no space left on device", ++ 24585: "read-only file system", ++ 24586: "is a directory", ++ 24587: "too many open files", ++ 24588: "cross-device link", ++ 24589: "too many symbolic links", ++ 24590: "broken pipe", ++ 28674: "argument too big", ++ 28675: "no child process", ++ 28676: "resource deadlock", ++ 28677: "file too large", ++ 28678: "too many links", ++ 28679: "file table overflow", ++ 28680: "no such device", ++ 28681: "no record locks available", ++ 28682: "function not implemented", ++ 28683: "not a tty", ++ 28684: "device not accessible", ++ 28685: "seek not allowed on file descriptor", ++ 28686: "no such process", ++ 28687: "file Position Error", ++ 28688: "signal Error", ++ 28689: "numerical argument out of range", ++ 28690: "range Error", ++ 28691: "protocol wrong type for socket", ++ 28692: "protocol not supported", ++ 28693: "protocol family not supported", ++ 28694: "address family not supported by protocol family", ++ 28695: "address already in use", ++ 28696: "can't assign requested address", ++ 28697: "network is down", ++ 28698: "network is unreachable", ++ 28699: "network dropped connection on reset", ++ 28700: "software caused connection abort", ++ 28701: "connection reset by peer", ++ 28702: "socket is already connected", ++ 28703: "socket is not connected", ++ 28704: "can't send after socket shutdown", ++ 28705: "connection refused", ++ 28706: "no route to host", ++ 28707: "protocol option not available", ++ 28708: "no buffer space available", ++ 28709: "operation now in progress", ++ 28710: "operation already in progress", ++ 28711: "illegal byte sequence", ++ 28712: "no message of desired type", ++ 28713: "stale file handle", ++ 28714: "value too large for defined type", ++ 28715: "message too long", ++ 28716: "operation not supported", ++ 28717: "socket operation on non-socket", ++ 28718: "unknown POSIX Error (-2147454931)", ++ 28719: "bad message", ++ 28720: "operation canceled", ++ 28721: "destination address required", ++ 28722: "reserved", ++ 28723: "identifier removed", ++ 28724: "reserved", ++ 28725: "no message available", ++ 28726: "reserved", ++ 28727: "no STREAM resources", ++ 28728: "not a STREAM", ++ 28729: "not supported", ++ 28730: "protocol error", ++ 28731: "STREAM ioctl() timeout", ++ 28732: "text file busy", ++ 28733: "no such attribute", ++ 0: "no error", ++} ++ ++// Signal table ++var signals = [...]string{ ++ 1: "hangup", ++ 2: "interrupt", ++ 3: "quit", ++ 4: "illegal instruction", ++ 5: "child exited", ++ 6: "abort", ++ 7: "broken pipe", ++ 8: "floating point exception", ++ 9: "killed (by death)", ++ 10: "stopped", ++ 11: "segmentation violation", ++ 12: "continued", ++ 13: "stopped (tty output)", ++ 14: "alarm", ++ 15: "termination requested", ++ 16: "stopped (tty input)", ++ 17: "stopped (tty output)", ++ 18: "user defined signal 1", ++ 19: "user defined signal 2", ++ 20: "window size changed", ++ 21: "kill Thread", ++ 22: "trace/breakpoint trap", ++ 23: "pollable event", ++ 24: "profiling timer expired", ++ 25: "bad system call", ++ 26: "high bandwidth data is available at socket", ++ 27: "virtual timer expired", ++ 28: "CPU time limit exceeded", ++ 29: "file size limit exceeded", ++ 30: "bus error", ++ 31: "reserved signal 1", ++ 32: "reserved signal 2", ++} +diff --git a/src/syscall/zsyscall_haiku_amd64.go b/src/syscall/zsyscall_haiku_amd64.go +new file mode 100644 +index 0000000..6f886c7 +--- /dev/null ++++ b/src/syscall/zsyscall_haiku_amd64.go +@@ -0,0 +1,937 @@ ++// mksyscall_haiku.pl -modname libroot syscall_haiku.go ++// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT ++ ++package syscall ++ ++import "unsafe" ++ ++var ( ++ modlibroot = newLazySO("libroot.so") ++ modlibnetwork = newLazySO("libnetwork.so") ++ //modlibbsd = newLazySO("libbsd.so") ++ ++ procpipe = modlibroot.NewProc("pipe") ++ procgetgroups = modlibroot.NewProc("getgroups") ++ procsetgroups = modlibroot.NewProc("setgroups") ++ //procwait4 = modlibbsd.NewProc("wait4") ++ procwaitpid = modlibroot.NewProc("waitpid") ++ procfcntl = modlibroot.NewProc("fcntl") ++ procaccept = modlibnetwork.NewProc("accept") ++ procsendmsg = modlibnetwork.NewProc("sendmsg") ++ procAccess = modlibroot.NewProc("access") ++ procAdjtime = modlibroot.NewProc("adjtime") ++ procChdir = modlibroot.NewProc("chdir") ++ procChmod = modlibroot.NewProc("chmod") ++ procChown = modlibroot.NewProc("chown") ++ procChroot = modlibroot.NewProc("chroot") ++ procClose = modlibroot.NewProc("close") ++ procDup = modlibroot.NewProc("dup") ++ procExit = modlibroot.NewProc("exit") ++ procFchdir = modlibroot.NewProc("fchdir") ++ procFchmod = modlibroot.NewProc("fchmod") ++ procFchown = modlibroot.NewProc("fchown") ++ procFpathconf = modlibroot.NewProc("fpathconf") ++ procFstat = modlibroot.NewProc("fstat") ++ procGetgid = modlibroot.NewProc("getgid") ++ procGetpid = modlibroot.NewProc("getpid") ++ procGeteuid = modlibroot.NewProc("geteuid") ++ procGetegid = modlibroot.NewProc("getegid") ++ procGetppid = modlibroot.NewProc("getppid") ++ procGetpriority = modlibroot.NewProc("getpriority") ++ procGetrlimit = modlibroot.NewProc("getrlimit") ++ procGettimeofday = modlibroot.NewProc("gettimeofday") ++ procGetuid = modlibroot.NewProc("getuid") ++ procKill = modlibroot.NewProc("kill") ++ procLchown = modlibroot.NewProc("lchown") ++ procLink = modlibroot.NewProc("link") ++ proclisten = modlibnetwork.NewProc("listen") ++ procLstat = modlibroot.NewProc("lstat") ++ procMkdir = modlibroot.NewProc("mkdir") ++ procMknod = modlibroot.NewProc("mknod") ++ procNanosleep = modlibroot.NewProc("nanosleep") ++ procOpen = modlibroot.NewProc("open") ++ procPathconf = modlibroot.NewProc("pathconf") ++ procPread = modlibroot.NewProc("pread") ++ procPwrite = modlibroot.NewProc("pwrite") ++ procread = modlibroot.NewProc("read") ++ procReadlink = modlibroot.NewProc("readlink") ++ procRename = modlibroot.NewProc("rename") ++ procRmdir = modlibroot.NewProc("rmdir") ++ proclseek = modlibroot.NewProc("lseek") ++ procSetegid = modlibroot.NewProc("setegid") ++ procSeteuid = modlibroot.NewProc("seteuid") ++ procSetgid = modlibroot.NewProc("setgid") ++ procSetpgid = modlibroot.NewProc("setpgid") ++ procSetpriority = modlibroot.NewProc("setpriority") ++ procSetregid = modlibroot.NewProc("setregid") ++ procSetreuid = modlibroot.NewProc("setreuid") ++ procSetrlimit = modlibroot.NewProc("setrlimit") ++ procSetsid = modlibroot.NewProc("setsid") ++ procSetuid = modlibroot.NewProc("setuid") ++ procshutdown = modlibnetwork.NewProc("shutdown") ++ procStat = modlibroot.NewProc("stat") ++ procSymlink = modlibroot.NewProc("symlink") ++ procSync = modlibroot.NewProc("sync") ++ procTruncate = modlibroot.NewProc("truncate") ++ procFsync = modlibroot.NewProc("fsync") ++ procFtruncate = modlibroot.NewProc("ftruncate") ++ procUmask = modlibroot.NewProc("umask") ++ procUnlink = modlibroot.NewProc("unlink") ++ procUtimes = modlibroot.NewProc("utimes") ++ procbind = modlibnetwork.NewProc("bind") ++ procconnect = modlibnetwork.NewProc("connect") ++ procmunmap = modlibroot.NewProc("munmap") ++ procsendto = modlibnetwork.NewProc("sendto") ++ procsocket = modlibnetwork.NewProc("socket") ++ procsocketpair = modlibnetwork.NewProc("socketpair") ++ procwrite = modlibroot.NewProc("write") ++ procgetsockopt = modlibnetwork.NewProc("getsockopt") ++ procgetpeername = modlibnetwork.NewProc("getpeername") ++ procgetsockname = modlibnetwork.NewProc("getsockname") ++ procsetsockopt = modlibnetwork.NewProc("setsockopt") ++ procrecvfrom = modlibnetwork.NewProc("recvfrom") ++ procrecvmsg = modlibnetwork.NewProc("recvmsg") ++ procFdopendir = modlibroot.NewProc("fdopendir") ++ procReaddir_r = modlibroot.NewProc("readdir_r") ++ procClosedir = modlibroot.NewProc("closedir") ++ ++) ++ ++func pipe2(fds []int) (err error) { ++ var _p0 *int ++ if len(fds) > 0 { ++ _p0 = &fds[0] ++ } ++ _, _, e1 := sysvicall6(procpipe.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(fds)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func getgroups(ngid int, gid *_Gid_t) (n int, err error) { ++ r0, _, e1 := rawSysvicall6(procgetgroups.Addr(), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func setgroups(ngid int, gid *_Gid_t) (err error) { ++ _, _, e1 := rawSysvicall6(procsetgroups.Addr(), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func wait4(pid uintptr, wstatus *WaitStatus, options uintptr, rusage *Rusage) (wpid int, err error) { ++ r0, _, e1 := sysvicall6(procwaitpid.Addr(), 3, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) ++ wpid = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func fcntl(fd int, cmd int, arg int) (val int, err error) { ++ r0, _, e1 := sysvicall6(procfcntl.Addr(), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0) ++ val = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { ++ r0, _, e1 := sysvicall6(procaccept.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { ++ r0, _, e1 := sysvicall6(procsendmsg.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Access(path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procAccess.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { ++ _, _, e1 := sysvicall6(procAdjtime.Addr(), 2, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Chdir(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procChdir.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Chmod(path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procChmod.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Chown(path string, uid int, gid int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procChown.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Chroot(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procChroot.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Close(fd int) (err error) { ++ _, _, e1 := sysvicall6(procClose.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Dup(fd int) (nfd int, err error) { ++ r0, _, e1 := sysvicall6(procDup.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0) ++ nfd = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Exit(code int) { ++ sysvicall6(procExit.Addr(), 1, uintptr(code), 0, 0, 0, 0, 0) ++ return ++} ++ ++func Fchdir(fd int) (err error) { ++ _, _, e1 := sysvicall6(procFchdir.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Fchmod(fd int, mode uint32) (err error) { ++ _, _, e1 := sysvicall6(procFchmod.Addr(), 2, uintptr(fd), uintptr(mode), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Fchown(fd int, uid int, gid int) (err error) { ++ _, _, e1 := sysvicall6(procFchown.Addr(), 3, uintptr(fd), uintptr(uid), uintptr(gid), 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Fpathconf(fd int, name int) (val int, err error) { ++ r0, _, e1 := sysvicall6(procFpathconf.Addr(), 2, uintptr(fd), uintptr(name), 0, 0, 0, 0) ++ val = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Fstat(fd int, stat *Stat_t) (err error) { ++ _, _, e1 := sysvicall6(procFstat.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Getgid() (gid int) { ++ r0, _, _ := rawSysvicall6(procGetgid.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ gid = int(r0) ++ return ++} ++ ++func Getpid() (pid int) { ++ r0, _, _ := rawSysvicall6(procGetpid.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ pid = int(r0) ++ return ++} ++ ++func Geteuid() (euid int) { ++ r0, _, _ := sysvicall6(procGeteuid.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ euid = int(r0) ++ return ++} ++ ++func Getegid() (egid int) { ++ r0, _, _ := sysvicall6(procGetegid.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ egid = int(r0) ++ return ++} ++ ++func Getppid() (ppid int) { ++ r0, _, _ := sysvicall6(procGetppid.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ ppid = int(r0) ++ return ++} ++ ++func Getpriority(which int, who int) (n int, err error) { ++ r0, _, e1 := sysvicall6(procGetpriority.Addr(), 2, uintptr(which), uintptr(who), 0, 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Getrlimit(which int, lim *Rlimit) (err error) { ++ _, _, e1 := rawSysvicall6(procGetrlimit.Addr(), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Gettimeofday(tv *Timeval) (err error) { ++ _, _, e1 := rawSysvicall6(procGettimeofday.Addr(), 1, uintptr(unsafe.Pointer(tv)), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Getuid() (uid int) { ++ r0, _, _ := rawSysvicall6(procGetuid.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ uid = int(r0) ++ return ++} ++ ++func Kill(pid int, signum Signal) (err error) { ++ _, _, e1 := sysvicall6(procKill.Addr(), 2, uintptr(pid), uintptr(signum), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Lchown(path string, uid int, gid int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procLchown.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Link(path string, link string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(link) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procLink.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ use(unsafe.Pointer(_p1)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Listen(s int, backlog int) (err error) { ++ _, _, e1 := sysvicall6(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Lstat(path string, stat *Stat_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procLstat.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Mkdir(path string, mode uint32) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procMkdir.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Mknod(path string, mode uint32, dev int) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procMknod.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Nanosleep(time *Timespec, leftover *Timespec) (err error) { ++ _, _, e1 := sysvicall6(procNanosleep.Addr(), 2, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Open(path string, mode int, perm uint32) (fd int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := sysvicall6(procOpen.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ fd = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Pathconf(path string, name int) (val int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ r0, _, e1 := sysvicall6(procPathconf.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ val = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Pread(fd int, p []byte, offset int64) (n int, err error) { ++ var _p0 *byte ++ if len(p) > 0 { ++ _p0 = &p[0] ++ } ++ r0, _, e1 := sysvicall6(procPread.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Pwrite(fd int, p []byte, offset int64) (n int, err error) { ++ var _p0 *byte ++ if len(p) > 0 { ++ _p0 = &p[0] ++ } ++ r0, _, e1 := sysvicall6(procPwrite.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func read(fd int, p []byte) (n int, err error) { ++ var _p0 *byte ++ if len(p) > 0 { ++ _p0 = &p[0] ++ } ++ r0, _, e1 := sysvicall6(procread.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Readlink(path string, buf []byte) (n int, err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ if len(buf) > 0 { ++ _p1 = &buf[0] ++ } ++ r0, _, e1 := sysvicall6(procReadlink.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(len(buf)), 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Rename(from string, to string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(from) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(to) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procRename.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ use(unsafe.Pointer(_p1)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Rmdir(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procRmdir.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { ++ r0, _, e1 := sysvicall6(proclseek.Addr(), 3, uintptr(fd), uintptr(offset), uintptr(whence), 0, 0, 0) ++ newoffset = int64(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setegid(egid int) (err error) { ++ _, _, e1 := rawSysvicall6(procSetegid.Addr(), 1, uintptr(egid), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Seteuid(euid int) (err error) { ++ _, _, e1 := rawSysvicall6(procSeteuid.Addr(), 1, uintptr(euid), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setgid(gid int) (err error) { ++ _, _, e1 := rawSysvicall6(procSetgid.Addr(), 1, uintptr(gid), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setpgid(pid int, pgid int) (err error) { ++ _, _, e1 := rawSysvicall6(procSetpgid.Addr(), 2, uintptr(pid), uintptr(pgid), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setpriority(which int, who int, prio int) (err error) { ++ _, _, e1 := sysvicall6(procSetpriority.Addr(), 3, uintptr(which), uintptr(who), uintptr(prio), 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setregid(rgid int, egid int) (err error) { ++ _, _, e1 := rawSysvicall6(procSetregid.Addr(), 2, uintptr(rgid), uintptr(egid), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setreuid(ruid int, euid int) (err error) { ++ _, _, e1 := rawSysvicall6(procSetreuid.Addr(), 2, uintptr(ruid), uintptr(euid), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setrlimit(which int, lim *Rlimit) (err error) { ++ _, _, e1 := rawSysvicall6(procSetrlimit.Addr(), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setsid() (pid int, err error) { ++ r0, _, e1 := rawSysvicall6(procSetsid.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ pid = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Setuid(uid int) (err error) { ++ _, _, e1 := rawSysvicall6(procSetuid.Addr(), 1, uintptr(uid), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Shutdown(s int, how int) (err error) { ++ _, _, e1 := sysvicall6(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Stat(path string, stat *Stat_t) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procStat.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Symlink(path string, link string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ var _p1 *byte ++ _p1, err = BytePtrFromString(link) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procSymlink.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ use(unsafe.Pointer(_p1)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Sync() (err error) { ++ _, _, e1 := sysvicall6(procSync.Addr(), 0, 0, 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Truncate(path string, length int64) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procTruncate.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Fsync(fd int) (err error) { ++ _, _, e1 := sysvicall6(procFsync.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Ftruncate(fd int, length int64) (err error) { ++ _, _, e1 := sysvicall6(procFtruncate.Addr(), 2, uintptr(fd), uintptr(length), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Umask(newmask int) (oldmask int) { ++ r0, _, _ := sysvicall6(procUmask.Addr(), 1, uintptr(newmask), 0, 0, 0, 0, 0) ++ oldmask = int(r0) ++ return ++} ++ ++func Unlink(path string) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procUnlink.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Utimes(path string, times *[2]Timeval) (err error) { ++ var _p0 *byte ++ _p0, err = BytePtrFromString(path) ++ if err != nil { ++ return ++ } ++ _, _, e1 := sysvicall6(procUtimes.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0, 0, 0, 0) ++ use(unsafe.Pointer(_p0)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { ++ _, _, e1 := sysvicall6(procbind.Addr(), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { ++ _, _, e1 := sysvicall6(procconnect.Addr(), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func munmap(addr uintptr, length uintptr) (err error) { ++ _, _, e1 := sysvicall6(procmunmap.Addr(), 2, uintptr(addr), uintptr(length), 0, 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { ++ var _p0 *byte ++ if len(buf) > 0 { ++ _p0 = &buf[0] ++ } ++ _, _, e1 := sysvicall6(procsendto.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func socket(domain int, typ int, proto int) (fd int, err error) { ++ r0, _, e1 := sysvicall6(procsocket.Addr(), 3, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0) ++ fd = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { ++ _, _, e1 := rawSysvicall6(procsocketpair.Addr(), 4, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func write(fd int, p []byte) (n int, err error) { ++ var _p0 *byte ++ if len(p) > 0 { ++ _p0 = &p[0] ++ } ++ r0, _, e1 := sysvicall6(procwrite.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { ++ _, _, e1 := sysvicall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { ++ _, _, e1 := rawSysvicall6(procgetpeername.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { ++ _, _, e1 := sysvicall6(procgetsockname.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { ++ _, _, e1 := sysvicall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { ++ var _p0 *byte ++ if len(p) > 0 { ++ _p0 = &p[0] ++ } ++ r0, _, e1 := sysvicall6(procrecvfrom.Addr(), 6, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { ++ r0, _, e1 := sysvicall6(procrecvmsg.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) ++ n = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Fdopendir(fd int) (dir unsafe.Pointer, err error) { ++ r0, _, e1 := sysvicall6(procFdopendir.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0) ++ dir = unsafe.Pointer(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++func Readdir_r(dir unsafe.Pointer, entry *Dirent, result **Dirent) (status int) { ++ r0, _, _ := sysvicall6(procReaddir_r.Addr(), 3, uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)), 0, 0, 0) ++ status = int(r0) ++ return ++} ++ ++func Closedir(dir unsafe.Pointer) (status int, err error) { ++ r0, _, e1 := sysvicall6(procClosedir.Addr(), 1, uintptr(dir), 0, 0, 0, 0, 0) ++ status = int(r0) ++ if e1 != 0 { ++ err = e1 ++ } ++ return ++} ++ ++ +diff --git a/src/syscall/zsysnum_haiku_amd64.go b/src/syscall/zsysnum_haiku_amd64.go +new file mode 100644 +index 0000000..43b3d8b +--- /dev/null ++++ b/src/syscall/zsysnum_haiku_amd64.go +@@ -0,0 +1,11 @@ ++// Copyright 2014 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 ++ ++// TODO(aram): remove these before Go 1.3. ++const ( ++ SYS_EXECVE = 59 ++ SYS_FCNTL = 62 ++) +diff --git a/src/syscall/ztypes_haiku_amd64.go b/src/syscall/ztypes_haiku_amd64.go +new file mode 100644 +index 0000000..1cec69a +--- /dev/null ++++ b/src/syscall/ztypes_haiku_amd64.go +@@ -0,0 +1,217 @@ ++// Created by cgo -godefs - DO NOT EDIT ++// cgo -godefs types_haiku.go ++ ++package syscall ++ ++const ( ++ sizeofPtr = 0x8 ++ sizeofShort = 0x2 ++ sizeofInt = 0x4 ++ sizeofLong = 0x8 ++ sizeofLongLong = 0x8 ++) ++ ++type ( ++ _C_short int16 ++ _C_int int32 ++ _C_long int64 ++ _C_long_long int64 ++) ++ ++type Timespec struct { ++ Sec int32 ++ Pad_cgo_0 [4]byte ++ Nsec int64 ++} ++ ++type Timeval struct { ++ Sec int32 ++ Usec int32 ++} ++ ++type Rusage struct { ++ Utime Timeval ++ Stime Timeval ++} ++ ++type Rlimit struct { ++ Cur uint64 ++ Max uint64 ++} ++ ++type _Gid_t uint32 ++ ++type Stat_t struct { ++ Dev int32 ++ Pad_cgo_0 [4]byte ++ Ino int64 ++ Mode uint32 ++ Nlink int32 ++ Uid uint32 ++ Gid uint32 ++ Size int64 ++ Rdev int32 ++ Blksize int32 ++ Atim Timespec ++ Mtim Timespec ++ Ctim Timespec ++ Crtim Timespec ++ Type uint32 ++ Pad_cgo_1 [4]byte ++ Blocks int64 ++} ++ ++type Flock_t struct { ++ Type int16 ++ Whence int16 ++ Pad_cgo_0 [4]byte ++ Start int64 ++ Len int64 ++ Pid int32 ++ Pad_cgo_1 [4]byte ++} ++ ++type Dirent struct { ++ Dev int32 ++ Pdev int32 ++ Ino int64 ++ Pino int64 ++ Reclen uint16 ++ Name [1 + 256]int8 ++ Pad_cgo_0 [1]byte ++} ++ ++type RawSockaddrInet4 struct { ++ Len uint8 ++ Family uint8 ++ Port uint16 ++ Addr [4]byte /* in_addr */ ++ Zero [24]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 [126]int8 ++} ++ ++type RawSockaddrDatalink struct { ++ Len uint8 ++ Family uint8 ++ E_type uint16 ++ Index uint32 ++ Type uint8 ++ Nlen uint8 ++ Alen uint8 ++ Slen uint8 ++ Data [20]uint8 ++} ++ ++type RawSockaddr struct { ++ Len uint8 ++ Family uint8 ++ Data [30]uint8 ++} ++ ++type RawSockaddrAny struct { ++ Addr RawSockaddr ++ Pad [96]int8 ++} ++ ++type _Socklen uint32 ++ ++type Linger struct { ++ Onoff int32 ++ Linger int32 ++} ++ ++type Iovec struct { ++ Base *byte ++ Len uint64 ++} ++ ++type IPMreq struct { ++ Multiaddr [4]byte /* in_addr */ ++ Interface [4]byte /* in_addr */ ++} ++ ++type IPv6Mreq struct { ++ Multiaddr [16]byte /* in6_addr */ ++ Interface uint32 ++} ++ ++type Msghdr struct { ++ Name *byte ++ Namelen uint32 ++ Pad_cgo_0 [4]byte ++ Iov *Iovec ++ Iovlen int32 ++ Pad_cgo_1 [4]byte ++ Control *byte ++ Controllen uint32 ++ Flags int32 ++} ++ ++type Cmsghdr struct { ++ Len uint32 ++ Level int32 ++ Type int32 ++} ++type IPv6MTUInfo struct { ++ Addr RawSockaddrInet6 ++ Mtu uint32 ++} ++ ++type Inet6Pktinfo struct { ++ Addr [16]byte /* in6_addr */ ++ Ifindex uint32 ++} ++ ++type ICMPv6Filter struct { ++ Filt [8]uint32 ++} ++ ++const ( ++ SizeofSockaddrInet4 = 0x20 ++ SizeofSockaddrInet6 = 0x1c ++ SizeofSockaddrAny = 0x80 ++ SizeofSockaddrUnix = 0x80 ++ SizeofSockaddrDatalink = 0x20 ++ SizeofLinger = 0x8 ++ SizeofIPMreq = 0x8 ++ SizeofIPv6Mreq = 0x14 ++ SizeofMsghdr = 0x30 ++ SizeofCmsghdr = 0xc ++ SizeofIPv6MTUInfo = 0x20 ++ SizeofInet6Pktinfo = 0x14 ++ SizeofICMPv6Filter = 0x20 ++) ++ ++type FdSet struct { ++ Bits [32]uint32 ++} ++ ++type Termios struct { ++ Iflag uint32 ++ Oflag uint32 ++ Cflag uint32 ++ Lflag uint32 ++ Line int8 ++ Ispeed uint8 ++ Ospeed uint8 ++ Cc [11]uint8 ++ Pad_cgo_0 [2]byte ++} ++ ++const ( ++ F_DUPFD_CLOEXEC = 0x0200 ++) +-- +2.19.0 + + +From 6f93a4bc5f82be54e7ab70d1519c2da965eff28b Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:57:47 +0100 +Subject: time: Haiku support. + + +diff --git a/src/time/sys_unix.go b/src/time/sys_unix.go +index 379e13d..c38d334 100644 +--- a/src/time/sys_unix.go ++++ b/src/time/sys_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package time + +diff --git a/src/time/zoneinfo_unix.go b/src/time/zoneinfo_unix.go +index ab7e461..f43c459 100644 +--- a/src/time/zoneinfo_unix.go ++++ b/src/time/zoneinfo_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + // Parse "zoneinfo" time zone file. + // This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others. +-- +2.19.0 + + +From fe1694cc1f58503a0e2d4e3578c7f47702362fea Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:58:28 +0100 +Subject: os: Add support for building on Haiku (including tests) + + +diff --git a/src/os/dir_haiku.go b/src/os/dir_haiku.go +new file mode 100644 +index 0000000..9f97fea +--- /dev/null ++++ b/src/os/dir_haiku.go +@@ -0,0 +1,60 @@ ++// 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" ++import "unsafe" ++ ++func clen(n []byte) int { ++ for i := 0; i < len(n); i++ { ++ if n[i] == 0 { ++ return i ++ } ++ } ++ return len(n) ++} ++ ++func (file *File) readdirnames(n int) (names []string, err error) { ++ size := n ++ if size <= 0 { ++ size = 100 ++ n = -1 ++ } ++ ++ names = make([]string, 0, size) // Empty with room to grow. ++ ++ dirfd, err := syscall.Dup(file.fd) ++ if err != nil { ++ return names, err ++ } ++ dir, err := syscall.Fdopendir(dirfd) ++ if err != nil { ++ return names, err ++ } ++ defer syscall.Closedir(dir) ++ var result *syscall.Dirent = nil ++ entry := syscall.Dirent{} ++ for n != 0 { ++ status := syscall.Readdir_r(dir, &entry, &result) ++ if status != 0 { ++ return names, syscall.Errno(status) ++ } ++ if result == nil { ++ break ++ } ++ if result.Ino == 0 { // File absent in directory ++ continue ++ } ++ bytes := (*[10000]byte)(unsafe.Pointer(&result.Name[0])) ++ name := string(bytes[0:clen(bytes[:])]) ++ if name == "." || name == ".." { ++ // considered "Useless names" by ParseDirent ++ continue ++ } ++ names = append(names, name) ++ n-- ++ } ++ return names, err ++} +diff --git a/src/os/env_unix_test.go b/src/os/env_unix_test.go +index 5ec07ee..12b89f6 100644 +--- a/src/os/env_unix_test.go ++++ b/src/os/env_unix_test.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package os_test + +diff --git a/src/os/error_unix.go b/src/os/error_unix.go +index f2aabbb..0747f90 100644 +--- a/src/os/error_unix.go ++++ b/src/os/error_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package os + +diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go +index 197d3e8..950cb3b 100644 +--- a/src/os/exec/exec_test.go ++++ b/src/os/exec/exec_test.go +@@ -76,6 +76,9 @@ func TestCommandRelativeName(t *testing.T) { + } + + func TestCatStdin(t *testing.T) { ++ if runtime.GOOS == "haiku" { ++ t.Skip("skipping on haiku") ++ } + // Cat, testing stdin and stdout. + input := "Input string\nLine 2" + p := helperCommand(t, "cat") +diff --git a/src/os/exec/lp_unix.go b/src/os/exec/lp_unix.go +index 3f895d5..51bf920 100644 +--- a/src/os/exec/lp_unix.go ++++ b/src/os/exec/lp_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package exec + +diff --git a/src/os/exec/lp_unix_test.go b/src/os/exec/lp_unix_test.go +index 051db66..0e344d6 100644 +--- a/src/os/exec/lp_unix_test.go ++++ b/src/os/exec/lp_unix_test.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package exec + +diff --git a/src/os/exec_posix.go b/src/os/exec_posix.go +index fb9d291..78e3b30 100644 +--- a/src/os/exec_posix.go ++++ b/src/os/exec_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package os + +diff --git a/src/os/exec_unix.go b/src/os/exec_unix.go +index ed97f85..20843b8 100644 +--- a/src/os/exec_unix.go ++++ b/src/os/exec_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package os + +diff --git a/src/os/file_posix.go b/src/os/file_posix.go +index fbb3b5e..6bbd8f1 100644 +--- a/src/os/file_posix.go ++++ b/src/os/file_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package os + +diff --git a/src/os/file_unix.go b/src/os/file_unix.go +index ff4fc7d..8dafc18 100644 +--- a/src/os/file_unix.go ++++ b/src/os/file_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package os + +@@ -311,6 +311,9 @@ func TempDir() string { + if dir == "" { + if runtime.GOOS == "android" { + dir = "/data/local/tmp" ++ } ++ if runtime.GOOS == "haiku" { ++ dir = "/boot/system/cache/tmp" + } else { + dir = "/tmp" + } +diff --git a/src/os/os_test.go b/src/os/os_test.go +index a30a2b0..3921d29 100644 +--- a/src/os/os_test.go ++++ b/src/os/os_test.go +@@ -70,6 +70,14 @@ var sysdir = func() (sd *sysDir) { + "local", + }, + } ++ case "haiku": ++ sd = &sysDir{ ++ "/system/settings/etc", ++ []string{ ++ "group", ++ "passwd", ++ }, ++ } + default: + sd = &sysDir{ + "/etc", +@@ -308,6 +316,12 @@ func smallReaddirnames(file *File, length int, t *testing.T) []string { + // as reading it all at once. + func TestReaddirnamesOneAtATime(t *testing.T) { + // big directory that doesn't change often. ++ switch runtime.GOOS { ++ case "haiku": ++ // Haiku doesn't really have a standard /bin path ++ t.Skipf("skipping test on %v", runtime.GOOS) ++ } ++ + dir := "/usr/bin" + switch runtime.GOOS { + case "android": +@@ -316,6 +330,8 @@ func TestReaddirnamesOneAtATime(t *testing.T) { + dir = "/bin" + case "windows": + dir = Getenv("SystemRoot") + "\\system32" ++ case "haiku": ++ dir = "/boot/system/bin" + } + file, err := Open(dir) + if err != nil { +@@ -332,6 +348,7 @@ func TestReaddirnamesOneAtATime(t *testing.T) { + } + defer file1.Close() + small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up ++ + if len(small) < len(all) { + t.Fatalf("len(small) is %d, less than %d", len(small), len(all)) + } +@@ -493,7 +510,7 @@ func TestReaddirStatFailures(t *testing.T) { + + func TestHardLink(t *testing.T) { + // Hardlinks are not supported under windows or Plan 9. +- if runtime.GOOS == "plan9" { ++ if runtime.GOOS == "plan9" || runtime.GOOS == "haiku"{ + return + } + from, to := "hardlinktestfrom", "hardlinktestto" +@@ -847,6 +864,8 @@ func TestChdirAndGetwd(t *testing.T) { + switch runtime.GOOS { + case "android": + dirs = []string{"/", "/system/bin"} ++ case "haiku": ++ dirs = []string{"/", "/boot/system/bin"} + case "plan9": + dirs = []string{"/", "/usr"} + } +diff --git a/src/os/os_unix_test.go b/src/os/os_unix_test.go +index 21d40cc..a9e0735 100644 +--- a/src/os/os_unix_test.go ++++ b/src/os/os_unix_test.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package os_test + +diff --git a/src/os/path_unix.go b/src/os/path_unix.go +index 0211107..333a863 100644 +--- a/src/os/path_unix.go ++++ b/src/os/path_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package os + +diff --git a/src/os/pipe_bsd.go b/src/os/pipe_bsd.go +index 3b81ed2..f6eda49 100644 +--- a/src/os/pipe_bsd.go ++++ b/src/os/pipe_bsd.go +@@ -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 darwin dragonfly freebsd nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku nacl netbsd openbsd solaris + + package os + +diff --git a/src/os/signal/signal_test.go b/src/os/signal/signal_test.go +index 22337a7..34dfe2e 100644 +--- a/src/os/signal/signal_test.go ++++ b/src/os/signal/signal_test.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package signal + +diff --git a/src/os/signal/signal_unix.go b/src/os/signal/signal_unix.go +index 94b8ab3..98d22f7 100644 +--- a/src/os/signal/signal_unix.go ++++ b/src/os/signal/signal_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package signal + +diff --git a/src/os/stat_haiku.go b/src/os/stat_haiku.go +new file mode 100644 +index 0000000..605c1d9 +--- /dev/null ++++ b/src/os/stat_haiku.go +@@ -0,0 +1,61 @@ ++// 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" ++ "time" ++) ++ ++func sameFile(fs1, fs2 *fileStat) bool { ++ stat1 := fs1.sys.(*syscall.Stat_t) ++ stat2 := fs2.sys.(*syscall.Stat_t) ++ return stat1.Dev == stat2.Dev && stat1.Ino == stat2.Ino ++} ++ ++func fileInfoFromStat(st *syscall.Stat_t, name string) FileInfo { ++ fs := &fileStat{ ++ name: basename(name), ++ size: int64(st.Size), ++ modTime: timespecToTime(st.Mtim), ++ sys: st, ++ } ++ fs.mode = FileMode(st.Mode & 0777) ++ switch st.Mode & syscall.S_IFMT { ++ case syscall.S_IFBLK: ++ fs.mode |= ModeDevice ++ case syscall.S_IFCHR: ++ fs.mode |= ModeDevice | ModeCharDevice ++ case syscall.S_IFDIR: ++ fs.mode |= ModeDir ++ case syscall.S_IFIFO: ++ fs.mode |= ModeNamedPipe ++ case syscall.S_IFLNK: ++ fs.mode |= ModeSymlink ++ case syscall.S_IFREG: ++ // nothing to do ++ case syscall.S_IFSOCK: ++ fs.mode |= ModeSocket ++ } ++ if st.Mode&syscall.S_ISGID != 0 { ++ fs.mode |= ModeSetgid ++ } ++ if st.Mode&syscall.S_ISUID != 0 { ++ fs.mode |= ModeSetuid ++ } ++ if st.Mode&syscall.S_ISVTX != 0 { ++ fs.mode |= ModeSticky ++ } ++ return fs ++} ++ ++func timespecToTime(ts syscall.Timespec) time.Time { ++ return time.Unix(int64(ts.Sec), int64(ts.Nsec)) ++} ++ ++// For testing. ++func atime(fi FileInfo) time.Time { ++ return timespecToTime(fi.Sys().(*syscall.Stat_t).Atim) ++} +diff --git a/src/os/sys_haiku.go b/src/os/sys_haiku.go +new file mode 100644 +index 0000000..f224f0d +--- /dev/null ++++ b/src/os/sys_haiku.go +@@ -0,0 +1,11 @@ ++// 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) { ++ return syscall.Gethostname() ++} +diff --git a/src/os/sys_unix.go b/src/os/sys_unix.go +index 39c20dc..6bdff82 100644 +--- a/src/os/sys_unix.go ++++ b/src/os/sys_unix.go +@@ -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 dragonfly linux netbsd openbsd solaris ++// +build dragonfly haiku linux netbsd openbsd solaris + + package os + +-- +2.19.0 + + +From b905785ed1e72dd24f6299e010206b84dc6acc03 Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:59:20 +0100 +Subject: net: Initial support for building the net package for Haiku. + + +diff --git a/src/net/conn_test.go b/src/net/conn_test.go +index 9c9d1a8..1501133 100644 +--- a/src/net/conn_test.go ++++ b/src/net/conn_test.go +@@ -33,12 +33,12 @@ func TestConnAndListener(t *testing.T) { + switch tt.net { + case "unix": + switch runtime.GOOS { +- case "nacl", "plan9", "windows": ++ case "haiku", "nacl", "plan9", "windows": + continue + } + case "unixpacket": + switch runtime.GOOS { +- case "android", "darwin", "nacl", "openbsd", "plan9", "windows": ++ case "android", "darwin", "haiku", "nacl", "openbsd", "plan9", "windows": + continue + case "freebsd": // FreeBSD 8 doesn't support unixpacket + continue +diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go +index 7511083..268ae21 100644 +--- a/src/net/dnsclient_unix.go ++++ b/src/net/dnsclient_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + // DNS client: see RFC 1035. + // Has to be linked into package net for Dial. +@@ -22,6 +22,7 @@ import ( + "os" + "sync" + "time" ++ "runtime" + ) + + // A dnsConn represents a DNS transport endpoint. +@@ -223,7 +224,12 @@ var onceLoadConfig sync.Once + + // Assume dns config file is /etc/resolv.conf here + func loadDefaultConfig() { +- loadConfig("/etc/resolv.conf", 5*time.Second, nil) ++ if runtime.GOOS != "haiku" { ++ loadConfig("/etc/resolv.conf", 5*time.Second, nil) ++ } else { ++ loadConfig("/boot/system/settings/network/resolv.conf", 5*time.Second, nil) ++ } ++ + } + + func loadConfig(resolvConfPath string, reloadTime time.Duration, quit <-chan chan struct{}) { +diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go +index 1167c26..4433b41 100644 +--- a/src/net/dnsclient_unix_test.go ++++ b/src/net/dnsclient_unix_test.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package net + +diff --git a/src/net/dnsconfig_unix.go b/src/net/dnsconfig_unix.go +index 66ab7c4..0d7d816 100644 +--- a/src/net/dnsconfig_unix.go ++++ b/src/net/dnsconfig_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + // Read system DNS config from /etc/resolv.conf + +diff --git a/src/net/dnsconfig_unix_test.go b/src/net/dnsconfig_unix_test.go +index 94fb0c3..f828cd1 100644 +--- a/src/net/dnsconfig_unix_test.go ++++ b/src/net/dnsconfig_unix_test.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package net + +diff --git a/src/net/fd_poll_runtime.go b/src/net/fd_poll_runtime.go +index 2bddc83..71cb6e3 100644 +--- a/src/net/fd_poll_runtime.go ++++ b/src/net/fd_poll_runtime.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd windows solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd windows solaris + + package net + +diff --git a/src/net/fd_unix.go b/src/net/fd_unix.go +index 7fa43f6..e845a9b 100644 +--- a/src/net/fd_unix.go ++++ b/src/net/fd_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package net + +diff --git a/src/net/fd_unix_test.go b/src/net/fd_unix_test.go +index fe8e8ff..2f0ab5e 100644 +--- a/src/net/fd_unix_test.go ++++ b/src/net/fd_unix_test.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package net + +diff --git a/src/net/file_unix.go b/src/net/file_unix.go +index 214a419..561893b 100644 +--- a/src/net/file_unix.go ++++ b/src/net/file_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package net + +diff --git a/src/net/interface_stub.go b/src/net/interface_stub.go +index c38fb7f..0b43b4a 100644 +--- a/src/net/interface_stub.go ++++ b/src/net/interface_stub.go +@@ -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 nacl plan9 solaris ++// +build haiku nacl plan9 solaris + + package net + +diff --git a/src/net/iprawsock_posix.go b/src/net/iprawsock_posix.go +index 99b081b..8fb5cbf 100644 +--- a/src/net/iprawsock_posix.go ++++ b/src/net/iprawsock_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package net + +diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go +index f9ebe40..82ebf37 100644 +--- a/src/net/ipsock_posix.go ++++ b/src/net/ipsock_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + // Internet protocol family sockets for POSIX + +diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go +index a545784..f4469d9 100644 +--- a/src/net/lookup_unix.go ++++ b/src/net/lookup_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + package net + +diff --git a/src/net/port_unix.go b/src/net/port_unix.go +index 348c771..363225e 100644 +--- a/src/net/port_unix.go ++++ b/src/net/port_unix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris + + // Read system port mappings from /etc/services + +diff --git a/src/net/sendfile_stub.go b/src/net/sendfile_stub.go +index 03426ef..aaf82bf 100644 +--- a/src/net/sendfile_stub.go ++++ b/src/net/sendfile_stub.go +@@ -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 darwin nacl netbsd openbsd solaris ++// +build darwin haiku nacl netbsd openbsd solaris + + package net + +diff --git a/src/net/sock_haiku.go b/src/net/sock_haiku.go +new file mode 100644 +index 0000000..90fe9de +--- /dev/null ++++ b/src/net/sock_haiku.go +@@ -0,0 +1,13 @@ ++// 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 net ++ ++import "syscall" ++ ++func maxListenerBacklog() int { ++ // TODO: Implement this ++ // NOTE: Never return a number bigger than 1<<16 - 1. See issue 5030. ++ return syscall.SOMAXCONN ++} +diff --git a/src/net/sock_posix.go b/src/net/sock_posix.go +index 3f956df..db3b6c4 100644 +--- a/src/net/sock_posix.go ++++ b/src/net/sock_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package net + +diff --git a/src/net/sockopt_haiku.go b/src/net/sockopt_haiku.go +new file mode 100644 +index 0000000..54c20b1 +--- /dev/null ++++ b/src/net/sockopt_haiku.go +@@ -0,0 +1,32 @@ ++// Copyright 2011 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 net ++ ++import ( ++ "os" ++ "syscall" ++) ++ ++func setDefaultSockopts(s, family, sotype int, ipv6only bool) error { ++ if family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW { ++ // Allow both IP versions even if the OS default ++ // is otherwise. Note that some operating systems ++ // never admit this option. ++ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only)) ++ } ++ // Allow broadcast. ++ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)) ++} ++ ++func setDefaultListenerSockopts(s int) error { ++ // Allow reuse of recently-used addresses. ++ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)) ++} ++ ++func setDefaultMulticastSockopts(s int) error { ++ // Allow multicast UDP and raw IP datagram sockets to listen ++ // concurrently across multiple listeners. ++ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)) ++} +diff --git a/src/net/sockopt_posix.go b/src/net/sockopt_posix.go +index 1654d1b..79875c3 100644 +--- a/src/net/sockopt_posix.go ++++ b/src/net/sockopt_posix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris windows + + package net + +diff --git a/src/net/sockoptip_stub.go b/src/net/sockoptip_stub.go +index 32ec5dd..e11c4bb 100644 +--- a/src/net/sockoptip_stub.go ++++ b/src/net/sockoptip_stub.go +@@ -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 nacl solaris ++// +build haiku nacl solaris + + package net + +diff --git a/src/net/sys_cloexec.go b/src/net/sys_cloexec.go +index 898fb7c..242b418 100644 +--- a/src/net/sys_cloexec.go ++++ b/src/net/sys_cloexec.go +@@ -5,7 +5,7 @@ + // This file implements sysSocket and accept for platforms that do not + // provide a fast path for setting SetNonblock and CloseOnExec. + +-// +build darwin dragonfly nacl netbsd openbsd solaris ++// +build darwin dragonfly haiku nacl netbsd openbsd solaris + + package net + +diff --git a/src/net/tcpsock_posix.go b/src/net/tcpsock_posix.go +index dd78aef..e471206 100644 +--- a/src/net/tcpsock_posix.go ++++ b/src/net/tcpsock_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package net + +diff --git a/src/net/tcpsockopt_haiku.go b/src/net/tcpsockopt_haiku.go +new file mode 100644 +index 0000000..eaab6b6 +--- /dev/null ++++ b/src/net/tcpsockopt_haiku.go +@@ -0,0 +1,27 @@ ++// Copyright 2013 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. ++ ++// TCP socket options for solaris ++ ++package net ++ ++import ( ++ "os" ++ "syscall" ++ "time" ++) ++ ++// Set keep alive period. ++func setKeepAlivePeriod(fd *netFD, d time.Duration) error { ++ if err := fd.incref(); err != nil { ++ return err ++ } ++ defer fd.decref() ++ ++ // The kernel expects seconds so round to next highest second. ++ d += (time.Second - time.Nanosecond) ++ secs := int(d.Seconds()) ++ ++ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.SO_KEEPALIVE, secs)) ++} +diff --git a/src/net/tcpsockopt_posix.go b/src/net/tcpsockopt_posix.go +index 0abf3f9..d408110 100644 +--- a/src/net/tcpsockopt_posix.go ++++ b/src/net/tcpsockopt_posix.go +@@ -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 darwin dragonfly freebsd linux netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux netbsd openbsd solaris windows + + package net + +diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go +index a053336..2fd2c3b 100644 +--- a/src/net/udpsock_posix.go ++++ b/src/net/udpsock_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package net + +diff --git a/src/net/unixsock_posix.go b/src/net/unixsock_posix.go +index 3c2e78b..0499934 100644 +--- a/src/net/unixsock_posix.go ++++ b/src/net/unixsock_posix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris windows + + package net + +-- +2.19.0 + + +From fc2b735d9cc9b61d5a6d4f63d8deb5dc65caf836 Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 00:59:47 +0100 +Subject: crypto: Build on Haiku. + + +diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go +index 62d0fbd..cf90cde 100644 +--- a/src/crypto/rand/rand_unix.go ++++ b/src/crypto/rand/rand_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd plan9 solaris + + // Unix cryptographically secure pseudorandom number + // generator. +diff --git a/src/crypto/x509/root_unix.go b/src/crypto/x509/root_unix.go +index f77d6c0..fee8232 100644 +--- a/src/crypto/x509/root_unix.go ++++ b/src/crypto/x509/root_unix.go +@@ -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 dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package x509 + +@@ -10,13 +10,14 @@ import "io/ioutil" + + // Possible certificate files; stop after finding one. + var certFiles = []string{ +- "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. +- "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL +- "/etc/ssl/ca-bundle.pem", // OpenSUSE +- "/etc/ssl/cert.pem", // OpenBSD +- "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly +- "/etc/pki/tls/cacert.pem", // OpenELEC +- "/etc/certs/ca-certificates.crt", // Solaris 11.2+ ++ "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. ++ "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL ++ "/etc/ssl/ca-bundle.pem", // OpenSUSE ++ "/etc/ssl/cert.pem", // OpenBSD ++ "/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly ++ "/etc/pki/tls/cacert.pem", // OpenELEC ++ "/etc/certs/ca-certificates.crt", // Solaris 11.2+ ++ "/boot/system/data/ssl/CARootCertificates.pem", // Haiku + } + + // Possible directories with certificate files; stop after successfully +-- +2.19.0 + + +From df8d0e4d87010933e93f738b70bb679a596fe04d Mon Sep 17 00:00:00 2001 +From: Calvin Hill +Date: Sun, 23 Sep 2018 01:00:37 +0100 +Subject: log, mime, path: Build on Haiku. + + +diff --git a/src/log/syslog/syslog_unix.go b/src/log/syslog/syslog_unix.go +index 1cdabec..7abd5f4 100644 +--- a/src/log/syslog/syslog_unix.go ++++ b/src/log/syslog/syslog_unix.go +@@ -16,7 +16,7 @@ import ( + + func unixSyslog() (conn serverConn, err error) { + logTypes := []string{"unixgram", "unix"} +- logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"} ++ logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log", "/var/log/syslog"} + for _, network := range logTypes { + for _, path := range logPaths { + conn, err := net.Dial(network, path) +diff --git a/src/mime/type_unix.go b/src/mime/type_unix.go +index 3e404cf..7ee5185 100644 +--- a/src/mime/type_unix.go ++++ b/src/mime/type_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package mime + +diff --git a/src/path/filepath/path_unix.go b/src/path/filepath/path_unix.go +index 4e7d0d1..524b9b6 100644 +--- a/src/path/filepath/path_unix.go ++++ b/src/path/filepath/path_unix.go +@@ -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 darwin dragonfly freebsd linux nacl netbsd openbsd solaris ++// +build darwin dragonfly freebsd haiku linux nacl netbsd openbsd solaris + + package filepath + +-- +2.19.0 +