Commit ab4578ad authored by Alex Brainman's avatar Alex Brainman

[dev.cc] runtime: convert remaining windows C code to Go

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/177090043
parent f4a52545
...@@ -152,5 +152,5 @@ func handlecompletion(gpp **g, op *net_op, errno int32, qty uint32) { ...@@ -152,5 +152,5 @@ func handlecompletion(gpp **g, op *net_op, errno int32, qty uint32) {
} }
op.errno = errno op.errno = errno
op.qty = qty op.qty = qty
netpollready(gpp, op.pd, mode) netpollready((**g)(noescape(unsafe.Pointer(gpp))), op.pd, mode)
} }
This diff is collapsed.
...@@ -2,63 +2,60 @@ ...@@ -2,63 +2,60 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include "runtime.h" package runtime
#include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h" import (
"unsafe"
void )
runtime·dumpregs(Context *r)
{ var text struct{}
runtime·printf("eax %x\n", r->Eax);
runtime·printf("ebx %x\n", r->Ebx); func dumpregs(r *context) {
runtime·printf("ecx %x\n", r->Ecx); print("eax ", hex(r.eax), "\n")
runtime·printf("edx %x\n", r->Edx); print("ebx ", hex(r.ebx), "\n")
runtime·printf("edi %x\n", r->Edi); print("ecx ", hex(r.ecx), "\n")
runtime·printf("esi %x\n", r->Esi); print("edx ", hex(r.edx), "\n")
runtime·printf("ebp %x\n", r->Ebp); print("edi ", hex(r.edi), "\n")
runtime·printf("esp %x\n", r->Esp); print("esi ", hex(r.esi), "\n")
runtime·printf("eip %x\n", r->Eip); print("ebp ", hex(r.ebp), "\n")
runtime·printf("eflags %x\n", r->EFlags); print("esp ", hex(r.esp), "\n")
runtime·printf("cs %x\n", r->SegCs); print("eip ", hex(r.eip), "\n")
runtime·printf("fs %x\n", r->SegFs); print("eflags ", hex(r.eflags), "\n")
runtime·printf("gs %x\n", r->SegGs); print("cs ", hex(r.segcs), "\n")
print("fs ", hex(r.segfs), "\n")
print("gs ", hex(r.seggs), "\n")
} }
bool func isgoexception(info *exceptionrecord, r *context) bool {
runtime·isgoexception(ExceptionRecord *info, Context *r)
{
extern byte runtime·text[], runtime·etext[];
// Only handle exception if executing instructions in Go binary // Only handle exception if executing instructions in Go binary
// (not Windows library code). // (not Windows library code).
if(r->Eip < (uint32)runtime·text || (uint32)runtime·etext < r->Eip) if r.eip < uint32(uintptr(unsafe.Pointer(&text))) || uint32(uintptr(unsafe.Pointer(&etext))) < r.eip {
return false; return false
}
if(!runtime·issigpanic(info->ExceptionCode)) if issigpanic(info.exceptioncode) == 0 {
return false; return false
}
return true; return true
} }
// Called by sigtramp from Windows VEH handler. // Called by sigtramp from Windows VEH handler.
// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION) // Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH). // or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
uint32 func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp) if !isgoexception(info, r) {
{ return _EXCEPTION_CONTINUE_SEARCH
uintptr *sp; }
if(!runtime·isgoexception(info, r))
return EXCEPTION_CONTINUE_SEARCH;
// Make it look like a call to the signal func. // Make it look like a call to the signal func.
// Have to pass arguments out of band since // Have to pass arguments out of band since
// augmenting the stack frame would break // augmenting the stack frame would break
// the unwinding code. // the unwinding code.
gp->sig = info->ExceptionCode; gp.sig = info.exceptioncode
gp->sigcode0 = info->ExceptionInformation[0]; gp.sigcode0 = uintptr(info.exceptioninformation[0])
gp->sigcode1 = info->ExceptionInformation[1]; gp.sigcode1 = uintptr(info.exceptioninformation[1])
gp->sigpc = r->Eip; gp.sigpc = uintptr(r.eip)
// Only push runtime·sigpanic if r->eip != 0. // Only push runtime·sigpanic if r->eip != 0.
// If r->eip == 0, probably panicked because of a // If r->eip == 0, probably panicked because of a
...@@ -66,63 +63,56 @@ runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp) ...@@ -66,63 +63,56 @@ runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
// make the trace look like a call to runtime·sigpanic instead. // make the trace look like a call to runtime·sigpanic instead.
// (Otherwise the trace will end at runtime·sigpanic and we // (Otherwise the trace will end at runtime·sigpanic and we
// won't get to see who faulted.) // won't get to see who faulted.)
if(r->Eip != 0) { if r.eip != 0 {
sp = (uintptr*)r->Esp; sp := unsafe.Pointer(uintptr(r.esp))
*--sp = r->Eip; sp = add(sp, ^uintptr(unsafe.Sizeof(uintptr(0))-1)) // sp--
r->Esp = (uintptr)sp; *((*uintptr)(sp)) = uintptr(r.eip)
r.esp = uint32(uintptr(sp))
} }
r->Eip = (uintptr)runtime·sigpanic; r.eip = uint32(funcPC(sigpanic))
return EXCEPTION_CONTINUE_EXECUTION; return _EXCEPTION_CONTINUE_EXECUTION
} }
// lastcontinuehandler is reached, because runtime cannot handle // lastcontinuehandler is reached, because runtime cannot handle
// current exception. lastcontinuehandler will print crash info and exit. // current exception. lastcontinuehandler will print crash info and exit.
uint32 func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp) _g_ := getg()
{
bool crash; if panicking != 0 { // traceback already printed
exit(2)
if(runtime·panicking) // traceback already printed }
runtime·exit(2); panicking = 1
runtime·panicking = 1;
print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.eip), "\n")
runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
(uintptr)info->ExceptionInformation[0], (uintptr)info->ExceptionInformation[1], (uintptr)r->Eip); print("PC=", hex(r.eip), "\n")
if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
runtime·printf("PC=%x\n", r->Eip); print("signal arrived during cgo execution\n")
if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) { gp = _g_.m.lockedg
runtime·printf("signal arrived during cgo execution\n"); }
gp = g->m->lockedg; print("\n")
var docrash bool
if gotraceback(&docrash) > 0 {
tracebacktrap(uintptr(r.eip), uintptr(r.esp), 0, gp)
tracebackothers(gp)
dumpregs(r)
} }
runtime·printf("\n");
if(runtime·gotraceback(&crash)){ if docrash {
runtime·tracebacktrap(r->Eip, r->Esp, 0, gp); crash()
runtime·tracebackothers(gp);
runtime·dumpregs(r);
} }
if(crash)
runtime·crash();
runtime·exit(2); exit(2)
return 0; // not reached return 0 // not reached
} }
void func sigenable(sig uint32) {
runtime·sigenable(uint32 sig)
{
USED(sig);
} }
void func sigdisable(sig uint32) {
runtime·sigdisable(uint32 sig)
{
USED(sig);
} }
void func dosigprof(r *context, gp *g, mp *m) {
runtime·dosigprof(Context *r, G *gp, M *mp) sigprof((*byte)(unsafe.Pointer(uintptr(r.eip))), (*byte)(unsafe.Pointer(uintptr(r.esp))), nil, gp, mp)
{
runtime·sigprof((uint8*)r->Eip, (uint8*)r->Esp, nil, gp, mp);
} }
...@@ -2,71 +2,68 @@ ...@@ -2,71 +2,68 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include "runtime.h" package runtime
#include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h" import (
"unsafe"
void )
runtime·dumpregs(Context *r)
{ var text struct{}
runtime·printf("rax %X\n", r->Rax);
runtime·printf("rbx %X\n", r->Rbx); func dumpregs(r *context) {
runtime·printf("rcx %X\n", r->Rcx); print("rax ", hex(r.rax), "\n")
runtime·printf("rdx %X\n", r->Rdx); print("rbx ", hex(r.rbx), "\n")
runtime·printf("rdi %X\n", r->Rdi); print("rcx ", hex(r.rcx), "\n")
runtime·printf("rsi %X\n", r->Rsi); print("rdi ", hex(r.rdi), "\n")
runtime·printf("rbp %X\n", r->Rbp); print("rsi ", hex(r.rsi), "\n")
runtime·printf("rsp %X\n", r->Rsp); print("rbp ", hex(r.rbp), "\n")
runtime·printf("r8 %X\n", r->R8 ); print("rsp ", hex(r.rsp), "\n")
runtime·printf("r9 %X\n", r->R9 ); print("r8 ", hex(r.r8), "\n")
runtime·printf("r10 %X\n", r->R10); print("r9 ", hex(r.r9), "\n")
runtime·printf("r11 %X\n", r->R11); print("r10 ", hex(r.r10), "\n")
runtime·printf("r12 %X\n", r->R12); print("r11 ", hex(r.r11), "\n")
runtime·printf("r13 %X\n", r->R13); print("r12 ", hex(r.r12), "\n")
runtime·printf("r14 %X\n", r->R14); print("r13 ", hex(r.r13), "\n")
runtime·printf("r15 %X\n", r->R15); print("r14 ", hex(r.r14), "\n")
runtime·printf("rip %X\n", r->Rip); print("r15 ", hex(r.r15), "\n")
runtime·printf("rflags %X\n", r->EFlags); print("rip ", hex(r.rip), "\n")
runtime·printf("cs %X\n", (uint64)r->SegCs); print("rflags ", hex(r.eflags), "\n")
runtime·printf("fs %X\n", (uint64)r->SegFs); print("cs ", hex(r.segcs), "\n")
runtime·printf("gs %X\n", (uint64)r->SegGs); print("fs ", hex(r.segfs), "\n")
print("gs ", hex(r.seggs), "\n")
} }
bool func isgoexception(info *exceptionrecord, r *context) bool {
runtime·isgoexception(ExceptionRecord *info, Context *r)
{
extern byte runtime·text[], runtime·etext[];
// Only handle exception if executing instructions in Go binary // Only handle exception if executing instructions in Go binary
// (not Windows library code). // (not Windows library code).
if(r->Rip < (uint64)runtime·text || (uint64)runtime·etext < r->Rip) if r.rip < uint64(uintptr(unsafe.Pointer(&text))) || uint64(uintptr(unsafe.Pointer(&etext))) < r.rip {
return false; return false
}
if(!runtime·issigpanic(info->ExceptionCode)) if issigpanic(info.exceptioncode) == 0 {
return false; return false
}
return true; return true
} }
// Called by sigtramp from Windows VEH handler. // Called by sigtramp from Windows VEH handler.
// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION) // Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH). // or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
uint32
runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
{
uintptr *sp;
if(!runtime·isgoexception(info, r)) func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
return EXCEPTION_CONTINUE_SEARCH; if !isgoexception(info, r) {
return _EXCEPTION_CONTINUE_SEARCH
}
// Make it look like a call to the signal func. // Make it look like a call to the signal func.
// Have to pass arguments out of band since // Have to pass arguments out of band since
// augmenting the stack frame would break // augmenting the stack frame would break
// the unwinding code. // the unwinding code.
gp->sig = info->ExceptionCode; gp.sig = info.exceptioncode
gp->sigcode0 = info->ExceptionInformation[0]; gp.sigcode0 = uintptr(info.exceptioninformation[0])
gp->sigcode1 = info->ExceptionInformation[1]; gp.sigcode1 = uintptr(info.exceptioninformation[1])
gp->sigpc = r->Rip; gp.sigpc = uintptr(r.rip)
// Only push runtime·sigpanic if r->rip != 0. // Only push runtime·sigpanic if r->rip != 0.
// If r->rip == 0, probably panicked because of a // If r->rip == 0, probably panicked because of a
...@@ -74,77 +71,67 @@ runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp) ...@@ -74,77 +71,67 @@ runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
// make the trace look like a call to runtime·sigpanic instead. // make the trace look like a call to runtime·sigpanic instead.
// (Otherwise the trace will end at runtime·sigpanic and we // (Otherwise the trace will end at runtime·sigpanic and we
// won't get to see who faulted.) // won't get to see who faulted.)
if(r->Rip != 0) { if r.rip != 0 {
sp = (uintptr*)r->Rsp; sp := unsafe.Pointer(uintptr(r.rsp))
*--sp = r->Rip; sp = add(sp, ^uintptr(unsafe.Sizeof(uintptr(0))-1)) // sp--
r->Rsp = (uintptr)sp; *((*uintptr)(sp)) = uintptr(r.rip)
r.rsp = uint64(uintptr(sp))
} }
r->Rip = (uintptr)runtime·sigpanic; r.rip = uint64(funcPC(sigpanic))
return EXCEPTION_CONTINUE_EXECUTION; return _EXCEPTION_CONTINUE_EXECUTION
} }
// It seems Windows searches ContinueHandler's list even // It seems Windows searches ContinueHandler's list even
// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION. // if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
// firstcontinuehandler will stop that search, // firstcontinuehandler will stop that search,
// if exceptionhandler did the same earlier. // if exceptionhandler did the same earlier.
uint32 func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
runtime·firstcontinuehandler(ExceptionRecord *info, Context *r, G *gp) if !isgoexception(info, r) {
{ return _EXCEPTION_CONTINUE_SEARCH
USED(gp); }
if(!runtime·isgoexception(info, r)) return _EXCEPTION_CONTINUE_EXECUTION
return EXCEPTION_CONTINUE_SEARCH;
return EXCEPTION_CONTINUE_EXECUTION;
} }
// lastcontinuehandler is reached, because runtime cannot handle // lastcontinuehandler is reached, because runtime cannot handle
// current exception. lastcontinuehandler will print crash info and exit. // current exception. lastcontinuehandler will print crash info and exit.
uint32 func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) uint32 {
runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp) _g_ := getg()
{
bool crash;
if(runtime·panicking) // traceback already printed if panicking != 0 { // traceback already printed
runtime·exit(2); exit(2)
runtime·panicking = 1; }
panicking = 1
runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode, print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.rip), "\n")
info->ExceptionInformation[0], info->ExceptionInformation[1], r->Rip);
print("PC=", hex(r.rip), "\n")
if _g_.m.lockedg != nil && _g_.m.ncgo > 0 && gp == _g_.m.g0 {
print("signal arrived during cgo execution\n")
gp = _g_.m.lockedg
}
print("\n")
runtime·printf("PC=%X\n", r->Rip); var docrash bool
if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) { if gotraceback(&docrash) > 0 {
runtime·printf("signal arrived during cgo execution\n"); tracebacktrap(uintptr(r.rip), uintptr(r.rsp), 0, gp)
gp = g->m->lockedg; tracebackothers(gp)
dumpregs(r)
} }
runtime·printf("\n");
if(runtime·gotraceback(&crash)){ if docrash {
runtime·tracebacktrap(r->Rip, r->Rsp, 0, gp); crash()
runtime·tracebackothers(gp);
runtime·dumpregs(r);
} }
if(crash)
runtime·crash();
runtime·exit(2); exit(2)
return 0; // not reached return 0 // not reached
} }
void func sigenable(sig uint32) {
runtime·sigenable(uint32 sig)
{
USED(sig);
} }
void func sigdisable(sig uint32) {
runtime·sigdisable(uint32 sig)
{
USED(sig);
} }
void func dosigprof(r *context, gp *g, mp *m) {
runtime·dosigprof(Context *r, G *gp, M *mp) sigprof((*byte)(unsafe.Pointer(uintptr(r.rip))), (*byte)(unsafe.Pointer(uintptr(r.rsp))), nil, gp, mp)
{
runtime·sigprof((uint8*)r->Rip, (uint8*)r->Rsp, nil, gp, mp);
} }
// 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 runtime
import "unsafe"
// Call a Windows function with stdcall conventions,
// and switch to os stack during the call.
func asmstdcall(fn unsafe.Pointer)
func getlasterror() uint32
func setlasterror(err uint32)
// Function to be called by windows CreateThread
// to start new os thread.
func tstart_stdcall(newm *m) uint32
func ctrlhandler(_type uint32) uint32
// TODO(brainman): should not need those
const (
_NSIG = 65
)
This diff is collapsed.
...@@ -4,24 +4,8 @@ ...@@ -4,24 +4,8 @@
package runtime package runtime
import "unsafe"
type stdFunction *byte type stdFunction *byte
func stdcall0(fn stdFunction) uintptr
func stdcall1(fn stdFunction, a0 uintptr) uintptr
func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr
func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr
func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr
func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr
func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr
func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr
func asmstdcall(fn unsafe.Pointer)
func getlasterror() uint32
func setlasterror(err uint32)
func usleep1(usec uint32)
func os_sigpipe() { func os_sigpipe() {
gothrow("too many writes on closed pipe") gothrow("too many writes on closed pipe")
} }
......
// 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.
extern void *runtime·LoadLibrary;
extern void *runtime·GetProcAddress;
extern void *runtime·GetQueuedCompletionStatusEx;
// Call a Windows function with stdcall conventions,
// and switch to os stack during the call.
void runtime·asmstdcall(void *c);
void *runtime·stdcall0(void *fn);
void *runtime·stdcall1(void *fn, uintptr a0);
void *runtime·stdcall2(void *fn, uintptr a0, uintptr a1);
void *runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2);
void *runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3);
void *runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4);
void *runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5);
void *runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6);
uint32 runtime·getlasterror(void);
void runtime·setlasterror(uint32 err);
// Function to be called by windows CreateThread
// to start new os thread.
uint32 runtime·tstart_stdcall(M *newm);
uint32 runtime·issigpanic(uint32);
void runtime·sigpanic(void);
uint32 runtime·ctrlhandler(uint32 type);
// Windows dll function to go callback entry.
byte *runtime·compilecallback(Eface fn, bool cleanstack);
void *runtime·callbackasm(void);
void runtime·install_exception_handler(void);
void runtime·remove_exception_handler(void);
// TODO(brainman): should not need those
enum {
NSIG = 65,
};
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build !solaris // +build !solaris
// +build !windows
package runtime package runtime
......
...@@ -41,20 +41,20 @@ func callbackasmAddr(i int) uintptr { ...@@ -41,20 +41,20 @@ func callbackasmAddr(i int) uintptr {
func compileCallback(fn eface, cleanstack bool) (code uintptr) { func compileCallback(fn eface, cleanstack bool) (code uintptr) {
if fn._type == nil || (fn._type.kind&kindMask) != kindFunc { if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
panic("compilecallback: not a function") panic("compileCallback: not a function")
} }
ft := (*functype)(unsafe.Pointer(fn._type)) ft := (*functype)(unsafe.Pointer(fn._type))
if len(ft.out) != 1 { if ft.out.len != 1 {
panic("compilecallback: function must have one output parameter") panic("compileCallback: function must have one output parameter")
} }
uintptrSize := unsafe.Sizeof(uintptr(0)) uintptrSize := unsafe.Sizeof(uintptr(0))
if t := (**_type)(unsafe.Pointer(&ft.out[0])); (*t).size != uintptrSize { if t := (**_type)(unsafe.Pointer(ft.out.array)); (*t).size != uintptrSize {
panic("compilecallback: output parameter size is wrong") panic("compileCallback: output parameter size is wrong")
} }
argsize := uintptr(0) argsize := uintptr(0)
for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] { for _, t := range (*[1024](*_type))(unsafe.Pointer(ft.in.array))[:ft.in.len] {
if (*t).size > uintptrSize { if (*t).size > uintptrSize {
panic("compilecallback: input parameter size is wrong") panic("compileCallback: input parameter size is wrong")
} }
argsize += uintptrSize argsize += uintptrSize
} }
...@@ -87,8 +87,6 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) { ...@@ -87,8 +87,6 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) {
return callbackasmAddr(n) return callbackasmAddr(n)
} }
func getLoadLibrary() uintptr
//go:nosplit //go:nosplit
func syscall_loadlibrary(filename *uint16) (handle, err uintptr) { func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
var c libcall var c libcall
...@@ -103,8 +101,6 @@ func syscall_loadlibrary(filename *uint16) (handle, err uintptr) { ...@@ -103,8 +101,6 @@ func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
return return
} }
func getGetProcAddress() uintptr
//go:nosplit //go:nosplit
func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) { func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
var c libcall var c libcall
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment