]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: syscall to return both AX and DX for windows/386
authorAlex Brainman <alex.brainman@gmail.com>
Wed, 14 Sep 2011 06:19:45 +0000 (16:19 +1000)
committerAlex Brainman <alex.brainman@gmail.com>
Wed, 14 Sep 2011 06:19:45 +0000 (16:19 +1000)
Fixes #2181.

R=golang-dev, jp
CC=golang-dev
https://golang.org/cl/5000042

src/pkg/runtime/runtime.h
src/pkg/runtime/syscall_windows_test.go
src/pkg/runtime/windows/386/sys.s
src/pkg/runtime/windows/amd64/sys.s
src/pkg/runtime/windows/os.h
src/pkg/runtime/windows/syscall.goc
src/pkg/runtime/windows/thread.c

index 6feedcbc821be590ffcb9ff96fa77d0a3d8c99ec..8753842a01e8bde2a7b3a499220f5e6750cc13de 100644 (file)
@@ -307,7 +307,8 @@ struct      WinCall
        void    (*fn)(void*);
        uintptr n;      // number of parameters
        void*   args;   // parameters
-       uintptr r;      // return value
+       uintptr r1;     // return values
+       uintptr r2;
        uintptr err;    // error number
 };
 
index c270607015a5a7a3015ee5b1c3efeebe475c7cb1..32eb0533fffaaa32626e5a33e3809d3091d8590d 100644 (file)
@@ -39,6 +39,77 @@ func TestStdCall(t *testing.T) {
        }
 }
 
+func Test64BitReturnStdCall(t *testing.T) {
+
+       const (
+               VER_BUILDNUMBER      = 0x0000004
+               VER_MAJORVERSION     = 0x0000002
+               VER_MINORVERSION     = 0x0000001
+               VER_PLATFORMID       = 0x0000008
+               VER_PRODUCT_TYPE     = 0x0000080
+               VER_SERVICEPACKMAJOR = 0x0000020
+               VER_SERVICEPACKMINOR = 0x0000010
+               VER_SUITENAME        = 0x0000040
+
+               VER_EQUAL         = 1
+               VER_GREATER       = 2
+               VER_GREATER_EQUAL = 3
+               VER_LESS          = 4
+               VER_LESS_EQUAL    = 5
+
+               ERROR_OLD_WIN_VERSION = 1150
+       )
+
+       type OSVersionInfoEx struct {
+               OSVersionInfoSize uint32
+               MajorVersion      uint32
+               MinorVersion      uint32
+               BuildNumber       uint32
+               PlatformId        uint32
+               CSDVersion        [128]uint16
+               ServicePackMajor  uint16
+               ServicePackMinor  uint16
+               SuiteMask         uint16
+               ProductType       byte
+               Reserve           byte
+       }
+
+       kernel32, e := syscall.LoadLibrary("kernel32.dll")
+       if e != 0 {
+               t.Fatalf("LoadLibrary(kernel32.dll) failed: %s", syscall.Errstr(e))
+       }
+       setMask, e := syscall.GetProcAddress(kernel32, "VerSetConditionMask")
+       if e != 0 {
+               t.Fatalf("GetProcAddress(kernel32.dll, VerSetConditionMask) failed: %s", syscall.Errstr(e))
+       }
+       verifyVersion, e := syscall.GetProcAddress(kernel32, "VerifyVersionInfoW")
+       if e != 0 {
+               t.Fatalf("GetProcAddress(kernel32.dll, VerifyVersionInfoW) failed: %s", syscall.Errstr(e))
+       }
+
+       var m1, m2 uintptr
+       m1, m2, _ = syscall.Syscall6(setMask, 4, m1, m2, VER_MAJORVERSION, VER_GREATER_EQUAL, 0, 0)
+       m1, m2, _ = syscall.Syscall6(setMask, 4, m1, m2, VER_MINORVERSION, VER_GREATER_EQUAL, 0, 0)
+       m1, m2, _ = syscall.Syscall6(setMask, 4, m1, m2, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL, 0, 0)
+       m1, m2, _ = syscall.Syscall6(setMask, 4, m1, m2, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL, 0, 0)
+
+       vi := OSVersionInfoEx{
+               MajorVersion:     5,
+               MinorVersion:     1,
+               ServicePackMajor: 2,
+               ServicePackMinor: 0,
+       }
+       vi.OSVersionInfoSize = uint32(unsafe.Sizeof(vi))
+       r, _, e2 := syscall.Syscall6(verifyVersion,
+               4,
+               uintptr(unsafe.Pointer(&vi)),
+               VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR|VER_SERVICEPACKMINOR,
+               m1, m2, 0, 0)
+       if r == 0 && e2 != ERROR_OLD_WIN_VERSION {
+               t.Errorf("VerifyVersionInfo failed: (%d) %s", e2, syscall.Errstr(int(e2)))
+       }
+}
+
 func TestCDecl(t *testing.T) {
        h, e := syscall.LoadLibrary("user32.dll")
        if e != 0 {
index 94aed83f06d337114291ac8ffbdda6a71cafb1a0..2d41d858d9331d02096e7be6c11206eff402a15d 100644 (file)
@@ -6,35 +6,35 @@
 
 // void runtime·asmstdcall(void *c);
 TEXT runtime·asmstdcall(SB),7,$0
-       MOVL    c+0(FP), DX
+       MOVL    c+0(FP), BX
 
        // SetLastError(0).
        MOVL    $0, 0x34(FS)
 
        // Copy args to the stack.
        MOVL    SP, BP
-       MOVL    wincall_n(DX), CX       // words
-       MOVL    CX, BX
-       SALL    $2, BX
-       SUBL    BX, SP                  // room for args
+       MOVL    wincall_n(BX), CX       // words
+       MOVL    CX, AX
+       SALL    $2, AX
+       SUBL    AX, SP                  // room for args
        MOVL    SP, DI
-       MOVL    wincall_args(DX), SI
+       MOVL    wincall_args(BX), SI
        CLD
        REP; MOVSL
 
        // Call stdcall or cdecl function.
        // DI SI BP BX are preserved, SP is not
-       MOVL    wincall_fn(DX), AX
-       CALL    AX
+       CALL    wincall_fn(BX)
        MOVL    BP, SP
 
        // Return result.
-       MOVL    c+0(FP), DX
-       MOVL    AX, wincall_r(DX)
+       MOVL    c+0(FP), BX
+       MOVL    AX, wincall_r1(BX)
+       MOVL    DX, wincall_r2(BX)
 
        // GetLastError().
-       MOVL    0x34(FS), BX
-       MOVL    BX, wincall_err(DX)
+       MOVL    0x34(FS), AX
+       MOVL    AX, wincall_err(BX)
 
        RET
 
index 9b4a17eda71178e8bb8b892ae7635a91f78469ff..3e50780dc958aaea831cc1f3a1116649eb1302e1 100644 (file)
@@ -49,7 +49,7 @@ loadregs:
 
        // Return result.
        POPQ    CX
-       MOVQ    AX, wincall_r(CX)
+       MOVQ    AX, wincall_r1(CX)
 
        // GetLastError().
        MOVQ    0x30(GS), DI
index a8cc299b8c914e0670f9723e4241661af4e23f0a..0ac5cbfd718c95a19e592dfd7694a05a8a90e37e 100644 (file)
@@ -12,7 +12,6 @@ extern void *runtime·GetProcAddress;
 #pragma        varargck        type            runtime·stdcall        uintptr
 void runtime·asmstdcall(void *c);
 void *runtime·stdcall(void *fn, int32 count, ...);
-uintptr runtime·syscall(void *fn, uintptr nargs, void *args, uintptr *err);
 
 uintptr runtime·getlasterror(void);
 void runtime·setlasterror(uintptr err);
index 4777a618967012813c4a2267ebc52a06ae7d2d64..68c3a4dfab08e08d241c2c050ece082673dda164 100644 (file)
@@ -5,15 +5,28 @@
 package syscall
 #include "runtime.h"
 #include "os.h"
+#include "cgocall.h"
 
 func loadlibraryex(filename uintptr) (handle uintptr) {
        uintptr args[3] = { filename };
-       handle = runtime·syscall(runtime·LoadLibraryEx, 3, args, nil);
+       WinCall c;
+
+       c.fn = runtime·LoadLibraryEx;
+       c.n = 3;
+       c.args = &args[0];
+       runtime·cgocall(runtime·asmstdcall, &c);
+       handle = c.r1;
 }
 
 func getprocaddress(handle uintptr, procname uintptr) (proc uintptr) {
+       WinCall c;
+
        USED(procname);
-       proc = runtime·syscall(runtime·GetProcAddress, 2, &handle, nil);
+       c.fn = runtime·GetProcAddress;
+       c.n = 2;
+       c.args = &handle;
+       runtime·cgocall(runtime·asmstdcall, &c);
+       proc = c.r1;
 }
 
 func NewCallback(fn Eface) (code uintptr) {
@@ -25,23 +38,39 @@ func NewCallbackCDecl(fn Eface) (code uintptr) {
 }
 
 func Syscall(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
+       WinCall c;
+
        USED(a2);
        USED(a3);
-       r1 = runtime·syscall((void*)fn, nargs, &a1, &err);
-       r2 = 0;
+       c.fn = (void*)fn;
+       c.n = nargs;
+       c.args = &a1;
+       runtime·cgocall(runtime·asmstdcall, &c);
+       err = c.err;
+       r1 = c.r1;
+       r2 = c.r2;
 }
 
 func Syscall6(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
+       WinCall c;
+
        USED(a2);
        USED(a3);
        USED(a4);
        USED(a5);
        USED(a6);
-       r1 = runtime·syscall((void*)fn, nargs, &a1, &err);
-       r2 = 0;
+       c.fn = (void*)fn;
+       c.n = nargs;
+       c.args = &a1;
+       runtime·cgocall(runtime·asmstdcall, &c);
+       err = c.err;
+       r1 = c.r1;
+       r2 = c.r2;
 }
 
 func Syscall9(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
+       WinCall c;
+
        USED(a2);
        USED(a3);
        USED(a4);
@@ -50,11 +79,18 @@ func Syscall9(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4
        USED(a7);
        USED(a8);
        USED(a9);
-       r1 = runtime·syscall((void*)fn, nargs, &a1, &err);
-       r2 = 0;
+       c.fn = (void*)fn;
+       c.n = nargs;
+       c.args = &a1;
+       runtime·cgocall(runtime·asmstdcall, &c);
+       err = c.err;
+       r1 = c.r1;
+       r2 = c.r2;
 }
 
 func Syscall12(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr, a10 uintptr, a11 uintptr, a12 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
+       WinCall c;
+
        USED(a2);
        USED(a3);
        USED(a4);
@@ -66,6 +102,11 @@ func Syscall12(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4
        USED(a10);
        USED(a11);
        USED(a12);
-       r1 = runtime·syscall((void*)fn, nargs, &a1, &err);
-       r2 = 0;
+       c.fn = (void*)fn;
+       c.n = nargs;
+       c.args = &a1;
+       runtime·cgocall(runtime·asmstdcall, &c);
+       err = c.err;
+       r1 = c.r1;
+       r2 = c.r2;
 }
index b76eaac596afc5068e9fd7b2494117501b59d1aa..fe8a24f1cd34630853c3956ba594009f4119c5d8 100644 (file)
@@ -6,7 +6,6 @@
 #include "type.h"
 #include "defs.h"
 #include "os.h"
-#include "cgocall.h"
 
 #pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
 #pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
@@ -228,21 +227,7 @@ runtime·stdcall(void *fn, int32 count, ...)
        c.n = count;
        c.args = (uintptr*)&count + 1;
        runtime·asmcgocall(runtime·asmstdcall, &c);
-       return (void*)c.r;
-}
-
-uintptr
-runtime·syscall(void *fn, uintptr nargs, void *args, uintptr *err)
-{
-       WinCall c;
-
-       c.fn = fn;
-       c.n = nargs;
-       c.args = args;
-       runtime·cgocall(runtime·asmstdcall, &c);
-       if(err)
-               *err = c.err;
-       return c.r;
+       return (void*)c.r1;
 }
 
 uint32