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
89f6bc2e
Commit
89f6bc2e
authored
Apr 09, 2009
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winebuild: Hardcode the stack frame offsets instead of using the data structures.
parent
d71284f0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
35 additions
and
46 deletions
+35
-46
relay.c
tools/winebuild/relay.c
+35
-46
No files found.
tools/winebuild/relay.c
View file @
89f6bc2e
...
...
@@ -28,26 +28,17 @@
#include <ctype.h>
#include <stdarg.h>
#define __WINESRC__
/* FIXME: for WINE_VM86_TEB_INFO */
#include "winternl.h"
#include "wine/winbase16.h"
#include "windef.h"
#include "build.h"
/* offset of a structure field relative to the start of the struct */
#define STRUCTOFFSET(type,field) ((int)FIELD_OFFSET(type,field))
/* 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) */
#define STACKOFFSET 0xc0
/*
STRUCT
OFFSET(TEB,WOW32Reserved) */
#define STACKOFFSET 0xc0
/*
FIELD_
OFFSET(TEB,WOW32Reserved) */
/* fix this if the ntdll_thread_regs structure is changed */
#define GS_OFFSET 0x1d8
/* STRUCTOFFSET(TEB,SystemReserved2) + STRUCTOFFSET(ntdll_thread_data,gs) */
#define GS_OFFSET 0x1d8
/* FIELD_OFFSET(TEB,SystemReserved2) + FIELD_OFFSET(ntdll_thread_data,gs) */
#define DPMI_VIF_OFFSET (0x1fc + 0)
/* FIELD_OFFSET(TEB,GdiTebBatch) + FIELD_OFFSET(WINE_VM86_TEB_INFO,dpmi_vif) */
#define VM86_PENDING_OFFSET (0x1fc + 4)
/* FIELD_OFFSET(TEB,GdiTebBatch) + FIELD_OFFSET(WINE_VM86_TEB_INFO,vm86_pending) */
static
void
function_header
(
const
char
*
name
)
{
...
...
@@ -190,7 +181,7 @@ static void BuildCallFrom16Core( int reg_func, int thunk )
output
(
"
\t
pushl %%ds
\n
"
);
output
(
"
\t
popl %%ss
\n
"
);
output
(
"
\t
movl %%ebp, %%esp
\n
"
);
output
(
"
\t
addl $
%d, %%ebp
\n
"
,
STACK32OFFSET
(
ebp
)
);
output
(
"
\t
addl $
0x20,%%ebp
\n
"
);
/* FIELD_OFFSET(STACK32FRAME,ebp) */
/* At this point:
...
...
@@ -207,10 +198,10 @@ static void BuildCallFrom16Core( int reg_func, int thunk )
if
(
thunk
)
{
/* Set up registers as expected and call thunk */
output
(
"
\t
leal
%d(%%edx), %%ebx
\n
"
,
(
int
)
sizeof
(
STACK16FRAME
)
-
22
);
output
(
"
\t
leal
0x1a(%%edx),%%ebx
\n
"
);
/* sizeof(STACK16FRAME)-22 */
output
(
"
\t
leal -4(%%esp), %%ebp
\n
"
);
output
(
"
\t
call *
%d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
output
(
"
\t
call *
0x26(%%edx)
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,entry_point) */
/* Switch stack back */
output
(
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
...
...
@@ -241,7 +232,7 @@ static void BuildCallFrom16Core( int reg_func, int thunk )
/* Build register CONTEXT */
if
(
reg_func
)
{
output
(
"
\t
subl $
%d, %%esp
\n
"
,
(
int
)
sizeof
(
CONTEXT86
)
);
output
(
"
\t
subl $
0x2cc,%%esp
\n
"
);
/* sizeof(CONTEXT86) */
output
(
"
\t
movl %%ecx,0xc0(%%esp)
\n
"
);
/* EFlags */
...
...
@@ -250,31 +241,31 @@ static void BuildCallFrom16Core( int reg_func, int thunk )
output
(
"
\t
movl %%esi,0xa0(%%esp)
\n
"
);
/* Esi */
output
(
"
\t
movl %%edi,0x9c(%%esp)
\n
"
);
/* Edi */
output
(
"
\t
movl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ebp
)
);
output
(
"
\t
movl
0x0c(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,ebp) */
output
(
"
\t
movl %%eax,0xb4(%%esp)
\n
"
);
/* Ebp */
output
(
"
\t
movl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ecx
)
);
output
(
"
\t
movl
0x08(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,ecx) */
output
(
"
\t
movl %%eax,0xac(%%esp)
\n
"
);
/* Ecx */
output
(
"
\t
movl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
edx
)
);
output
(
"
\t
movl
0x04(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,edx) */
output
(
"
\t
movl %%eax,0xa8(%%esp)
\n
"
);
/* Edx */
output
(
"
\t
movzwl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ds
)
);
output
(
"
\t
movzwl
0x10(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,ds) */
output
(
"
\t
movl %%eax,0x98(%%esp)
\n
"
);
/* SegDs */
output
(
"
\t
movzwl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
es
)
);
output
(
"
\t
movzwl
0x12(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,es) */
output
(
"
\t
movl %%eax,0x94(%%esp)
\n
"
);
/* SegEs */
output
(
"
\t
movzwl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
fs
)
);
output
(
"
\t
movzwl
0x14(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,fs) */
output
(
"
\t
movl %%eax,0x90(%%esp)
\n
"
);
/* SegFs */
output
(
"
\t
movzwl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
gs
)
);
output
(
"
\t
movzwl
0x16(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,gs) */
output
(
"
\t
movl %%eax,0x8c(%%esp)
\n
"
);
/* SegGs */
output
(
"
\t
movzwl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
cs
)
);
output
(
"
\t
movzwl
0x2e(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,cs) */
output
(
"
\t
movl %%eax,0xbc(%%esp)
\n
"
);
/* SegCs */
output
(
"
\t
movzwl
%d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
output
(
"
\t
movzwl
0x2c(%%edx),%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,ip) */
output
(
"
\t
movl %%eax,0xb8(%%esp)
\n
"
);
/* Eip */
output
(
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
+
2
);
output
(
"
\t
movl %%eax,0xc8(%%esp)
\n
"
);
/* SegSs */
output
(
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
);
output
(
"
\t
addl $
%d, %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
output
(
"
\t
addl $
0x2c,%%eax
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,ip) */
output
(
"
\t
movl %%eax,0xc4(%%esp)
\n
"
);
/* Esp */
#if 0
output( "\tfsave 0x1c(%%esp)\n" ); /* FloatSave */
...
...
@@ -294,14 +285,14 @@ static void BuildCallFrom16Core( int reg_func, int thunk )
}
/* Call relay routine (which will call the API entry point) */
output
(
"
\t
leal
%d(%%edx), %%eax
\n
"
,
(
int
)
sizeof
(
STACK16FRAME
)
);
output
(
"
\t
leal
0x30(%%edx),%%eax
\n
"
);
/* sizeof(STACK16FRAME) */
output
(
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
pushl
%d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
output
(
"
\t
call *
%d(%%edx)
\n
"
,
STACK16OFFSET
(
relay
)
);
output
(
"
\t
pushl
0x26(%%edx)
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,entry_point) */
output
(
"
\t
call *
0x20(%%edx)
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,relay) */
if
(
reg_func
)
{
output
(
"
\t
leal -
%d(%%ebp), %%ebx
\n
"
,
(
int
)
sizeof
(
CONTEXT
)
+
STACK32OFFSET
(
ebp
)
);
output
(
"
\t
leal -
748(%%ebp),%%ebx
\n
"
);
/* sizeof(CONTEXT) + FIELD_OFFSET(STACK32FRAME,ebp) */
/* Switch stack back */
output
(
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
...
...
@@ -309,7 +300,7 @@ static void BuildCallFrom16Core( int reg_func, int thunk )
output
(
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
/* Get return address to CallFrom16 stub */
output
(
"
\t
addw $
%d, %%sp
\n
"
,
STACK16OFFSET
(
callfrom_ip
)
-
4
);
output
(
"
\t
addw $
0x14,%%sp
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,callfrom_ip)-4 */
output
(
"
\t
popl %%eax
\n
"
);
output
(
"
\t
popl %%edx
\n
"
);
...
...
@@ -439,7 +430,7 @@ static void BuildCallTo16Core( int reg_func )
* at the cost of a somewhat less efficient return path.]
*/
output
(
"
\t
movl
%d(%%esp), %%edi
\n
"
,
STACK32OFFSET
(
target
)
-
STACK32OFFSET
(
edi
));
output
(
"
\t
movl
0x14(%%esp),%%edi
\n
"
);
/* FIELD_OFFSET(STACK32FRAME,target) - FIELD_OFFSET(STACK32FRAME,edi) */
/* everything above edi has been popped already */
output
(
"
\t
movl %%eax,0xb0(%%edi)
\n
"
);
/* Eax */
...
...
@@ -473,15 +464,15 @@ static void BuildCallTo16Core( int reg_func )
/* Make %bp point to the previous stackframe (built by CallFrom16) */
output
(
"
\t
movzwl %%sp,%%ebp
\n
"
);
output
(
"
\t
leal
%d(%%ebp),%%ebp
\n
"
,
STACK16OFFSET
(
bp
)
);
output
(
"
\t
leal
0x2a(%%ebp),%%ebp
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,bp) */
/* Add the specified offset to the new sp */
output
(
"
\t
subw
%d(%%edx), %%sp
\n
"
,
STACK32OFFSET
(
nb_args
)
);
output
(
"
\t
subw
0x2c(%%edx), %%sp
\n
"
);
/* FIELD_OFFSET(STACK32FRAME,nb_args) */
if
(
reg_func
)
{
/* Push the called routine address */
output
(
"
\t
movl
%d(%%edx),%%edx
\n
"
,
STACK32OFFSET
(
target
)
);
output
(
"
\t
movl
0x28(%%edx),%%edx
\n
"
);
/* FIELD_OFFSET(STACK32FRAME,target) */
output
(
"
\t
pushw 0xbc(%%edx)
\n
"
);
/* SegCs */
output
(
"
\t
pushw 0xb8(%%edx)
\n
"
);
/* Eip */
...
...
@@ -507,12 +498,12 @@ static void BuildCallTo16Core( int reg_func )
else
/* not a register function */
{
/* Push the called routine address */
output
(
"
\t
pushl
%d(%%edx)
\n
"
,
STACK32OFFSET
(
target
)
);
output
(
"
\t
pushl
0x28(%%edx)
\n
"
);
/* FIELD_OFFSET(STACK32FRAME,target) */
/* Set %fs and %gs to the value saved by the last CallFrom16 */
output
(
"
\t
pushw
%d(%%ebp)
\n
"
,
STACK16OFFSET
(
fs
)
-
STACK16OFFSET
(
bp
)
);
output
(
"
\t
pushw
-22(%%ebp)
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,fs)-FIELD_OFFSET(STACK16FRAME,bp) */
output
(
"
\t
popw %%fs
\n
"
);
output
(
"
\t
pushw
%d(%%ebp)
\n
"
,
STACK16OFFSET
(
gs
)
-
STACK16OFFSET
(
bp
)
);
output
(
"
\t
pushw
-20(%%ebp)
\n
"
);
/* FIELD_OFFSET(STACK16FRAME,gs)-FIELD_OFFSET(STACK16FRAME,bp) */
output
(
"
\t
popw %%gs
\n
"
);
/* Set %ds and %es (and %ax just in case) equal to %ss */
...
...
@@ -758,7 +749,7 @@ static void BuildCallTo32CBClient( BOOL isEx )
*/
static
void
BuildCallFrom32Regs
(
void
)
{
static
const
int
STACK_SPACE
=
128
+
sizeof
(
CONTEXT86
)
;
static
const
int
STACK_SPACE
=
128
+
0x2cc
/* sizeof(CONTEXT86) */
;
/* Function header */
...
...
@@ -888,11 +879,9 @@ static void BuildPendingEventCheck(void)
/* Check for pending events. */
output
(
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
GdiTebBatch
)
+
STRUCTOFFSET
(
WINE_VM86_TEB_INFO
,
vm86_pending
)
);
output
(
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
VM86_PENDING_OFFSET
);
output
(
"
\t
je %s
\n
"
,
asm_name
(
"DPMI_PendingEventCheck_Cleanup"
)
);
output
(
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
GdiTebBatch
)
+
STRUCTOFFSET
(
WINE_VM86_TEB_INFO
,
dpmi_vif
)
);
output
(
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
DPMI_VIF_OFFSET
);
output
(
"
\t
je %s
\n
"
,
asm_name
(
"DPMI_PendingEventCheck_Cleanup"
)
);
/* Process pending events. */
...
...
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