Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
3dff7bb8
Commit
3dff7bb8
authored
Jul 11, 1999
by
Ulrich Weigand
Committed by
Alexandre Julliard
Jul 11, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modularized CallFrom/To16 routines. Adapted dependent routines,
16-bit snoop/relay debugging, and make rules.
parent
03c13bbd
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
1394 additions
and
1168 deletions
+1394
-1168
Make.rules.in
Make.rules.in
+15
-4
.cvsignore
if1632/.cvsignore
+90
-44
Makefile.in
if1632/Makefile.in
+7
-18
builtin.c
if1632/builtin.c
+9
-7
relay.c
if1632/relay.c
+42
-42
snoop.c
if1632/snoop.c
+3
-3
thunk.c
if1632/thunk.c
+119
-122
builtin16.h
include/builtin16.h
+63
-0
callback.h
include/callback.h
+27
-27
module.h
include/module.h
+1
-1
stackframe.h
include/stackframe.h
+14
-11
callback.c
misc/callback.c
+47
-123
main.c
miscemu/main.c
+2
-6
.cvsignore
relay32/.cvsignore
+43
-43
Makefile.in
relay32/Makefile.in
+2
-18
syslevel.c
scheduler/syslevel.c
+4
-13
build.c
tools/build.c
+906
-686
No files found.
Make.rules.in
View file @
3dff7bb8
...
@@ -9,6 +9,8 @@
...
@@ -9,6 +9,8 @@
# ASM_SRCS : assembly sources (optional)
# ASM_SRCS : assembly sources (optional)
# GEN_ASM_SRCS : generated assembly sources (optional)
# GEN_ASM_SRCS : generated assembly sources (optional)
# RC_SRCS : resource source files (optional)
# RC_SRCS : resource source files (optional)
# SPEC_SRCS : interface definition files (optional)
# GLUE : C sources for which glue code needs to be generated (optional)
# EXTRA_SRCS : extra source files for make depend (optional)
# EXTRA_SRCS : extra source files for make depend (optional)
# EXTRA_OBJS : extra object files (optional)
# EXTRA_OBJS : extra object files (optional)
# WRCEXTRA : extra wrc flags (e.g. '-p _SysRes') (optional)
# WRCEXTRA : extra wrc flags (e.g. '-p _SysRes') (optional)
...
@@ -69,12 +71,12 @@ mandir = @mandir@/man1
...
@@ -69,12 +71,12 @@ mandir = @mandir@/man1
manext = .1
manext = .1
includedir = @includedir@/wine
includedir = @includedir@/wine
OBJS = $(C_SRCS:.c=.o) $(GEN_ASM_SRCS:.s=.o) $(ASM_SRCS:.S=.o) \
OBJS = $(C_SRCS:.c=.o) $(GEN_ASM_SRCS:.s=.o) $(ASM_SRCS:.S=.o)
$(RC_SRCS:.rc=.o)
\
$(
RC_SRCS:.rc=
.o) $(EXTRA_OBJS)
$(
SPEC_SRCS:.spec=.spec.o) $(GLUE:.c=.glue
.o) $(EXTRA_OBJS)
# Implicit rules
# Implicit rules
.SUFFIXES: .rc .res
.SUFFIXES: .rc .res
.spec .spec.c .glue.s
.c.o:
.c.o:
$(CC) -c $(ALLCFLAGS) -o $*.o $<
$(CC) -c $(ALLCFLAGS) -o $*.o $<
...
@@ -100,6 +102,11 @@ OBJS = $(C_SRCS:.c=.o) $(GEN_ASM_SRCS:.s=.o) $(ASM_SRCS:.S=.o) \
...
@@ -100,6 +102,11 @@ OBJS = $(C_SRCS:.c=.o) $(GEN_ASM_SRCS:.s=.o) $(ASM_SRCS:.S=.o) \
.res.h:
.res.h:
$(WRC) $(WRCFLAGS) $(WRCEXTRA) -bnh $<
$(WRC) $(WRCFLAGS) $(WRCEXTRA) -bnh $<
.spec.spec.c:
$(BUILD) -o $@ -spec $<
.c.glue.s:
$(BUILD) -o $@ -glue $<
# Rule to rebuild the resource compiler
# Rule to rebuild the resource compiler
...
@@ -147,11 +154,15 @@ lint:
...
@@ -147,11 +154,15 @@ lint:
# Misc. rules
# Misc. rules
$(SPEC_SRCS:.spec=.spec.c): $(BUILD) $(TOPSRCDIR)/include/builtin16.h $(TOPSRCDIR)/include/builtin32.h
$(GLUE:.c=.glue.s): $(BUILD)
depend:: $(MAKEDEP) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
depend:: $(MAKEDEP) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
$(MAKEDEP) $(DIVINCL) -C$(SRCDIR) $(C_SRCS) $(RC_SRCS) $(EXTRA_SRCS)
clean::
clean::
$(RM) *.o \#*\# *~ *% .#* *.bak *.orig *.rej *.flc y.tab.c y.tab.h lex.yy.c core $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.s) $(RC_SRCS:.rc=.h) $(PROGRAMS)
$(RM) *.o \#*\# *~ *% .#* *.bak *.orig *.rej *.flc y.tab.c y.tab.h lex.yy.c core $(GEN_ASM_SRCS) $(RC_SRCS:.rc=.s) $(RC_SRCS:.rc=.h) $(
SPEC_SRCS:.spec=.spec.c) $(GLUE:.c=.glue.s) $(
PROGRAMS)
dummy:
dummy:
...
...
if1632/.cvsignore
View file @
3dff7bb8
Makefile
Makefile
avifile.s
avifile.spec.c
callfrom16.s
avifile.spec.glue.s
callto16.s
call16.s
comm.s
callfrom16.spec.c
commdlg.s
callfrom16.spec.glue.s
compobj.s
callto16.spec.c
ddeml.s
callto16.spec.glue.s
dispdib.s
comm.spec.c
display.s
comm.spec.glue.s
gdi.s
commdlg.spec.c
kernel.s
commdlg.spec.glue.s
keyboard.s
compobj.spec.c
lzexpand.s
compobj.spec.glue.s
mmsystem.s
ddeml.spec.c
mouse.s
ddeml.spec.glue.s
msacm.s
dispdib.spec.c
msvideo.s
dispdib.spec.glue.s
ole2.s
display.spec.c
ole2conv.s
display.spec.glue.s
ole2disp.s
gdi.spec.c
ole2nls.s
gdi.spec.glue.s
ole2prox.s
kernel.spec.c
ole2thk.s
kernel.spec.glue.s
olecli.s
keyboard.spec.c
olesvr.s
keyboard.spec.glue.s
rasapi16.s
lzexpand.spec.c
shell.s
lzexpand.spec.glue.s
sound.s
mmsystem.spec.c
storage.s
mmsystem.spec.glue.s
stress.s
mouse.spec.c
system.s
mouse.spec.glue.s
toolhelp.s
msacm.spec.c
typelib.s
msacm.spec.glue.s
user.s
msvideo.spec.c
ver.s
msvideo.spec.glue.s
w32sys.s
ole2.spec.c
win32s16.s
ole2.spec.glue.s
win87em.s
ole2conv.spec.c
winaspi.s
ole2conv.spec.glue.s
windebug.s
ole2disp.spec.c
wineps.s
ole2disp.spec.glue.s
wing.s
ole2nls.spec.c
winsock.s
ole2nls.spec.glue.s
wprocs.s
ole2prox.spec.c
ole2prox.spec.glue.s
ole2thk.spec.c
ole2thk.spec.glue.s
olecli.spec.c
olecli.spec.glue.s
olesvr.spec.c
olesvr.spec.glue.s
rasapi16.spec.c
rasapi16.spec.glue.s
shell.spec.c
shell.spec.glue.s
sound.spec.c
sound.spec.glue.s
storage.spec.c
storage.spec.glue.s
stress.spec.c
stress.spec.glue.s
system.spec.c
system.spec.glue.s
thunk.glue.s
toolhelp.spec.c
toolhelp.spec.glue.s
typelib.spec.c
typelib.spec.glue.s
user.spec.c
user.spec.glue.s
ver.spec.c
ver.spec.glue.s
w32sys.spec.c
w32sys.spec.glue.s
win32s16.spec.c
win32s16.spec.glue.s
win87em.spec.c
win87em.spec.glue.s
winaspi.spec.c
winaspi.spec.glue.s
windebug.spec.c
windebug.spec.glue.s
wineps.spec.c
wineps.spec.glue.s
wing.spec.c
wing.spec.glue.s
winsock.spec.c
winsock.spec.glue.s
wprocs.spec.c
wprocs.spec.glue.s
if1632/Makefile.in
View file @
3dff7bb8
...
@@ -5,7 +5,7 @@ SRCDIR = @srcdir@
...
@@ -5,7 +5,7 @@ SRCDIR = @srcdir@
VPATH
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
if1632
MODULE
=
if1632
DLL
S
=
\
SPEC_SRC
S
=
\
avifile.spec
\
avifile.spec
\
comm.spec
\
comm.spec
\
commdlg.spec
\
commdlg.spec
\
...
@@ -49,8 +49,6 @@ DLLS = \
...
@@ -49,8 +49,6 @@ DLLS = \
winsock.spec
\
winsock.spec
\
wprocs.spec
wprocs.spec
SPEC_FILES
=
$
(
DLLS:.spec
=
.s
)
C_SRCS
=
\
C_SRCS
=
\
builtin.c
\
builtin.c
\
dummy.c
\
dummy.c
\
...
@@ -59,25 +57,16 @@ C_SRCS = \
...
@@ -59,25 +57,16 @@ C_SRCS = \
thunk.c
thunk.c
GEN_ASM_SRCS
=
\
GEN_ASM_SRCS
=
\
$(SPEC_FILES)
\
call16.s
callfrom16.s
\
callto16.s
.SUFFIXES
:
.spec
.spec.s
:
GLUE
=
$
(
SPEC_SRCS:.spec
=
.spec.c
)
\
$(BUILD)
-o
$@
-spec
$<
thunk.c
all
:
checkbuild
$(MODULE).o
all
:
$(MODULE).o
@MAKE_RULES@
@MAKE_RULES@
$(SPEC_FILES)
:
$(BUILD)
call16.s
:
$(BUILD)
$(BUILD)
-o
$@
-call16
callfrom16.s
:
$(SPEC_FILES)
$(BUILD)
-o
$@
-callfrom16
`
cat
$(SPEC_FILES)
|
grep
CallFrom16_ |
sed
's/.*CallFrom16_\(.*\)/\1/'
|
sort
|
uniq
`
callto16.s
:
$(SRCDIR)/thunk.c $(BUILD)
$(BUILD)
-o
$@
-callto16
$(SRCDIR)
/thunk.c
### Dependencies:
### Dependencies:
if1632/builtin.c
View file @
3dff7bb8
...
@@ -263,12 +263,11 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force )
...
@@ -263,12 +263,11 @@ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force )
/***********************************************************************
/***********************************************************************
* BUILTIN_GetEntryPoint16
* BUILTIN_GetEntryPoint16
*
*
* Return the ordinal
and name
corresponding to a CS:IP address.
* Return the ordinal
, name, and type info
corresponding to a CS:IP address.
* This is used only by relay debugging.
* This is used only by relay debugging.
*/
*/
LPCSTR
BUILTIN_GetEntryPoint16
(
WORD
cs
,
WORD
ip
,
WORD
*
pOrd
)
LPCSTR
BUILTIN_GetEntryPoint16
(
WORD
cs
,
WORD
ip
,
LPSTR
name
,
WORD
*
pOrd
)
{
{
static
char
buffer
[
80
];
WORD
i
,
max_offset
;
WORD
i
,
max_offset
;
register
BYTE
*
p
;
register
BYTE
*
p
;
NE_MODULE
*
pModule
;
NE_MODULE
*
pModule
;
...
@@ -286,7 +285,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
...
@@ -286,7 +285,7 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
entry
=
(
ET_ENTRY
*
)((
BYTE
*
)
bundle
+
6
);
entry
=
(
ET_ENTRY
*
)((
BYTE
*
)
bundle
+
6
);
for
(
i
=
bundle
->
first
+
1
;
i
<=
bundle
->
last
;
i
++
)
for
(
i
=
bundle
->
first
+
1
;
i
<=
bundle
->
last
;
i
++
)
{
{
if
((
entry
->
offs
<
=
ip
)
if
((
entry
->
offs
<
ip
)
&&
(
entry
->
segnum
==
1
)
/* code segment ? */
&&
(
entry
->
segnum
==
1
)
/* code segment ? */
&&
(
entry
->
offs
>=
max_offset
))
&&
(
entry
->
offs
>=
max_offset
))
{
{
...
@@ -308,11 +307,13 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
...
@@ -308,11 +307,13 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
if
(
*
(
WORD
*
)(
p
+
*
p
+
1
)
==
*
pOrd
)
break
;
if
(
*
(
WORD
*
)(
p
+
*
p
+
1
)
==
*
pOrd
)
break
;
}
}
sprintf
(
buffer
,
"%.*s.%d: %.*s"
,
sprintf
(
name
,
"%.*s.%d: %.*s"
,
*
((
BYTE
*
)
pModule
+
pModule
->
name_table
),
*
((
BYTE
*
)
pModule
+
pModule
->
name_table
),
(
char
*
)
pModule
+
pModule
->
name_table
+
1
,
(
char
*
)
pModule
+
pModule
->
name_table
+
1
,
*
pOrd
,
*
p
,
(
char
*
)(
p
+
1
)
);
*
pOrd
,
*
p
,
(
char
*
)(
p
+
1
)
);
return
buffer
;
/* Retrieve type info string */
return
*
(
LPCSTR
*
)((
LPBYTE
)
PTR_SEG_OFF_TO_LIN
(
cs
,
ip
)
-
6
)
+
10
;
}
}
...
@@ -324,8 +325,9 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
...
@@ -324,8 +325,9 @@ LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd )
void
BUILTIN_DefaultIntHandler
(
CONTEXT86
*
context
)
void
BUILTIN_DefaultIntHandler
(
CONTEXT86
*
context
)
{
{
WORD
ordinal
;
WORD
ordinal
;
char
name
[
80
];
STACK16FRAME
*
frame
=
CURRENT_STACK16
;
STACK16FRAME
*
frame
=
CURRENT_STACK16
;
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
&
ordinal
);
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
name
,
&
ordinal
);
INT_BARF
(
context
,
ordinal
-
FIRST_INTERRUPT_ORDINAL
);
INT_BARF
(
context
,
ordinal
-
FIRST_INTERRUPT_ORDINAL
);
}
}
if1632/relay.c
View file @
3dff7bb8
...
@@ -30,34 +30,27 @@ BOOL RELAY_Init(void)
...
@@ -30,34 +30,27 @@ BOOL RELAY_Init(void)
/* Allocate the code selector for CallTo16 routines */
/* Allocate the code selector for CallTo16 routines */
extern
void
CALLTO16_Start
(),
CALLTO16_End
();
extern
void
Call16_Ret_Start
(),
Call16_Ret_End
();
extern
void
CALLTO16_Ret_word
(),
CALLTO16_Ret_long
();
extern
void
CallTo16_Ret
();
extern
void
CALLTO16_Ret_eax
();
extern
void
CALL32_CBClient_Ret
();
extern
void
CALL32_CBClient_Ret
();
extern
void
CALL32_CBClientEx_Ret
();
extern
void
CALL32_CBClientEx_Ret
();
extern
DWORD
CALLTO16_RetAddr_word
;
extern
DWORD
CallTo16_RetAddr
;
extern
DWORD
CALLTO16_RetAddr_long
;
extern
DWORD
CALLTO16_RetAddr_eax
;
extern
DWORD
CALL32_CBClient_RetAddr
;
extern
DWORD
CALL32_CBClient_RetAddr
;
extern
DWORD
CALL32_CBClientEx_RetAddr
;
extern
DWORD
CALL32_CBClientEx_RetAddr
;
codesel
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
(
void
*
)
C
ALLTO16
_Start
,
codesel
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
(
void
*
)
C
all16_Ret
_Start
,
(
int
)
C
ALLTO16_End
-
(
int
)
CALLTO16
_Start
,
(
int
)
C
all16_Ret_End
-
(
int
)
Call16_Ret
_Start
,
0
,
TRUE
,
TRUE
,
FALSE
,
NULL
);
0
,
TRUE
,
TRUE
,
FALSE
,
NULL
);
if
(
!
codesel
)
return
FALSE
;
if
(
!
codesel
)
return
FALSE
;
/* Patch the return addresses for CallTo16 routines */
/* Patch the return addresses for CallTo16 routines */
CALLTO16_RetAddr_word
=
MAKELONG
(
(
int
)
CALLTO16_Ret_word
-
(
int
)
CALLTO16_Start
,
CallTo16_RetAddr
=
codesel
);
MAKELONG
(
(
int
)
CallTo16_Ret
-
(
int
)
Call16_Ret_Start
,
codesel
);
CALLTO16_RetAddr_long
=
MAKELONG
(
(
int
)
CALLTO16_Ret_long
-
(
int
)
CALLTO16_Start
,
codesel
);
CALLTO16_RetAddr_eax
=
MAKELONG
(
(
int
)
CALLTO16_Ret_eax
-
(
int
)
CALLTO16_Start
,
codesel
);
CALL32_CBClient_RetAddr
=
CALL32_CBClient_RetAddr
=
MAKELONG
(
(
int
)
CALL32_CBClient_Ret
-
(
int
)
C
ALLTO16
_Start
,
codesel
);
MAKELONG
(
(
int
)
CALL32_CBClient_Ret
-
(
int
)
C
all16_Ret
_Start
,
codesel
);
CALL32_CBClientEx_RetAddr
=
CALL32_CBClientEx_RetAddr
=
MAKELONG
(
(
int
)
CALL32_CBClientEx_Ret
-
(
int
)
C
ALLTO16
_Start
,
codesel
);
MAKELONG
(
(
int
)
CALL32_CBClientEx_Ret
-
(
int
)
C
all16_Ret
_Start
,
codesel
);
/* Create built-in modules */
/* Create built-in modules */
if
(
!
BUILTIN_Init
())
return
FALSE
;
if
(
!
BUILTIN_Init
())
return
FALSE
;
...
@@ -73,25 +66,29 @@ extern char **debug_relay_excludelist,**debug_relay_includelist;
...
@@ -73,25 +66,29 @@ extern char **debug_relay_excludelist,**debug_relay_includelist;
/***********************************************************************
/***********************************************************************
* RELAY_DebugCallFrom16
* RELAY_DebugCallFrom16
*/
*/
void
RELAY_DebugCallFrom16
(
int
func_type
,
char
*
args
,
void
RELAY_DebugCallFrom16
(
CONTEXT86
*
context
)
void
*
entry_point
,
CONTEXT86
*
context
)
{
{
STACK16FRAME
*
frame
;
STACK16FRAME
*
frame
;
WORD
ordinal
;
WORD
ordinal
;
char
*
args16
;
char
*
args16
,
funstr
[
80
]
;
const
char
*
funstr
;
const
char
*
args
;
int
i
;
int
i
,
usecdecl
,
reg_func
;
if
(
!
TRACE_ON
(
relay
))
return
;
if
(
!
TRACE_ON
(
relay
))
return
;
frame
=
CURRENT_STACK16
;
frame
=
CURRENT_STACK16
;
funstr
=
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
&
ordinal
);
args
=
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
funstr
,
&
ordinal
);
if
(
!
funstr
)
return
;
/* happens for the two snoop register relays */
if
(
!
args
)
return
;
/* happens for the two snoop register relays */
if
(
!
RELAY_ShowDebugmsgRelay
(
funstr
))
return
;
if
(
!
RELAY_ShowDebugmsgRelay
(
funstr
))
return
;
DPRINTF
(
"Call %s("
,
funstr
);
DPRINTF
(
"Call %s("
,
funstr
);
VA_START16
(
args16
);
VA_START16
(
args16
);
if
(
func_type
&
4
)
/* cdecl */
usecdecl
=
(
*
args
==
'c'
);
args
+=
2
;
reg_func
=
(
memcmp
(
args
,
"regs_"
,
5
)
==
0
);
args
+=
5
;
if
(
usecdecl
)
{
{
while
(
*
args
)
while
(
*
args
)
{
{
...
@@ -185,11 +182,11 @@ void RELAY_DebugCallFrom16( int func_type, char *args,
...
@@ -185,11 +182,11 @@ void RELAY_DebugCallFrom16( int func_type, char *args,
DPRINTF
(
") ret=%04x:%04x ds=%04x
\n
"
,
frame
->
cs
,
frame
->
ip
,
frame
->
ds
);
DPRINTF
(
") ret=%04x:%04x ds=%04x
\n
"
,
frame
->
cs
,
frame
->
ip
,
frame
->
ds
);
VA_END16
(
args16
);
VA_END16
(
args16
);
if
(
func_type
&
2
)
/* register function */
if
(
reg_func
)
DPRINTF
(
" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx
\n
"
,
DPRINTF
(
" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx
\n
"
,
AX_reg
(
context
),
BX_reg
(
context
),
CX_reg
(
context
),
AX_reg
(
context
),
BX_reg
(
context
),
CX_reg
(
context
),
DX_reg
(
context
),
SI_reg
(
context
),
DI_reg
(
context
),
DX_reg
(
context
),
SI_reg
(
context
),
DI_reg
(
context
),
(
WORD
)
ES_reg
(
context
),
EFL_reg
(
context
)
);
(
WORD
)
ES_reg
(
context
),
EFL_reg
(
context
)
);
SYSLEVEL_CheckNotLevel
(
2
);
SYSLEVEL_CheckNotLevel
(
2
);
}
}
...
@@ -198,36 +195,38 @@ void RELAY_DebugCallFrom16( int func_type, char *args,
...
@@ -198,36 +195,38 @@ void RELAY_DebugCallFrom16( int func_type, char *args,
/***********************************************************************
/***********************************************************************
* RELAY_DebugCallFrom16Ret
* RELAY_DebugCallFrom16Ret
*/
*/
void
RELAY_DebugCallFrom16Ret
(
int
func_type
,
int
ret_val
,
CONTEXT86
*
context
)
void
RELAY_DebugCallFrom16Ret
(
CONTEXT86
*
context
,
int
ret_val
)
{
{
STACK16FRAME
*
frame
;
STACK16FRAME
*
frame
;
WORD
ordinal
;
WORD
ordinal
;
const
char
*
funstr
;
char
funstr
[
80
];
const
char
*
args
;
if
(
!
TRACE_ON
(
relay
))
return
;
if
(
!
TRACE_ON
(
relay
))
return
;
frame
=
CURRENT_STACK16
;
frame
=
CURRENT_STACK16
;
funstr
=
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
&
ordinal
);
args
=
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
funstr
,
&
ordinal
);
if
(
!
funstr
)
return
;
if
(
!
args
)
return
;
if
(
!
RELAY_ShowDebugmsgRelay
(
funstr
))
return
;
if
(
!
RELAY_ShowDebugmsgRelay
(
funstr
))
return
;
DPRINTF
(
"Ret %s() "
,
funstr
);
DPRINTF
(
"Ret %s() "
,
funstr
);
switch
(
func_type
)
if
(
memcmp
(
args
+
2
,
"long_"
,
5
)
==
0
)
{
{
case
0
:
/* long */
DPRINTF
(
"retval=0x%08x ret=%04x:%04x ds=%04x
\n
"
,
DPRINTF
(
"retval=0x%08x ret=%04x:%04x ds=%04x
\n
"
,
ret_val
,
frame
->
cs
,
frame
->
ip
,
frame
->
ds
);
ret_val
,
frame
->
cs
,
frame
->
ip
,
frame
->
ds
);
break
;
}
case
1
:
/* word */
else
if
(
memcmp
(
args
+
2
,
"word_"
,
5
)
==
0
)
{
DPRINTF
(
"retval=0x%04x ret=%04x:%04x ds=%04x
\n
"
,
DPRINTF
(
"retval=0x%04x ret=%04x:%04x ds=%04x
\n
"
,
ret_val
&
0xffff
,
frame
->
cs
,
frame
->
ip
,
frame
->
ds
);
ret_val
&
0xffff
,
frame
->
cs
,
frame
->
ip
,
frame
->
ds
);
break
;
}
case
2
:
/* regs */
else
if
(
memcmp
(
args
+
2
,
"regs_"
,
5
)
==
0
)
{
DPRINTF
(
"retval=none ret=%04x:%04x ds=%04x
\n
"
,
DPRINTF
(
"retval=none ret=%04x:%04x ds=%04x
\n
"
,
(
WORD
)
CS_reg
(
context
),
IP_reg
(
context
),
(
WORD
)
DS_reg
(
context
));
(
WORD
)
CS_reg
(
context
),
IP_reg
(
context
),
(
WORD
)
DS_reg
(
context
));
DPRINTF
(
" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx
\n
"
,
DPRINTF
(
" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx
\n
"
,
AX_reg
(
context
),
BX_reg
(
context
),
CX_reg
(
context
),
AX_reg
(
context
),
BX_reg
(
context
),
CX_reg
(
context
),
DX_reg
(
context
),
SI_reg
(
context
),
DI_reg
(
context
),
DX_reg
(
context
),
SI_reg
(
context
),
DI_reg
(
context
),
(
WORD
)
ES_reg
(
context
),
EFL_reg
(
context
)
);
(
WORD
)
ES_reg
(
context
),
EFL_reg
(
context
)
);
break
;
}
}
SYSLEVEL_CheckNotLevel
(
2
);
SYSLEVEL_CheckNotLevel
(
2
);
...
@@ -243,10 +242,11 @@ void RELAY_DebugCallFrom16Ret( int func_type, int ret_val, CONTEXT86 *context)
...
@@ -243,10 +242,11 @@ void RELAY_DebugCallFrom16Ret( int func_type, int ret_val, CONTEXT86 *context)
void
RELAY_Unimplemented16
(
void
)
void
RELAY_Unimplemented16
(
void
)
{
{
WORD
ordinal
;
WORD
ordinal
;
char
name
[
80
];
STACK16FRAME
*
frame
=
CURRENT_STACK16
;
STACK16FRAME
*
frame
=
CURRENT_STACK16
;
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
name
,
&
ordinal
);
MESSAGE
(
"No handler for Win16 routine %s (called from %04x:%04x)
\n
"
,
MESSAGE
(
"No handler for Win16 routine %s (called from %04x:%04x)
\n
"
,
BUILTIN_GetEntryPoint16
(
frame
->
entry_cs
,
frame
->
entry_ip
,
&
ordinal
),
name
,
frame
->
cs
,
frame
->
ip
);
frame
->
cs
,
frame
->
ip
);
ExitProcess
(
1
);
ExitProcess
(
1
);
}
}
...
...
if1632/snoop.c
View file @
3dff7bb8
...
@@ -24,7 +24,7 @@ DEFAULT_DEBUG_CHANNEL(snoop)
...
@@ -24,7 +24,7 @@ DEFAULT_DEBUG_CHANNEL(snoop)
void
WINAPI
SNOOP16_Entry
(
CONTEXT86
*
context
);
void
WINAPI
SNOOP16_Entry
(
CONTEXT86
*
context
);
void
WINAPI
SNOOP16_Return
(
CONTEXT86
*
context
);
void
WINAPI
SNOOP16_Return
(
CONTEXT86
*
context
);
extern
void
CallFrom16_p_regs_
();
extern
void
KERNEL_
CallFrom16_p_regs_
();
/* Generic callfrom16_p_regs function entry.
/* Generic callfrom16_p_regs function entry.
* pushw %bp 0x55
* pushw %bp 0x55
...
@@ -103,14 +103,14 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
...
@@ -103,14 +103,14 @@ SNOOP16_RegisterDLL(NE_MODULE *pModule,LPCSTR name) {
snr
[
0
].
pushl
=
0x68
;
snr
[
0
].
pushl
=
0x68
;
snr
[
0
].
realfun
=
(
DWORD
)
SNOOP16_Entry
;
snr
[
0
].
realfun
=
(
DWORD
)
SNOOP16_Entry
;
snr
[
0
].
lcall
=
0x9a
;
snr
[
0
].
lcall
=
0x9a
;
snr
[
0
].
callfromregs
=
(
DWORD
)
CallFrom16_p_regs_
;
snr
[
0
].
callfromregs
=
(
DWORD
)
KERNEL_
CallFrom16_p_regs_
;
GET_CS
(
snr
[
0
].
seg
);
GET_CS
(
snr
[
0
].
seg
);
snr
[
1
].
prefix
=
0x66
;
snr
[
1
].
prefix
=
0x66
;
snr
[
1
].
pushbp
=
0x55
;
snr
[
1
].
pushbp
=
0x55
;
snr
[
1
].
pushl
=
0x68
;
snr
[
1
].
pushl
=
0x68
;
snr
[
1
].
realfun
=
(
DWORD
)
SNOOP16_Return
;
snr
[
1
].
realfun
=
(
DWORD
)
SNOOP16_Return
;
snr
[
1
].
lcall
=
0x9a
;
snr
[
1
].
lcall
=
0x9a
;
snr
[
1
].
callfromregs
=
(
DWORD
)
CallFrom16_p_regs_
;
snr
[
1
].
callfromregs
=
(
DWORD
)
KERNEL_
CallFrom16_p_regs_
;
GET_CS
(
snr
[
1
].
seg
);
GET_CS
(
snr
[
1
].
seg
);
}
}
while
(
*
dll
)
{
while
(
*
dll
)
{
...
...
if1632/thunk.c
View file @
3dff7bb8
...
@@ -26,85 +26,84 @@ DECLARE_DEBUG_CHANNEL(system)
...
@@ -26,85 +26,84 @@ DECLARE_DEBUG_CHANNEL(system)
DECLARE_DEBUG_CHANNEL
(
thunk
)
DECLARE_DEBUG_CHANNEL
(
thunk
)
extern
LONG
CallTo16RegisterShort
(
const
CONTEXT86
*
context
,
INT
offset
);
extern
LONG
CallTo16RegisterLong
(
const
CONTEXT86
*
context
,
INT
offset
);
/* List of the 16-bit callback functions. This list is used */
/* List of the 16-bit callback functions. This list is used */
/* by the build program to generate the file if1632/callto16.S */
/* by the build program to generate the file if1632/callto16.S */
/* ### start build ### */
/* ### start build ### */
extern
LONG
CALLBACK
CallTo16_sreg_
(
const
CONTEXT86
*
context
,
INT
offset
);
extern
WORD
THUNK_CallTo16_word_
(
FARPROC16
);
extern
LONG
CALLBACK
CallTo16_lreg_
(
const
CONTEXT86
*
context
,
INT
offset
);
extern
LONG
THUNK_CallTo16_long_
(
FARPROC16
);
extern
WORD
CALLBACK
CallTo16_word_
(
FARPROC16
);
extern
WORD
THUNK_CallTo16_word_w
(
FARPROC16
,
WORD
);
extern
LONG
CALLBACK
CallTo16_long_
(
FARPROC16
);
extern
WORD
THUNK_CallTo16_word_l
(
FARPROC16
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_w
(
FARPROC16
,
WORD
);
extern
LONG
THUNK_CallTo16_long_l
(
FARPROC16
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_l
(
FARPROC16
,
LONG
);
extern
WORD
THUNK_CallTo16_word_ww
(
FARPROC16
,
WORD
,
WORD
);
extern
LONG
CALLBACK
CallTo16_long_l
(
FARPROC16
,
LONG
);
extern
WORD
THUNK_CallTo16_word_wl
(
FARPROC16
,
WORD
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_ww
(
FARPROC16
,
WORD
,
WORD
);
extern
WORD
THUNK_CallTo16_word_ll
(
FARPROC16
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_wl
(
FARPROC16
,
WORD
,
LONG
);
extern
LONG
THUNK_CallTo16_long_ll
(
FARPROC16
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_ll
(
FARPROC16
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_www
(
FARPROC16
,
WORD
,
WORD
,
WORD
);
extern
LONG
CALLBACK
CallTo16_long_ll
(
FARPROC16
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_wwl
(
FARPROC16
,
WORD
,
WORD
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_www
(
FARPROC16
,
WORD
,
WORD
,
WORD
);
extern
WORD
THUNK_CallTo16_word_wlw
(
FARPROC16
,
WORD
,
LONG
,
WORD
);
extern
WORD
CALLBACK
CallTo16_word_wwl
(
FARPROC16
,
WORD
,
WORD
,
LONG
);
extern
LONG
THUNK_CallTo16_long_wwl
(
FARPROC16
,
WORD
,
WORD
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_wlw
(
FARPROC16
,
WORD
,
LONG
,
WORD
);
extern
LONG
THUNK_CallTo16_long_lll
(
FARPROC16
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_wwl
(
FARPROC16
,
WORD
,
WORD
,
LONG
);
extern
WORD
THUNK_CallTo16_word_llwl
(
FARPROC16
,
LONG
,
LONG
,
WORD
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lll
(
FARPROC16
,
LONG
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_lwll
(
FARPROC16
,
LONG
,
WORD
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_llwl
(
FARPROC16
,
LONG
,
LONG
,
WORD
,
LONG
);
extern
WORD
THUNK_CallTo16_word_lwww
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
WORD
);
extern
WORD
CALLBACK
CallTo16_word_lwll
(
FARPROC16
,
LONG
,
WORD
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_wlww
(
FARPROC16
,
WORD
,
LONG
,
WORD
,
WORD
);
extern
WORD
CALLBACK
CallTo16_word_lwww
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
WORD
);
extern
WORD
THUNK_CallTo16_word_wwll
(
FARPROC16
,
WORD
,
WORD
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_wlww
(
FARPROC16
,
WORD
,
LONG
,
WORD
,
WORD
);
extern
WORD
THUNK_CallTo16_word_wwwl
(
FARPROC16
,
WORD
,
WORD
,
WORD
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_wwll
(
FARPROC16
,
WORD
,
WORD
,
LONG
,
LONG
);
extern
LONG
THUNK_CallTo16_long_wwwl
(
FARPROC16
,
WORD
,
WORD
,
WORD
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_wwwl
(
FARPROC16
,
WORD
,
WORD
,
WORD
,
LONG
);
extern
WORD
THUNK_CallTo16_word_llll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_wwwl
(
FARPROC16
,
WORD
,
WORD
,
WORD
,
LONG
);
extern
LONG
THUNK_CallTo16_long_llll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_llll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_wllwl
(
FARPROC16
,
WORD
,
LONG
,
LONG
,
WORD
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_llll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_lwwww
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
WORD
,
WORD
);
extern
WORD
CALLBACK
CallTo16_word_wllwl
(
FARPROC16
,
WORD
,
LONG
,
LONG
,
WORD
,
LONG
);
extern
LONG
THUNK_CallTo16_long_lwwll
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_lwwww
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
WORD
,
WORD
);
extern
WORD
THUNK_CallTo16_word_wwlll
(
FARPROC16
,
WORD
,
WORD
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lwwll
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_wwwww
(
FARPROC16
,
WORD
,
WORD
,
WORD
,
WORD
,
WORD
);
extern
WORD
CALLBACK
CallTo16_word_wwlll
(
FARPROC16
,
WORD
,
WORD
,
LONG
,
LONG
,
LONG
);
extern
WORD
THUNK_CallTo16_word_lwlll
(
FARPROC16
,
LONG
,
WORD
,
LONG
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_wwwww
(
FARPROC16
,
WORD
,
WORD
,
WORD
,
WORD
,
WORD
);
extern
LONG
THUNK_CallTo16_long_lwlll
(
FARPROC16
,
LONG
,
WORD
,
LONG
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_lwlll
(
FARPROC16
,
LONG
,
WORD
,
LONG
,
LONG
,
LONG
);
extern
LONG
THUNK_CallTo16_long_lllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lwlll
(
FARPROC16
,
LONG
,
WORD
,
LONG
,
LONG
,
LONG
);
extern
LONG
THUNK_CallTo16_long_llllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
LONG
THUNK_CallTo16_long_lllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_llllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
extern
WORD
THUNK_CallTo16_word_llwwlll
(
FARPROC16
,
LONG
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
,
LONG
);
LONG
);
extern
LONG
THUNK_CallTo16_word_lwwlllll
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
,
extern
LONG
CALLBACK
CallTo16_long_lllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
WORD
CALLBACK
CallTo16_word_llwwlll
(
FARPROC16
,
LONG
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_word_lwwlllll
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_llllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_llllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_lllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_llllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_llllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_lllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
);
extern
LONG
CALLBACK
CallTo16_long_llllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_llllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lwwllwlllllw
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_lwwllwlllllw
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
,
WORD
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
WORD
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
WORD
);
LONG
,
WORD
);
extern
LONG
CALLBACK
CallTo16_long_lllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_lllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_llllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_llllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
);
extern
LONG
CALLBACK
CallTo16_word_lwwwwlwwwwllll
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
extern
LONG
THUNK_
CallTo16_word_lwwwwlwwwwllll
(
FARPROC16
,
LONG
,
WORD
,
WORD
,
WORD
,
WORD
,
LONG
,
WORD
,
WORD
,
WORD
,
WORD
,
LONG
,
WORD
,
WORD
,
WORD
,
WORD
,
LONG
,
LONG
,
LONG
,
WORD
,
WORD
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
);
extern
LONG
CALLBACK
CallTo16_long_lllllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_lllllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
);
extern
LONG
CALLBACK
CallTo16_long_llllllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
extern
LONG
THUNK_
CallTo16_long_llllllllllllllll
(
FARPROC16
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
,
LONG
);
LONG
,
LONG
,
LONG
);
extern
void
THUNK_CallFrom16_p_long_wwwll
();
/* ### stop build ### */
/* ### stop build ### */
...
@@ -144,38 +143,36 @@ static BOOL WINAPI THUNK_WOWCallback16Ex( FARPROC16,DWORD,DWORD,
...
@@ -144,38 +143,36 @@ static BOOL WINAPI THUNK_WOWCallback16Ex( FARPROC16,DWORD,DWORD,
LPVOID
,
LPDWORD
);
LPVOID
,
LPDWORD
);
static
BOOL
THUNK_ThunkletInit
(
void
);
static
BOOL
THUNK_ThunkletInit
(
void
);
extern
void
CallFrom16_p_long_wwwll
(
void
);
/* Callbacks function table for the emulator */
/* Callbacks function table for the emulator */
static
const
CALLBACKS_TABLE
CALLBACK_EmulatorTable
=
static
const
CALLBACKS_TABLE
CALLBACK_EmulatorTable
=
{
{
(
void
*
)
CallTo16
_sreg_
,
/* CallRegisterShortProc */
(
void
*
)
CallTo16
RegisterShort
,
/* CallRegisterShortProc */
(
void
*
)
CallTo16
_lreg_
,
/* CallRegisterLongProc */
(
void
*
)
CallTo16
RegisterLong
,
/* CallRegisterLongProc */
(
void
*
)
CallFrom16_p_long_wwwll
,
/* CallFrom16WndProc */
(
void
*
)
THUNK_
CallFrom16_p_long_wwwll
,
/* CallFrom16WndProc */
THUNK_CallWndProc16
,
/* CallWndProc */
THUNK_CallWndProc16
,
/* CallWndProc */
(
void
*
)
CallTo16_long_lwwll
,
/* CallDriverProc */
(
void
*
)
THUNK_
CallTo16_long_lwwll
,
/* CallDriverProc */
(
void
*
)
CallTo16_word_wwlll
,
/* CallDriverCallback */
(
void
*
)
THUNK_
CallTo16_word_wwlll
,
/* CallDriverCallback */
(
void
*
)
CallTo16_word_wwlll
,
/* CallTimeFuncProc */
(
void
*
)
THUNK_
CallTo16_word_wwlll
,
/* CallTimeFuncProc */
(
void
*
)
CallTo16_word_w
,
/* CallWindowsExitProc */
(
void
*
)
THUNK_
CallTo16_word_w
,
/* CallWindowsExitProc */
(
void
*
)
CallTo16_word_lwww
,
/* CallWordBreakProc */
(
void
*
)
THUNK_
CallTo16_word_lwww
,
/* CallWordBreakProc */
(
void
*
)
CallTo16_word_ww
,
/* CallBootAppProc */
(
void
*
)
THUNK_
CallTo16_word_ww
,
/* CallBootAppProc */
(
void
*
)
CallTo16_word_www
,
/* CallLoadAppSegProc */
(
void
*
)
THUNK_
CallTo16_word_www
,
/* CallLoadAppSegProc */
(
void
*
)
CallTo16_word_www
,
/* CallLocalNotifyFunc */
(
void
*
)
THUNK_
CallTo16_word_www
,
/* CallLocalNotifyFunc */
(
void
*
)
CallTo16_word_www
,
/* CallResourceHandlerProc */
(
void
*
)
THUNK_
CallTo16_word_www
,
/* CallResourceHandlerProc */
(
void
*
)
CallTo16_long_l
,
/* CallWOWCallbackProc */
(
void
*
)
THUNK_
CallTo16_long_l
,
/* CallWOWCallbackProc */
THUNK_WOWCallback16Ex
,
/* CallWOWCallback16Ex */
THUNK_WOWCallback16Ex
,
/* CallWOWCallback16Ex */
(
void
*
)
CallTo16_long_ll
,
/* CallUTProc */
(
void
*
)
THUNK_
CallTo16_long_ll
,
/* CallUTProc */
(
void
*
)
CallTo16_long_l
,
/* CallASPIPostProc */
(
void
*
)
THUNK_
CallTo16_long_l
,
/* CallASPIPostProc */
(
void
*
)
CallTo16_word_lwll
,
/* CallDrvControlProc */
(
void
*
)
THUNK_
CallTo16_word_lwll
,
/* CallDrvControlProc */
(
void
*
)
CallTo16_word_lwlll
,
/* CallDrvEnableProc */
(
void
*
)
THUNK_
CallTo16_word_lwlll
,
/* CallDrvEnableProc */
(
void
*
)
CallTo16_word_llll
,
/* CallDrvEnumDFontsProc */
(
void
*
)
THUNK_
CallTo16_word_llll
,
/* CallDrvEnumDFontsProc */
(
void
*
)
CallTo16_word_lwll
,
/* CallDrvEnumObjProc */
(
void
*
)
THUNK_
CallTo16_word_lwll
,
/* CallDrvEnumObjProc */
(
void
*
)
CallTo16_word_lwwlllll
,
/* CallDrvOutputProc */
(
void
*
)
THUNK_
CallTo16_word_lwwlllll
,
/* CallDrvOutputProc */
(
void
*
)
CallTo16_long_lwlll
,
/* CallDrvRealizeProc */
(
void
*
)
THUNK_
CallTo16_long_lwlll
,
/* CallDrvRealizeProc */
(
void
*
)
CallTo16_word_lwwwwlwwwwllll
,
/* CallDrvStretchBltProc */
(
void
*
)
THUNK_
CallTo16_word_lwwwwlwwwwllll
,
/* CallDrvStretchBltProc */
(
void
*
)
CallTo16_long_lwwllwlllllw
,
/* CallDrvExtTextOutProc */
(
void
*
)
THUNK_
CallTo16_long_lwwllwlllllw
,
/* CallDrvExtTextOutProc */
(
void
*
)
CallTo16_word_llwwlll
,
/* CallDrvGetCharWidth */
(
void
*
)
THUNK_
CallTo16_word_llwwlll
,
/* CallDrvGetCharWidth */
(
void
*
)
CallTo16_word_ww
/* CallDrvAbortProc */
(
void
*
)
THUNK_
CallTo16_word_ww
/* CallDrvAbortProc */
};
};
...
@@ -307,7 +304,7 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
...
@@ -307,7 +304,7 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
args
[
3
]
=
msg
;
args
[
3
]
=
msg
;
args
[
4
]
=
hwnd
;
args
[
4
]
=
hwnd
;
ret
=
CallTo16
_sreg_
(
&
context
,
5
*
sizeof
(
WORD
)
);
ret
=
CallTo16
RegisterShort
(
&
context
,
5
*
sizeof
(
WORD
)
);
if
(
offset
)
STACK16_POP
(
teb
,
offset
);
if
(
offset
)
STACK16_POP
(
teb
,
offset
);
WIN_RestoreWndsLock
(
iWndsLocks
);
WIN_RestoreWndsLock
(
iWndsLocks
);
...
@@ -322,7 +319,7 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
...
@@ -322,7 +319,7 @@ static LRESULT WINAPI THUNK_CallWndProc16( WNDPROC16 proc, HWND16 hwnd,
INT16
WINAPI
THUNK_EnumObjects16
(
HDC16
hdc
,
INT16
nObjType
,
INT16
WINAPI
THUNK_EnumObjects16
(
HDC16
hdc
,
INT16
nObjType
,
GOBJENUMPROC16
func
,
LPARAM
lParam
)
GOBJENUMPROC16
func
,
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_ll
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_ll
);
return
EnumObjects16
(
hdc
,
nObjType
,
(
GOBJENUMPROC16
)
&
thunk
,
lParam
);
return
EnumObjects16
(
hdc
,
nObjType
,
(
GOBJENUMPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -333,7 +330,7 @@ INT16 WINAPI THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
...
@@ -333,7 +330,7 @@ INT16 WINAPI THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
INT16
WINAPI
THUNK_EnumFonts16
(
HDC16
hdc
,
LPCSTR
lpFaceName
,
INT16
WINAPI
THUNK_EnumFonts16
(
HDC16
hdc
,
LPCSTR
lpFaceName
,
FONTENUMPROC16
func
,
LPARAM
lParam
)
FONTENUMPROC16
func
,
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_llwl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_llwl
);
return
EnumFonts16
(
hdc
,
lpFaceName
,
(
FONTENUMPROC16
)
&
thunk
,
lParam
);
return
EnumFonts16
(
hdc
,
lpFaceName
,
(
FONTENUMPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -343,7 +340,7 @@ INT16 WINAPI THUNK_EnumFonts16( HDC16 hdc, LPCSTR lpFaceName,
...
@@ -343,7 +340,7 @@ INT16 WINAPI THUNK_EnumFonts16( HDC16 hdc, LPCSTR lpFaceName,
BOOL16
WINAPI
THUNK_EnumMetaFile16
(
HDC16
hdc
,
HMETAFILE16
hmf
,
BOOL16
WINAPI
THUNK_EnumMetaFile16
(
HDC16
hdc
,
HMETAFILE16
hmf
,
MFENUMPROC16
func
,
LPARAM
lParam
)
MFENUMPROC16
func
,
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_wllwl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_wllwl
);
return
EnumMetaFile16
(
hdc
,
hmf
,
(
MFENUMPROC16
)
&
thunk
,
lParam
);
return
EnumMetaFile16
(
hdc
,
hmf
,
(
MFENUMPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -354,7 +351,7 @@ BOOL16 WINAPI THUNK_EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
...
@@ -354,7 +351,7 @@ BOOL16 WINAPI THUNK_EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
INT16
WINAPI
THUNK_EnumFontFamilies16
(
HDC16
hdc
,
LPCSTR
lpszFamily
,
INT16
WINAPI
THUNK_EnumFontFamilies16
(
HDC16
hdc
,
LPCSTR
lpszFamily
,
FONTENUMPROC16
func
,
LPARAM
lParam
)
FONTENUMPROC16
func
,
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_llwl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_llwl
);
return
EnumFontFamilies16
(
hdc
,
lpszFamily
,
(
FONTENUMPROC16
)
&
thunk
,
lParam
);
return
EnumFontFamilies16
(
hdc
,
lpszFamily
,
(
FONTENUMPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -366,7 +363,7 @@ INT16 WINAPI THUNK_EnumFontFamiliesEx16( HDC16 hdc, LPLOGFONT16 lpLF,
...
@@ -366,7 +363,7 @@ INT16 WINAPI THUNK_EnumFontFamiliesEx16( HDC16 hdc, LPLOGFONT16 lpLF,
FONTENUMPROCEX16
func
,
LPARAM
lParam
,
FONTENUMPROCEX16
func
,
LPARAM
lParam
,
DWORD
reserved
)
DWORD
reserved
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_llwl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_llwl
);
return
EnumFontFamiliesEx16
(
hdc
,
lpLF
,
(
FONTENUMPROCEX16
)
&
thunk
,
return
EnumFontFamiliesEx16
(
hdc
,
lpLF
,
(
FONTENUMPROCEX16
)
&
thunk
,
lParam
,
reserved
);
lParam
,
reserved
);
}
}
...
@@ -378,7 +375,7 @@ INT16 WINAPI THUNK_EnumFontFamiliesEx16( HDC16 hdc, LPLOGFONT16 lpLF,
...
@@ -378,7 +375,7 @@ INT16 WINAPI THUNK_EnumFontFamiliesEx16( HDC16 hdc, LPLOGFONT16 lpLF,
void
WINAPI
THUNK_LineDDA16
(
INT16
nXStart
,
INT16
nYStart
,
INT16
nXEnd
,
void
WINAPI
THUNK_LineDDA16
(
INT16
nXStart
,
INT16
nYStart
,
INT16
nXEnd
,
INT16
nYEnd
,
LINEDDAPROC16
func
,
LPARAM
lParam
)
INT16
nYEnd
,
LINEDDAPROC16
func
,
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_wwl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_wwl
);
LineDDA16
(
nXStart
,
nYStart
,
nXEnd
,
nYEnd
,
(
LINEDDAPROC16
)
&
thunk
,
lParam
);
LineDDA16
(
nXStart
,
nYStart
,
nXEnd
,
nYEnd
,
(
LINEDDAPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -388,7 +385,7 @@ void WINAPI THUNK_LineDDA16( INT16 nXStart, INT16 nYStart, INT16 nXEnd,
...
@@ -388,7 +385,7 @@ void WINAPI THUNK_LineDDA16( INT16 nXStart, INT16 nYStart, INT16 nXEnd,
*/
*/
BOOL16
WINAPI
THUNK_EnumWindows16
(
WNDENUMPROC16
func
,
LPARAM
lParam
)
BOOL16
WINAPI
THUNK_EnumWindows16
(
WNDENUMPROC16
func
,
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_wl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_wl
);
return
EnumWindows16
(
(
WNDENUMPROC16
)
&
thunk
,
lParam
);
return
EnumWindows16
(
(
WNDENUMPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -399,7 +396,7 @@ BOOL16 WINAPI THUNK_EnumWindows16( WNDENUMPROC16 func, LPARAM lParam )
...
@@ -399,7 +396,7 @@ BOOL16 WINAPI THUNK_EnumWindows16( WNDENUMPROC16 func, LPARAM lParam )
BOOL16
WINAPI
THUNK_EnumChildWindows16
(
HWND16
parent
,
WNDENUMPROC16
func
,
BOOL16
WINAPI
THUNK_EnumChildWindows16
(
HWND16
parent
,
WNDENUMPROC16
func
,
LPARAM
lParam
)
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_wl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_wl
);
return
EnumChildWindows16
(
parent
,
(
WNDENUMPROC16
)
&
thunk
,
lParam
);
return
EnumChildWindows16
(
parent
,
(
WNDENUMPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -410,7 +407,7 @@ BOOL16 WINAPI THUNK_EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
...
@@ -410,7 +407,7 @@ BOOL16 WINAPI THUNK_EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
BOOL16
WINAPI
THUNK_EnumTaskWindows16
(
HTASK16
hTask
,
WNDENUMPROC16
func
,
BOOL16
WINAPI
THUNK_EnumTaskWindows16
(
HTASK16
hTask
,
WNDENUMPROC16
func
,
LPARAM
lParam
)
LPARAM
lParam
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_wl
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_wl
);
return
EnumTaskWindows16
(
hTask
,
(
WNDENUMPROC16
)
&
thunk
,
lParam
);
return
EnumTaskWindows16
(
hTask
,
(
WNDENUMPROC16
)
&
thunk
,
lParam
);
}
}
...
@@ -420,7 +417,7 @@ BOOL16 WINAPI THUNK_EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
...
@@ -420,7 +417,7 @@ BOOL16 WINAPI THUNK_EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
*/
*/
INT16
WINAPI
THUNK_EnumProps16
(
HWND16
hwnd
,
PROPENUMPROC16
func
)
INT16
WINAPI
THUNK_EnumProps16
(
HWND16
hwnd
,
PROPENUMPROC16
func
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_wlw
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_wlw
);
return
EnumProps16
(
hwnd
,
(
PROPENUMPROC16
)
&
thunk
);
return
EnumProps16
(
hwnd
,
(
PROPENUMPROC16
)
&
thunk
);
}
}
...
@@ -433,7 +430,7 @@ BOOL16 WINAPI THUNK_GrayString16( HDC16 hdc, HBRUSH16 hbr,
...
@@ -433,7 +430,7 @@ BOOL16 WINAPI THUNK_GrayString16( HDC16 hdc, HBRUSH16 hbr,
INT16
cch
,
INT16
x
,
INT16
y
,
INT16
cch
,
INT16
x
,
INT16
y
,
INT16
cx
,
INT16
cy
)
INT16
cx
,
INT16
cy
)
{
{
DECL_THUNK
(
thunk
,
func
,
CallTo16_word_wlw
);
DECL_THUNK
(
thunk
,
func
,
THUNK_
CallTo16_word_wlw
);
if
(
!
func
)
if
(
!
func
)
return
GrayString16
(
hdc
,
hbr
,
NULL
,
lParam
,
cch
,
x
,
y
,
cx
,
cy
);
return
GrayString16
(
hdc
,
hbr
,
NULL
,
lParam
,
cch
,
x
,
y
,
cx
,
cy
);
else
else
...
@@ -449,7 +446,7 @@ FARPROC16 WINAPI THUNK_SetWindowsHook16( INT16 id, HOOKPROC16 proc )
...
@@ -449,7 +446,7 @@ FARPROC16 WINAPI THUNK_SetWindowsHook16( INT16 id, HOOKPROC16 proc )
{
{
HINSTANCE16
hInst
=
FarGetOwner16
(
HIWORD
(
proc
)
);
HINSTANCE16
hInst
=
FarGetOwner16
(
HIWORD
(
proc
)
);
HTASK16
hTask
=
(
id
==
WH_MSGFILTER
)
?
GetCurrentTask
()
:
0
;
HTASK16
hTask
=
(
id
==
WH_MSGFILTER
)
?
GetCurrentTask
()
:
0
;
THUNK
*
thunk
=
THUNK_Alloc
(
(
FARPROC16
)
proc
,
(
RELAY
)
CallTo16_long_wwl
);
THUNK
*
thunk
=
THUNK_Alloc
(
(
FARPROC16
)
proc
,
(
RELAY
)
THUNK_
CallTo16_long_wwl
);
if
(
!
thunk
)
return
0
;
if
(
!
thunk
)
return
0
;
return
(
FARPROC16
)
SetWindowsHookEx16
(
id
,
(
HOOKPROC16
)
thunk
,
hInst
,
hTask
);
return
(
FARPROC16
)
SetWindowsHookEx16
(
id
,
(
HOOKPROC16
)
thunk
,
hInst
,
hTask
);
}
}
...
@@ -475,7 +472,7 @@ BOOL16 WINAPI THUNK_UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
...
@@ -475,7 +472,7 @@ BOOL16 WINAPI THUNK_UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
HHOOK
WINAPI
THUNK_SetWindowsHookEx16
(
INT16
id
,
HOOKPROC16
proc
,
HHOOK
WINAPI
THUNK_SetWindowsHookEx16
(
INT16
id
,
HOOKPROC16
proc
,
HINSTANCE16
hInst
,
HTASK16
hTask
)
HINSTANCE16
hInst
,
HTASK16
hTask
)
{
{
THUNK
*
thunk
=
THUNK_Alloc
(
(
FARPROC16
)
proc
,
(
RELAY
)
CallTo16_long_wwl
);
THUNK
*
thunk
=
THUNK_Alloc
(
(
FARPROC16
)
proc
,
(
RELAY
)
THUNK_
CallTo16_long_wwl
);
if
(
!
thunk
)
return
0
;
if
(
!
thunk
)
return
0
;
return
SetWindowsHookEx16
(
id
,
(
HOOKPROC16
)
thunk
,
hInst
,
hTask
);
return
SetWindowsHookEx16
(
id
,
(
HOOKPROC16
)
thunk
,
hInst
,
hTask
);
}
}
...
@@ -518,7 +515,7 @@ BOOL16 WINAPI THUNK_SetDCHook( HDC16 hdc, FARPROC16 proc, DWORD dwHookData )
...
@@ -518,7 +515,7 @@ BOOL16 WINAPI THUNK_SetDCHook( HDC16 hdc, FARPROC16 proc, DWORD dwHookData )
thunk
=
NULL
;
thunk
=
NULL
;
else
if
(
proc
!=
defDCHookProc
)
else
if
(
proc
!=
defDCHookProc
)
{
{
thunk
=
THUNK_Alloc
(
proc
,
(
RELAY
)
CallTo16_word_wwll
);
thunk
=
THUNK_Alloc
(
proc
,
(
RELAY
)
THUNK_
CallTo16_word_wwll
);
if
(
!
thunk
)
return
FALSE
;
if
(
!
thunk
)
return
FALSE
;
}
}
else
thunk
=
(
THUNK
*
)
DCHook16
;
else
thunk
=
(
THUNK
*
)
DCHook16
;
...
@@ -560,7 +557,7 @@ DWORD WINAPI THUNK_GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
...
@@ -560,7 +557,7 @@ DWORD WINAPI THUNK_GetDCHook( HDC16 hdc, FARPROC16 *phookProc )
*/
*/
FARPROC16
WINAPI
THUNK_SetTaskSignalProc
(
HTASK16
hTask
,
FARPROC16
proc
)
FARPROC16
WINAPI
THUNK_SetTaskSignalProc
(
HTASK16
hTask
,
FARPROC16
proc
)
{
{
THUNK
*
thunk
=
THUNK_Alloc
(
proc
,
(
RELAY
)
CallTo16_word_wwwww
);
THUNK
*
thunk
=
THUNK_Alloc
(
proc
,
(
RELAY
)
THUNK_
CallTo16_word_wwwww
);
if
(
!
thunk
)
return
NULL
;
if
(
!
thunk
)
return
NULL
;
thunk
=
(
THUNK
*
)
SetTaskSignalProc
(
hTask
,
(
FARPROC16
)
thunk
);
thunk
=
(
THUNK
*
)
SetTaskSignalProc
(
hTask
,
(
FARPROC16
)
thunk
);
...
@@ -580,7 +577,7 @@ static DWORD CALLBACK THUNK_StartThread16( LPVOID threadArgs )
...
@@ -580,7 +577,7 @@ static DWORD CALLBACK THUNK_StartThread16( LPVOID threadArgs )
DWORD
param
=
((
DWORD
*
)
threadArgs
)[
1
];
DWORD
param
=
((
DWORD
*
)
threadArgs
)[
1
];
HeapFree
(
GetProcessHeap
(),
0
,
threadArgs
);
HeapFree
(
GetProcessHeap
(),
0
,
threadArgs
);
return
CallTo16_long_l
(
start
,
param
);
return
THUNK_
CallTo16_long_l
(
start
,
param
);
}
}
HANDLE
WINAPI
THUNK_CreateThread16
(
SECURITY_ATTRIBUTES
*
sa
,
DWORD
stack
,
HANDLE
WINAPI
THUNK_CreateThread16
(
SECURITY_ATTRIBUTES
*
sa
,
DWORD
stack
,
FARPROC16
start
,
SEGPTR
param
,
FARPROC16
start
,
SEGPTR
param
,
...
@@ -621,61 +618,61 @@ static BOOL WINAPI THUNK_WOWCallback16Ex(
...
@@ -621,61 +618,61 @@ static BOOL WINAPI THUNK_WOWCallback16Ex(
args
[
i
]
=
((
DWORD
*
)
xargs
)[
cbArgs
-
i
-
1
];
args
[
i
]
=
((
DWORD
*
)
xargs
)[
cbArgs
-
i
-
1
];
}
}
switch
(
cbArgs
)
{
switch
(
cbArgs
)
{
case
0
:
ret
=
CallTo16_long_
(
proc
);
break
;
case
0
:
ret
=
THUNK_
CallTo16_long_
(
proc
);
break
;
case
1
:
ret
=
CallTo16_long_l
(
proc
,
args
[
0
]);
break
;
case
1
:
ret
=
THUNK_
CallTo16_long_l
(
proc
,
args
[
0
]);
break
;
case
2
:
ret
=
CallTo16_long_ll
(
proc
,
args
[
0
],
args
[
1
]);
break
;
case
2
:
ret
=
THUNK_
CallTo16_long_ll
(
proc
,
args
[
0
],
args
[
1
]);
break
;
case
3
:
ret
=
CallTo16_long_lll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
]);
break
;
case
3
:
ret
=
THUNK_
CallTo16_long_lll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
]);
break
;
case
4
:
ret
=
CallTo16_long_llll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]);
case
4
:
ret
=
THUNK_
CallTo16_long_llll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]);
break
;
break
;
case
5
:
ret
=
CallTo16_long_lllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
case
5
:
ret
=
THUNK_
CallTo16_long_lllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
]
args
[
4
]
);
);
break
;
break
;
case
6
:
ret
=
CallTo16_long_llllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
case
6
:
ret
=
THUNK_
CallTo16_long_llllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
]
args
[
4
],
args
[
5
]
);
);
break
;
break
;
case
7
:
ret
=
CallTo16_long_lllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
case
7
:
ret
=
THUNK_
CallTo16_long_lllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
]
args
[
4
],
args
[
5
],
args
[
6
]
);
);
break
;
break
;
case
8
:
ret
=
CallTo16_long_llllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
case
8
:
ret
=
THUNK_
CallTo16_long_llllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
]
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
]
);
);
break
;
break
;
case
9
:
ret
=
CallTo16_long_lllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
case
9
:
ret
=
THUNK_
CallTo16_long_lllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
]
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
]
);
);
break
;
break
;
case
10
:
ret
=
CallTo16_long_llllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
case
10
:
ret
=
THUNK_
CallTo16_long_llllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
]
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
]
);
);
break
;
break
;
case
11
:
ret
=
CallTo16_long_lllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
case
11
:
ret
=
THUNK_
CallTo16_long_lllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
]
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
]
);
);
break
;
break
;
case
12
:
ret
=
CallTo16_long_llllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
case
12
:
ret
=
THUNK_
CallTo16_long_llllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
]
args
[
10
],
args
[
11
]
);
);
break
;
break
;
case
13
:
ret
=
CallTo16_long_lllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
case
13
:
ret
=
THUNK_
CallTo16_long_lllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
]
args
[
10
],
args
[
11
],
args
[
12
]
);
);
break
;
break
;
case
14
:
ret
=
CallTo16_long_llllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
case
14
:
ret
=
THUNK_
CallTo16_long_llllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
]
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
]
);
);
break
;
break
;
case
15
:
ret
=
CallTo16_long_lllllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
case
15
:
ret
=
THUNK_
CallTo16_long_lllllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
],
args
[
14
]
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
],
args
[
14
]
);
);
break
;
break
;
case
16
:
ret
=
CallTo16_long_llllllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
case
16
:
ret
=
THUNK_
CallTo16_long_llllllllllllllll
(
proc
,
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
],
args
[
14
],
args
[
15
]
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
],
args
[
14
],
args
[
15
]
);
);
...
@@ -712,7 +709,7 @@ static VOID WINAPI THUNK_CallMouseEventProc( FARPROC16 proc,
...
@@ -712,7 +709,7 @@ static VOID WINAPI THUNK_CallMouseEventProc( FARPROC16 proc,
SI_reg
(
&
context
)
=
LOWORD
(
dwExtraInfo
);
SI_reg
(
&
context
)
=
LOWORD
(
dwExtraInfo
);
DI_reg
(
&
context
)
=
HIWORD
(
dwExtraInfo
);
DI_reg
(
&
context
)
=
HIWORD
(
dwExtraInfo
);
CallTo16
_sreg_
(
&
context
,
0
);
CallTo16
RegisterShort
(
&
context
,
0
);
}
}
VOID
WINAPI
THUNK_MOUSE_Enable
(
FARPROC16
proc
)
VOID
WINAPI
THUNK_MOUSE_Enable
(
FARPROC16
proc
)
{
{
...
@@ -774,7 +771,7 @@ static VOID WINAPI THUNK_CallKeybdEventProc( FARPROC16 proc,
...
@@ -774,7 +771,7 @@ static VOID WINAPI THUNK_CallKeybdEventProc( FARPROC16 proc,
SI_reg
(
&
context
)
=
LOWORD
(
dwExtraInfo
);
SI_reg
(
&
context
)
=
LOWORD
(
dwExtraInfo
);
DI_reg
(
&
context
)
=
HIWORD
(
dwExtraInfo
);
DI_reg
(
&
context
)
=
HIWORD
(
dwExtraInfo
);
CallTo16
_sreg_
(
&
context
,
0
);
CallTo16
RegisterShort
(
&
context
,
0
);
}
}
VOID
WINAPI
THUNK_KEYBOARD_Enable
(
FARPROC16
proc
,
LPBYTE
lpKeyState
)
VOID
WINAPI
THUNK_KEYBOARD_Enable
(
FARPROC16
proc
,
LPBYTE
lpKeyState
)
{
{
...
@@ -834,7 +831,7 @@ static void THUNK_CallSystemTimerProc( FARPROC16 proc, WORD timer )
...
@@ -834,7 +831,7 @@ static void THUNK_CallSystemTimerProc( FARPROC16 proc, WORD timer )
return
;
return
;
}
}
CallTo16
_sreg_
(
&
context
,
0
);
CallTo16
RegisterShort
(
&
context
,
0
);
/* FIXME: This does not work if the signal occurs while this thread
/* FIXME: This does not work if the signal occurs while this thread
is currently in 16-bit code. With the current structure
is currently in 16-bit code. With the current structure
...
@@ -890,7 +887,7 @@ void THUNK_InitCallout(void)
...
@@ -890,7 +887,7 @@ void THUNK_InitCallout(void)
#define GETADDR( var, name, thk ) \
#define GETADDR( var, name, thk ) \
*(FARPROC *)&Callout.##var = (FARPROC) \
*(FARPROC *)&Callout.##var = (FARPROC) \
THUNK_Alloc( WIN32_GetProcAddress16( hModule, name ), \
THUNK_Alloc( WIN32_GetProcAddress16( hModule, name ), \
(RELAY)CallTo16_##thk )
(RELAY)
THUNK_
CallTo16_##thk )
GETADDR
(
PeekMessage16
,
"PeekMessage"
,
word_lwwww
);
GETADDR
(
PeekMessage16
,
"PeekMessage"
,
word_lwwww
);
GETADDR
(
GetMessage16
,
"GetMessage"
,
word_lwww
);
GETADDR
(
GetMessage16
,
"GetMessage"
,
word_lwww
);
...
@@ -1006,7 +1003,7 @@ UINT WINAPI ThunkConnect16(
...
@@ -1006,7 +1003,7 @@ UINT WINAPI ThunkConnect16(
void
WINAPI
C16ThkSL
(
CONTEXT86
*
context
)
void
WINAPI
C16ThkSL
(
CONTEXT86
*
context
)
{
{
extern
void
CallFrom16
_t_long_
(
void
);
extern
void
CallFrom16
Thunk
(
void
);
LPBYTE
stub
=
PTR_SEG_TO_LIN
(
EAX_reg
(
context
)),
x
=
stub
;
LPBYTE
stub
=
PTR_SEG_TO_LIN
(
EAX_reg
(
context
)),
x
=
stub
;
WORD
cs
,
ds
;
WORD
cs
,
ds
;
GET_CS
(
cs
);
GET_CS
(
cs
);
...
@@ -1031,7 +1028,7 @@ void WINAPI C16ThkSL(CONTEXT86 *context)
...
@@ -1031,7 +1028,7 @@ void WINAPI C16ThkSL(CONTEXT86 *context)
*
x
++
=
0x55
;
*
x
++
=
0x55
;
*
x
++
=
0x66
;
*
x
++
=
0x52
;
*
x
++
=
0x66
;
*
x
++
=
0x52
;
*
x
++
=
0x66
;
*
x
++
=
0x9A
;
*
((
DWORD
*
)
x
)
++
=
(
DWORD
)
CallFrom16
_t_long_
;
*
x
++
=
0x66
;
*
x
++
=
0x9A
;
*
((
DWORD
*
)
x
)
++
=
(
DWORD
)
CallFrom16
Thunk
;
*
((
WORD
*
)
x
)
++
=
cs
;
*
((
WORD
*
)
x
)
++
=
cs
;
/* Jump to the stub code just created */
/* Jump to the stub code just created */
...
@@ -1056,7 +1053,7 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
...
@@ -1056,7 +1053,7 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
struct
ThunkDataSL16
*
SL16
=
PTR_SEG_TO_LIN
(
EDX_reg
(
context
));
struct
ThunkDataSL16
*
SL16
=
PTR_SEG_TO_LIN
(
EDX_reg
(
context
));
struct
ThunkDataSL
*
td
=
SL16
->
fpData
;
struct
ThunkDataSL
*
td
=
SL16
->
fpData
;
extern
void
CallFrom16
_t_long_
(
void
);
extern
void
CallFrom16
Thunk
(
void
);
DWORD
procAddress
=
(
DWORD
)
GetProcAddress16
(
GetModuleHandle16
(
"KERNEL"
),
631
);
DWORD
procAddress
=
(
DWORD
)
GetProcAddress16
(
GetModuleHandle16
(
"KERNEL"
),
631
);
WORD
cs
;
WORD
cs
;
GET_CS
(
cs
);
GET_CS
(
cs
);
...
@@ -1086,7 +1083,7 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
...
@@ -1086,7 +1083,7 @@ void WINAPI C16ThkSL01(CONTEXT86 *context)
*
x
++
=
0x55
;
*
x
++
=
0x55
;
*
x
++
=
0x66
;
*
x
++
=
0x52
;
*
x
++
=
0x66
;
*
x
++
=
0x52
;
*
x
++
=
0x66
;
*
x
++
=
0x9A
;
*
((
DWORD
*
)
x
)
++
=
(
DWORD
)
CallFrom16
_t_long_
;
*
x
++
=
0x66
;
*
x
++
=
0x9A
;
*
((
DWORD
*
)
x
)
++
=
(
DWORD
)
CallFrom16
Thunk
;
*
((
WORD
*
)
x
)
++
=
cs
;
*
((
WORD
*
)
x
)
++
=
cs
;
/* Jump to the stub code just created */
/* Jump to the stub code just created */
...
...
include/builtin16.h
0 → 100644
View file @
3dff7bb8
/*
* Win16 built-in DLLs definitions
*
* Copyright 1999 Ulrich Weigand
*/
#ifndef __WINE_BUILTIN16_H
#define __WINE_BUILTIN16_H
#include "windef.h"
#include "pshpack1.h"
typedef
struct
{
WORD
pushw_bp
;
/* pushw %bp */
BYTE
pushl
;
/* pushl $target */
DWORD
target
;
BYTE
lcall
;
/* lcall __FLATCS__:relay */
DWORD
relay
;
WORD
flatcs
;
}
STD_ENTRYPOINT16
;
typedef
struct
{
WORD
movw_ax
;
/* movw $<ax>, %ax */
WORD
ax
;
WORD
movw_dx
;
/* movw $<dx>, %dx */
WORD
dx
;
WORD
lret
;
/* lret $<args> */
WORD
args
;
WORD
nopnop
;
/* nop; nop */
}
RET_ENTRYPOINT16
;
typedef
union
{
STD_ENTRYPOINT16
std
;
RET_ENTRYPOINT16
ret
;
}
ENTRYPOINT16
;
#define EP_STD( target, relay ) \
{ std: { 0x5566, 0x68, (DWORD)(target), 0x9a, (DWORD)(relay), __FLATCS__ } }
#define EP_RET( retval, nargs ) \
{ ret: { 0xb866, LOWORD(retval), 0xba66, HIWORD(retval), \
(nargs)? 0xca66 : 0xcb66, (nargs)? (nargs) : 0x9090, 0x9090 } }
#include "poppack.h"
typedef
struct
{
const
char
*
name
;
/* DLL name */
void
*
module_start
;
/* 32-bit address of the module data */
int
module_size
;
/* Size of the module data */
const
BYTE
*
code_start
;
/* 32-bit address of DLL code */
const
BYTE
*
data_start
;
/* 32-bit address of DLL data */
}
WIN16_DESCRIPTOR
;
extern
void
RELAY_Unimplemented16
(
void
);
#endif
/* __WINE_BUILTIN16_H */
include/callback.h
View file @
3dff7bb8
...
@@ -20,53 +20,53 @@ extern int (*IF1632_CallLargeStack)( int (*func)(void), void *arg );
...
@@ -20,53 +20,53 @@ extern int (*IF1632_CallLargeStack)( int (*func)(void), void *arg );
typedef
struct
typedef
struct
{
{
LONG
(
CALLBACK
*
CallRegisterShortProc
)(
CONTEXT86
*
,
INT
);
LONG
(
*
CallRegisterShortProc
)(
CONTEXT86
*
,
INT
);
LONG
(
CALLBACK
*
CallRegisterLongProc
)(
CONTEXT86
*
,
INT
);
LONG
(
*
CallRegisterLongProc
)(
CONTEXT86
*
,
INT
);
VOID
(
CALLBACK
*
CallFrom16WndProc
)(
void
);
VOID
(
*
CallFrom16WndProc
)(
void
);
LRESULT
(
CALLBACK
*
CallWndProc
)(
WNDPROC16
,
HWND16
,
UINT16
,
LRESULT
(
*
CallWndProc
)(
WNDPROC16
,
HWND16
,
UINT16
,
WPARAM16
,
LPARAM
);
WPARAM16
,
LPARAM
);
LRESULT
(
CALLBACK
*
CallDriverProc
)(
DRIVERPROC16
,
DWORD
,
HDRVR16
,
LRESULT
(
*
CallDriverProc
)(
DRIVERPROC16
,
DWORD
,
HDRVR16
,
UINT16
,
LPARAM
,
LPARAM
);
UINT16
,
LPARAM
,
LPARAM
);
LRESULT
(
CALLBACK
*
CallDriverCallback
)(
FARPROC16
,
HANDLE16
,
UINT16
,
LRESULT
(
*
CallDriverCallback
)(
FARPROC16
,
HANDLE16
,
UINT16
,
DWORD
,
LPARAM
,
LPARAM
);
DWORD
,
LPARAM
,
LPARAM
);
LRESULT
(
CALLBACK
*
CallTimeFuncProc
)(
FARPROC16
,
WORD
,
UINT16
,
LRESULT
(
*
CallTimeFuncProc
)(
FARPROC16
,
WORD
,
UINT16
,
DWORD
,
LPARAM
,
LPARAM
);
DWORD
,
LPARAM
,
LPARAM
);
INT16
(
CALLBACK
*
CallWindowsExitProc
)(
FARPROC16
,
INT16
);
INT16
(
*
CallWindowsExitProc
)(
FARPROC16
,
INT16
);
INT16
(
CALLBACK
*
CallWordBreakProc
)(
EDITWORDBREAKPROC16
,
SEGPTR
,
INT16
,
INT16
(
*
CallWordBreakProc
)(
EDITWORDBREAKPROC16
,
SEGPTR
,
INT16
,
INT16
,
INT16
);
INT16
,
INT16
);
VOID
(
CALLBACK
*
CallBootAppProc
)(
FARPROC16
,
HANDLE16
,
HFILE16
);
VOID
(
*
CallBootAppProc
)(
FARPROC16
,
HANDLE16
,
HFILE16
);
WORD
(
CALLBACK
*
CallLoadAppSegProc
)(
FARPROC16
,
HANDLE16
,
HFILE16
,
WORD
);
WORD
(
*
CallLoadAppSegProc
)(
FARPROC16
,
HANDLE16
,
HFILE16
,
WORD
);
WORD
(
CALLBACK
*
CallLocalNotifyFunc
)(
FARPROC16
,
WORD
,
HLOCAL16
,
WORD
);
WORD
(
*
CallLocalNotifyFunc
)(
FARPROC16
,
WORD
,
HLOCAL16
,
WORD
);
HGLOBAL16
(
CALLBACK
*
CallResourceHandlerProc
)(
FARPROC16
,
HGLOBAL16
,
HMODULE16
,
HRSRC16
);
HGLOBAL16
(
*
CallResourceHandlerProc
)(
FARPROC16
,
HGLOBAL16
,
HMODULE16
,
HRSRC16
);
DWORD
(
CALLBACK
*
CallWOWCallbackProc
)(
FARPROC16
,
DWORD
);
DWORD
(
*
CallWOWCallbackProc
)(
FARPROC16
,
DWORD
);
BOOL
(
CALLBACK
*
CallWOWCallback16Ex
)(
FARPROC16
,
DWORD
,
DWORD
,
LPVOID
,
BOOL
(
*
CallWOWCallback16Ex
)(
FARPROC16
,
DWORD
,
DWORD
,
LPVOID
,
LPDWORD
);
LPDWORD
);
DWORD
(
CALLBACK
*
CallUTProc
)(
FARPROC16
,
DWORD
,
DWORD
);
DWORD
(
*
CallUTProc
)(
FARPROC16
,
DWORD
,
DWORD
);
LRESULT
(
CALLBACK
*
CallASPIPostProc
)(
FARPROC16
,
SEGPTR
);
LRESULT
(
*
CallASPIPostProc
)(
FARPROC16
,
SEGPTR
);
/* Following are the graphics driver callbacks */
/* Following are the graphics driver callbacks */
WORD
(
CALLBACK
*
CallDrvControlProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
WORD
(
*
CallDrvControlProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
SEGPTR
,
SEGPTR
);
SEGPTR
,
SEGPTR
);
WORD
(
CALLBACK
*
CallDrvEnableProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
SEGPTR
,
WORD
(
*
CallDrvEnableProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
SEGPTR
,
SEGPTR
,
SEGPTR
);
SEGPTR
,
SEGPTR
);
WORD
(
CALLBACK
*
CallDrvEnumDFontsProc
)(
FARPROC16
,
SEGPTR
,
SEGPTR
,
WORD
(
*
CallDrvEnumDFontsProc
)(
FARPROC16
,
SEGPTR
,
SEGPTR
,
FARPROC16
,
SEGPTR
);
FARPROC16
,
SEGPTR
);
WORD
(
CALLBACK
*
CallDrvEnumObjProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
FARPROC16
,
WORD
(
*
CallDrvEnumObjProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
FARPROC16
,
SEGPTR
);
SEGPTR
);
WORD
(
CALLBACK
*
CallDrvOutputProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
WORD
,
SEGPTR
,
WORD
(
*
CallDrvOutputProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
WORD
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
);
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
);
DWORD
(
CALLBACK
*
CallDrvRealizeProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
SEGPTR
,
DWORD
(
*
CallDrvRealizeProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
SEGPTR
,
SEGPTR
,
SEGPTR
);
SEGPTR
,
SEGPTR
);
WORD
(
CALLBACK
*
CallDrvStretchBltProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
WORD
,
WORD
(
*
CallDrvStretchBltProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
WORD
,
WORD
,
WORD
,
SEGPTR
,
WORD
,
WORD
,
WORD
,
WORD
,
SEGPTR
,
WORD
,
WORD
,
WORD
,
WORD
,
DWORD
,
SEGPTR
,
SEGPTR
,
WORD
,
WORD
,
DWORD
,
SEGPTR
,
SEGPTR
,
SEGPTR
);
SEGPTR
);
DWORD
(
CALLBACK
*
CallDrvExtTextOutProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
WORD
,
DWORD
(
*
CallDrvExtTextOutProc
)(
FARPROC16
,
SEGPTR
,
WORD
,
WORD
,
SEGPTR
,
SEGPTR
,
INT16
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
INT16
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
SEGPTR
,
WORD
);
WORD
);
WORD
(
CALLBACK
*
CallDrvGetCharWidthProc
)(
FARPROC16
,
SEGPTR
,
SEGPTR
,
WORD
,
WORD
(
*
CallDrvGetCharWidthProc
)(
FARPROC16
,
SEGPTR
,
SEGPTR
,
WORD
,
WORD
,
SEGPTR
,
SEGPTR
,
SEGPTR
);
WORD
,
SEGPTR
,
SEGPTR
,
SEGPTR
);
BOOL16
(
CALLBACK
*
CallDrvAbortProc
)(
FARPROC16
,
HDC16
,
INT16
);
BOOL16
(
*
CallDrvAbortProc
)(
FARPROC16
,
HDC16
,
INT16
);
}
CALLBACKS_TABLE
;
}
CALLBACKS_TABLE
;
extern
const
CALLBACKS_TABLE
*
Callbacks
;
extern
const
CALLBACKS_TABLE
*
Callbacks
;
...
...
include/module.h
View file @
3dff7bb8
...
@@ -235,7 +235,7 @@ HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD s
...
@@ -235,7 +235,7 @@ HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD s
/* if1632/builtin.c */
/* if1632/builtin.c */
extern
BOOL
BUILTIN_Init
(
void
);
extern
BOOL
BUILTIN_Init
(
void
);
extern
HMODULE16
BUILTIN_LoadModule
(
LPCSTR
name
,
BOOL
force
);
extern
HMODULE16
BUILTIN_LoadModule
(
LPCSTR
name
,
BOOL
force
);
extern
LPCSTR
BUILTIN_GetEntryPoint16
(
WORD
cs
,
WORD
ip
,
WORD
*
pOrd
);
extern
LPCSTR
BUILTIN_GetEntryPoint16
(
WORD
cs
,
WORD
ip
,
LPSTR
name
,
WORD
*
pOrd
);
/* relay32/builtin.c */
/* relay32/builtin.c */
extern
HMODULE
BUILTIN32_LoadImage
(
LPCSTR
name
,
OFSTRUCT
*
ofs
);
extern
HMODULE
BUILTIN32_LoadImage
(
LPCSTR
name
,
OFSTRUCT
*
ofs
);
...
...
include/stackframe.h
View file @
3dff7bb8
...
@@ -32,17 +32,20 @@ typedef struct _STACK32FRAME
...
@@ -32,17 +32,20 @@ typedef struct _STACK32FRAME
typedef
struct
typedef
struct
{
{
STACK32FRAME
*
frame32
;
/* 00 32-bit frame from last CallTo16() */
STACK32FRAME
*
frame32
;
/* 00 32-bit frame from last CallTo16() */
DWORD
ebp
;
/* 04 full 32-bit content of ebp */
DWORD
edx
;
/* 04 saved registers */
WORD
mutex_count
;
/* 08 Win16Mutex recursion count */
DWORD
ecx
;
/* 08 */
WORD
fs
;
/* 0a fs */
DWORD
ebp
;
/* 0c */
WORD
entry_ip
;
/* 0c ip of entry point */
WORD
ds
;
/* 10 */
WORD
ds
;
/* 0e ds */
WORD
es
;
/* 12 */
WORD
entry_cs
;
/* 10 cs of entry point */
WORD
fs
;
/* 14 */
WORD
es
;
/* 12 es */
WORD
gs
;
/* 16 */
DWORD
entry_point
;
/* 14 32-bit entry point to call */
DWORD
relay
;
/* 18 address of argument relay stub */
WORD
bp
;
/* 18 16-bit bp */
DWORD
entry_ip
;
/* 1c ip of entry point */
WORD
ip
;
/* 1a return address */
DWORD
entry_cs
;
/* 20 cs of entry point */
WORD
cs
;
/* 1c */
DWORD
entry_point
;
/* 24 API entry point to call, reused as mutex count */
WORD
bp
;
/* 28 16-bit stack frame chain */
WORD
ip
;
/* 2a return address */
WORD
cs
;
/* 2c */
}
STACK16FRAME
;
}
STACK16FRAME
;
#include "poppack.h"
#include "poppack.h"
...
...
misc/callback.c
View file @
3dff7bb8
...
@@ -21,7 +21,7 @@ DEFAULT_DEBUG_CHANNEL(relay)
...
@@ -21,7 +21,7 @@ DEFAULT_DEBUG_CHANNEL(relay)
/**********************************************************************
/**********************************************************************
* CALLBACK_CallWndProc
* CALLBACK_CallWndProc
*/
*/
static
LRESULT
WINAPI
CALLBACK_CallWndProc
(
WNDPROC16
proc
,
HWND16
hwnd
,
static
LRESULT
CALLBACK_CallWndProc
(
WNDPROC16
proc
,
HWND16
hwnd
,
UINT16
msg
,
WPARAM16
wParam
,
UINT16
msg
,
WPARAM16
wParam
,
LPARAM
lParam
)
LPARAM
lParam
)
{
{
...
@@ -36,225 +36,149 @@ static LRESULT WINAPI CALLBACK_CallWndProc( WNDPROC16 proc, HWND16 hwnd,
...
@@ -36,225 +36,149 @@ static LRESULT WINAPI CALLBACK_CallWndProc( WNDPROC16 proc, HWND16 hwnd,
return
retvalue
;
return
retvalue
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallRegisterProc
* CALLBACK_CallRegisterProc
*/
*/
static
LONG
WINAPI
CALLBACK_CallRegisterProc
(
CONTEXT86
*
context
,
INT
offset
)
static
LONG
CALLBACK_CallRegisterProc
(
CONTEXT86
*
context
,
INT
offset
)
{
{
ERR
(
"Cannot call a register proc in Winelib
\n
"
);
ERR
(
"Cannot call a register proc in Winelib
\n
"
);
assert
(
FALSE
);
assert
(
FALSE
);
return
0
;
return
0
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallDriverProc
* CALLBACK_CallDriverProc
*/
*/
static
LRESULT
WINAPI
CALLBACK_CallDriverProc
(
DRIVERPROC16
proc
,
DWORD
dwId
,
static
LRESULT
CALLBACK_CallDriverProc
(
DRIVERPROC16
proc
,
DWORD
dwId
,
HDRVR16
hdrvr
,
UINT16
msg
,
HDRVR16
hdrvr
,
UINT16
msg
,
LPARAM
lp1
,
LPARAM
lp2
)
LPARAM
lp1
,
LPARAM
lp2
)
{
{
return
proc
(
dwId
,
hdrvr
,
msg
,
lp1
,
lp2
);
ERR
(
"Cannot call a 16-bit driver proc in Winelib
\n
"
);
assert
(
FALSE
);
return
0
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallDriverCallback
* CALLBACK_CallDriverCallback
*/
*/
static
LRESULT
WINAPI
CALLBACK_CallDriverCallback
(
FARPROC16
proc
,
static
LRESULT
CALLBACK_CallDriverCallback
(
FARPROC16
proc
,
HANDLE16
hDev
,
UINT16
msg
,
HANDLE16
hDev
,
UINT16
msg
,
DWORD
dwUser
,
LPARAM
lp1
,
DWORD
dwUser
,
LPARAM
lp1
,
LPARAM
lp2
)
LPARAM
lp2
)
{
{
return
proc
(
hDev
,
msg
,
dwUser
,
lp1
,
lp2
);
ERR
(
"Cannot call a 16-bit driver proc in Winelib
\n
"
);
assert
(
FALSE
);
return
0
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallTimeFuncProc
* CALLBACK_CallTimeFuncProc
*/
*/
static
LRESULT
WINAPI
CALLBACK_CallTimeFuncProc
(
FARPROC16
proc
,
WORD
id
,
static
LRESULT
CALLBACK_CallTimeFuncProc
(
FARPROC16
proc
,
WORD
id
,
UINT16
msg
,
DWORD
dwUser
,
UINT16
msg
,
DWORD
dwUser
,
LPARAM
lp1
,
LPARAM
lp2
)
LPARAM
lp1
,
LPARAM
lp2
)
{
{
return
proc
(
id
,
msg
,
dwUser
,
lp1
,
lp2
);
return
proc
(
id
,
msg
,
dwUser
,
lp1
,
lp2
);
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallWindowsExitProc
* CALLBACK_CallWindowsExitProc
*/
*/
static
INT16
WINAPI
CALLBACK_CallWindowsExitProc
(
FARPROC16
proc
,
INT16
type
)
static
INT16
CALLBACK_CallWindowsExitProc
(
FARPROC16
proc
,
INT16
type
)
{
{
return
proc
(
type
);
return
proc
(
type
);
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallWordBreakProc
* CALLBACK_CallWordBreakProc
*/
*/
static
INT16
WINAPI
CALLBACK_CallWordBreakProc
(
EDITWORDBREAKPROC16
proc
,
static
INT16
CALLBACK_CallWordBreakProc
(
EDITWORDBREAKPROC16
proc
,
SEGPTR
text
,
INT16
word
,
SEGPTR
text
,
INT16
word
,
INT16
len
,
INT16
action
)
INT16
len
,
INT16
action
)
{
{
return
proc
(
(
LPSTR
)
text
,
word
,
len
,
action
);
return
proc
(
(
LPSTR
)
text
,
word
,
len
,
action
);
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallBootAppProc
* CALLBACK_CallBootAppProc
*/
*/
static
void
WINAPI
CALLBACK_CallBootAppProc
(
FARPROC16
proc
,
HANDLE16
module
,
static
void
CALLBACK_CallBootAppProc
(
FARPROC16
proc
,
HANDLE16
module
,
HFILE16
file
)
HFILE16
file
)
{
{
proc
(
module
,
file
);
ERR
(
"Cannot call a 16-bit self-load handler in Winelib
\n
"
);
assert
(
FALSE
);
return
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallLoadAppSegProc
* CALLBACK_CallLoadAppSegProc
*/
*/
static
WORD
WINAPI
CALLBACK_CallLoadAppSegProc
(
FARPROC16
proc
,
static
WORD
CALLBACK_CallLoadAppSegProc
(
FARPROC16
proc
,
HANDLE16
module
,
HFILE16
file
,
HANDLE16
module
,
HFILE16
file
,
WORD
seg
)
WORD
seg
)
{
{
return
proc
(
module
,
file
,
seg
);
ERR
(
"Cannot call a 16-bit self-load handler in Winelib
\n
"
);
assert
(
FALSE
);
return
0
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallLocalNotifyFunc
* CALLBACK_CallLocalNotifyFunc
*/
*/
static
WORD
WINAPI
CALLBACK_CallLocalNotifyFunc
(
FARPROC16
proc
,
static
WORD
CALLBACK_CallLocalNotifyFunc
(
FARPROC16
proc
,
WORD
wMsg
,
HLOCAL16
hMem
,
WORD
wMsg
,
HLOCAL16
hMem
,
WORD
wArg
)
WORD
wArg
)
{
{
return
proc
(
wMsg
,
hMem
,
wArg
);
ERR
(
"Cannot call a 16-bit notification handler in Winelib
\n
"
);
assert
(
FALSE
);
return
0
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallResourceHandlerProc
* CALLBACK_CallResourceHandlerProc
*/
*/
static
HGLOBAL16
WINAPI
CALLBACK_CallResourceHandlerProc
(
FARPROC16
proc
,
static
HGLOBAL16
CALLBACK_CallResourceHandlerProc
(
FARPROC16
proc
,
HGLOBAL16
hMemObj
,
HGLOBAL16
hMemObj
,
HMODULE16
hModule
,
HMODULE16
hModule
,
HRSRC16
hRsrc
)
HRSRC16
hRsrc
)
{
{
ERR
(
"Cannot call a 16-bit resource handler in Winelib
\n
"
);
ERR
(
"Cannot call a 16-bit resource handler in Winelib
\n
"
);
assert
(
FALSE
);
assert
(
FALSE
);
return
0
;
return
0
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallASPIPostProc
* CALLBACK_CallASPIPostProc
*/
*/
static
LRESULT
WINAPI
CALLBACK_CallASPIPostProc
(
FARPROC16
proc
,
SEGPTR
ptr
)
static
LRESULT
CALLBACK_CallASPIPostProc
(
FARPROC16
proc
,
SEGPTR
ptr
)
{
{
return
proc
(
ptr
);
return
proc
(
ptr
);
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallWOWCallbackProc
* CALLBACK_CallWOWCallbackProc
*/
*/
static
DWORD
WINAPI
CALLBACK_CallWOWCallbackProc
(
FARPROC16
proc
,
DWORD
dw
)
static
DWORD
CALLBACK_CallWOWCallbackProc
(
FARPROC16
proc
,
DWORD
dw
)
{
{
return
proc
(
dw
);
ERR
(
"Cannot call a WOW thunk proc in Winelib
\n
"
);
assert
(
FALSE
);
return
0
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallWOWCallback16Ex
* CALLBACK_CallWOWCallback16Ex
*
* WCB16_MAX_CBARGS (16) is the maximum number of args.
*
* Can call functions using CDECL or PASCAL calling conventions. The CDECL
* ones are reversed (not 100% sure about that).
*/
*/
static
BOOL
WINAPI
CALLBACK_CallWOWCallback16Ex
(
static
BOOL
CALLBACK_CallWOWCallback16Ex
(
FARPROC16
proc
,
DWORD
dwFlags
,
FARPROC16
proc
,
DWORD
dwFlags
,
DWORD
cbArgs
,
LPVOID
xargs
,
LPDWORD
pdwret
DWORD
cbArgs
,
LPVOID
xargs
,
LPDWORD
pdwret
)
)
{
{
LPDWORD
args
=
(
LPDWORD
)
xargs
;
ERR
(
"Cannot call a WOW thunk proc in Winelib
\n
"
);
DWORD
ret
,
i
;
assert
(
FALSE
);
return
0
;
if
(
dwFlags
==
WCB16_CDECL
)
{
/* swap the arguments */
args
=
HeapAlloc
(
GetProcessHeap
(),
0
,
cbArgs
*
sizeof
(
DWORD
));
for
(
i
=
0
;
i
<
cbArgs
;
i
++
)
args
[
i
]
=
((
DWORD
*
)
xargs
)[
cbArgs
-
i
-
1
];
}
switch
(
cbArgs
)
{
case
0
:
ret
=
proc
();
break
;
case
1
:
ret
=
proc
(
args
[
0
]);
break
;
case
2
:
ret
=
proc
(
args
[
0
],
args
[
1
]);
break
;
case
3
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
]);
break
;
case
4
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]);
break
;
case
5
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
]);
break
;
case
6
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
]);
break
;
case
7
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
]
);
break
;
case
8
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
]
);
break
;
case
9
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
]
);
break
;
case
10
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
]
);
break
;
case
11
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
]
);
break
;
case
12
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
]
);
break
;
case
13
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
]
);
break
;
case
14
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
]
);
break
;
case
15
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
],
args
[
14
]
);
break
;
case
16
:
ret
=
proc
(
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
],
args
[
5
],
args
[
6
],
args
[
7
],
args
[
8
],
args
[
9
],
args
[
10
],
args
[
11
],
args
[
12
],
args
[
13
],
args
[
14
],
args
[
15
]
);
break
;
default
:
WARN
(
"(%ld) arguments not supported.
\n
"
,
cbArgs
);
if
(
dwFlags
==
WCB16_CDECL
)
HeapFree
(
GetProcessHeap
(),
0
,
args
);
return
FALSE
;
}
if
(
dwFlags
==
WCB16_CDECL
)
HeapFree
(
GetProcessHeap
(),
0
,
args
);
if
(
pdwret
)
*
pdwret
=
ret
;
return
TRUE
;
}
}
/**********************************************************************
/**********************************************************************
* CALLBACK_CallUTProc
* CALLBACK_CallUTProc
*/
*/
static
DWORD
WINAPI
CALLBACK_CallUTProc
(
FARPROC16
proc
,
DWORD
w1
,
DWORD
w2
)
static
DWORD
CALLBACK_CallUTProc
(
FARPROC16
proc
,
DWORD
w1
,
DWORD
w2
)
{
{
ERR
(
"Cannot call a UT thunk proc in Winelib
\n
"
);
ERR
(
"Cannot call a UT thunk proc in Winelib
\n
"
);
assert
(
FALSE
);
assert
(
FALSE
);
...
...
miscemu/main.c
View file @
3dff7bb8
...
@@ -27,12 +27,8 @@ extern int (*INSTR_IsRelay)( const void *addr );
...
@@ -27,12 +27,8 @@ extern int (*INSTR_IsRelay)( const void *addr );
static
int
is_relay_addr
(
const
void
*
addr
)
static
int
is_relay_addr
(
const
void
*
addr
)
{
{
extern
char
CallFrom16_Start
,
CallFrom16_End
,
CALLTO16_Start
,
CALLTO16_End
;
extern
char
Call16_Start
,
Call16_End
;
return
((
char
*
)
addr
>=
&
Call16_Start
)
&&
((
char
*
)
addr
<
&
Call16_End
);
return
((((
char
*
)
addr
>=
&
CallFrom16_Start
)
&&
((
char
*
)
addr
<
&
CallFrom16_End
))
||
(((
char
*
)
addr
>=
&
CALLTO16_Start
)
&&
((
char
*
)
addr
<
&
CALLTO16_End
)));
}
}
/***********************************************************************
/***********************************************************************
...
...
relay32/.cvsignore
View file @
3dff7bb8
Makefile
Makefile
advapi32.c
advapi32.
spec.
c
avifil32.c
avifil32.
spec.
c
call32.s
call32.s
comctl32.c
comctl32.
spec.
c
comdlg32.c
comdlg32.
spec.
c
crtdll.c
crtdll.
spec.
c
dciman32.c
dciman32.
spec.
c
ddraw.c
ddraw.
spec.
c
dinput.c
dinput.
spec.
c
dplay.c
dplay.
spec.
c
dplayx.c
dplayx.
spec.
c
dsound.c
dsound.
spec.
c
gdi32.c
gdi32.
spec.
c
imagehlp.c
imagehlp.
spec.
c
imm32.c
imm32.
spec.
c
kernel32.c
kernel32.
spec.
c
lz32.c
lz32.
spec.
c
mcianim.c
mcianim.
spec.
c
mciavi.c
mciavi.
spec.
c
mcicda.c
mcicda.
spec.
c
mciseq.c
mciseq.
spec.
c
mciwave.c
mciwave.
spec.
c
mpr.c
mpr.
spec.
c
msacm32.c
msacm32.
spec.
c
msnet32.c
msnet32.
spec.
c
msvfw32.c
msvfw32.
spec.
c
ntdll.c
ntdll.
spec.
c
ole32.c
ole32.
spec.
c
oleaut32.c
oleaut32.
spec.
c
olecli32.c
olecli32.
spec.
c
oledlg.c
oledlg.
spec.
c
olesvr32.c
olesvr32.
spec.
c
psapi.c
psapi.
spec.
c
rasapi32.c
rasapi32.
spec.
c
shell32.c
shell32.
spec.
c
tapi32.c
tapi32.
spec.
c
user32.c
user32.
spec.
c
version.c
version.
spec.
c
w32skrnl.c
w32skrnl.
spec.
c
winmm.c
winmm.
spec.
c
winspool.c
winspool.
spec.
c
wnaspi32.c
wnaspi32.
spec.
c
wow32.c
wow32.
spec.
c
wsock32.c
wsock32.
spec.
c
relay32/Makefile.in
View file @
3dff7bb8
...
@@ -5,7 +5,7 @@ SRCDIR = @srcdir@
...
@@ -5,7 +5,7 @@ SRCDIR = @srcdir@
VPATH
=
@srcdir@
VPATH
=
@srcdir@
MODULE
=
relay32
MODULE
=
relay32
DLL
S
=
\
SPEC_SRC
S
=
\
advapi32.spec
\
advapi32.spec
\
avifil32.spec
\
avifil32.spec
\
comctl32.spec
\
comctl32.spec
\
...
@@ -56,30 +56,14 @@ C_SRCS = \
...
@@ -56,30 +56,14 @@ C_SRCS = \
snoop.c
\
snoop.c
\
utthunk.c
utthunk.c
SPEC_FILES
=
$
(
DLLS:.spec
=
.c
)
EXTRA_OBJS
=
$
(
DLLS:.spec
=
.o
)
GEN_ASM_SRCS
=
\
GEN_ASM_SRCS
=
\
call32.s
call32.s
.SUFFIXES
:
.spec
all
:
$(MODULE).o
.spec.c
:
$(BUILD)
-o
$@
-spec
$<
all
:
checkbuild $(MODULE).o
@MAKE_RULES@
@MAKE_RULES@
$(SPEC_FILES)
:
$(BUILD)
$(EXTRA_OBJS)
:
$(TOPSRCDIR)/include/builtin32.h
call32.s
:
$(BUILD)
call32.s
:
$(BUILD)
$(BUILD)
-o
$@
-call32
$(BUILD)
-o
$@
-call32
clean
::
$(RM)
$(SPEC_FILES)
### Dependencies:
### Dependencies:
scheduler/syslevel.c
View file @
3dff7bb8
...
@@ -204,14 +204,10 @@ VOID WINAPI RestoreThunkLock(DWORD mutex_count)
...
@@ -204,14 +204,10 @@ VOID WINAPI RestoreThunkLock(DWORD mutex_count)
*/
*/
VOID
SYSLEVEL_ReleaseWin16Lock
(
VOID
)
VOID
SYSLEVEL_ReleaseWin16Lock
(
VOID
)
{
{
DWORD
count
;
/* entry_point is never used again once the entry point has
been called. Thus we re-use it to hold the Win16Lock count */
ReleaseThunkLock
(
&
count
);
ReleaseThunkLock
(
&
CURRENT_STACK16
->
entry_point
);
if
(
count
>
0xffff
)
ERR
(
"Win16Mutex recursion count too large!
\n
"
);
CURRENT_STACK16
->
mutex_count
=
(
WORD
)
count
;
}
}
/************************************************************************
/************************************************************************
...
@@ -219,12 +215,7 @@ VOID SYSLEVEL_ReleaseWin16Lock(VOID)
...
@@ -219,12 +215,7 @@ VOID SYSLEVEL_ReleaseWin16Lock(VOID)
*/
*/
VOID
SYSLEVEL_RestoreWin16Lock
(
VOID
)
VOID
SYSLEVEL_RestoreWin16Lock
(
VOID
)
{
{
DWORD
count
=
CURRENT_STACK16
->
mutex_count
;
RestoreThunkLock
(
CURRENT_STACK16
->
entry_point
);
if
(
!
count
)
ERR
(
"Win16Mutex recursion count is zero!
\n
"
);
RestoreThunkLock
(
count
);
}
}
/************************************************************************
/************************************************************************
...
...
tools/build.c
View file @
3dff7bb8
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
* Copyright 1995 Martin von Loewis
* Copyright 1995 Martin von Loewis
* Copyright 1995, 1996, 1997 Alexandre Julliard
* Copyright 1995, 1996, 1997 Alexandre Julliard
* Copyright 1997 Eric Youngdale
* Copyright 1997 Eric Youngdale
* Copyright 1999 Ulrich Weigand
*/
*/
#include <assert.h>
#include <assert.h>
...
@@ -18,6 +19,7 @@
...
@@ -18,6 +19,7 @@
#include "neexe.h"
#include "neexe.h"
#include "selectors.h"
#include "selectors.h"
#include "stackframe.h"
#include "stackframe.h"
#include "builtin16.h"
#include "thread.h"
#include "thread.h"
#ifdef NEED_UNDERSCORE_PREFIX
#ifdef NEED_UNDERSCORE_PREFIX
...
@@ -176,6 +178,12 @@ static int debugging = 1;
...
@@ -176,6 +178,12 @@ static int debugging = 1;
/* Offset of register relative to the start of the CONTEXT struct */
/* Offset of register relative to the start of the CONTEXT struct */
#define CONTEXTOFFSET(reg) STRUCTOFFSET(CONTEXT86,reg)
#define CONTEXTOFFSET(reg) STRUCTOFFSET(CONTEXT86,reg)
/* Offset of register relative to the start of the STACK16FRAME struct */
#define STACK16OFFSET(reg) STRUCTOFFSET(STACK16FRAME,reg)
/* Offset of register relative to the start of the STACK32FRAME struct */
#define STACK32OFFSET(reg) STRUCTOFFSET(STACK32FRAME,reg)
/* Offset of the stack pointer relative to %fs:(0) */
/* Offset of the stack pointer relative to %fs:(0) */
#define STACKOFFSET (STRUCTOFFSET(TEB,cur_stack))
#define STACKOFFSET (STRUCTOFFSET(TEB,cur_stack))
...
@@ -815,19 +823,19 @@ static int StoreVariableCode( unsigned char *buffer, int size, ORDDEF *odp )
...
@@ -815,19 +823,19 @@ static int StoreVariableCode( unsigned char *buffer, int size, ORDDEF *odp )
* Dump a byte stream into the assembly code.
* Dump a byte stream into the assembly code.
*/
*/
static
void
DumpBytes
(
FILE
*
outfile
,
const
unsigned
char
*
data
,
int
len
,
static
void
DumpBytes
(
FILE
*
outfile
,
const
unsigned
char
*
data
,
int
len
,
const
char
*
section
,
const
char
*
label_start
)
const
char
*
label
)
{
{
int
i
;
int
i
;
if
(
section
)
fprintf
(
outfile
,
"
\t
%s
\n
"
,
section
);
if
(
label_start
)
fprintf
(
outfile
,
"%s:
\n
"
,
label_start
);
fprintf
(
outfile
,
"
\n
static BYTE %s[] =
\n
{"
,
label
);
for
(
i
=
0
;
i
<
len
;
i
++
)
for
(
i
=
0
;
i
<
len
;
i
++
)
{
{
if
(
!
(
i
&
0x0f
))
fprintf
(
outfile
,
"
\
t
.byte
"
);
if
(
!
(
i
&
0x0f
))
fprintf
(
outfile
,
"
\
n
"
);
fprintf
(
outfile
,
"%d"
,
*
data
++
);
fprintf
(
outfile
,
"%d"
,
*
data
++
);
if
(
i
<
len
-
1
)
if
(
i
<
len
-
1
)
fprintf
(
outfile
,
", "
);
fprintf
(
outfile
,
"%c"
,
((
i
&
0x0f
)
!=
0x0f
)
?
','
:
'\n'
);
}
}
fprintf
(
outfile
,
"
\n
"
);
fprintf
(
outfile
,
"
\n
};
\n
"
);
}
}
...
@@ -865,6 +873,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
...
@@ -865,6 +873,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
buffer
=
xmalloc
(
0x10000
);
buffer
=
xmalloc
(
0x10000
);
pModule
=
(
NE_MODULE
*
)
buffer
;
pModule
=
(
NE_MODULE
*
)
buffer
;
memset
(
pModule
,
0
,
sizeof
(
*
pModule
)
);
pModule
->
magic
=
IMAGE_OS2_SIGNATURE
;
pModule
->
magic
=
IMAGE_OS2_SIGNATURE
;
pModule
->
count
=
1
;
pModule
->
count
=
1
;
pModule
->
next
=
0
;
pModule
->
next
=
0
;
...
@@ -1024,7 +1033,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
...
@@ -1024,7 +1033,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset,
/* Dump the module content */
/* Dump the module content */
DumpBytes
(
outfile
,
(
char
*
)
pModule
,
(
int
)
pstr
-
(
int
)
pModule
,
DumpBytes
(
outfile
,
(
char
*
)
pModule
,
(
int
)
pstr
-
(
int
)
pModule
,
"
.data"
,
"Module_Start
"
);
"
Module
"
);
return
(
int
)
pstr
-
(
int
)
pModule
;
return
(
int
)
pstr
-
(
int
)
pModule
;
}
}
...
@@ -1258,6 +1267,28 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
...
@@ -1258,6 +1267,28 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
return
0
;
return
0
;
}
}
/*******************************************************************
* Spec16TypeCompare
*/
static
int
Spec16TypeCompare
(
const
void
*
e1
,
const
void
*
e2
)
{
const
ORDDEF
*
odp1
=
*
(
const
ORDDEF
**
)
e1
;
const
ORDDEF
*
odp2
=
*
(
const
ORDDEF
**
)
e2
;
int
type1
=
(
odp1
->
type
==
TYPE_CDECL
)
?
0
:
(
odp1
->
type
==
TYPE_REGISTER
)
?
3
:
(
odp1
->
type
==
TYPE_PASCAL_16
)
?
1
:
2
;
int
type2
=
(
odp2
->
type
==
TYPE_CDECL
)
?
0
:
(
odp2
->
type
==
TYPE_REGISTER
)
?
3
:
(
odp2
->
type
==
TYPE_PASCAL_16
)
?
1
:
2
;
int
retval
=
type1
-
type2
;
if
(
!
retval
)
retval
=
strcmp
(
odp1
->
u
.
func
.
arg_types
,
odp2
->
u
.
func
.
arg_types
);
return
retval
;
}
/*******************************************************************
/*******************************************************************
* BuildSpec16File
* BuildSpec16File
...
@@ -1266,18 +1297,89 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
...
@@ -1266,18 +1297,89 @@ static int BuildSpec32File( char * specfile, FILE *outfile )
*/
*/
static
int
BuildSpec16File
(
char
*
specfile
,
FILE
*
outfile
)
static
int
BuildSpec16File
(
char
*
specfile
,
FILE
*
outfile
)
{
{
ORDDEF
*
odp
;
ORDDEF
*
odp
,
**
typelist
;
int
i
;
int
i
,
j
,
k
;
int
code_offset
,
data_offset
,
module_size
;
int
code_offset
,
data_offset
,
module_size
;
unsigned
char
*
data
;
unsigned
char
*
data
;
/* File header */
fprintf
(
outfile
,
"/* File generated automatically from %s; do not edit! */
\n\n
"
,
specfile
);
fprintf
(
outfile
,
"#define __FLATCS__ 0x%04x
\n
"
,
Code_Selector
);
fprintf
(
outfile
,
"#include
\"
builtin16.h
\"\n\n
"
);
data
=
(
unsigned
char
*
)
xmalloc
(
0x10000
);
data
=
(
unsigned
char
*
)
xmalloc
(
0x10000
);
memset
(
data
,
0
,
16
);
memset
(
data
,
0
,
16
);
data_offset
=
16
;
data_offset
=
16
;
fprintf
(
outfile
,
"/* File generated automatically; do not edit! */
\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
/* Build sorted list of all argument types, without duplicates */
fprintf
(
outfile
,
"Code_Start:
\n
"
);
typelist
=
(
ORDDEF
**
)
calloc
(
Limit
+
1
,
sizeof
(
ORDDEF
*
)
);
odp
=
OrdinalDefinitions
;
for
(
i
=
j
=
0
;
i
<=
Limit
;
i
++
,
odp
++
)
{
switch
(
odp
->
type
)
{
case
TYPE_REGISTER
:
case
TYPE_CDECL
:
case
TYPE_PASCAL
:
case
TYPE_PASCAL_16
:
case
TYPE_STUB
:
typelist
[
j
++
]
=
odp
;
default:
break
;
}
}
qsort
(
typelist
,
j
,
sizeof
(
ORDDEF
*
),
Spec16TypeCompare
);
i
=
k
=
0
;
while
(
i
<
j
)
{
typelist
[
k
++
]
=
typelist
[
i
++
];
while
(
i
<
j
&&
Spec16TypeCompare
(
typelist
+
i
,
typelist
+
k
-
1
)
==
0
)
i
++
;
}
/* Output CallFrom16 profiles needed by this .spec file */
fprintf
(
outfile
,
"
\n
/* ### start build ### */
\n
"
);
for
(
i
=
0
;
i
<
k
;
i
++
)
fprintf
(
outfile
,
"extern void %s_CallFrom16_%s_%s_%s();
\n
"
,
DLLName
,
(
typelist
[
i
]
->
type
==
TYPE_CDECL
)
?
"c"
:
"p"
,
(
typelist
[
i
]
->
type
==
TYPE_REGISTER
)
?
"regs"
:
(
typelist
[
i
]
->
type
==
TYPE_PASCAL_16
)
?
"word"
:
"long"
,
typelist
[
i
]
->
u
.
func
.
arg_types
);
fprintf
(
outfile
,
"/* ### stop build ### */
\n\n
"
);
/* Output the DLL functions prototypes */
odp
=
OrdinalDefinitions
;
for
(
i
=
0
;
i
<=
Limit
;
i
++
,
odp
++
)
{
switch
(
odp
->
type
)
{
case
TYPE_REGISTER
:
case
TYPE_CDECL
:
case
TYPE_PASCAL
:
case
TYPE_PASCAL_16
:
fprintf
(
outfile
,
"extern void %s();
\n
"
,
odp
->
u
.
func
.
link_name
);
break
;
default:
break
;
}
}
/* Output code segment */
fprintf
(
outfile
,
"
\n
static ENTRYPOINT16 Code_Segment[] =
\n
{
\n
"
);
code_offset
=
0
;
code_offset
=
0
;
odp
=
OrdinalDefinitions
;
odp
=
OrdinalDefinitions
;
...
@@ -1309,20 +1411,12 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
...
@@ -1309,20 +1411,12 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
break
;
break
;
case
TYPE_RETURN
:
case
TYPE_RETURN
:
fprintf
(
outfile
,
"/* %s.%d */
\n
"
,
DLLName
,
i
);
fprintf
(
outfile
,
" /* %s.%d */ "
,
DLLName
,
i
);
fprintf
(
outfile
,
"
\t
movw $%d,%%ax
\n
"
,
LOWORD
(
odp
->
u
.
ret
.
ret_value
));
fprintf
(
outfile
,
"EP_RET( %d, %d ),
\n
"
,
fprintf
(
outfile
,
"
\t
movw $%d,%%dx
\n
"
,
HIWORD
(
odp
->
u
.
ret
.
ret_value
));
odp
->
u
.
ret
.
ret_value
,
odp
->
u
.
ret
.
arg_size
);
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
if
(
odp
->
u
.
ret
.
arg_size
!=
0
)
fprintf
(
outfile
,
"
\t
lret $%d
\n\n
"
,
odp
->
u
.
ret
.
arg_size
);
else
{
fprintf
(
outfile
,
"
\t
lret
\n
"
);
fprintf
(
outfile
,
"
\t
nop
\n
"
);
fprintf
(
outfile
,
"
\t
nop
\n\n
"
);
}
odp
->
offset
=
code_offset
;
odp
->
offset
=
code_offset
;
code_offset
+=
12
;
/* Assembly code is 12 bytes long */
code_offset
+=
sizeof
(
ENTRYPOINT16
);
break
;
break
;
case
TYPE_REGISTER
:
case
TYPE_REGISTER
:
...
@@ -1330,20 +1424,17 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
...
@@ -1330,20 +1424,17 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
case
TYPE_PASCAL
:
case
TYPE_PASCAL
:
case
TYPE_PASCAL_16
:
case
TYPE_PASCAL_16
:
case
TYPE_STUB
:
case
TYPE_STUB
:
fprintf
(
outfile
,
"/* %s.%d */
\n
"
,
DLLName
,
i
);
fprintf
(
outfile
,
" /* %s.%d */ "
,
DLLName
,
i
);
fprintf
(
outfile
,
"
\t
pushw %%bp
\n
"
);
fprintf
(
outfile
,
"EP_STD( %s, %s_CallFrom16_%s_%s_%s ),
\n
"
,
fprintf
(
outfile
,
"
\t
pushl $"
PREFIX
"%s
\n
"
,
odp
->
u
.
func
.
link_name
);
odp
->
u
.
func
.
link_name
,
/* FreeBSD does not understand lcall, so do it the hard way */
DLLName
,
fprintf
(
outfile
,
"
\t
.byte 0x9a
\n
"
);
(
odp
->
type
==
TYPE_CDECL
)
?
"c"
:
"p"
,
fprintf
(
outfile
,
"
\t
.long "
PREFIX
"CallFrom16_%s_%s_%s
\n
"
,
(
odp
->
type
==
TYPE_REGISTER
)
?
"regs"
:
(
odp
->
type
==
TYPE_CDECL
)
?
"c"
:
"p"
,
(
odp
->
type
==
TYPE_PASCAL_16
)
?
"word"
:
"long"
,
(
odp
->
type
==
TYPE_REGISTER
)
?
"regs"
:
odp
->
u
.
func
.
arg_types
);
(
odp
->
type
==
TYPE_PASCAL_16
)
?
"word"
:
"long"
,
odp
->
u
.
func
.
arg_types
);
fprintf
(
outfile
,
"
\t
.long 0x%08lx
\n
"
,
MAKELONG
(
Code_Selector
,
0x9090
/* nop ; nop */
)
);
odp
->
offset
=
code_offset
;
odp
->
offset
=
code_offset
;
code_offset
+=
16
;
/* Assembly code is 16 bytes long */
code_offset
+=
sizeof
(
ENTRYPOINT16
);
break
;
break
;
default:
default:
...
@@ -1355,13 +1446,15 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
...
@@ -1355,13 +1446,15 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
if
(
!
code_offset
)
/* Make sure the code segment is not empty */
if
(
!
code_offset
)
/* Make sure the code segment is not empty */
{
{
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
fprintf
(
outfile
,
"
{ },
\n
"
);
code_offset
++
;
code_offset
+=
sizeof
(
ENTRYPOINT16
)
;
}
}
fprintf
(
outfile
,
"};
\n
"
);
/* Output data segment */
/* Output data segment */
DumpBytes
(
outfile
,
data
,
data_offset
,
NULL
,
"Data_Star
t"
);
DumpBytes
(
outfile
,
data
,
data_offset
,
"Data_Segmen
t"
);
/* Build the module */
/* Build the module */
...
@@ -1369,16 +1462,14 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
...
@@ -1369,16 +1462,14 @@ static int BuildSpec16File( char * specfile, FILE *outfile )
/* Output the DLL descriptor */
/* Output the DLL descriptor */
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"
\n
WIN16_DESCRIPTOR %s_Descriptor =
\n
{
\n
"
,
DLLName
);
fprintf
(
outfile
,
"DLLName:
\t
"
STRING
"
\"
%s
\\
0
\"\n
"
,
DLLName
);
fprintf
(
outfile
,
"
\"
%s
\"
,
\n
"
,
DLLName
);
fprintf
(
outfile
,
"
\t
.align 4
\n
"
);
fprintf
(
outfile
,
" Module,
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"%s_Descriptor
\n
"
,
DLLName
);
fprintf
(
outfile
,
" sizeof(Module),
\n
"
);
fprintf
(
outfile
,
PREFIX
"%s_Descriptor:
\n
"
,
DLLName
);
fprintf
(
outfile
,
" (BYTE *)Code_Segment,
\n
"
);
fprintf
(
outfile
,
"
\t
.long DLLName
\n
"
);
/* Name */
fprintf
(
outfile
,
" (BYTE *)Data_Segment
\n
"
);
fprintf
(
outfile
,
"
\t
.long Module_Start
\n
"
);
/* Module start */
fprintf
(
outfile
,
"};
\n
"
);
fprintf
(
outfile
,
"
\t
.long %d
\n
"
,
module_size
);
/* Module size */
fprintf
(
outfile
,
"
\t
.long Code_Start
\n
"
);
/* Code start */
fprintf
(
outfile
,
"
\t
.long Data_Start
\n
"
);
/* Data start */
return
0
;
return
0
;
}
}
...
@@ -1414,216 +1505,352 @@ static int BuildSpecFile( FILE *outfile, char *specname )
...
@@ -1414,216 +1505,352 @@ static int BuildSpecFile( FILE *outfile, char *specname )
/*******************************************************************
/*******************************************************************
*
TransferArgs16To32
*
BuildCallFrom16Func
*
*
* Get the arguments from the 16-bit stack and push them on the 32-bit stack.
* Build a 16-bit-to-Wine callback glue function. The syntax of the function
* The 16-bit stack layout is:
* profile is: call_type_xxxxx, where 'call' is the letter 'c' or 'p' for C or
* ... ...
* Pascal calling convention, 'type' is one of 'regs', 'word' or
* (bp+8) arg2
* 'long' and each 'x' is an argument ('w'=word, 's'=signed word,
* (bp+6) arg1
* 'l'=long, 'p'=linear pointer, 't'=linear pointer to null-terminated string,
* (bp+4) cs
* 'T'=segmented pointer to null-terminated string).
* (bp+2) ip
* For register functions, the arguments are ignored, but they are still
* (bp) bp
* removed from the stack upon return. !! FIXME !!
*
* This glue function contains only that part of the 16->32 thunk that is
* variable (depending on the type and number of arguments); the glue routine
* is part of a particular DLL and uses a routine provided by the core to
* perform those actions that do not depend on the argument type.
*
* The 16->32 glue routine consists of a main entry point (which must be part
* of the ELF .data section) and two auxillary routines (in the .text section).
* The main entry point pushes address of the 'Thunk' auxillary routine onto
* the stack and then jumps to the appropriate core CallFrom16... routine.
* Furthermore, at a fixed position relative to the main entry point, the
* function profile string is stored if relay debugging is active; this string
* will be consulted by the debugging routines in the core to correctly
* display the arguments.
*
* The core will perform the switch to 32-bit, and then call back to the
* 'Thunk' auxillary routine. This routine is expected to perform the
* following tasks:
* - modify the auxillary routine address in the STACK16FRAME to now
* point to the 'ThunkRet' routine
* - convert arguemnts and push them onto the 32-bit stack
* - call the 32-bit target routine
*
* After the target routine (and then the 'Thunk' routine) have returned,
* the core part will switch back to 16-bit, and finally jump to the
* 'ThunkRet' auxillary routine. This routine is expected to convert the
* return value if necessary (%eax -> %dx:%ax), and perform the appropriate
* return to the 16-bit caller (lret or lret $argsize).
*
*
* For 'cdecl' argn up to arg1 are reversed.
* In the case of a 'register' routine, there is no 'ThunkRet' auxillary
* routine, as the reloading of all registers and return to 16-bit code
* is done by the core routine. The number of arguments to be popped off
* the caller's stack must be returned (in %eax) by the 'Thunk' routine.
*
* NOTE: The generated routines contain only proper position-independent
* code and may thus be used within shared objects (e.g. libwine.so
* or elfdlls). The exception is the main entry point, which must
* contain absolute relocations but cannot yet use the GOT; thus
* this entry point is made part of the ELF .data section.
*/
*/
static
int
TransferArgs16To32
(
FILE
*
outfile
,
char
*
args
,
int
usecdecl
)
static
void
BuildCallFrom16Func
(
FILE
*
outfile
,
char
*
profile
,
char
*
prefix
)
{
{
int
i
,
pos16
,
pos32
;
int
i
,
pos
,
argsize
=
0
;
char
*
xargs
;
int
short_ret
=
0
;
int
reg_func
=
0
;
int
usecdecl
=
0
;
char
*
args
=
profile
+
7
;
/*
Copy the arguments
*/
/*
Parse function type
*/
pos16
=
6
;
/* skip bp and return address */
if
(
!
strncmp
(
"c_"
,
profile
,
2
))
usecdecl
=
1
;
pos32
=
usecdecl
?
-
(
strlen
(
args
)
*
4
)
:
0
;
else
if
(
strncmp
(
"p_"
,
profile
,
2
))
xargs
=
usecdecl
?
args
:
args
+
strlen
(
args
);
{
fprintf
(
stderr
,
"Invalid function name '%s', ignored
\n
"
,
profile
);
return
;
}
for
(
i
=
strlen
(
args
);
i
>
0
;
i
--
)
if
(
!
strncmp
(
"word_"
,
profile
+
2
,
5
))
short_ret
=
1
;
else
if
(
!
strncmp
(
"regs_"
,
profile
+
2
,
5
))
reg_func
=
1
;
else
if
(
strncmp
(
"long_"
,
profile
+
2
,
5
))
{
{
if
(
!
usecdecl
)
{
fprintf
(
stderr
,
"Invalid function name '%s', ignored
\n
"
,
profile
);
pos32
-=
4
;
return
;
xargs
--
;
}
for
(
i
=
0
;
args
[
i
];
i
++
)
switch
(
args
[
i
]
)
{
case
'w'
:
/* word */
case
's'
:
/* s_word */
argsize
+=
2
;
break
;
case
'l'
:
/* long or segmented pointer */
case
'T'
:
/* segmented pointer to null-terminated string */
case
'p'
:
/* linear pointer */
case
't'
:
/* linear pointer to null-terminated string */
argsize
+=
4
;
break
;
}
}
switch
(
*
xargs
)
/*
* Build main entry point (in .data section)
*
* NOTE: If you change this, you must also change the retrieval of
* the profile string relative to the main entry point address
* (see BUILTIN_GetEntryPoint16 in if1632/builtin.c).
*/
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"%s_CallFrom16_%s
\n
"
,
prefix
,
profile
);
fprintf
(
outfile
,
PREFIX
"%s_CallFrom16_%s:
\n
"
,
prefix
,
profile
);
fprintf
(
outfile
,
"
\t
pushl $.L%s_Thunk_%s
\n
"
,
prefix
,
profile
);
fprintf
(
outfile
,
"
\t
jmp "
PREFIX
"%s
\n
"
,
!
reg_func
?
"CallFrom16"
:
"CallFrom16Register"
);
if
(
debugging
)
fprintf
(
outfile
,
"
\t
"
STRING
"
\"
%s
\\
0
\"\n
"
,
profile
);
/*
* Build *Thunk* routine
*
* This routine gets called by the main CallFrom16 routine with
* registers set up as follows:
*
* STACK16FRAME is completely set up on the 16-bit stack
* DS, ES, SS: flat data segment
* FS: current TEB
* ESP: points to 32-bit stack
* EBP: points to ebp member of last STACK32FRAME
* EDX: points to current STACK16FRAME
* ECX: points to ldt_copy
*/
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
".L%s_Thunk_%s:
\n
"
,
prefix
,
profile
);
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
leal 4(%%esp), %%eax
\n
"
"
\t
pushl %%eax
\n
"
);
else
fprintf
(
outfile
,
"
\t
addl $[.L%s_ThunkRet_%s - .L%s_Thunk_%s], %d(%%edx)
\n
"
,
prefix
,
profile
,
prefix
,
profile
,
STACK16OFFSET
(
relay
));
if
(
!
reg_func
)
/* FIXME */
{
/* Copy the arguments */
pos
=
(
usecdecl
?
argsize
:
0
)
+
sizeof
(
STACK16FRAME
);
args
=
profile
+
7
;
for
(
i
=
strlen
(
args
)
-
1
;
i
>=
0
;
i
--
)
switch
(
args
[
i
])
{
{
case
'w'
:
/* word */
case
'w'
:
/* word */
fprintf
(
outfile
,
"
\t
movzwl %d(%%ebp),%%eax
\n
"
,
pos16
);
if
(
usecdecl
)
pos
-=
2
;
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
pos32
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx),%%eax
\n
"
,
pos
);
pos16
+=
2
;
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
if
(
!
usecdecl
)
pos
+=
2
;
break
;
break
;
case
's'
:
/* s_word */
case
's'
:
/* s_word */
fprintf
(
outfile
,
"
\t
movswl %d(%%ebp),%%eax
\n
"
,
pos16
);
if
(
usecdecl
)
pos
-=
2
;
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
pos32
);
fprintf
(
outfile
,
"
\t
movswl %d(%%edx),%%eax
\n
"
,
pos
);
pos16
+=
2
;
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
if
(
!
usecdecl
)
pos
+=
2
;
break
;
break
;
case
'l'
:
/* long or segmented pointer */
case
'l'
:
/* long or segmented pointer */
case
'T'
:
/* segmented pointer to null-terminated string */
case
'T'
:
/* segmented pointer to null-terminated string */
fprintf
(
outfile
,
"
\t
movl %d(%%ebp),%%eax
\n
"
,
pos16
)
;
if
(
usecdecl
)
pos
-=
4
;
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
pos32
);
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
pos
);
pos16
+=
4
;
if
(
!
usecdecl
)
pos
+=
4
;
break
;
break
;
case
'p'
:
/* linear pointer */
case
'p'
:
/* linear pointer */
case
't'
:
/* linear pointer to null-terminated string */
case
't'
:
/* linear pointer to null-terminated string */
if
(
usecdecl
)
pos
-=
4
;
/* Get the selector */
/* Get the selector */
fprintf
(
outfile
,
"
\t
mov
w %d(%%ebp),%%ax
\n
"
,
pos16
+
2
);
fprintf
(
outfile
,
"
\t
mov
zwl %d(%%edx),%%eax
\n
"
,
pos
+
2
);
/* Get the selector base */
/* Get the selector base */
fprintf
(
outfile
,
"
\t
andl $0xfff8,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0xfff8,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"ldt_copy(%%eax),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl (%%ecx,%%eax)
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
pos32
);
/* Add the offset */
/* Add the offset */
fprintf
(
outfile
,
"
\t
movzwl %d(%%e
bp),%%eax
\n
"
,
pos16
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%e
dx),%%eax
\n
"
,
pos
);
fprintf
(
outfile
,
"
\t
addl %%eax,
%d(%%ebx)
\n
"
,
pos32
);
fprintf
(
outfile
,
"
\t
addl %%eax,
(%%esp)
\n
"
);
pos16
+=
4
;
if
(
!
usecdecl
)
pos
+=
4
;
break
;
break
;
default:
default:
fprintf
(
stderr
,
"Unknown arg type '%c'
\n
"
,
*
xargs
);
fprintf
(
stderr
,
"Unknown arg type '%c'
\n
"
,
args
[
i
]
);
}
}
/* Call entry point */
fprintf
(
outfile
,
"
\t
call *%d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
movl $%d, %%eax
\n
"
,
argsize
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
/*
* Build *ThunkRet* routine
*
* At this point, all registers are set up for return to 16-bit code.
* EAX contains the function return value.
* SS:SP point to the return address to the caller (on 16-bit stack).
*/
if
(
!
reg_func
)
{
fprintf
(
outfile
,
".L%s_ThunkRet_%s:
\n
"
,
prefix
,
profile
);
if
(
!
short_ret
)
fprintf
(
outfile
,
"
\t
shldl $16, %%eax, %%edx
\n
"
);
if
(
!
usecdecl
&&
argsize
)
{
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret $%d
\n
"
,
argsize
);
}
}
if
(
usecdecl
)
{
else
pos32
+=
4
;
{
xargs
++
;
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
}
}
}
}
fprintf
(
outfile
,
"
\n
"
);
return
pos16
-
6
;
/* Return the size of the 16-bit args */
}
}
/*******************************************************************
/*******************************************************************
* BuildContext16
* BuildCallTo16Func
*
* Build a Wine-to-16-bit callback glue function. As above, this glue
* routine will only contain the argument-type dependent part of the
* thunk; the rest will be done by a routine provided by the core.
*
* Prototypes for the CallTo16 functions:
* extern WORD PREFIX_CallTo16_word_xxx( FARPROC16 func, args... );
* extern LONG PREFIX_CallTo16_long_xxx( FARPROC16 func, args... );
*
* The main entry point of the glue routine simply performs a call to
* the proper core routine depending on the return type (WORD/LONG).
* Note that the core will never perform a return from this call; however,
* it will use the return address on the stack to access the other
* argument-type dependent parts of the thunk. (If relay debugging is
* active, the core routine will access the number of arguments stored
* in the code section immediately precending the main entry point).
*
* After the core routine has performed the switch to 16-bit code, it
* will call the argument-transfer routine provided by the glue code
* immediately after the main entry point. This routine is expected
* to transfer the arguments to the 16-bit stack, finish loading the
* register for 16-bit code (%ds and %es must be loaded from %ss),
* and call the 16-bit target.
*
* The target will return to a 16:16 return address provided by the core.
* The core will finalize the switch back to 32-bit and the return to
* the caller without additional support by the glue code. Note that
* the 32-bit arguments will not be popped off the stack (hence the
* CallTo... routine must *not* be declared WINAPI/CALLBACK).
*
*
* Build the context structure on the 32-bit stack.
*/
*/
static
void
BuildC
ontext16
(
FILE
*
outfile
)
static
void
BuildC
allTo16Func
(
FILE
*
outfile
,
char
*
profile
,
char
*
prefix
)
{
{
/* Store the registers */
char
*
args
=
profile
+
5
;
int
pos
,
short_ret
=
0
;
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Eax
)
-
sizeof
(
CONTEXT86
)
);
if
(
!
strncmp
(
"word_"
,
profile
,
5
))
short_ret
=
1
;
fprintf
(
outfile
,
"
\t
movl %%ecx,%d(%%ebx)
\n
"
,
else
if
(
strncmp
(
"long_"
,
profile
,
5
))
CONTEXTOFFSET
(
Ecx
)
-
sizeof
(
CONTEXT86
)
);
{
fprintf
(
outfile
,
"
\t
movl %%edx,%d(%%ebx)
\n
"
,
fprintf
(
stderr
,
"Invalid function name '%s'.
\n
"
,
profile
);
CONTEXTOFFSET
(
Edx
)
-
sizeof
(
CONTEXT86
)
);
exit
(
1
);
fprintf
(
outfile
,
"
\t
movl %%esi,%d(%%ebx)
\n
"
,
}
CONTEXTOFFSET
(
Esi
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movl %%edi,%d(%%ebx)
\n
"
,
if
(
debugging
)
CONTEXTOFFSET
(
Edi
)
-
sizeof
(
CONTEXT86
)
);
{
/* Number of arguments (for relay debugging) */
fprintf
(
outfile
,
"
\t
movl -24(%%ebp),%%eax
\n
"
);
/* Get %ebx from stack*/
fprintf
(
outfile
,
"
\n\t
.align 4
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
fprintf
(
outfile
,
"
\t
.long %d
\n
"
,
strlen
(
args
)
);
CONTEXTOFFSET
(
Ebx
)
-
sizeof
(
CONTEXT86
)
);
}
fprintf
(
outfile
,
"
\t
movzwl -10(%%ebp),%%eax
\n
"
);
/* Get %ds from stack*/
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
/* Main entry point */
CONTEXTOFFSET
(
SegDs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movzwl -6(%%ebp),%%eax
\n
"
);
/* Get %es from stack*/
#ifdef USE_STABS
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
fprintf
(
outfile
,
".stabs
\"
%s_CallTo16_%s:F1
\"
,36,0,0,"
PREFIX
"%s_CallTo16_%s
\n
"
,
CONTEXTOFFSET
(
SegEs
)
-
sizeof
(
CONTEXT86
)
);
prefix
,
profile
,
prefix
,
profile
);
fprintf
(
outfile
,
"
\t
pushfl
\n
"
);
fprintf
(
outfile
,
"
\t
popl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movl -20(%%ebp),%%eax
\n
"
);
/* Get %ebp from stack */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movzwl 2(%%ebp),%%eax
\n
"
);
/* Get %ip from stack */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
leal 2(%%ebp),%%eax
\n
"
);
/* Get initial %sp */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Esp
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movzwl 4(%%ebp),%%eax
\n
"
);
/* Get %cs from stack */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movzwl -14(%%ebp),%%eax
\n
"
);
/* Get %fs from stack */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movw %%gs,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movw %%ss,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
-
sizeof
(
CONTEXT86
)
);
#if 0
fprintf( outfile, "\tfsave %d(%%ebx)\n",
CONTEXTOFFSET(FloatSave) - sizeof(CONTEXT86) );
#endif
#endif
}
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"%s_CallTo16_%s
\n
"
,
prefix
,
profile
);
fprintf
(
outfile
,
PREFIX
"%s_CallTo16_%s:
\n
"
,
prefix
,
profile
);
if
(
short_ret
)
fprintf
(
outfile
,
"
\t
call "
PREFIX
"CallTo16Word
\n
"
);
else
fprintf
(
outfile
,
"
\t
call "
PREFIX
"CallTo16Long
\n
"
);
/*
* The core routine will call here with registers set up as follows:
*
* SS:SP points to the 16-bit stack
* SS:BP points to the bp member of last STACK16FRAME
* EDX points to the current STACK32FRAME
* ECX contains the 16:16 return address
* FS contains the last 16-bit %fs value
*/
/*******************************************************************
/* Transfer the arguments */
* RestoreContext16
*
pos
=
STACK32OFFSET
(
args
)
+
4
;
/* first arg is target address */
* Restore the registers from the context structure.
while
(
*
args
)
*/
{
static
void
RestoreContext16
(
FILE
*
outfile
)
switch
(
*
args
++
)
{
{
/* Get the 32-bit stack pointer */
case
'w'
:
/* word */
fprintf
(
outfile
,
"
\t
pushw %d(%%edx)
\n
"
,
pos
);
fprintf
(
outfile
,
"
\t
leal -%d(%%ebp),%%ebx
\n
"
,
break
;
STRUCTOFFSET
(
STACK32FRAME
,
ebp
)
);
case
'l'
:
/* long */
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
pos
);
/* Remove everything up to (including) the return address
break
;
* from the 16-bit stack */
default:
fprintf
(
stderr
,
"Unexpected case '%c' in BuildCallTo16Func
\n
"
,
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%eax
\n
"
,
args
[
-
1
]
);
CONTEXTOFFSET
(
SegSs
)
-
sizeof
(
CONTEXT86
)
);
}
fprintf
(
outfile
,
"
\t
movw %%ax,%%ss
\n
"
);
pos
+=
4
;
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%esp
\n
"
,
}
CONTEXTOFFSET
(
Esp
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
addl $4,%%esp
\n
"
);
/* Remove return address */
/* Push the return address */
/* Restore the registers */
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%ecx
\n
"
,
/* Push the called routine address */
CONTEXTOFFSET
(
Ecx
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%edx
\n
"
,
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
STACK32OFFSET
(
args
)
);
CONTEXTOFFSET
(
Edx
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%esi
\n
"
,
/* Set %ds and %es (and %ax just in case) equal to %ss */
CONTEXTOFFSET
(
Esi
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%edi
\n
"
,
fprintf
(
outfile
,
"
\t
movw %%ss,%%ax
\n
"
);
CONTEXTOFFSET
(
Edi
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%ds
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%ebp
\n
"
,
fprintf
(
outfile
,
"
\t
movw %%ax,%%es
\n
"
);
CONTEXTOFFSET
(
Ebp
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
/* Push new cs */
/* Jump to the called routine */
CONTEXTOFFSET
(
SegCs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
/* Push new ip */
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
CONTEXTOFFSET
(
Eip
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
/* Push new ds */
CONTEXTOFFSET
(
SegDs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
/* Push new es */
CONTEXTOFFSET
(
SegEs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
/* Push new fs */
CONTEXTOFFSET
(
SegFs
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
popfl
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
-
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
popl %%fs
\n
"
);
/* Set fs */
fprintf
(
outfile
,
"
\t
popl %%es
\n
"
);
/* Set es */
fprintf
(
outfile
,
"
\t
popl %%ds
\n
"
);
/* Set ds */
}
}
/*******************************************************************
/*******************************************************************
* BuildCallFrom16
Func
* BuildCallFrom16
Core
*
*
* Build a 16-bit-to-Wine callback function. The syntax of the function
* This routine builds the core routines used in 16->32 thunks:
* profile is: call_type_xxxxx, where 'call' is the letter 'c' or 'p' for C or
* CallFrom16, CallFrom16Register, and CallFrom16Thunk.
* Pascal calling convention, 'type' is one of 'regs', 'word' or
* 'long' and each 'x' is an argument ('w'=word, 's'=signed word,
* 'l'=long, 'p'=linear pointer, 't'=linear pointer to null-terminated string,
* 'T'=segmented pointer to null-terminated string).
* For register functions, the arguments are ignored, but they are still
* removed from the stack upon return.
*
*
* A special variant of the callback function is generated by the function
* CallFrom16 and CallFrom16Register are used by the 16->32 glue code
* profile "t_long_". This is used by the Win95 16->32 thunk
* as described above. CallFrom16Thunk is a special variant used by
* functions C16ThkSL and C16ThkSL01 and is implemented as follows:
* the implementation of the Win95 16->32 thunk functions C16ThkSL and
* C16ThkSL01 and is implemented as follows:
* On entry, the EBX register is set up to contain a flat pointer to the
* On entry, the EBX register is set up to contain a flat pointer to the
* 16-bit stack such that EBX+22 points to the first argument.
* 16-bit stack such that EBX+22 points to the first argument.
* Then, the entry point is called, while EBP is set up to point
* Then, the entry point is called, while EBP is set up to point
...
@@ -1631,536 +1858,521 @@ static void RestoreContext16( FILE *outfile )
...
@@ -1631,536 +1858,521 @@ static void RestoreContext16( FILE *outfile )
* The called function returns with CX set to the number of bytes
* The called function returns with CX set to the number of bytes
* to be popped of the caller's stack.
* to be popped of the caller's stack.
*
*
* Stack layout upon entry to the c
allback function
:
* Stack layout upon entry to the c
ore routine (STACK16FRAME)
:
* ... ...
* ... ...
* (sp+18) word first 16-bit arg
* (sp+22) word first 16-bit arg
* (sp+16) word cs
* (sp+20) word cs
* (sp+14) word ip
* (sp+18) word ip
* (sp+12) word bp
* (sp+16) word bp
* (sp+8) long 32-bit entry point (used to store edx)
* (sp+12) long 32-bit entry point (reused for Win16 mutex recursion count)
* (sp+6) word high word of cs (always 0, used to store es)
* (sp+8) long cs of 16-bit entry point
* (sp+4) word low word of cs of 16-bit entry point
* (sp+4) long ip of 16-bit entry point
* (sp+2) word high word of ip (always 0, used to store ds)
* (sp) long auxillary relay function address
* (sp) word low word of ip of 16-bit entry point
*
*
* Added on the stack:
* Added on the stack:
* (sp-2) word saved fs
* (sp-2) word saved gs
* (sp-4) word buffer for Win16Mutex recursion count
* (sp-4) word saved fs
* (sp-8) long ebp
* (sp-6) word saved es
* (sp-12) long saved previous stack
* (sp-8) word saved ds
* (sp-12) long saved ebp
* (sp-16) long saved ecx
* (sp-20) long saved edx
* (sp-24) long saved previous stack
*/
*/
static
void
BuildCallFrom16
Func
(
FILE
*
outfile
,
char
*
profile
)
static
void
BuildCallFrom16
Core
(
FILE
*
outfile
,
int
reg_func
,
int
thunk
)
{
{
int
argsize
=
0
;
char
*
name
=
thunk
?
"Thunk"
:
reg_func
?
"Register"
:
""
;
int
short_ret
=
0
;
int
reg_func
=
0
;
int
Cdecl
=
0
;
int
thunk
=
0
;
char
*
args
=
profile
+
7
;
/* Parse function type */
if
(
!
strncmp
(
"c_"
,
profile
,
2
))
Cdecl
=
1
;
else
if
(
!
strncmp
(
"t_"
,
profile
,
2
))
thunk
=
1
;
else
if
(
strncmp
(
"p_"
,
profile
,
2
))
{
fprintf
(
stderr
,
"Invalid function name '%s', ignored
\n
"
,
profile
);
return
;
}
if
(
!
strncmp
(
"word_"
,
profile
+
2
,
5
))
short_ret
=
1
;
else
if
(
!
strncmp
(
"regs_"
,
profile
+
2
,
5
))
reg_func
=
1
;
else
if
(
strncmp
(
"long_"
,
profile
+
2
,
5
))
{
fprintf
(
stderr
,
"Invalid function name '%s', ignored
\n
"
,
profile
);
return
;
}
/* Function header */
/* Function header */
fprintf
(
outfile
,
"
\n\t
.align 4
\n
"
);
fprintf
(
outfile
,
"
\n\t
.align 4
\n
"
);
#ifdef USE_STABS
#ifdef USE_STABS
fprintf
(
outfile
,
".stabs
\"
CallFrom16
_%s:F1
\"
,36,0,0,"
PREFIX
"CallFrom16_
%s
\n
"
,
fprintf
(
outfile
,
".stabs
\"
CallFrom16
%s:F1
\"
,36,0,0,"
PREFIX
"CallFrom16
%s
\n
"
,
profile
,
profil
e
);
name
,
nam
e
);
#endif
#endif
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CallFrom16_%s
\n
"
,
profile
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CallFrom16%s
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CallFrom16_%s:
\n
"
,
profile
);
fprintf
(
outfile
,
PREFIX
"CallFrom16%s:
\n
"
,
name
);
/* Save 16-bit fs and leave room for Win16Mutex recursion count */
/* No relay function for 'thunk' */
if
(
thunk
)
fprintf
(
outfile
,
"
\t
.byte 0x66
\n\t
pushl %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
pushl $0
\n
"
);
fprintf
(
outfile
,
"
\t
pushw $0
\n
"
);
/* Create STACK16FRAME (except STACK32FRAME link) */
/* Setup bp to point to its copy on the stack */
fprintf
(
outfile
,
"
\t
pushw %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
pushw %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
/* Save the full 32-bit ebp */
fprintf
(
outfile
,
"
\t
pushw %%es
\n
"
);
fprintf
(
outfile
,
"
\t
movzwl %%sp,%%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushw %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
addw $20,%%bp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
/* Save 16-bit ds and es */
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
/* Stupid FreeBSD assembler doesn't know these either */
/* fprintf( outfile, "\tmovw %%ds,-10(%%ebp)\n" ); */
fprintf
(
outfile
,
"
\t
.byte 0x66,0x8c,0x5d,0xf6
\n
"
);
/* fprintf( outfile, "\tmovw %%es,-6(%%ebp)\n" ); */
fprintf
(
outfile
,
"
\t
.byte 0x66,0x8c,0x45,0xfa
\n
"
);
/* Save %ebx */
fprintf
(
outfile
,
"
\t
pushl %%ebx
\n
"
);
/* Restore 32-bit segment registers */
#ifdef USE__PIC__
/* Get Global Offset Table into %ecx */
fprintf
(
outfile
,
"
\t
call .LCallFrom16%s.getgot
\n
"
,
name
);
fprintf
(
outfile
,
".LCallFrom16%s.getgot:
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
addl $_GLOBAL_OFFSET_TABLE+[.-.LCallFrom16%s.getgot], %%ecx
\n
"
);
#endif
fprintf
(
outfile
,
"
\t
movw $0x%04x,%%bx
\n
"
,
Data_Selector
);
/* Load 32-bit segment registers */
fprintf
(
outfile
,
"
\t
movw $0x%04x, %%dx
\n
"
,
Data_Selector
);
#ifdef __svr4__
#ifdef __svr4__
fprintf
(
outfile
,
"
\t
data16
\n
"
);
fprintf
(
outfile
,
"
\t
data16
\n
"
);
#endif
#endif
fprintf
(
outfile
,
"
\t
movw %%
bx,
%%ds
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%
dx,
%%ds
\n
"
);
#ifdef __svr4__
#ifdef __svr4__
fprintf
(
outfile
,
"
\t
data16
\n
"
);
fprintf
(
outfile
,
"
\t
data16
\n
"
);
#endif
#endif
fprintf
(
outfile
,
"
\t
movw %%bx,%%es
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%dx, %%es
\n
"
);
#ifdef USE__PIC__
fprintf
(
outfile
,
"
\t
movw "
PREFIX
"SYSLEVEL_Win16CurrentTeb,%%fs
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"SYSLEVEL_Win16CurrentTeb@GOT(%%ecx), %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movw (%%edx), %%fs
\n
"
);
#else
fprintf
(
outfile
,
"
\t
movw "
PREFIX
"SYSLEVEL_Win16CurrentTeb, %%fs
\n
"
);
#endif
/* Get the 32-bit stack pointer from the TEB */
/* Get address of ldt_copy array into %ecx */
#ifdef USE__PIC__
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"ldt_copy@GOT(%%ecx), %%ecx
\n
"
);
#else
fprintf
(
outfile
,
"
\t
movl $"
PREFIX
"ldt_copy, %%ecx
\n
"
);
#endif
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl (%d),%%ebx
\n
"
,
STACKOFFSET
);
/* Translate STACK16FRAME base to flat offset in %edx */
fprintf
(
outfile
,
"
\t
movw %%ss, %%dx
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0xfff8, %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movl (%%ecx,%%edx), %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
leal -4(%%ebp,%%edx), %%edx
\n
"
);
/* -4 since STACK16FRAME not yet complete! */
/* Save the 16-bit stack */
/* Get the 32-bit stack pointer from the TEB and complete STACK16FRAME */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl (%d), %%ebp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
/* Switch stacks */
#ifdef __svr4__
#ifdef __svr4__
fprintf
(
outfile
,
"
\t
data16
\n
"
);
fprintf
(
outfile
,
"
\t
data16
\n
"
);
#endif
#endif
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw %%ss,(%d)
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw %%ss, (%d)
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw %%sp,(%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw %%sp, (%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
pushl %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ss
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ebp, %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
addl $%d, %%ebp
\n
"
,
STRUCTOFFSET
(
STACK32FRAME
,
ebp
)
);
/* Transfer the arguments */
if
(
reg_func
)
BuildContext16
(
outfile
);
/* At this point:
else
if
(
*
args
)
argsize
=
TransferArgs16To32
(
outfile
,
args
,
Cdecl
);
STACK16FRAME is completely set up
else
if
(
thunk
)
DS, ES, SS: flat data segment
FS: current TEB
ESP: points to last STACK32FRAME
EBP: points to ebp member of last STACK32FRAME
EDX: points to current STACK16FRAME
ECX: points to ldt_copy
all other registers: unchanged */
/* Special case: C16ThkSL stub */
if
(
thunk
)
{
{
/* Get the stack selector base */
/* Set up registers as expected and call thunk */
fprintf
(
outfile
,
"
\t
movw %%ss,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
leal %d(%%edx), %%ebx
\n
"
,
sizeof
(
STACK16FRAME
)
-
22
);
fprintf
(
outfile
,
"
\t
andl $0xfff8,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
leal -4(%%esp), %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"ldt_copy(%%eax),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,-24(%%ebp)
\n
"
);
/* Add the offset */
fprintf
(
outfile
,
"
\t
leal -16(%%ebp),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
addl %%eax,-24(%%ebp)
\n
"
);
}
/* Get the address of the API function */
fprintf
(
outfile
,
"
\t
call *%d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
fprintf
(
outfile
,
"
\t
movl -4(%%ebp),%%eax
\n
"
);
/* Switch stack back */
/* fprintf( outfile, "\t.byte 0x64\n\tlssw (%d), %%sp\n", STACKOFFSET ); */
fprintf
(
outfile
,
"
\t
.byte 0x64,0x66,0x0f,0xb2,0x25
\n\t
.long %d
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
/* If necessary, save %edx over the API function address */
/* Restore registers and return directly to caller */
fprintf
(
outfile
,
"
\t
addl $8, %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%es
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
addl $18, %%esp
\n
"
);
if
(
!
reg_func
&&
short_ret
)
fprintf
(
outfile
,
"
\t
xorb %%ch, %%ch
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%edx,-4(%%ebp)
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
addw %%cx, %%sp
\n
"
);
fprintf
(
outfile
,
"
\t
push %%ebx
\n
"
);
/* Restore %ebx and store the 32-bit stack pointer instead */
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ebx,%%ebp
\n
"
);
return
;
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
}
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
/* Switch to the 32-bit stack */
fprintf
(
outfile
,
"
\t
pushl %%ds
\n
"
);
/* Build register CONTEXT */
fprintf
(
outfile
,
"
\t
popl %%ss
\n
"
);
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
leal -%d(%%ebp),%%esp
\n
"
,
{
reg_func
?
sizeof
(
CONTEXT86
)
:
4
*
strlen
(
args
)
);
fprintf
(
outfile
,
"
\t
subl $%d, %%esp
\n
"
,
sizeof
(
CONTEXT
)
);
if
(
reg_func
)
/* Push the address of the context struct */
fprintf
(
outfile
,
"
\t
pushl %%esp
\n
"
);
/* Setup %ebp to point to the previous stack frame (built by CallTo16) */
fprintf
(
outfile
,
"
\t
pushfl
\n
"
);
fprintf
(
outfile
,
"
\t
popl %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
fprintf
(
outfile
,
"
\t
addl $%d,%%ebp
\n
"
,
STRUCTOFFSET
(
STACK32FRAME
,
ebp
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %%ebx, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
movl %%esi, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
movl %%edi, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
/* Print the debug information before the call */
fprintf
(
outfile
,
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ebp
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ecx
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
edx
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
if
(
debugging
&&
!
thunk
)
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ds
)
);
{
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
int
ftype
=
0
;
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
es
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
fs
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
gs
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
if
(
Cdecl
)
ftype
|=
4
;
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
cs
)
);
if
(
reg_func
)
ftype
|=
2
;
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
if
(
short_ret
)
ftype
|=
1
;
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
pushl $Profile_%s
\n
"
,
profile
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
fprintf
(
outfile
,
"
\t
pushl $%d
\n
"
,
ftype
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallFrom16
\n
"
);
fprintf
(
outfile
,
"
\t
addl $%d, %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
#if 0
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf( outfile, "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
#endif
}
}
/* Call the entry point */
if
(
thunk
)
/* Print debug info before call */
if
(
debugging
)
{
{
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
leal -4(%%esp), %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
call *%%eax
\n
"
);
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
leal -%d(%%ebp), %%eax
\n\t
pushl %%eax
\n
"
,
sizeof
(
CONTEXT
)
+
STRUCTOFFSET
(
STACK32FRAME
,
ebp
)
);
else
fprintf
(
outfile
,
"
\t
pushl $0
\n
"
);
#if USE__PIC__
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallFrom16@PLT
\n
"
);
#else
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallFrom16
\n
"
);
#endif
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
}
}
else
fprintf
(
outfile
,
"
\t
call *%%eax
\n
"
);
/* Print the debug information after the call */
/* Call *Thunk* relay routine (which will call the API entry point) */
fprintf
(
outfile
,
"
\t
call *%d(%%edx)
\n
"
,
STACK16OFFSET
(
relay
)
);
if
(
debugging
&&
!
thunk
)
/* Print debug info after call */
if
(
debugging
)
{
{
if
(
reg_func
)
{
/* Push again the address of the context struct in case */
/* it has been removed by an stdcall function */
fprintf
(
outfile
,
"
\t
leal -%d(%%ebp),%%esp
\n
"
,
sizeof
(
CONTEXT86
)
+
STRUCTOFFSET
(
STACK32FRAME
,
ebp
)
);
fprintf
(
outfile
,
"
\t
pushl %%esp
\n
"
);
}
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl $%d
\n
"
,
reg_func
?
2
:
(
short_ret
?
1
:
0
));
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallFrom16Ret
\n
"
);
fprintf
(
outfile
,
"
\t
leal -%d(%%ebp), %%eax
\n\t
pushl %%eax
\n
"
,
sizeof
(
CONTEXT
)
+
STRUCTOFFSET
(
STACK32FRAME
,
ebp
)
);
else
fprintf
(
outfile
,
"
\t
pushl $0
\n
"
);
#if USE__PIC__
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallFrom16Ret@PLT
\n
"
);
#else
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallFrom16Ret
\n
"
);
#endif
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
}
}
/* Restore the 16-bit stack */
#ifdef __svr4__
fprintf
(
outfile
,
"
\t
data16
\n
"
);
#endif
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d),%%esp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
if
(
reg_func
)
{
/* Calc the arguments size */
while
(
*
args
)
{
switch
(
*
args
)
{
case
'w'
:
case
's'
:
argsize
+=
2
;
break
;
case
'p'
:
case
't'
:
case
'l'
:
case
'T'
:
argsize
+=
4
;
break
;
default:
fprintf
(
stderr
,
"Unknown arg type '%c'
\n
"
,
*
args
);
}
args
++
;
}
/* Restore registers from the context structure */
if
(
reg_func
)
RestoreContext16
(
outfile
);
}
else
{
{
/* Restore high 16 bits of ebp */
fprintf
(
outfile
,
"
\t
movl %%esp, %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
/* Restore ds and es */
/* Switch stack back */
fprintf
(
outfile
,
"
\t
incl %%esp
\n
"
);
/* Remove mutex count */
/* fprintf( outfile, "\t.byte 0x64\n\tlssw (%d), %%sp\n", STACKOFFSET ); */
fprintf
(
outfile
,
"
\t
incl %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64,0x66,0x0f,0xb2,0x25
\n\t
.long %d
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
/* Remove ip and fs */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
movw %%dx,%%fs
\n
"
);
/* and restore fs */
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
/* Remove cs and ds */
fprintf
(
outfile
,
"
\t
movw %%dx,%%ds
\n
"
);
/* and restore ds */
fprintf
(
outfile
,
"
\t
.byte 0x66
\n\t
popl %%es
\n
"
);
/* Restore es */
if
(
short_ret
)
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
/* Restore edx */
/* Restore all registers from CONTEXT */
else
fprintf
(
outfile
,
"
\t
movw %d(%%ebx), %%ss
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
{
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%esp
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
/* Get the return value into dx:ax */
fprintf
(
outfile
,
"
\t
leal 4(%%esp, %%eax), %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
shrl $16,%%edx
\n
"
);
/* Remove API entry point */
fprintf
(
outfile
,
"
\t
addl $4,%%esp
\n
"
);
}
/* Restore low 16 bits of ebp */
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
fprintf
(
outfile
,
"
\t
popw %%bp
\n
"
);
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
}
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
/* Remove the arguments and return */
fprintf
(
outfile
,
"
\t
movw %d(%%ebx), %%es
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
movw %d(%%ebx), %%fs
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
if
(
thunk
)
fprintf
(
outfile
,
"
\t
movw %d(%%ebx), %%gs
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
{
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
xorb %%ch,%%ch
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
addw %%cx, %%sp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
fprintf
(
outfile
,
"
\t
pushl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
popl %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popfl
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
}
}
else
if
(
argsize
&&
!
Cdecl
)
{
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret $%d
\n
"
,
argsize
);
}
else
else
{
{
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
/* Switch stack back */
fprintf
(
outfile
,
"
\t
lret
\n
"
);
/* fprintf( outfile, "\t.byte 0x64\n\tlssw (%d), %%sp\n", STACKOFFSET ); */
fprintf
(
outfile
,
"
\t
.byte 0x64,0x66,0x0f,0xb2,0x25
\n\t
.long %d
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
/* Restore registers and return to *ThunkRet* routine */
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%es
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
ret $14
\n
"
);
}
}
}
}
/*******************************************************************
/*******************************************************************
* BuildCallTo16
Func
* BuildCallTo16
Core
*
*
* Build a Wine-to-16-bit callback function.
* This routine builds the core routines used in 32->16 thunks:
* CallTo16Word, CallTo16Long, CallTo16RegisterShort, and
* CallTo16RegisterLong.
*
*
* Stack frame of the callback function:
* CallTo16Word and CallTo16Long are used by the 32->16 glue code
* ... ...
* as described above. The register functions can be called directly:
* (ebp+16) arg2
* (ebp+12) arg1
* (ebp+8) func to call
* (ebp+4) return address
* (ebp) previous ebp
*
*
* Prototypes for the CallTo16 functions:
* extern void CallTo16RegisterShort( const CONTEXT86 *context, int nb_args );
* extern WINAPI WORD CallTo16_word_xxx( FARPROC16 func, args... );
* extern void CallTo16RegisterLong ( const CONTEXT86 *context, int nb_args );
* extern WINAPI LONG CallTo16_long_xxx( FARPROC16 func, args... );
*
* extern WINAPI void CallTo16_sreg_( const CONTEXT86 *context, int nb_args );
* They call to 16-bit code with all registers except SS:SP set up as specified
* extern WINAPI void CallTo16_lreg_( const CONTEXT86 *context, int nb_args );
* by the 'context' structure, and SS:SP set to point to the current 16-bit
* stack, decremented by the value specified in the 'nb_args' argument.
*/
*/
static
void
BuildCallTo16Func
(
FILE
*
outfile
,
char
*
profile
)
{
int
short_ret
=
0
;
int
reg_func
=
0
;
char
*
args
=
profile
+
5
;
if
(
!
strncmp
(
"word_"
,
profile
,
5
))
short_ret
=
1
;
static
void
BuildCallTo16Core
(
FILE
*
outfile
,
int
short_ret
,
int
reg_func
)
else
if
(
!
strncmp
(
"sreg_"
,
profile
,
5
))
reg_func
=
1
;
{
else
if
(
!
strncmp
(
"lreg_"
,
profile
,
5
))
reg_func
=
2
;
char
*
name
=
reg_func
==
2
?
"RegisterLong"
:
else
if
(
strncmp
(
"long_"
,
profile
,
5
))
reg_func
==
1
?
"RegisterShort"
:
{
short_ret
?
"Word"
:
"Long"
;
fprintf
(
stderr
,
"Invalid function name '%s'.
\n
"
,
profile
);
exit
(
1
);
}
/* Function header */
/* Function header */
fprintf
(
outfile
,
"
\n\t
.align 4
\n
"
);
fprintf
(
outfile
,
"
\n\t
.align 4
\n
"
);
#ifdef USE_STABS
#ifdef USE_STABS
fprintf
(
outfile
,
".stabs
\"
CallTo16
_%s:F1
\"
,36,0,0,"
PREFIX
"CallTo16_
%s
\n
"
,
fprintf
(
outfile
,
".stabs
\"
CallTo16
%s:F1
\"
,36,0,0,"
PREFIX
"CallTo16
%s
\n
"
,
profile
,
profil
e
);
name
,
nam
e
);
#endif
#endif
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CallTo16
_%s
\n
"
,
profil
e
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CallTo16
%s
\n
"
,
nam
e
);
fprintf
(
outfile
,
PREFIX
"CallTo16
_%s:
\n
"
,
profil
e
);
fprintf
(
outfile
,
PREFIX
"CallTo16
%s:
\n
"
,
nam
e
);
/* Entry code */
/* Retrieve relay target address */
if
(
!
reg_func
)
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
/* Function entry sequence */
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp,%%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp,
%%ebp
\n
"
);
/* Save the 32-bit registers */
/* Save the 32-bit registers */
fprintf
(
outfile
,
"
\t
pushl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edi
\n
"
);
/* Enter Win16 Mutex */
#ifdef USE__PIC__
/* Get Global Offset Table into %ebx */
fprintf
(
outfile
,
"
\t
call .LCallTo16%s.getgot
\n
"
,
name
);
fprintf
(
outfile
,
".LCallFrom16%s.getgot:
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
addl $_GLOBAL_OFFSET_TABLE+[.-.LCallFrom16%s.getgot], %%ebx
\n
"
);
#endif
/* Move relay target address to %edi */
if
(
!
reg_func
)
fprintf
(
outfile
,
"
\t
movl %%eax, %%edi
\n
"
);
/* Enter Win16 Mutex */
#ifdef USE__PIC__
fprintf
(
outfile
,
"
\t
call "
PREFIX
"SYSLEVEL_EnterWin16Lock@PLT
\n
"
);
#else
fprintf
(
outfile
,
"
\t
call "
PREFIX
"SYSLEVEL_EnterWin16Lock
\n
"
);
fprintf
(
outfile
,
"
\t
call "
PREFIX
"SYSLEVEL_EnterWin16Lock
\n
"
);
#endif
/* Print debugging info */
/* Print debugging info */
if
(
debugging
)
if
(
debugging
)
{
{
/* Push number of arguments (from relay stub) */
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
pushl $-1
\n
"
);
else
fprintf
(
outfile
,
"
\t
pushl -9(%%edi)
\n
"
);
/* Push the address of the first argument */
/* Push the address of the first argument */
fprintf
(
outfile
,
"
\t
leal 8(%%ebp),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
leal 8(%%ebp),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl $%d
\n
"
,
reg_func
?
-
1
:
strlen
(
args
)
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
#ifdef USE__PIC__
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallTo16@PLT
\n
"
);
#else
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallTo16
\n
"
);
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallTo16
\n
"
);
#endif
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
}
}
/* Call the actual CallTo16 routine (simulate a lcall) */
/* Get return address */
#ifdef USE__PIC__
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"CallTo16_RetAddr@GOTOFF(%%ebx), %%ecx
\n
"
);
#else
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"CallTo16_RetAddr, %%ecx
\n
"
);
#endif
/* Call the actual CallTo16 routine (simulate a lcall) */
fprintf
(
outfile
,
"
\t
pushl %%cs
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%cs
\n
"
);
fprintf
(
outfile
,
"
\t
call
do_callto16_%s
\n
"
,
profil
e
);
fprintf
(
outfile
,
"
\t
call
.LCallTo16%s
\n
"
,
nam
e
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
/* Convert and push return value */
if
(
short_ret
)
{
fprintf
(
outfile
,
"
\t
movzwl %%ax, %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
}
else
if
(
reg_func
!=
2
)
{
fprintf
(
outfile
,
"
\t
shll $16,%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%dx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
}
else
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
/* Print debugging info */
/* Print debugging info */
if
(
debugging
)
if
(
debugging
)
{
{
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
#ifdef USE__PIC__
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallTo16Ret@PLT
\n
"
);
#else
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallTo16Ret
\n
"
);
fprintf
(
outfile
,
"
\t
call "
PREFIX
"RELAY_DebugCallTo16Ret
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
#endif
}
}
/* Leave Win16 Mutex */
/* Leave Win16 Mutex */
#ifdef USE__PIC__
fprintf
(
outfile
,
"
\t
call "
PREFIX
"SYSLEVEL_LeaveWin16Lock@PLT
\n
"
);
#else
fprintf
(
outfile
,
"
\t
call "
PREFIX
"SYSLEVEL_LeaveWin16Lock
\n
"
);
fprintf
(
outfile
,
"
\t
call "
PREFIX
"SYSLEVEL_LeaveWin16Lock
\n
"
);
#endif
/* Restore the 32-bit registers */
/* Get return value */
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
/* Restore the 32-bit registers */
fprintf
(
outfile
,
"
\t
popl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
/* Exit code */
/* Function exit sequence */
#if 0
/* FIXME: this is a hack because of task.c */
if (!strcmp( profile, "word_" ))
{
fprintf( outfile, ".globl " PREFIX "CALLTO16_Restore\n" );
fprintf( outfile, PREFIX "CALLTO16_Restore:\n" );
}
#endif
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
ret
$%d
\n
"
,
4
*
strlen
(
args
)
+
4
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
/* Start of the actual CallTo16 routine */
/* Start of the actual CallTo16 routine */
fprintf
(
outfile
,
"do_callto16_%s:
\n
"
,
profile
);
fprintf
(
outfile
,
".LCallTo16%s:
\n
"
,
name
);
/* Save the 32-bit stack */
/* Complete STACK32FRAME */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
pushl (%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
pushl (%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
movl %%ebp,%%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp,%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp,%%edx
\n
"
);
if
(
reg_func
)
/* Switch to the 16-bit stack */
{
/* Switch to the 16-bit stack, saving the current %%esp, */
/* and adding the specified offset to the new sp */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d),%%eax
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
subl 12(%%ebx),%%eax
\n
"
);
/* Get the offset */
#ifdef __svr4__
#ifdef __svr4__
fprintf
(
outfile
,
"
\t
data16
\n
"
);
fprintf
(
outfile
,
"
\t
data16
\n
"
);
#endif
#endif
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
movl %%eax,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%sp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl %%edx,(%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl %%edx,(%d)
\n
"
,
STACKOFFSET
);
/* Get the registers. ebx is handled later on. */
if
(
reg_func
)
{
fprintf
(
outfile
,
"
\t
movl 8(%%ebx),%%ebx
\n
"
);
/* Add the specified offset to the new sp */
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%eax
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
subw %d(%%edx), %%sp
\n
"
,
STACK32OFFSET
(
args
)
+
4
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%es
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%eax
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%fs
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
/* Push the return address
/* Push the return address
* With sreg suffix, we push 16:16 address (normal lret)
* With sreg suffix, we push 16:16 address (normal lret)
* With lreg suffix, we push 16:32 address (0x66 lret, for KERNEL32_45)
* With lreg suffix, we push 16:32 address (0x66 lret, for KERNEL32_45)
*/
*/
if
(
reg_func
==
1
)
if
(
reg_func
==
1
)
fprintf
(
outfile
,
"
\t
pushl
"
PREFIX
"CALLTO16_RetAddr_long
\n
"
);
fprintf
(
outfile
,
"
\t
pushl
%%ecx
\n
"
);
else
else
{
{
fprintf
(
outfile
,
"
\t
shldl $16, %%ecx, %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushw $0
\n
"
);
fprintf
(
outfile
,
"
\t
pushw $0
\n
"
);
fprintf
(
outfile
,
"
\t
pushw
"
PREFIX
"CALLTO16_RetAddr_eax+2
\n
"
);
fprintf
(
outfile
,
"
\t
pushw
%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
pushw $0
\n
"
);
fprintf
(
outfile
,
"
\t
pushw $0
\n
"
);
fprintf
(
outfile
,
"
\t
pushw
"
PREFIX
"CALLTO16_RetAddr_ea
x
\n
"
);
fprintf
(
outfile
,
"
\t
pushw
%%c
x
\n
"
);
}
}
/* Push the called routine address */
/* Push the called routine address */
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%edx
\n
"
,
STACK32OFFSET
(
args
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
/* Get the registers */
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%eax
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%es
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%eax
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%fs
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
/* Get the 16-bit ds */
/* Get the 16-bit ds */
fprintf
(
outfile
,
"
\t
popw %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
/* Jump to the called routine */
/* Get ebx from the 32-bit stack */
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx),%%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ds
\n
"
);
}
}
else
/* not a register function */
else
/* not a register function */
{
{
int
pos
=
12
;
/* first argument position */
/* Switch to the 16-bit stack */
#ifdef __svr4__
fprintf
(
outfile
,
"
\t
data16
\n
"
);
#endif
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%sp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl %%edx,(%d)
\n
"
,
STACKOFFSET
);
/* Make %bp point to the previous stackframe (built by CallFrom16) */
/* Make %bp point to the previous stackframe (built by CallFrom16) */
fprintf
(
outfile
,
"
\t
movzwl %%sp,%%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movzwl %%sp,%%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
leal %d(%%ebp),%%ebp
\n
"
,
fprintf
(
outfile
,
"
\t
leal %d(%%ebp),%%ebp
\n
"
,
STACK16OFFSET
(
bp
)
);
STRUCTOFFSET
(
STACK16FRAME
,
bp
)
);
/* Transfer the arguments */
while
(
*
args
)
{
switch
(
*
args
++
)
{
case
'w'
:
/* word */
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
pos
);
break
;
case
'l'
:
/* long */
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
pos
);
break
;
default:
fprintf
(
stderr
,
"Unexpected case '%c' in BuildCallTo16Func
\n
"
,
args
[
-
1
]
);
}
pos
+=
4
;
}
/* Push the return address */
fprintf
(
outfile
,
"
\t
pushl "
PREFIX
"CALLTO16_RetAddr_%s
\n
"
,
short_ret
?
"word"
:
"long"
);
/* Push the called routine address */
fprintf
(
outfile
,
"
\t
pushl 8(%%ebx)
\n
"
);
/* Set %fs to the value saved by the last CallFrom16 */
/* Set %fs to the value saved by the last CallFrom16 */
fprintf
(
outfile
,
"
\t
movw %d(%%ebp),%%ax
\n
"
,
STACK16OFFSET
(
fs
)
-
STACK16OFFSET
(
bp
)
);
fprintf
(
outfile
,
"
\t
movw -14(%%ebp),%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%fs
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%fs
\n
"
);
/* Set %ds and %es (and %ax just in case) equal to %ss */
/* Jump to the relay code */
fprintf
(
outfile
,
"
\t
jmp *%%edi
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ss,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%ds
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%es
\n
"
);
}
}
/* Jump to the called routine */
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
}
}
/*******************************************************************
/*******************************************************************
* BuildRet16Func
* BuildRet16Func
*
*
...
@@ -2168,20 +2380,13 @@ static void BuildCallTo16Func( FILE *outfile, char *profile )
...
@@ -2168,20 +2380,13 @@ static void BuildCallTo16Func( FILE *outfile, char *profile )
*/
*/
static
void
BuildRet16Func
(
FILE
*
outfile
)
static
void
BuildRet16Func
(
FILE
*
outfile
)
{
{
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_Ret_word
\n
"
);
/*
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_Ret_long
\n
"
);
* Note: This must reside in the .data section to allow
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_Ret_eax
\n
"
);
* run-time relocation of the SYSLEVEL_Win16CurrentTeb symbol
*/
fprintf
(
outfile
,
PREFIX
"CALLTO16_Ret_word:
\n
"
);
fprintf
(
outfile
,
"
\t
xorl %%edx,%%edx
\n
"
);
/* Put return value into %eax */
fprintf
(
outfile
,
PREFIX
"CALLTO16_Ret_long:
\n
"
);
fprintf
(
outfile
,
"
\n\t
.globl "
PREFIX
"CallTo16_Ret
\n
"
);
fprintf
(
outfile
,
"
\t
shll $16,%%edx
\n
"
);
fprintf
(
outfile
,
PREFIX
"CallTo16_Ret:
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%dx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%edx,%%eax
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALLTO16_Ret_eax:
\n
"
);
/* Restore 32-bit segment registers */
/* Restore 32-bit segment registers */
...
@@ -2210,16 +2415,10 @@ static void BuildRet16Func( FILE *outfile )
...
@@ -2210,16 +2415,10 @@ static void BuildRet16Func( FILE *outfile )
fprintf
(
outfile
,
"
\t
lret
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
/* Declare the return address variable
s
*/
/* Declare the return address variable */
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\n\t
.globl "
PREFIX
"CallTo16_RetAddr
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_RetAddr_word
\n
"
);
fprintf
(
outfile
,
PREFIX
"CallTo16_RetAddr:
\t
.long 0
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_RetAddr_long
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_RetAddr_eax
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALLTO16_RetAddr_word:
\t
.long 0
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALLTO16_RetAddr_long:
\t
.long 0
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALLTO16_RetAddr_eax:
\t
.long 0
\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
}
}
/*******************************************************************
/*******************************************************************
...
@@ -2446,10 +2645,15 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
...
@@ -2446,10 +2645,15 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
fprintf
(
outfile
,
"
\t
popl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
}
static
void
BuildCallTo32CBClientRet
(
FILE
*
outfile
,
BOOL
isEx
)
{
char
*
name
=
isEx
?
"CBClientEx"
:
"CBClient"
;
/* '16-bit' return stub */
/* '16-bit' return stub */
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_%s_Ret
\n
"
,
name
);
fprintf
(
outfile
,
"
\
n\
t
.globl "
PREFIX
"CALL32_%s_Ret
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CALL32_%s_Ret:
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CALL32_%s_Ret:
\n
"
,
name
);
if
(
!
isEx
)
if
(
!
isEx
)
...
@@ -2468,14 +2672,11 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
...
@@ -2468,14 +2672,11 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
/* Declare the return address variable */
/* Declare the return address variable */
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\n\t
.globl "
PREFIX
"CALL32_%s_RetAddr
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_%s_RetAddr
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CALL32_%s_RetAddr:
\t
.long 0
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CALL32_%s_RetAddr:
\t
.long 0
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
}
}
/*******************************************************************
/*******************************************************************
* BuildCallTo32LargeStack
* BuildCallTo32LargeStack
*
*
...
@@ -2721,18 +2922,26 @@ static int BuildSpec( FILE *outfile, int argc, char *argv[] )
...
@@ -2721,18 +2922,26 @@ static int BuildSpec( FILE *outfile, int argc, char *argv[] )
return
0
;
return
0
;
}
}
/*******************************************************************
/*******************************************************************
* Build
CallFrom16
* Build
Glue
*
*
* Build the 16-bit-to-Wine
callbacks
* Build the 16-bit-to-Wine
/Wine-to-16-bit callback glue code
*/
*/
static
int
Build
CallFrom16
(
FILE
*
outfile
,
char
*
outname
,
int
argc
,
char
*
argv
[]
)
static
int
Build
Glue
(
FILE
*
outfile
,
char
*
outname
,
int
argc
,
char
*
argv
[]
)
{
{
int
i
;
#ifdef USE_STABS
char
buffer
[
1024
];
char
buffer
[
1024
];
#endif
FILE
*
infile
;
if
(
argc
>
2
)
{
infile
=
fopen
(
argv
[
2
],
"r"
);
if
(
!
infile
)
{
perror
(
argv
[
2
]
);
exit
(
1
);
}
}
else
infile
=
stdin
;
/* File header */
/* File header */
...
@@ -2753,30 +2962,41 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[
...
@@ -2753,30 +2962,41 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[
fprintf
(
outfile
,
"
\t
.align 4
\n
"
);
fprintf
(
outfile
,
"
\t
.align 4
\n
"
);
fprintf
(
outfile
,
"Code_Start:
\n\n
"
);
fprintf
(
outfile
,
"Code_Start:
\n\n
"
);
#endif
#endif
fprintf
(
outfile
,
PREFIX
"CallFrom16_Start:
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CallFrom16_Start
\n
"
);
/* Build the callback functions */
/* Build the callback
glue
functions */
for
(
i
=
2
;
i
<
argc
;
i
++
)
BuildCallFrom16Func
(
outfile
,
argv
[
i
]
);
while
(
fgets
(
buffer
,
sizeof
(
buffer
),
infile
))
{
/* Build the thunk callback function */
if
(
strstr
(
buffer
,
"### start build ###"
))
break
;
}
BuildCallFrom16Func
(
outfile
,
"t_long_"
);
while
(
fgets
(
buffer
,
sizeof
(
buffer
),
infile
))
/* Output the argument debugging strings */
if
(
debugging
)
{
{
fprintf
(
outfile
,
"/* Argument strings */
\n
"
);
char
*
p
;
for
(
i
=
2
;
i
<
argc
;
i
++
)
if
(
(
p
=
strstr
(
buffer
,
"CallFrom16_"
))
!=
NULL
)
{
char
*
q
,
*
profile
=
p
+
strlen
(
"CallFrom16_"
);
for
(
q
=
profile
;
(
*
q
==
'_'
)
||
isalpha
(
*
q
);
q
++
)
;
*
q
=
'\0'
;
for
(
q
=
p
-
1
;
q
>
buffer
&&
((
*
q
==
'_'
)
||
isalnum
(
*
q
));
q
--
)
;
if
(
++
q
<
p
)
p
[
-
1
]
=
'\0'
;
else
q
=
""
;
BuildCallFrom16Func
(
outfile
,
profile
,
q
);
}
if
(
(
p
=
strstr
(
buffer
,
"CallTo16_"
))
!=
NULL
)
{
{
fprintf
(
outfile
,
"Profile_%s:
\t
"
,
argv
[
i
]
);
char
*
q
,
*
profile
=
p
+
strlen
(
"CallTo16_"
);
fprintf
(
outfile
,
STRING
"
\"
%s
\\
0
\"\n
"
,
argv
[
i
]
+
7
);
for
(
q
=
profile
;
(
*
q
==
'_'
)
||
isalpha
(
*
q
);
q
++
)
;
*
q
=
'\0'
;
for
(
q
=
p
-
1
;
q
>
buffer
&&
((
*
q
==
'_'
)
||
isalnum
(
*
q
));
q
--
)
;
if
(
++
q
<
p
)
p
[
-
1
]
=
'\0'
;
else
q
=
""
;
BuildCallTo16Func
(
outfile
,
profile
,
q
);
}
}
if
(
strstr
(
buffer
,
"### stop build ###"
))
break
;
}
}
fprintf
(
outfile
,
PREFIX
"CallFrom16_End:
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CallFrom16_End
\n
"
);
#ifdef USE_STABS
#ifdef USE_STABS
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
...
@@ -2784,30 +3004,20 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[
...
@@ -2784,30 +3004,20 @@ static int BuildCallFrom16( FILE *outfile, char * outname, int argc, char *argv[
fprintf
(
outfile
,
".Letext:
\n
"
);
fprintf
(
outfile
,
".Letext:
\n
"
);
#endif
#endif
fclose
(
infile
);
return
0
;
return
0
;
}
}
/*******************************************************************
/*******************************************************************
* BuildCall
To
16
* BuildCall16
*
*
* Build the
Wine-to-
16-bit callbacks
* Build the 16-bit callbacks
*/
*/
static
int
BuildCall
To16
(
FILE
*
outfile
,
char
*
outname
,
int
argc
,
char
*
argv
[]
)
static
int
BuildCall
16
(
FILE
*
outfile
,
char
*
outname
)
{
{
#ifdef USE_STABS
char
buffer
[
1024
];
char
buffer
[
1024
];
FILE
*
infile
;
#endif
if
(
argc
>
2
)
{
infile
=
fopen
(
argv
[
2
],
"r"
);
if
(
!
infile
)
{
perror
(
argv
[
2
]
);
exit
(
1
);
}
}
else
infile
=
stdin
;
/* File header */
/* File header */
...
@@ -2828,57 +3038,67 @@ static int BuildCallTo16( FILE *outfile, char * outname, int argc, char *argv[]
...
@@ -2828,57 +3038,67 @@ static int BuildCallTo16( FILE *outfile, char * outname, int argc, char *argv[]
fprintf
(
outfile
,
"
\t
.align 4
\n
"
);
fprintf
(
outfile
,
"
\t
.align 4
\n
"
);
fprintf
(
outfile
,
"Code_Start:
\n\n
"
);
fprintf
(
outfile
,
"Code_Start:
\n\n
"
);
#endif
#endif
fprintf
(
outfile
,
PREFIX
"Call16_Start:
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"Call16_Start
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0
\n\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_Start
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALLTO16_Start:
\n
"
);
/* Build the callback functions */
/* Standard CallFrom16 routine */
BuildCallFrom16Core
(
outfile
,
FALSE
,
FALSE
);
while
(
fgets
(
buffer
,
sizeof
(
buffer
),
infile
))
/* Register CallFrom16 routine */
{
BuildCallFrom16Core
(
outfile
,
TRUE
,
FALSE
);
if
(
strstr
(
buffer
,
"### start build ###"
))
break
;
}
while
(
fgets
(
buffer
,
sizeof
(
buffer
),
infile
))
{
char
*
p
=
strstr
(
buffer
,
"CallTo16_"
);
if
(
p
)
{
char
*
profile
=
p
+
strlen
(
"CallTo16_"
);
p
=
profile
;
while
((
*
p
==
'_'
)
||
isalpha
(
*
p
))
p
++
;
*
p
=
'\0'
;
BuildCallTo16Func
(
outfile
,
profile
);
}
if
(
strstr
(
buffer
,
"### stop build ###"
))
break
;
}
/* Output the 16-bit return code */
/* C16ThkSL CallFrom16 routine */
BuildCallFrom16Core
(
outfile
,
FALSE
,
TRUE
);
BuildRet16Func
(
outfile
);
/* Standard CallTo16 routine (WORD return) */
BuildCallTo16Core
(
outfile
,
TRUE
,
FALSE
);
/* Output the CBClient callback functions
/* Standard CallTo16 routine (DWORD return) */
* (while this does not really 'call to 16-bit' code, it is placed
BuildCallTo16Core
(
outfile
,
FALSE
,
FALSE
);
* here so that its 16-bit return stub is defined within the CALLTO16
* 16-bit segment)
/* Register CallTo16 routine (16:16 retf) */
*/
BuildCallTo16Core
(
outfile
,
FALSE
,
1
);
/* Register CallTo16 routine (16:32 retf) */
BuildCallTo16Core
(
outfile
,
FALSE
,
2
);
/* CBClientThunkSL routine */
BuildCallTo32CBClient
(
outfile
,
FALSE
);
BuildCallTo32CBClient
(
outfile
,
FALSE
);
BuildCallTo32CBClient
(
outfile
,
TRUE
);
/* CBClientThunkSLEx routine */
BuildCallTo32CBClient
(
outfile
,
TRUE
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_End
\n
"
);
fprintf
(
outfile
,
PREFIX
"Call16_End:
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALLTO16_End:
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"Call16_End
\n
"
);
#ifdef USE_STABS
#ifdef USE_STABS
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.stabs
\"\"
,100,0,0,.Letext
\n
"
);
fprintf
(
outfile
,
"
\t
.stabs
\"\"
,100,0,0,.Letext
\n
"
);
fprintf
(
outfile
,
".Letext:
\n
"
);
fprintf
(
outfile
,
".Letext:
\n
"
);
#endif
#endif
fclose
(
infile
);
/* The whole Call16_Ret segment must lie within the .data section */
fprintf
(
outfile
,
"
\n\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"Call16_Ret_Start
\n
"
);
fprintf
(
outfile
,
PREFIX
"Call16_Ret_Start:
\n
"
);
/* Standard CallTo16 return stub */
BuildRet16Func
(
outfile
);
/* CBClientThunkSL return stub */
BuildCallTo32CBClientRet
(
outfile
,
FALSE
);
/* CBClientThunkSLEx return stub */
BuildCallTo32CBClientRet
(
outfile
,
TRUE
);
/* End of Call16_Ret segment */
fprintf
(
outfile
,
"
\n\t
.globl "
PREFIX
"Call16_Ret_End
\n
"
);
fprintf
(
outfile
,
PREFIX
"Call16_Ret_End:
\n
"
);
return
0
;
return
0
;
}
}
/*******************************************************************
/*******************************************************************
* BuildCall32
* BuildCall32
*
*
...
@@ -2943,8 +3163,8 @@ static void usage(void)
...
@@ -2943,8 +3163,8 @@ static void usage(void)
{
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"usage: build [-o outfile] -spec SPECNAMES
\n
"
"usage: build [-o outfile] -spec SPECNAMES
\n
"
" build [-o outfile] -
callfrom16 FUNCTION_PROFILES
\n
"
" build [-o outfile] -
glue SOURCE_FILE
\n
"
" build [-o outfile] -call
to16 FUNCTION_PROFILES
\n
"
" build [-o outfile] -call
16
\n
"
" build [-o outfile] -call32
\n
"
);
" build [-o outfile] -call32
\n
"
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -2983,10 +3203,10 @@ int main(int argc, char **argv)
...
@@ -2983,10 +3203,10 @@ int main(int argc, char **argv)
if
(
!
strcmp
(
argv
[
1
],
"-spec"
))
if
(
!
strcmp
(
argv
[
1
],
"-spec"
))
res
=
BuildSpec
(
outfile
,
argc
,
argv
);
res
=
BuildSpec
(
outfile
,
argc
,
argv
);
else
if
(
!
strcmp
(
argv
[
1
],
"-
callfrom16
"
))
else
if
(
!
strcmp
(
argv
[
1
],
"-
glue
"
))
res
=
Build
CallFrom16
(
outfile
,
outname
,
argc
,
argv
);
res
=
Build
Glue
(
outfile
,
outname
,
argc
,
argv
);
else
if
(
!
strcmp
(
argv
[
1
],
"-call
to
16"
))
else
if
(
!
strcmp
(
argv
[
1
],
"-call16"
))
res
=
BuildCall
To16
(
outfile
,
outname
,
argc
,
argv
);
res
=
BuildCall
16
(
outfile
,
outname
);
else
if
(
!
strcmp
(
argv
[
1
],
"-call32"
))
else
if
(
!
strcmp
(
argv
[
1
],
"-call32"
))
res
=
BuildCall32
(
outfile
,
outname
);
res
=
BuildCall32
(
outfile
,
outname
);
else
else
...
...
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