Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
c1e20720
Commit
c1e20720
authored
Jun 11, 2010
by
Alex Brainman
Committed by
Russ Cox
Jun 11, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
runtime: switch to OS stack during Windows syscall
R=rsc CC=golang-dev
https://golang.org/cl/1381041
parent
fdb460ec
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
163 additions
and
56 deletions
+163
-56
src/pkg/runtime/windows/386/sys.s
src/pkg/runtime/windows/386/sys.s
+33
-18
src/pkg/runtime/windows/mem.c
src/pkg/runtime/windows/mem.c
+1
-1
src/pkg/runtime/windows/os.h
src/pkg/runtime/windows/os.h
+23
-4
src/pkg/runtime/windows/syscall.goc
src/pkg/runtime/windows/syscall.goc
+61
-13
src/pkg/runtime/windows/thread.c
src/pkg/runtime/windows/thread.c
+45
-20
No files found.
src/pkg/runtime/windows/386/sys.s
View file @
c1e20720
...
...
@@ -12,9 +12,10 @@ TEXT get_kernel_module(SB),7,$0
MOVL
0x08
(
AX
),
AX
//
get
base
of
module
RET
//
TODO
(
rsc
,
hectorchu
):
Switch
to
m
stack
before
call
.
TEXT
stdcall
(
SB
),7,$0
CALL
·
entersyscall
(
SB
)
//
void
*
stdcall_raw
(
void
*
fn
,
...
)
;
//
Call
fn
with
stdcall
calling
convention
.
//
fn
parameters
are
on
stack
.
TEXT
stdcall_raw
(
SB
),7,$0
get_tls
(
CX
)
MOVL
m
(
CX
),
CX
POPL
m_return_address
(
CX
)
//
save
return
address
...
...
@@ -26,23 +27,37 @@ TEXT stdcall(SB),7,$0
MOVL
m_stack_pointer
(
CX
),
SP
PUSHL
AX
PUSHL
m_return_address
(
CX
)
CALL
·
exitsyscall
(
SB
)
MOVL
4
(
SP
),
AX
RET
//
TODO
(
rsc
,
hectorchu
):
Switch
to
m
stack
before
call
.
TEXT
stdcall_raw
(
SB
),7,$0
get_tls
(
CX
)
MOVL
m
(
CX
),
CX
POPL
m_return_address
(
CX
)
//
save
return
address
POPL
AX
//
first
arg
is
function
pointer
MOVL
SP
,
m_stack_pointer
(
CX
)
//
save
stack
pointer
CALL
AX
get_tls
(
CX
)
MOVL
m
(
CX
),
CX
MOVL
m_stack_pointer
(
CX
),
SP
PUSHL
AX
PUSHL
m_return_address
(
CX
)
//
void
syscall
(
StdcallParams
*
p
)
;
//
Call
p
.
fn
syscall
+
GetLastError
on
os
stack
.
TEXT
syscall
(
SB
),7,$16
MOVL
p
+
0
(
FP
),
AX
MOVL
SP
,
CX
//
Figure
out
if
we
need
to
switch
to
m
->
g0
stack
.
get_tls
(
DI
)
MOVL
m
(
DI
),
DX
MOVL
m_g0
(
DX
),
SI
CMPL
g
(
DI
),
SI
JEQ
2
(
PC
)
MOVL
(
m_sched
+
gobuf_sp
)(
DX
),
SP
//
Now
on
a
scheduling
stack
(
an
os
stack
)
.
MOVL
g
(
DI
),
BP
MOVL
BP
,
8
(
SP
)
MOVL
SI
,
g
(
DI
)
MOVL
CX
,
4
(
SP
)
MOVL
AX
,
0
(
SP
)
CALL
call_syscall
(
SB
)
//
Back
; switch to original g and stack, re-establish
//
"DF is clear"
invariant
.
CLD
get_tls
(
DI
)
MOVL
8
(
SP
),
SI
MOVL
SI
,
g
(
DI
)
MOVL
4
(
SP
),
SP
RET
TEXT
threadstart
(
SB
),7,$0
...
...
src/pkg/runtime/windows/mem.c
View file @
c1e20720
...
...
@@ -10,7 +10,7 @@
void
*
SysAlloc
(
uintptr
n
)
{
return
stdcall
_raw
(
VirtualAlloc
,
nil
,
n
,
0x3000
,
0x40
);
return
stdcall
(
VirtualAlloc
,
4
,
nil
,
n
,
0x3000
,
0x40
);
}
void
...
...
src/pkg/runtime/windows/os.h
View file @
c1e20720
...
...
@@ -7,10 +7,6 @@
// The arguments are strings.
void
*
get_proc_addr
(
void
*
library
,
void
*
name
);
// Call a Windows function with stdcall conventions.
void
*
stdcall
(
void
*
fn
,
...);
void
*
stdcall_raw
(
void
*
fn
,
...);
extern
void
*
VirtualAlloc
;
extern
void
*
LoadLibraryEx
;
extern
void
*
GetProcAddress
;
...
...
@@ -21,3 +17,26 @@ void windows_goargs(void);
// Get start address of symbol data in memory.
void
*
get_symdat_addr
(
void
);
// Call a Windows function with stdcall conventions.
void
*
stdcall_raw
(
void
*
fn
,
...);
// Call a Windows function with stdcall conventions,
// and switch to os stack during the call.
void
*
stdcall
(
void
*
fn
,
int32
count
,
...);
// Call stdcall Windows function StdcallParams.fn
// with params StdcallParams.args,
// followed immediately by GetLastError call.
// Both return values are returned in StdcallParams.r and
// StdcallParams.err. Will use os stack during the call.
typedef
struct
StdcallParams
StdcallParams
;
struct
StdcallParams
{
void
*
fn
;
uintptr
args
[
9
];
uintptr
r
;
uintptr
err
;
};
void
call_syscall
(
void
*
args
);
void
syscall
(
StdcallParams
*
p
);
src/pkg/runtime/windows/syscall.goc
View file @
c1e20720
...
...
@@ -7,39 +7,87 @@ package syscall
#
include
"os.h"
func
loadlibraryex
(
filename
uintptr
)
(
handle
uint32
)
{
handle
=
(
uint32
)
stdcall
(
LoadLibraryEx
,
filename
,
0
,
0
);
StdcallParams
p
;
p
.
fn
=
(
void
*)
LoadLibraryEx
;
p
.
args
[
0
]
=
filename
;
p
.
args
[
1
]
=
0
;
p
.
args
[
2
]
=
0
;
·
entersyscall
();
syscall
(&
p
);
·
exitsyscall
();
handle
=
p
.
r
;
}
func
getprocaddress
(
handle
uint32
,
procname
uintptr
)
(
proc
uintptr
)
{
proc
=
(
uintptr
)
stdcall
(
GetProcAddress
,
handle
,
procname
);
StdcallParams
p
;
p
.
fn
=
(
void
*)
GetProcAddress
;
p
.
args
[
0
]
=
handle
;
p
.
args
[
1
]
=
procname
;
·
entersyscall
();
syscall
(&
p
);
·
exitsyscall
();
proc
=
p
.
r
;
}
func
Syscall
(
trap
uintptr
,
a1
uintptr
,
a2
uintptr
,
a3
uintptr
)
(
r1
uintptr
,
r2
uintptr
,
err
uintptr
)
{
StdcallParams
p
;
p
.
fn
=
(
void
*)
trap
;
p
.
args
[
0
]
=
a1
;
p
.
args
[
1
]
=
a2
;
p
.
args
[
2
]
=
a3
;
·
entersyscall
();
r1
=
(
uintptr
)
stdcall_raw
((
void
*)
trap
,
a1
,
a2
,
a3
);
r2
=
0
;
err
=
(
uintptr
)
stdcall_raw
(
GetLastError
);
syscall
(&
p
);
·
exitsyscall
();
r1
=
p
.
r
;
r2
=
0
;
err
=
p
.
err
;
}
func
Syscall6
(
trap
uintptr
,
a1
uintptr
,
a2
uintptr
,
a3
uintptr
,
a4
uintptr
,
a5
uintptr
,
a6
uintptr
)
(
r1
uintptr
,
r2
uintptr
,
err
uintptr
)
{
StdcallParams
p
;
p
.
fn
=
(
void
*)
trap
;
p
.
args
[
0
]
=
a1
;
p
.
args
[
1
]
=
a2
;
p
.
args
[
2
]
=
a3
;
p
.
args
[
3
]
=
a4
;
p
.
args
[
4
]
=
a5
;
p
.
args
[
5
]
=
a6
;
·
entersyscall
();
r1
=
(
uintptr
)
stdcall_raw
((
void
*)
trap
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
);
r2
=
0
;
err
=
(
uintptr
)
stdcall_raw
(
GetLastError
);
syscall
(&
p
);
·
exitsyscall
();
r1
=
p
.
r
;
r2
=
0
;
err
=
p
.
err
;
}
func
Syscall9
(
trap
uintptr
,
a1
uintptr
,
a2
uintptr
,
a3
uintptr
,
a4
uintptr
,
a5
uintptr
,
a6
uintptr
,
a7
uintptr
,
a8
uintptr
,
a9
uintptr
)
(
r1
uintptr
,
r2
uintptr
,
lasterr
uintptr
)
{
StdcallParams
p
;
p
.
fn
=
(
void
*)
trap
;
p
.
args
[
0
]
=
a1
;
p
.
args
[
1
]
=
a2
;
p
.
args
[
2
]
=
a3
;
p
.
args
[
3
]
=
a4
;
p
.
args
[
4
]
=
a5
;
p
.
args
[
5
]
=
a6
;
p
.
args
[
6
]
=
a7
;
p
.
args
[
7
]
=
a8
;
p
.
args
[
8
]
=
a9
;
·
entersyscall
();
r1
=
(
uintptr
)
stdcall_raw
((
void
*)
trap
,
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
);
r2
=
0
;
lasterr
=
(
uintptr
)
stdcall_raw
(
GetLastError
);
syscall
(&
p
);
·
exitsyscall
();
r1
=
p
.
r
;
r2
=
0
;
lasterr
=
p
.
err
;
}
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
);
StdcallParams
p
;
p
.
fn
=
(
void
*)
trap
;
p
.
args
[
0
]
=
a1
;
p
.
args
[
1
]
=
a2
;
p
.
args
[
2
]
=
a3
;
syscall
(&
p
);
r1
=
p
.
r
;
r2
=
0
;
err
=
(
uintptr
)
stdcall_raw
(
GetLastError
)
;
err
=
p
.
err
;
}
src/pkg/runtime/windows/thread.c
View file @
c1e20720
...
...
@@ -5,8 +5,6 @@
#include "runtime.h"
#include "os.h"
#define stdcall stdcall_raw
extern
void
*
get_kernel_module
(
void
);
// Also referenced by external packages
...
...
@@ -75,8 +73,8 @@ get_proc_addr(void *library, void *name)
{
void
*
base
;
base
=
stdcall
(
LoadLibraryEx
,
library
,
0
,
0
);
return
stdcall
(
GetProcAddress
,
base
,
name
);
base
=
stdcall
_raw
(
LoadLibraryEx
,
library
,
0
,
0
);
return
stdcall
_raw
(
GetProcAddress
,
base
,
name
);
}
void
...
...
@@ -96,9 +94,9 @@ windows_goargs(void)
clta
=
get_proc_addr
(
"shell32.dll"
,
"CommandLineToArgvW"
);
ges
=
get_proc_addr
(
"kernel32.dll"
,
"GetEnvironmentStringsW"
);
cmd
=
stdcall
(
gcl
);
env
=
stdcall
(
ges
);
argv
=
stdcall
(
clta
,
cmd
,
&
argc
);
cmd
=
stdcall
(
gcl
,
0
);
env
=
stdcall
(
ges
,
0
);
argv
=
stdcall
(
clta
,
2
,
cmd
,
&
argc
);
envc
=
0
;
for
(
envp
=
env
;
*
envp
;
envc
++
)
...
...
@@ -126,7 +124,7 @@ windows_goargs(void)
void
exit
(
int32
code
)
{
stdcall
(
ExitProcess
,
code
);
stdcall
(
ExitProcess
,
1
,
code
);
}
int32
...
...
@@ -138,15 +136,15 @@ write(int32 fd, void *buf, int32 n)
written
=
0
;
switch
(
fd
)
{
case
1
:
handle
=
stdcall
(
GetStdHandle
,
-
11
);
handle
=
stdcall
(
GetStdHandle
,
1
,
-
11
);
break
;
case
2
:
handle
=
stdcall
(
GetStdHandle
,
-
12
);
handle
=
stdcall
(
GetStdHandle
,
1
,
-
12
);
break
;
default:
return
-
1
;
}
stdcall
(
WriteFile
,
handle
,
buf
,
n
,
&
written
,
0
);
stdcall
(
WriteFile
,
5
,
handle
,
buf
,
n
,
&
written
,
0
);
return
written
;
}
...
...
@@ -157,7 +155,7 @@ get_symdat_addr(void)
uint32
peh
,
add
;
uint16
oph
;
mod
=
stdcall
(
GetModuleHandle
,
0
);
mod
=
stdcall
(
GetModuleHandle
,
1
,
0
);
peh
=
*
(
uint32
*
)(
mod
+
0x3c
);
p
=
mod
+
peh
+
4
;
oph
=
*
(
uint16
*
)(
p
+
0x10
);
...
...
@@ -174,10 +172,10 @@ initevent(void **pevent)
{
void
*
event
;
event
=
stdcall
(
CreateEvent
,
0
,
0
,
0
,
0
);
event
=
stdcall
(
CreateEvent
,
4
,
0
,
0
,
0
,
0
);
if
(
!
casp
(
pevent
,
0
,
event
))
{
// Someone else filled it in. Use theirs.
stdcall
(
CloseHandle
,
event
);
stdcall
(
CloseHandle
,
1
,
event
);
}
}
...
...
@@ -189,14 +187,14 @@ eventlock(Lock *l)
initevent
(
&
l
->
event
);
if
(
xadd
(
&
l
->
key
,
1
)
>
1
)
// someone else has it; wait
stdcall
(
WaitForSingleObject
,
l
->
event
,
-
1
);
stdcall
(
WaitForSingleObject
,
2
,
l
->
event
,
-
1
);
}
static
void
eventunlock
(
Lock
*
l
)
{
if
(
xadd
(
&
l
->
key
,
-
1
)
>
0
)
// someone else is waiting
stdcall
(
SetEvent
,
l
->
event
);
stdcall
(
SetEvent
,
1
,
l
->
event
);
}
void
...
...
@@ -253,10 +251,10 @@ newosproc(M *m, G *g, void *stk, void (*fn)(void))
extern
uint32
threadstart
(
void
*
p
);
USED
(
g
,
stk
,
fn
);
param
.
event_handle
=
stdcall
(
CreateEvent
,
0
,
0
,
0
,
0
);
stdcall
(
CreateThread
,
0
,
0
,
threadstart
,
&
param
,
0
,
0
);
stdcall
(
WaitForSingleObject
,
param
.
event_handle
,
-
1
);
stdcall
(
CloseHandle
,
param
.
event_handle
);
param
.
event_handle
=
stdcall
(
CreateEvent
,
4
,
0
,
0
,
0
,
0
);
stdcall
(
CreateThread
,
6
,
0
,
0
,
threadstart
,
&
param
,
0
,
0
);
stdcall
(
WaitForSingleObject
,
2
,
param
.
event_handle
,
-
1
);
stdcall
(
CloseHandle
,
1
,
param
.
event_handle
);
}
// Called to initialize a new m (including the bootstrap m).
...
...
@@ -264,3 +262,30 @@ void
minit
(
void
)
{
}
// Calling stdcall on os stack.
#pragma textflag 7
void
*
stdcall
(
void
*
fn
,
int32
count
,
...)
{
uintptr
*
a
;
StdcallParams
p
;
p
.
fn
=
fn
;
a
=
(
uintptr
*
)(
&
count
+
1
);
while
(
count
>
0
)
{
count
--
;
p
.
args
[
count
]
=
a
[
count
];
}
syscall
(
&
p
);
return
(
void
*
)(
p
.
r
);
}
void
call_syscall
(
void
*
args
)
{
StdcallParams
*
p
=
(
StdcallParams
*
)
args
;
p
->
r
=
(
uintptr
)
stdcall_raw
((
void
*
)
p
->
fn
,
p
->
args
[
0
],
p
->
args
[
1
],
p
->
args
[
2
],
p
->
args
[
3
],
p
->
args
[
4
],
p
->
args
[
5
],
p
->
args
[
6
],
p
->
args
[
7
],
p
->
args
[
8
]);
p
->
err
=
(
uintptr
)
stdcall_raw
(
GetLastError
);
return
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment