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
9cf066e3
Commit
9cf066e3
authored
Jan 24, 1999
by
Ulrich Weigand
Committed by
Alexandre Julliard
Jan 24, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented KERNEL.621 (CBClientThunkSLEx).
parent
40c11ebf
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
136 additions
and
26 deletions
+136
-26
kernel.spec
if1632/kernel.spec
+1
-1
relay.c
if1632/relay.c
+4
-0
thunk.c
if1632/thunk.c
+29
-0
build.c
tools/build.c
+102
-25
No files found.
if1632/kernel.spec
View file @
9cf066e3
...
...
@@ -490,7 +490,7 @@ file krnl386.exe
618 pascal16 GetDialog32Size(ptr) GetDialog32Size
619 pascal16 RegisterCBClient(word ptr long) RegisterCBClient
620 register CBClientThunkSL() CBClientThunkSL
621
stub KERNEL_621 # (cbclient)
621
register CBClientThunkSLEx() CBClientThunkSLEx
622 pascal16 UnRegisterCBClient(word ptr long) UnRegisterCBClient
623 pascal16 InitCBClient(long) InitCBClient
624 pascal SetFastQueue(long long) SetFastQueue
...
...
if1632/relay.c
View file @
9cf066e3
...
...
@@ -30,10 +30,12 @@ BOOL32 RELAY_Init(void)
extern
void
CALLTO16_Ret_word
(),
CALLTO16_Ret_long
();
extern
void
CALLTO16_Ret_eax
();
extern
void
CALL32_CBClient_Ret
();
extern
void
CALL32_CBClientEx_Ret
();
extern
DWORD
CALLTO16_RetAddr_word
;
extern
DWORD
CALLTO16_RetAddr_long
;
extern
DWORD
CALLTO16_RetAddr_eax
;
extern
DWORD
CALL32_CBClient_RetAddr
;
extern
DWORD
CALL32_CBClientEx_RetAddr
;
codesel
=
GLOBAL_CreateBlock
(
GMEM_FIXED
,
(
void
*
)
CALLTO16_Start
,
(
int
)
CALLTO16_End
-
(
int
)
CALLTO16_Start
,
...
...
@@ -50,6 +52,8 @@ BOOL32 RELAY_Init(void)
codesel
);
CALL32_CBClient_RetAddr
=
MAKELONG
(
(
int
)
CALL32_CBClient_Ret
-
(
int
)
CALLTO16_Start
,
codesel
);
CALL32_CBClientEx_RetAddr
=
MAKELONG
(
(
int
)
CALL32_CBClientEx_Ret
-
(
int
)
CALLTO16_Start
,
codesel
);
/* Create built-in modules */
if
(
!
BUILTIN_Init
())
return
FALSE
;
...
...
if1632/thunk.c
View file @
9cf066e3
...
...
@@ -1535,3 +1535,32 @@ void WINAPI CBClientThunkSL( CONTEXT *context )
EAX_reg
(
context
)
=
CALL32_CBClient
(
proc
,
args
);
}
/***********************************************************************
* CBClientThunkSLEx (KERNEL.621)
*/
void
WINAPI
CBClientThunkSLEx
(
CONTEXT
*
context
)
{
/* Call 32-bit relay code */
extern
DWORD
WINAPI
CALL32_CBClientEx
(
FARPROC32
proc
,
LPWORD
args
,
INT32
*
nArgs
);
LPWORD
args
=
PTR_SEG_OFF_TO_LIN
(
SS_reg
(
context
),
BP_reg
(
context
)
);
FARPROC32
proc
=
CBClientRelay32
[
args
[
2
]
][
args
[
1
]
];
INT32
nArgs
;
LPWORD
stackLin
;
EAX_reg
(
context
)
=
CALL32_CBClientEx
(
proc
,
args
,
&
nArgs
);
/* Restore registers saved by CBClientGlueSL */
stackLin
=
(
LPWORD
)((
LPBYTE
)
CURRENT_STACK16
+
sizeof
(
STACK16FRAME
)
-
4
);
BP_reg
(
context
)
=
stackLin
[
3
];
SI_reg
(
context
)
=
stackLin
[
2
];
DI_reg
(
context
)
=
stackLin
[
1
];
DS_reg
(
context
)
=
stackLin
[
0
];
SP_reg
(
context
)
+=
16
+
nArgs
;
/* Return to caller of CBClient thunklet */
CS_reg
(
context
)
=
stackLin
[
9
];
EIP_reg
(
context
)
=
stackLin
[
8
];
}
tools/build.c
View file @
9cf066e3
...
...
@@ -2150,7 +2150,7 @@ static void BuildRet16Func( FILE *outfile )
* and perform a far return to 16-bit code.
*
* To trick the relay stub into returning to us, we push a 16-bit
* cs:ip pair pointing to ou
t
return entry point onto the 16-bit stack,
* cs:ip pair pointing to ou
r
return entry point onto the 16-bit stack,
* followed by a ss:sp pair pointing to *that* cs:ip pair.
* Our return stub thus called will then reload the 32-bit ss:esp and
* return to 32-bit code (by using and ss:esp value that we have also
...
...
@@ -2165,22 +2165,60 @@ static void BuildRet16Func( FILE *outfile )
* (ebx+2) 16-bit ss (16-bit stack segment)
* (ebx+0) 16-bit sp (points to ebx+4)
*
* The second variant of this routine, CALL32_CBClientEx, which is used
* to implement KERNEL.621, has to cope with yet another problem: Here,
* the 32-bit side directly returns to the caller of the CBClient thunklet,
* restoring registers saved by CBClientGlueSL and cleaning up the stack.
* As we have to return to our 32-bit code first, we have to adapt the
* layout of our temporary area so as to include values for the registers
* that are to be restored, and later (in the implementation of KERNEL.621)
* we *really* restore them. The return stub restores DS, DI, SI, and BP
* from the stack, skips the next 8 bytes (CBClient relay code / target),
* and then performs a lret NN, where NN is the number of arguments to be
* removed. Thus, we prepare our temporary area as follows:
*
* (ebx+22) 16-bit cs (this segment)
* (ebx+20) 16-bit ip ('16-bit' return entry point)
* (ebx+16) 32-bit ss (flat)
* (ebx+12) 32-bit sp (32-bit stack pointer)
* (ebx+10) 16-bit bp (points to ebx+24)
* (ebx+8) 16-bit si (ignored)
* (ebx+6) 16-bit di (ignored)
* (ebx+4) 16-bit ds (we actually use the flat DS here)
* (ebx+2) 16-bit ss (16-bit stack segment)
* (ebx+0) 16-bit sp (points to ebx+4)
*
* Note that we ensure that DS is not changed and remains the flat segment,
* and the 32-bit stack pointer our own return stub needs fits just
* perfectly into the 8 bytes that are skipped by the Windows stub.
* One problem is that we have to determine the number of removed arguments,
* as these have to be really removed in KERNEL.621. Thus, the BP value
* that we place in the temporary area to be restored, contains the value
* that SP would have if no arguments were removed. By comparing the actual
* value of SP with this value in our return stub we can compute the number
* of removed arguments. This is then returned to KERNEL.621.
*
* The stack layout of this function:
* (ebp+16) nArgs pointer to variable receiving nr. of args (Ex only)
* (ebp+12) arg ebp value to be set for relay stub
* (ebp+8) func CBClient relay stub address
* (ebp+4) ret addr
* (ebp) ebp
*/
static
void
BuildCallTo32CBClient
(
FILE
*
outfile
)
static
void
BuildCallTo32CBClient
(
FILE
*
outfile
,
BOOL32
isEx
)
{
char
*
name
=
isEx
?
"CBClientEx"
:
"CBClient"
;
int
size
=
isEx
?
24
:
16
;
/* Function header */
fprintf
(
outfile
,
"
\n\t
.align 4
\n
"
);
#ifdef USE_STABS
fprintf
(
outfile
,
".stabs
\"
CALL32_CBClient:F1
\"
,36,0,0,"
PREFIX
"CALL32_CBClient
\n
"
);
fprintf
(
outfile
,
".stabs
\"
CALL32_%s:F1
\"
,36,0,0,"
PREFIX
"CALL32_%s
\n
"
,
name
,
name
);
#endif
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_
CBClient
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALL32_
CBClient:
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_
%s
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CALL32_
%s:
\n
"
,
name
);
/* Entry code */
...
...
@@ -2206,29 +2244,50 @@ static void BuildCallTo32CBClient( FILE *outfile )
fprintf
(
outfile
,
"
\t
pushf
\n
"
);
fprintf
(
outfile
,
"
\t
cld
\n
"
);
fprintf
(
outfile
,
"
\t
leal -
16(%%esi), %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
leal -
%d(%%esi), %%edi
\n
"
,
size
);
fprintf
(
outfile
,
"
\t
movl $%d, %%ecx
\n
"
,
sizeof
(
STACK16FRAME
)
);
fprintf
(
outfile
,
"
\t
rep
\n\t
movsb
\n
"
);
fprintf
(
outfile
,
"
\t
popf
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
subw $
16,(%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
subw $
%d,(%d)
\n
"
,
size
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
pushl %%edi
\n
"
);
/* remember address */
/* Set up temporary area */
fprintf
(
outfile
,
"
\t
addl $%d, %%ebx
\n
"
,
sizeof
(
STACK16FRAME
)
-
16
+
4
);
fprintf
(
outfile
,
"
\t
addl $%d, %%ebx
\n
"
,
sizeof
(
STACK16FRAME
)
-
size
+
4
);
fprintf
(
outfile
,
"
\t
movl %%ebx, (%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"CALL32_CBClient_RetAddr, %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, 4(%%edi)
\n
"
);
if
(
!
isEx
)
{
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"CALL32_%s_RetAddr, %%eax
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
movl %%eax, 4(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
leal -8(%%esp), %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, 8(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ss, %%ax
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0x0000ffff, %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, 12(%%edi)
\n
"
);
}
else
{
fprintf
(
outfile
,
"
\t
movl %%ds, %%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax, 4(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
leal -8(%%esp), %%ea
x
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, 8
(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
addl $20, %%eb
x
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%bx, 10
(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ss, %%ax
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0x0000ffff, %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, 12(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
leal -8(%%esp), %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, 12(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ss, %%ax
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0x0000ffff, %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax, 16(%%edi)
\n
"
);
fprintf
(
outfile
,
"
\t
movl "
PREFIX
"CALL32_%s_RetAddr, %%eax
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
movl %%eax, 20(%%edi)
\n
"
);
}
/* Setup registers and call CBClient relay stub (simulating a far call) */
...
...
@@ -2246,12 +2305,19 @@ static void BuildCallTo32CBClient( FILE *outfile )
fprintf
(
outfile
,
"
\t
pushf
\n
"
);
fprintf
(
outfile
,
"
\t
std
\n
"
);
fprintf
(
outfile
,
"
\t
dec %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
leal
16(%%esi), %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
leal
%d(%%esi), %%edi
\n
"
,
size
);
fprintf
(
outfile
,
"
\t
movl $%d, %%ecx
\n
"
,
sizeof
(
STACK16FRAME
)
);
fprintf
(
outfile
,
"
\t
rep
\n\t
movsb
\n
"
);
fprintf
(
outfile
,
"
\t
popf
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
addw $16,(%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
addw $%d,(%d)
\n
"
,
size
,
STACKOFFSET
);
/* Return argument size to caller */
if
(
isEx
)
{
fprintf
(
outfile
,
"
\t
movl 28(%%esp), %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ebp, (%%ebx)
\n
"
);
}
/* Restore registers and return */
...
...
@@ -2263,18 +2329,28 @@ static void BuildCallTo32CBClient( FILE *outfile )
/* '16-bit' return stub */
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_
CBClient_Ret
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALL32_
CBClient_Ret:
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_
%s_Ret
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CALL32_
%s_Ret:
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
lssl %%ss:(%%ebx), %%esp
\n
"
);
if
(
!
isEx
)
{
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
lssl %%ss:(%%ebx), %%esp
\n
"
);
}
else
{
fprintf
(
outfile
,
"
\t
movzwl %%bp, %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
subw %%bp, %%sp
\n
"
);
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
lssl %%ss:-12(%%ebx), %%esp
\n
"
);
}
fprintf
(
outfile
,
"
\t
lret
\n
"
);
/* Declare the return address variable */
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_
CBClient_RetAddr
\n
"
);
fprintf
(
outfile
,
PREFIX
"CALL32_
CBClient_RetAddr:
\t
.long 0
\n
"
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALL32_
%s_RetAddr
\n
"
,
name
);
fprintf
(
outfile
,
PREFIX
"CALL32_
%s_RetAddr:
\t
.long 0
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
}
...
...
@@ -2618,12 +2694,13 @@ static int BuildCallTo16( FILE *outfile, char * outname, int argc, char *argv[]
BuildRet16Func
(
outfile
);
/* Output the CBClient callback function
/* Output the CBClient callback function
s
* (while this does not really 'call to 16-bit' code, it is placed
* here so that its 16-bit return stub is defined within the CALLTO16
* 16-bit segment)
*/
BuildCallTo32CBClient
(
outfile
);
BuildCallTo32CBClient
(
outfile
,
FALSE
);
BuildCallTo32CBClient
(
outfile
,
TRUE
);
fprintf
(
outfile
,
"
\t
.globl "
PREFIX
"CALLTO16_End
\n
"
);
...
...
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