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
89024a63
Commit
89024a63
authored
Sep 18, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make the users of wine_call_from_32_regs save %eax so that we don't
need a special hack in the import thunk. Added a get_pc_thunk_eax function to simplify the code a bit.
parent
66f603ce
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
69 additions
and
55 deletions
+69
-55
relay.c
dlls/ntdll/relay.c
+14
-13
port.h
include/wine/port.h
+1
-0
import.c
tools/winebuild/import.c
+23
-25
relay.c
tools/winebuild/relay.c
+8
-6
spec32.c
tools/winebuild/spec32.c
+23
-11
No files found.
dlls/ntdll/relay.c
View file @
89024a63
...
...
@@ -516,10 +516,11 @@ static LONGLONG RELAY_CallFrom32( int ret_addr, ... )
* Stack layout (esp is context->Esp, not the current %esp):
*
* ...
* (esp+4) first arg
* (esp) return addr to caller
* (esp-4) return addr to DEBUG_ENTRY_POINT
* (esp-8) ptr to relay entry code for RELAY_CallFrom32Regs
* (esp+4) first arg
* (esp) return addr to caller
* (esp-4) return addr to DEBUG_ENTRY_POINT
* (esp-8) saved %eax
* (esp-12) ptr to relay entry code for RELAY_CallFrom32Regs
* ... >128 bytes space free to be modified (ensured by the assembly glue)
*/
void
WINAPI
__regs_RELAY_CallFrom32Regs
(
CONTEXT86
*
context
)
...
...
@@ -541,7 +542,8 @@ void WINAPI __regs_RELAY_CallFrom32Regs( CONTEXT86 *context )
context
->
Esp
+=
nb_args
*
sizeof
(
int
);
entry_point
=
(
BYTE
*
)
relay
->
orig
;
assert
(
*
entry_point
==
0xe8
/* lcall */
);
assert
(
entry_point
[
0
]
==
0x50
/* pushl %eax */
);
assert
(
entry_point
[
1
]
==
0xe8
/* call */
);
if
(
TRACE_ON
(
relay
))
{
...
...
@@ -564,7 +566,7 @@ void WINAPI __regs_RELAY_CallFrom32Regs( CONTEXT86 *context )
memcpy
(
args_copy
,
args
,
nb_args
*
sizeof
(
args
[
0
])
);
args_copy
[
nb_args
]
=
(
int
)
context
;
/* append context argument */
call_entry_point
(
(
entry_point
+
5
+
*
(
DWORD
*
)(
entry_point
+
5
)),
nb_args
+
1
,
args_copy
);
call_entry_point
(
(
entry_point
+
6
+
*
(
DWORD
*
)(
entry_point
+
6
)),
nb_args
+
1
,
args_copy
);
if
(
TRACE_ON
(
relay
))
{
...
...
@@ -591,9 +593,10 @@ static BOOL is_register_entry_point( const BYTE *addr )
const
int
*
offset
;
const
void
*
ptr
;
if
(
*
addr
!=
0xe8
)
return
FALSE
;
/* not a call */
if
(
addr
[
0
]
!=
0x50
)
return
FALSE
;
/* pushl %eax */
if
(
addr
[
1
]
!=
0xe8
)
return
FALSE
;
/* call */
/* check if call target is __wine_call_from_32_regs */
offset
=
(
const
int
*
)(
addr
+
1
);
offset
=
(
const
int
*
)(
addr
+
2
);
if
(
*
offset
==
(
const
char
*
)
__wine_call_from_32_regs
-
(
const
char
*
)(
offset
+
1
))
return
TRUE
;
/* now check if call target is an import table jump to __wine_call_from_32_regs */
addr
=
(
const
BYTE
*
)(
offset
+
1
)
+
*
offset
;
...
...
@@ -606,11 +609,9 @@ static BOOL is_register_entry_point( const BYTE *addr )
}
else
/* check for import thunk */
{
if
(
addr
[
0
]
!=
0x50
)
return
FALSE
;
/* pushl %eax */
if
(
addr
[
1
]
!=
0xe8
||
addr
[
2
]
||
addr
[
3
]
||
addr
[
4
]
||
addr
[
5
])
return
FALSE
;
/* call .+0 */
if
(
addr
[
6
]
!=
0x58
)
return
FALSE
;
/* popl %eax */
if
(
addr
[
7
]
!=
0x8b
||
addr
[
8
]
!=
0x80
)
return
FALSE
;
/* movl offset(%eax),%eax */
ptr
=
addr
+
6
+
*
(
const
int
*
)(
addr
+
9
);
if
(
addr
[
0
]
!=
0xe8
)
return
FALSE
;
/* call get_pc_thunk */
if
(
addr
[
5
]
!=
0xff
||
addr
[
6
]
!=
0xa0
)
return
FALSE
;
/* jmp *offset(%eax) */
ptr
=
addr
+
5
+
*
(
const
int
*
)(
addr
+
7
);
}
return
(
*
(
const
char
*
const
*
)
ptr
==
(
char
*
)
__wine_call_from_32_regs
);
}
...
...
include/wine/port.h
View file @
89024a63
...
...
@@ -241,6 +241,7 @@ struct statvfs
#ifdef __i386__
#define DEFINE_REGS_ENTRYPOINT( name, args, pop_args ) \
__ASM_GLOBAL_FUNC( name, \
"pushl %eax\n\t" \
"call " __ASM_NAME("__wine_call_from_32_regs") "\n\t" \
".long " __ASM_NAME("__regs_") #name "-.\n\t" \
".byte " #args "," #pop_args )
...
...
tools/winebuild/import.c
View file @
89024a63
...
...
@@ -610,6 +610,21 @@ int resolve_imports( DLLSPEC *spec )
return
1
;
}
/* output the get_pc thunk if needed */
static
void
output_get_pc_thunk
(
FILE
*
outfile
)
{
if
(
target_cpu
!=
CPU_x86
)
return
;
if
(
!
UsePIC
)
return
;
fprintf
(
outfile
,
"
\n\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
output_function_size
(
outfile
,
"__wine_spec_get_pc_thunk_eax"
);
}
/* output a single import thunk */
static
void
output_import_thunk
(
FILE
*
outfile
,
const
char
*
name
,
const
char
*
table
,
int
pos
)
{
...
...
@@ -627,31 +642,15 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta
}
else
{
if
(
!
strcmp
(
name
,
"__wine_call_from_32_regs"
))
{
/* special case: need to preserve all registers */
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
call .L__wine_spec_%s
\n
"
,
name
);
fprintf
(
outfile
,
".L__wine_spec_%s:
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
if
(
!
strcmp
(
name
,
"__wine_call_from_16_regs"
))
fprintf
(
outfile
,
"
\t
.byte 0x2e
\n
"
);
fprintf
(
outfile
,
"
\t
movl %s+%d-.L__wine_spec_%s(%%eax),%%eax
\n
"
,
table
,
pos
,
name
);
fprintf
(
outfile
,
"
\t
xchgl %%eax,(%%esp)
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
}
else
if
(
!
strcmp
(
name
,
"__wine_call_from_16_regs"
))
if
(
!
strcmp
(
name
,
"__wine_call_from_16_regs"
))
{
/* special case: need to preserve all registers */
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
call
.L__wine_spec_%s
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
call
%s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
".L__wine_spec_%s:
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x2e
\n
"
);
fprintf
(
outfile
,
"
\t
movl %s+%d-.L__wine_spec_%s(%%eax),%%eax
\n
"
,
table
,
pos
,
name
);
fprintf
(
outfile
,
"1:
\t
.byte 0x2e
\n
"
);
fprintf
(
outfile
,
"
\t
movl %s+%d-1b(%%eax),%%eax
\n
"
,
table
,
pos
);
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x36
\n
"
);
fprintf
(
outfile
,
"
\t
xchgl %%eax,4(%%ecx)
\n
"
);
...
...
@@ -660,13 +659,11 @@ static void output_import_thunk( FILE *outfile, const char *name, const char *ta
}
else
{
fprintf
(
outfile
,
"
\t
call .L__wine_spec_%s
\n
"
,
name
);
fprintf
(
outfile
,
".L__wine_spec_%s:
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:"
);
if
(
strstr
(
name
,
"__wine_call_from_16"
))
fprintf
(
outfile
,
"
\t
.byte 0x2e
\n
"
);
fprintf
(
outfile
,
"
\t
jmp *%s+%d-.L__wine_spec_%s(%%eax)
\n
"
,
table
,
pos
,
name
);
fprintf
(
outfile
,
"
\t
jmp *%s+%d-1b(%%eax)
\n
"
,
table
,
pos
);
}
}
break
;
...
...
@@ -1129,4 +1126,5 @@ void output_imports( FILE *outfile, DLLSPEC *spec )
output_delayed_imports
(
outfile
,
spec
);
output_immediate_import_thunks
(
outfile
);
output_delayed_import_thunks
(
outfile
,
spec
);
if
(
nb_imports
||
has_stubs
(
spec
))
output_get_pc_thunk
(
outfile
);
}
tools/winebuild/relay.c
View file @
89024a63
...
...
@@ -736,8 +736,9 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
*
* Stack layout:
* ...
* (ebp+12) first arg
* (ebp+8) ret addr to user code
* (ebp+16) first arg
* (ebp+12) ret addr to user code
* (ebp+8) eax saved by relay code
* (ebp+4) ret addr to relay code
* (ebp+0) saved ebp
* (ebp-128) buffer area to allow stack frame manipulation
...
...
@@ -767,12 +768,13 @@ static void BuildCallFrom32Regs( FILE *outfile )
/* Build the context structure */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Eax
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
pushfl
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movl 0(%%ebp),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movl 4(%%ebp),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Eax
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movl %%ebx,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Ebx
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movl %%ecx,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Ecx
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movl %%edx,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Edx
)
-
STACK_SPACE
);
...
...
@@ -797,7 +799,7 @@ static void BuildCallFrom32Regs( FILE *outfile )
fprintf
(
outfile
,
"
\t
movl $0x%x,%%eax
\n
"
,
CONTEXT86_FULL
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
ContextFlags
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movl
8
(%%ebp),%%eax
\n
"
);
/* Get %eip at time of call */
fprintf
(
outfile
,
"
\t
movl
12
(%%ebp),%%eax
\n
"
);
/* Get %eip at time of call */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Eip
)
-
STACK_SPACE
);
/* Transfer the arguments */
...
...
@@ -807,14 +809,14 @@ static void BuildCallFrom32Regs( FILE *outfile )
fprintf
(
outfile
,
"
\t
movzbl 4(%%ebx),%%ecx
\n
"
);
/* fetch number of args to copy */
fprintf
(
outfile
,
"
\t
jecxz 1f
\n
"
);
fprintf
(
outfile
,
"
\t
subl %%ecx,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
leal 1
2
(%%ebp),%%esi
\n
"
);
/* get %esp at time of call */
fprintf
(
outfile
,
"
\t
leal 1
6
(%%ebp),%%esi
\n
"
);
/* get %esp at time of call */
fprintf
(
outfile
,
"
\t
movl %%esp,%%edi
\n
"
);
fprintf
(
outfile
,
"
\t
shrl $2,%%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
cld
\n
"
);
fprintf
(
outfile
,
"
\t
rep
\n\t
movsl
\n
"
);
/* copy args */
fprintf
(
outfile
,
"1:
\t
movzbl 5(%%ebx),%%eax
\n
"
);
/* fetch number of args to remove */
fprintf
(
outfile
,
"
\t
leal 1
2
(%%ebp,%%eax),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
leal 1
6
(%%ebp,%%eax),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Esp
)
-
STACK_SPACE
);
/* Call the entry point */
...
...
tools/winebuild/spec32.c
View file @
89024a63
...
...
@@ -292,21 +292,33 @@ static void output_stubs( FILE *outfile, DLLSPEC *spec )
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
asm_name
(
name
)
);
fprintf
(
outfile
,
"
\t
call .L__wine_stub_getpc_%d
\n
"
,
i
);
fprintf
(
outfile
,
".L__wine_stub_getpc_%d:
\n
"
,
i
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
if
(
exp_name
)
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
leal .L__wine_stub_strings+%d-.L__wine_stub_getpc_%d(%%eax),%%ecx
\n
"
,
pos
,
i
);
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:"
);
if
(
exp_name
)
{
fprintf
(
outfile
,
"
\t
leal .L__wine_stub_strings+%d-1b(%%eax),%%ecx
\n
"
,
pos
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
pos
+=
strlen
(
exp_name
)
+
1
;
}
else
fprintf
(
outfile
,
"
\t
pushl $%d
\n
"
,
odp
->
ordinal
);
fprintf
(
outfile
,
"
\t
leal %s-1b(%%eax),%%ecx
\n
"
,
asm_name
(
"__wine_spec_file_name"
)
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
pos
+=
strlen
(
exp_name
)
+
1
;
}
else
fprintf
(
outfile
,
"
\t
pushl $%d
\n
"
,
odp
->
ordinal
);
fprintf
(
outfile
,
"
\t
leal %s-.L__wine_stub_getpc_%d(%%eax),%%ecx
\n
"
,
asm_name
(
"__wine_spec_file_name"
),
i
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
{
if
(
exp_name
)
{
fprintf
(
outfile
,
"
\t
pushl $.L__wine_stub_strings+%d
\n
"
,
pos
);
pos
+=
strlen
(
exp_name
)
+
1
;
}
else
fprintf
(
outfile
,
"
\t
pushl $%d
\n
"
,
odp
->
ordinal
);
fprintf
(
outfile
,
"
\t
pushl $%s
\n
"
,
asm_name
(
"__wine_spec_file_name"
)
);
}
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_unimplemented_stub"
)
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_size
(
name
)
);
}
...
...
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