mirror of
https://github.com/golang/go
synced 2024-11-22 07:34:40 -07:00
syscall: minimal mingw version of syscall to call windows dlls
lots of missing parts, but builds and can call dlls, see a sample code in syscall_mingw.go R=rsc CC=golang-dev https://golang.org/cl/218042
This commit is contained in:
parent
75e5ece03a
commit
e00795859b
@ -27,6 +27,9 @@ GOFILES=\
|
|||||||
GOFILES_pchw=\
|
GOFILES_pchw=\
|
||||||
pchw/io.go\
|
pchw/io.go\
|
||||||
|
|
||||||
|
OFILES_mingw=\
|
||||||
|
syscall.$O\
|
||||||
|
|
||||||
# 386-specific object files
|
# 386-specific object files
|
||||||
OFILES_386=\
|
OFILES_386=\
|
||||||
vlop.$O\
|
vlop.$O\
|
||||||
|
@ -12,6 +12,9 @@ void *stdcall(void *fn, ...);
|
|||||||
void *stdcall_raw(void *fn, ...);
|
void *stdcall_raw(void *fn, ...);
|
||||||
|
|
||||||
extern void *VirtualAlloc;
|
extern void *VirtualAlloc;
|
||||||
|
extern void *LoadLibraryEx;
|
||||||
|
extern void *GetProcAddress;
|
||||||
|
extern void *GetLastError;
|
||||||
|
|
||||||
#define goargs mingw_goargs
|
#define goargs mingw_goargs
|
||||||
void mingw_goargs(void);
|
void mingw_goargs(void);
|
||||||
|
37
src/pkg/runtime/mingw/syscall.cgo
Normal file
37
src/pkg/runtime/mingw/syscall.cgo
Normal file
@ -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
|
||||||
|
#include "runtime.h"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
func loadlibraryex(filename uintptr) (handle uint32) {
|
||||||
|
handle = (uint32)stdcall(LoadLibraryEx, filename, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
func getprocaddress(handle uint32, procname uintptr) (proc uintptr) {
|
||||||
|
proc = (uintptr)stdcall(GetProcAddress, handle, procname);
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
||||||
|
·entersyscall();
|
||||||
|
r1 = (uintptr)stdcall_raw((void*)trap, a1, a2, a3);
|
||||||
|
r2 = 0;
|
||||||
|
err = (uintptr)stdcall_raw(GetLastError);
|
||||||
|
·exitsyscall();
|
||||||
|
}
|
||||||
|
|
||||||
|
func Syscall6(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
||||||
|
·entersyscall();
|
||||||
|
r1 = (uintptr)stdcall_raw((void*)trap, a1, a2, a3, a4, a5, a6);
|
||||||
|
r2 = 0;
|
||||||
|
err = (uintptr)stdcall_raw(GetLastError);
|
||||||
|
·exitsyscall();
|
||||||
|
}
|
||||||
|
|
||||||
|
func RawSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
|
||||||
|
r1 = (uintptr)stdcall_raw((void*)trap, a1, a2, a3);
|
||||||
|
r2 = 0;
|
||||||
|
err = (uintptr)stdcall_raw(GetLastError);
|
||||||
|
}
|
@ -16,12 +16,13 @@ void *GetStdHandle;
|
|||||||
void *SetEvent;
|
void *SetEvent;
|
||||||
void *WriteFile;
|
void *WriteFile;
|
||||||
void *VirtualAlloc;
|
void *VirtualAlloc;
|
||||||
|
void *LoadLibraryEx;
|
||||||
|
void *GetProcAddress;
|
||||||
|
void *GetLastError;
|
||||||
|
|
||||||
static void *CreateEvent;
|
static void *CreateEvent;
|
||||||
static void *CreateThread;
|
static void *CreateThread;
|
||||||
static void *GetModuleHandle;
|
static void *GetModuleHandle;
|
||||||
static void *GetProcAddress;
|
|
||||||
static void *LoadLibraryEx;
|
|
||||||
static void *WaitForSingleObject;
|
static void *WaitForSingleObject;
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
@ -65,6 +66,7 @@ osinit(void)
|
|||||||
VirtualAlloc = get_proc_addr("kernel32.dll", "VirtualAlloc");
|
VirtualAlloc = get_proc_addr("kernel32.dll", "VirtualAlloc");
|
||||||
WaitForSingleObject = get_proc_addr("kernel32.dll", "WaitForSingleObject");
|
WaitForSingleObject = get_proc_addr("kernel32.dll", "WaitForSingleObject");
|
||||||
WriteFile = get_proc_addr("kernel32.dll", "WriteFile");
|
WriteFile = get_proc_addr("kernel32.dll", "WriteFile");
|
||||||
|
GetLastError = get_proc_addr("kernel32.dll", "GetLastError");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The arguments are strings.
|
// The arguments are strings.
|
||||||
|
7
src/pkg/syscall/asm_mingw_386.s
Normal file
7
src/pkg/syscall/asm_mingw_386.s
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for 386, Windows are implemented in ../runtime/mingw/syscall.cgo
|
||||||
|
//
|
@ -144,6 +144,13 @@ linux_arm)
|
|||||||
mktypes="godefs -gsyscall -carm-gcc"
|
mktypes="godefs -gsyscall -carm-gcc"
|
||||||
mkerrors="mkerrors.sh"
|
mkerrors="mkerrors.sh"
|
||||||
;;
|
;;
|
||||||
|
mingw_386)
|
||||||
|
# TODO(brainman): create proper mksyscall / mksysnum / mktypes
|
||||||
|
mksyscall="mksyscall.sh -l32"
|
||||||
|
mksysnum="XXXXXX_mksysnum.sh"
|
||||||
|
mktypes="XXXXXX_godefs -gsyscall -f-m32"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
|
163
src/pkg/syscall/syscall_mingw.go
Normal file
163
src/pkg/syscall/syscall_mingw.go
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
// Windows system calls.
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
const OS = "mingw"
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
small demo to detect version of windows you are running:
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func print_version(v uint32) {
|
||||||
|
major := byte(v)
|
||||||
|
minor := uint8(v >> 8)
|
||||||
|
build := uint16(v >> 16)
|
||||||
|
print("windows version ", major, ".", minor, " (Build ", build, ")\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
h, err := syscall.LoadLibrary("kernel32.dll")
|
||||||
|
if err != 0 {
|
||||||
|
panic("failed to LoadLibrary #", err, "\n")
|
||||||
|
}
|
||||||
|
defer syscall.FreeLibrary(h)
|
||||||
|
proc, err := syscall.GetProcAddress(h, "GetVersion")
|
||||||
|
if err != 0 {
|
||||||
|
panic("could not GetProcAddress #", err, "\n")
|
||||||
|
}
|
||||||
|
r, _, e := syscall.Syscall(uintptr(proc), 0, 0, 0)
|
||||||
|
err = int(e)
|
||||||
|
if err != 0 {
|
||||||
|
panic("GetVersion failed #", err, "\n")
|
||||||
|
}
|
||||||
|
print_version(uint32(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
//sys GetLastError() (lasterrno int)
|
||||||
|
|
||||||
|
// TODO(brainman): probably should use LoadLibraryW here instead
|
||||||
|
//sys LoadLibraryA(libname string) (handle Module, errno int)
|
||||||
|
|
||||||
|
func LoadLibrary(libname string) (handle Module, errno int) {
|
||||||
|
h, e := LoadLibraryA(libname)
|
||||||
|
if int(h) != 0 {
|
||||||
|
return h, 0
|
||||||
|
}
|
||||||
|
return h, e
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(brainman): should handle errors like in LoadLibrary, otherwise will be returning 'old' errors
|
||||||
|
//sys FreeLibrary(handle Module) (ok Bool, errno int)
|
||||||
|
//sys GetProcAddress(module Module, procname string) (proc uint32, errno int)
|
||||||
|
//sys GetVersion() (ver uint32, errno int)
|
||||||
|
|
||||||
|
// dll helpers
|
||||||
|
|
||||||
|
// implemented in ../pkg/runtime/mingw/syscall.cgo
|
||||||
|
func loadlibraryex(filename uintptr) (handle uint32)
|
||||||
|
func getprocaddress(handle uint32, procname uintptr) (proc uintptr)
|
||||||
|
|
||||||
|
func loadDll(fname string) Module {
|
||||||
|
m := loadlibraryex(uintptr(unsafe.Pointer(StringBytePtr(fname))))
|
||||||
|
if m == 0 {
|
||||||
|
panic("syscall: could not LoadLibraryEx ", fname)
|
||||||
|
}
|
||||||
|
return Module(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSysProcAddr(m Module, pname string) uintptr {
|
||||||
|
p := getprocaddress(uint32(m), uintptr(unsafe.Pointer(StringBytePtr(pname))))
|
||||||
|
if p == 0 {
|
||||||
|
panic("syscall: could not GetProcAddress for ", pname)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(brainman): fix all this meaningless code, it is here to compile exec.go
|
||||||
|
|
||||||
|
func Pipe(p []int) (errno int) { return EMINGW }
|
||||||
|
|
||||||
|
//sys Close(fd int) (errno int)
|
||||||
|
//sys read(fd int, buf *byte, nbuf int) (n int, errno int)
|
||||||
|
|
||||||
|
func fcntl(fd, cmd, arg int) (val int, errno int) {
|
||||||
|
return 0, EMINGW
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
F_SETFD = 1 + iota
|
||||||
|
FD_CLOEXEC
|
||||||
|
F_GETFL
|
||||||
|
F_SETFL
|
||||||
|
O_NONBLOCK
|
||||||
|
SYS_FORK
|
||||||
|
SYS_PTRACE
|
||||||
|
SYS_CHDIR
|
||||||
|
SYS_DUP2
|
||||||
|
SYS_FCNTL
|
||||||
|
SYS_EXECVE
|
||||||
|
PTRACE_TRACEME
|
||||||
|
SYS_CLOSE
|
||||||
|
SYS_WRITE
|
||||||
|
SYS_EXIT
|
||||||
|
SYS_READ
|
||||||
|
EPIPE
|
||||||
|
EINTR
|
||||||
|
)
|
||||||
|
|
||||||
|
type Rusage struct {
|
||||||
|
Utime Timeval
|
||||||
|
Stime Timeval
|
||||||
|
Maxrss int32
|
||||||
|
Ixrss int32
|
||||||
|
Idrss int32
|
||||||
|
Isrss int32
|
||||||
|
Minflt int32
|
||||||
|
Majflt int32
|
||||||
|
Nswap int32
|
||||||
|
Inblock int32
|
||||||
|
Oublock int32
|
||||||
|
Msgsnd int32
|
||||||
|
Msgrcv int32
|
||||||
|
Nsignals int32
|
||||||
|
Nvcsw int32
|
||||||
|
Nivcsw int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, errno int) {
|
||||||
|
return 0, EMINGW
|
||||||
|
}
|
||||||
|
|
||||||
|
type WaitStatus uint32
|
||||||
|
|
||||||
|
func (WaitStatus) Exited() bool { return false }
|
||||||
|
|
||||||
|
func (WaitStatus) ExitStatus() int { return -1 }
|
||||||
|
|
||||||
|
func (WaitStatus) Signal() int { return -1 }
|
||||||
|
|
||||||
|
func (WaitStatus) CoreDump() bool { return false }
|
||||||
|
|
||||||
|
func (WaitStatus) Stopped() bool { return false }
|
||||||
|
|
||||||
|
func (WaitStatus) Continued() bool { return false }
|
||||||
|
|
||||||
|
func (WaitStatus) StopSignal() int { return -1 }
|
||||||
|
|
||||||
|
func (WaitStatus) Signaled() bool { return false }
|
||||||
|
|
||||||
|
func (WaitStatus) TrapCause() int { return -1 }
|
5
src/pkg/syscall/syscall_mingw_386.go
Normal file
5
src/pkg/syscall/syscall_mingw_386.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// 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
|
15
src/pkg/syscall/zerrors_mingw_386.go
Normal file
15
src/pkg/syscall/zerrors_mingw_386.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// mkerrors_nacl.sh /home/rsc/pub/nacl/native_client/src/trusted/service_runtime/include/sys/errno.h
|
||||||
|
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
// TODO(brainman): populate errors in zerrors_mingw.go
|
||||||
|
|
||||||
|
const (
|
||||||
|
EMINGW = 99 /* otherwise unused */
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error table
|
||||||
|
var errors = [...]string{
|
||||||
|
EMINGW: "not supported by windows",
|
||||||
|
}
|
53
src/pkg/syscall/zsyscall_mingw_386.go
Normal file
53
src/pkg/syscall/zsyscall_mingw_386.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// mksyscall.sh -l32 syscall_mingw.go
|
||||||
|
// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
func GetLastError() (lasterrno int) {
|
||||||
|
r0, _, _ := Syscall(SYS_GET_LAST_ERROR, 0, 0, 0)
|
||||||
|
lasterrno = int(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadLibraryA(libname string) (handle Module, errno int) {
|
||||||
|
r0, _, e1 := Syscall(SYS_LOAD_LIBRARY_A, uintptr(unsafe.Pointer(StringBytePtr(libname))), 0, 0)
|
||||||
|
handle = Module(r0)
|
||||||
|
errno = int(e1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func FreeLibrary(handle Module) (ok Bool, errno int) {
|
||||||
|
r0, _, e1 := Syscall(SYS_FREE_LIBRARY, uintptr(handle), 0, 0)
|
||||||
|
ok = Bool(r0)
|
||||||
|
errno = int(e1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetProcAddress(module Module, procname string) (proc uint32, errno int) {
|
||||||
|
r0, _, e1 := Syscall(SYS_GET_PROC_ADDRESS, uintptr(module), uintptr(unsafe.Pointer(StringBytePtr(procname))), 0)
|
||||||
|
proc = uint32(r0)
|
||||||
|
errno = int(e1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVersion() (ver uint32, errno int) {
|
||||||
|
r0, _, e1 := Syscall(SYS_GET_VERSION, 0, 0, 0)
|
||||||
|
ver = uint32(r0)
|
||||||
|
errno = int(e1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Close(fd int) (errno int) {
|
||||||
|
_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
|
||||||
|
errno = int(e1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func read(fd int, buf *byte, nbuf int) (n int, errno int) {
|
||||||
|
r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
|
||||||
|
n = int(r0)
|
||||||
|
errno = int(e1)
|
||||||
|
return
|
||||||
|
}
|
15
src/pkg/syscall/zsysnum_mingw_386.go
Normal file
15
src/pkg/syscall/zsysnum_mingw_386.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// mksysnum_nacl.sh /home/rsc/pub/nacl/native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h
|
||||||
|
// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
// TODO(brainman): autogenerate winapi proc pointers in zsysnum_mingw.go
|
||||||
|
|
||||||
|
var (
|
||||||
|
SYS_KERNEL32 = loadDll("kernel32.dll")
|
||||||
|
SYS_GET_LAST_ERROR = getSysProcAddr(SYS_KERNEL32, "GetLastError")
|
||||||
|
SYS_LOAD_LIBRARY_A = getSysProcAddr(SYS_KERNEL32, "LoadLibraryA")
|
||||||
|
SYS_FREE_LIBRARY = getSysProcAddr(SYS_KERNEL32, "FreeLibrary")
|
||||||
|
SYS_GET_PROC_ADDRESS = getSysProcAddr(SYS_KERNEL32, "GetProcAddress")
|
||||||
|
SYS_GET_VERSION = getSysProcAddr(SYS_KERNEL32, "GetVersion")
|
||||||
|
)
|
44
src/pkg/syscall/ztypes_mingw_386.go
Normal file
44
src/pkg/syscall/ztypes_mingw_386.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// godefs -gsyscall -f-m32 types_linux.c
|
||||||
|
|
||||||
|
// MACHINE GENERATED - DO NOT EDIT.
|
||||||
|
|
||||||
|
package syscall
|
||||||
|
|
||||||
|
// TODO(brainman): autogenerate types in ztypes_mingw_386.go
|
||||||
|
|
||||||
|
//import "unsafe"
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
const (
|
||||||
|
sizeofPtr = 0x4
|
||||||
|
sizeofShort = 0x2
|
||||||
|
sizeofInt = 0x4
|
||||||
|
sizeofLong = 0x4
|
||||||
|
sizeofLongLong = 0x8
|
||||||
|
PathMax = 0x1000
|
||||||
|
SizeofSockaddrInet4 = 0x10
|
||||||
|
SizeofSockaddrInet6 = 0x1c
|
||||||
|
SizeofSockaddrAny = 0x70
|
||||||
|
SizeofSockaddrUnix = 0x6e
|
||||||
|
SizeofLinger = 0x8
|
||||||
|
SizeofMsghdr = 0x1c
|
||||||
|
SizeofCmsghdr = 0xc
|
||||||
|
)
|
||||||
|
|
||||||
|
// Types
|
||||||
|
|
||||||
|
type _C_short int16
|
||||||
|
|
||||||
|
type _C_int int32
|
||||||
|
|
||||||
|
type _C_long int32
|
||||||
|
|
||||||
|
type _C_long_long int64
|
||||||
|
|
||||||
|
type Bool uint32
|
||||||
|
type Module uint32
|
||||||
|
|
||||||
|
type Timeval struct {
|
||||||
|
Sec int32
|
||||||
|
Usec int32
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user