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
e0188c83
Commit
e0188c83
authored
Aug 30, 2010
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winebuild: Use a proper enum for function arguments instead of storing them in a string.
parent
2a5b3755
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
183 additions
and
99 deletions
+183
-99
build.h
tools/winebuild/build.h
+19
-1
parser.c
tools/winebuild/parser.c
+42
-42
spec16.c
tools/winebuild/spec16.c
+91
-50
spec32.c
tools/winebuild/spec32.c
+11
-6
utils.c
tools/winebuild/utils.c
+20
-0
No files found.
tools/winebuild/build.h
View file @
e0188c83
...
...
@@ -58,6 +58,22 @@ typedef enum
SPEC_WIN32
}
SPEC_TYPE
;
enum
arg_type
{
ARG_WORD
,
/* 16-bit word */
ARG_SWORD
,
/* 16-bit signed word */
ARG_SEGPTR
,
/* segmented pointer */
ARG_SEGSTR
,
/* segmented pointer to Ansi string */
ARG_LONG
,
/* long */
ARG_PTR
,
/* pointer */
ARG_STR
,
/* pointer to Ansi string */
ARG_WSTR
,
/* pointer to Unicode string */
ARG_DOUBLE
,
/* floating point double */
ARG_MAXARG
=
ARG_DOUBLE
};
#define MAX_ARGUMENTS 32
typedef
struct
{
int
n_values
;
...
...
@@ -66,7 +82,8 @@ typedef struct
typedef
struct
{
char
arg_types
[
21
];
unsigned
int
nb_args
;
enum
arg_type
args
[
MAX_ARGUMENTS
];
}
ORD_FUNCTION
;
typedef
struct
...
...
@@ -244,6 +261,7 @@ extern enum target_cpu get_cpu_from_name( const char *name );
extern
unsigned
int
get_alignment
(
unsigned
int
align
);
extern
unsigned
int
get_page_size
(
void
);
extern
unsigned
int
get_ptr_size
(
void
);
extern
unsigned
int
get_args_size
(
const
ORDDEF
*
odp
);
extern
const
char
*
asm_name
(
const
char
*
func
);
extern
const
char
*
func_declaration
(
const
char
*
func
);
extern
const
char
*
asm_globl
(
const
char
*
func
);
...
...
tools/winebuild/parser.c
View file @
e0188c83
...
...
@@ -72,6 +72,19 @@ static const char * const FlagNames[] =
NULL
};
static
const
char
*
const
ArgNames
[
ARG_MAXARG
+
1
]
=
{
"word"
,
/* ARG_WORD */
"s_word"
,
/* ARG_SWORD */
"segptr"
,
/* ARG_SEGPTR */
"segstr"
,
/* ARG_SEGSTR */
"long"
,
/* ARG_LONG */
"ptr"
,
/* ARG_PTR */
"str"
,
/* ARG_STR */
"wstr"
,
/* ARG_WSTR */
"double"
/* ARG_DOUBLE */
};
static
int
IsNumberString
(
const
char
*
s
)
{
while
(
*
s
)
if
(
!
isdigit
(
*
s
++
))
return
0
;
...
...
@@ -228,7 +241,7 @@ static int parse_spec_variable( ORDDEF *odp, DLLSPEC *spec )
static
int
parse_spec_export
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
{
const
char
*
token
;
unsigned
int
i
;
unsigned
int
i
,
arg
;
int
is_win32
=
(
spec
->
type
==
SPEC_WIN32
)
||
(
odp
->
flags
&
FLAG_EXPORT32
);
if
(
!
is_win32
&&
odp
->
type
==
TYPE_STDCALL
)
...
...
@@ -254,61 +267,42 @@ static int parse_spec_export( ORDDEF *odp, DLLSPEC *spec )
return
0
;
}
for
(
i
=
0
;
i
<
sizeof
(
odp
->
u
.
func
.
arg_types
);
i
++
)
odp
->
u
.
func
.
nb_args
=
0
;
for
(
i
=
0
;
i
<
MAX_ARGUMENTS
;
i
++
)
{
if
(
!
(
token
=
GetToken
(
0
)))
return
0
;
if
(
*
token
==
')'
)
break
;
if
(
!
strcmp
(
token
,
"word"
))
odp
->
u
.
func
.
arg_types
[
i
]
=
'w'
;
else
if
(
!
strcmp
(
token
,
"s_word"
))
odp
->
u
.
func
.
arg_types
[
i
]
=
's'
;
else
if
(
!
strcmp
(
token
,
"long"
)
||
!
strcmp
(
token
,
"segptr"
))
odp
->
u
.
func
.
arg_types
[
i
]
=
'l'
;
else
if
(
!
strcmp
(
token
,
"ptr"
))
odp
->
u
.
func
.
arg_types
[
i
]
=
'p'
;
else
if
(
!
strcmp
(
token
,
"str"
))
odp
->
u
.
func
.
arg_types
[
i
]
=
't'
;
else
if
(
!
strcmp
(
token
,
"wstr"
))
odp
->
u
.
func
.
arg_types
[
i
]
=
'W'
;
else
if
(
!
strcmp
(
token
,
"segstr"
))
odp
->
u
.
func
.
arg_types
[
i
]
=
'T'
;
else
if
(
!
strcmp
(
token
,
"double"
))
{
odp
->
u
.
func
.
arg_types
[
i
++
]
=
'l'
;
if
(
get_ptr_size
()
==
4
&&
i
<
sizeof
(
odp
->
u
.
func
.
arg_types
))
odp
->
u
.
func
.
arg_types
[
i
]
=
'l'
;
}
else
for
(
arg
=
0
;
arg
<=
ARG_MAXARG
;
arg
++
)
if
(
!
strcmp
(
ArgNames
[
arg
],
token
))
break
;
if
(
arg
>
ARG_MAXARG
)
{
error
(
"Unknown argument type '%s'
\n
"
,
token
);
return
0
;
}
if
(
is_win32
)
if
(
is_win32
)
switch
(
arg
)
{
if
(
strcmp
(
token
,
"long"
)
&&
strcmp
(
token
,
"ptr"
)
&&
strcmp
(
token
,
"str"
)
&&
strcmp
(
token
,
"wstr"
)
&&
strcmp
(
token
,
"double"
))
{
error
(
"Type '%s' not supported for Win32 function
\n
"
,
token
);
return
0
;
}
case
ARG_WORD
:
case
ARG_SWORD
:
case
ARG_SEGPTR
:
case
ARG_SEGSTR
:
error
(
"Argument type '%s' only allowed for Win16
\n
"
,
token
);
return
0
;
}
odp
->
u
.
func
.
args
[
i
]
=
arg
;
}
if
(
(
*
token
!=
')'
)
||
(
i
>=
sizeof
(
odp
->
u
.
func
.
arg_types
))
)
if
(
*
token
!=
')'
)
{
error
(
"Too many arguments
\n
"
);
return
0
;
}
odp
->
u
.
func
.
arg_types
[
i
]
=
'\0'
;
odp
->
u
.
func
.
nb_args
=
i
;
if
(
odp
->
type
==
TYPE_VARARGS
)
odp
->
flags
|=
FLAG_NORELAY
;
/* no relay debug possible for varags entry point */
if
(
odp
->
type
==
TYPE_THISCALL
&&
odp
->
u
.
func
.
arg_types
[
0
]
!=
'p'
)
if
(
odp
->
type
==
TYPE_THISCALL
&&
(
!
i
||
odp
->
u
.
func
.
args
[
0
]
!=
ARG_PTR
)
)
{
error
(
"First argument of a thiscall function must be a pointer
\n
"
);
return
0
;
...
...
@@ -386,7 +380,7 @@ static int parse_spec_equate( ORDDEF *odp, DLLSPEC *spec )
*/
static
int
parse_spec_stub
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
{
odp
->
u
.
func
.
arg_types
[
0
]
=
'\0'
;
odp
->
u
.
func
.
nb_args
=
0
;
odp
->
link_name
=
xstrdup
(
""
);
odp
->
flags
|=
FLAG_CPU
(
CPU_x86
)
|
FLAG_CPU
(
CPU_x86_64
);
/* don't bother generating stubs for Winelib */
return
1
;
...
...
@@ -806,7 +800,8 @@ void add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 )
odp
->
lineno
=
odp16
->
lineno
;
odp
->
ordinal
=
-
1
;
odp
->
link_name
=
xstrdup
(
odp16
->
link_name
);
strcpy
(
odp
->
u
.
func
.
arg_types
,
odp16
->
u
.
func
.
arg_types
);
odp
->
u
.
func
.
nb_args
=
odp16
->
u
.
func
.
nb_args
;
memcpy
(
odp
->
u
.
func
.
args
,
odp16
->
u
.
func
.
args
,
odp
->
u
.
func
.
nb_args
*
sizeof
(
odp
->
u
.
func
.
args
[
0
])
);
}
assign_names
(
spec32
);
...
...
@@ -936,18 +931,23 @@ static int parse_def_export( char *name, DLLSPEC *spec )
odp
->
ordinal
=
-
1
;
odp
->
name
=
name
;
args
=
remove_stdcall_decoration
(
odp
->
name
);
if
(
args
==
-
1
)
odp
->
type
=
TYPE_CDECL
;
if
(
args
==
-
1
)
{
odp
->
type
=
TYPE_CDECL
;
args
=
0
;
}
else
{
odp
->
type
=
TYPE_STDCALL
;
args
/=
get_ptr_size
();
if
(
args
>=
sizeof
(
odp
->
u
.
func
.
arg_types
)
)
if
(
args
>=
MAX_ARGUMENTS
)
{
error
(
"Too many arguments in stdcall function '%s'
\n
"
,
odp
->
name
);
return
0
;
}
for
(
i
=
0
;
i
<
args
;
i
++
)
odp
->
u
.
func
.
arg
_types
[
i
]
=
'l'
;
for
(
i
=
0
;
i
<
args
;
i
++
)
odp
->
u
.
func
.
arg
s
[
i
]
=
ARG_LONG
;
}
odp
->
u
.
func
.
nb_args
=
args
;
/* check for optional internal name */
...
...
tools/winebuild/spec16.c
View file @
e0188c83
...
...
@@ -36,14 +36,14 @@
/* argument type flags for relay debugging */
enum
arg_types
{
ARG_NONE
=
0
,
/* indicates end of arg list */
ARG_WORD
,
/* unsigned word */
ARG_SWORD
,
/* signed word */
ARG_LONG
,
/* long or segmented pointer */
ARG_PTR
,
/* linear pointer */
ARG_STR
,
/* linear pointer to null-terminated string */
ARG_SEGSTR
,
/* segmented pointer to null-terminated string */
ARG_VARARG
/* start of varargs */
ARG
16
_NONE
=
0
,
/* indicates end of arg list */
ARG
16
_WORD
,
/* unsigned word */
ARG
16
_SWORD
,
/* signed word */
ARG
16
_LONG
,
/* long or segmented pointer */
ARG
16
_PTR
,
/* linear pointer */
ARG
16
_STR
,
/* linear pointer to null-terminated string */
ARG
16
_SEGSTR
,
/* segmented pointer to null-terminated string */
ARG
16
_VARARG
/* start of varargs */
};
/* sequences of nops to fill a certain number of words */
...
...
@@ -64,6 +64,30 @@ static inline int is_function( const ORDDEF *odp )
odp
->
type
==
TYPE_STUB
);
}
static
const
char
*
get_args_str
(
const
ORDDEF
*
odp
)
{
static
char
buffer
[
MAX_ARGUMENTS
*
2
+
1
];
unsigned
int
i
;
buffer
[
0
]
=
0
;
for
(
i
=
0
;
i
<
odp
->
u
.
func
.
nb_args
;
i
++
)
{
switch
(
odp
->
u
.
func
.
args
[
i
])
{
case
ARG_WORD
:
strcat
(
buffer
,
"w"
);
break
;
case
ARG_SWORD
:
strcat
(
buffer
,
"s"
);
break
;
case
ARG_SEGSTR
:
strcat
(
buffer
,
"T"
);
break
;
case
ARG_STR
:
strcat
(
buffer
,
"t"
);
break
;
case
ARG_DOUBLE
:
strcat
(
buffer
,
"ll"
);
break
;
case
ARG_LONG
:
case
ARG_SEGPTR
:
strcat
(
buffer
,
"l"
);
break
;
case
ARG_PTR
:
case
ARG_WSTR
:
strcat
(
buffer
,
"p"
);
break
;
}
}
return
buffer
;
}
/*******************************************************************
* output_entries
*
...
...
@@ -203,7 +227,7 @@ static const char *get_callfrom16_name( const ORDDEF *odp )
(
odp
->
type
==
TYPE_VARARGS
)
?
"v"
:
"c"
,
(
odp
->
flags
&
FLAG_REGISTER
)
?
"regs"
:
(
odp
->
flags
&
FLAG_RET16
)
?
"word"
:
"long"
,
odp
->
u
.
func
.
arg_types
);
get_args_str
(
odp
)
);
return
buffer
;
}
...
...
@@ -231,7 +255,7 @@ static const char *get_relay_name( const ORDDEF *odp )
default:
assert
(
0
);
}
strcat
(
buffer
,
odp
->
u
.
func
.
arg_types
);
strcat
(
buffer
,
get_args_str
(
odp
)
);
for
(
p
=
buffer
+
2
;
*
p
;
p
++
)
{
/* map string types to the corresponding plain pointer type */
...
...
@@ -248,25 +272,27 @@ static const char *get_relay_name( const ORDDEF *odp )
*/
static
int
get_function_argsize
(
const
ORDDEF
*
odp
)
{
const
char
*
args
;
int
argsize
=
0
;
unsigned
int
i
,
argsize
=
0
;
for
(
args
=
odp
->
u
.
func
.
arg_types
;
*
args
;
args
++
)
for
(
i
=
0
;
i
<
odp
->
u
.
func
.
nb_args
;
i
++
)
{
switch
(
*
args
)
switch
(
odp
->
u
.
func
.
args
[
i
]
)
{
case
'w'
:
/* word */
case
's'
:
/* s_word */
case
ARG_WORD
:
case
ARG_SWORD
:
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 */
case
ARG_SEGPTR
:
case
ARG_SEGSTR
:
case
ARG_LONG
:
case
ARG_PTR
:
case
ARG_STR
:
case
ARG_WSTR
:
argsize
+=
4
;
break
;
default:
assert
(
0
);
case
ARG_DOUBLE
:
argsize
+=
8
;
break
;
}
}
return
argsize
;
...
...
@@ -304,9 +330,8 @@ static void output_call16_function( ORDDEF *odp )
{
char
*
name
;
int
i
,
pos
,
stack_words
;
const
char
*
args
=
odp
->
u
.
func
.
arg_types
;
int
argsize
=
get_function_argsize
(
odp
);
int
needs_ldt
=
strchr
(
args
,
'p'
)
||
strchr
(
args
,
't'
);
int
needs_ldt
=
(
strpbrk
(
get_args_str
(
odp
),
"pt"
)
!=
NULL
);
name
=
strmake
(
".L__wine_spec_call16_%s"
,
get_relay_name
(
odp
)
);
...
...
@@ -335,11 +360,13 @@ static void output_call16_function( ORDDEF *odp )
}
/* preserve 16-byte stack alignment */
stack_words
+=
strlen
(
args
);
stack_words
+=
odp
->
u
.
func
.
nb_args
;
for
(
i
=
0
;
i
<
odp
->
u
.
func
.
nb_args
;
i
++
)
if
(
odp
->
u
.
func
.
args
[
i
]
==
ARG_DOUBLE
)
stack_words
++
;
if
((
odp
->
flags
&
FLAG_REGISTER
)
||
(
odp
->
type
==
TYPE_VARARGS
))
stack_words
++
;
if
(
stack_words
%
4
)
output
(
"
\t
subl $%d,%%esp
\n
"
,
16
-
4
*
(
stack_words
%
4
)
);
if
(
args
[
0
]
||
odp
->
type
==
TYPE_VARARGS
)
if
(
odp
->
u
.
func
.
nb_args
||
odp
->
type
==
TYPE_VARARGS
)
output
(
"
\t
movl 12(%%ebp),%%ecx
\n
"
);
/* args */
if
(
odp
->
flags
&
FLAG_REGISTER
)
...
...
@@ -353,33 +380,40 @@ static void output_call16_function( ORDDEF *odp )
}
pos
=
(
odp
->
type
==
TYPE_PASCAL
)
?
0
:
argsize
;
for
(
i
=
strlen
(
args
)
-
1
;
i
>=
0
;
i
--
)
for
(
i
=
odp
->
u
.
func
.
nb_args
-
1
;
i
>=
0
;
i
--
)
{
switch
(
args
[
i
])
switch
(
odp
->
u
.
func
.
args
[
i
])
{
case
'w'
:
/* word */
case
ARG_WORD
:
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
2
;
output
(
"
\t
movzwl %d(%%ecx),%%eax
\n
"
,
pos
);
output
(
"
\t
pushl %%eax
\n
"
);
if
(
odp
->
type
==
TYPE_PASCAL
)
pos
+=
2
;
break
;
case
's'
:
/* s_word */
case
ARG_SWORD
:
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
2
;
output
(
"
\t
movswl %d(%%ecx),%%eax
\n
"
,
pos
);
output
(
"
\t
pushl %%eax
\n
"
);
if
(
odp
->
type
==
TYPE_PASCAL
)
pos
+=
2
;
break
;
case
'l'
:
/* long or segmented pointer */
case
'T'
:
/* segmented pointer to null-terminated string */
case
ARG_DOUBLE
:
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
4
;
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
pos
);
if
(
odp
->
type
==
TYPE_PASCAL
)
pos
+=
4
;
/* fall through */
case
ARG_LONG
:
case
ARG_SEGPTR
:
case
ARG_SEGSTR
:
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
4
;
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
pos
);
if
(
odp
->
type
==
TYPE_PASCAL
)
pos
+=
4
;
break
;
case
'p'
:
/* linear pointer */
case
't'
:
/* linear pointer to null-terminated string */
case
ARG_PTR
:
case
ARG_STR
:
case
ARG_WSTR
:
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
4
;
output
(
"
\t
movzwl %d(%%ecx),%%edx
\n
"
,
pos
+
2
);
/* sel */
output
(
"
\t
shr $3,%%edx
\n
"
);
...
...
@@ -388,9 +422,6 @@ static void output_call16_function( ORDDEF *odp )
output
(
"
\t
pushl %%eax
\n
"
);
if
(
odp
->
type
==
TYPE_PASCAL
)
pos
+=
4
;
break
;
default:
assert
(
0
);
}
}
...
...
@@ -423,6 +454,7 @@ static int callfrom16_type_compare( const void *e1, const void *e2 )
int
retval
;
int
type1
=
odp1
->
type
;
int
type2
=
odp2
->
type
;
char
args1
[
80
];
if
(
type1
==
TYPE_STUB
)
type1
=
TYPE_CDECL
;
if
(
type2
==
TYPE_STUB
)
type2
=
TYPE_CDECL
;
...
...
@@ -434,7 +466,8 @@ static int callfrom16_type_compare( const void *e1, const void *e2 )
if
((
retval
=
type1
-
type2
)
!=
0
)
return
retval
;
return
strcmp
(
odp1
->
u
.
func
.
arg_types
,
odp2
->
u
.
func
.
arg_types
);
strcpy
(
args1
,
get_args_str
(
odp1
));
return
strcmp
(
args1
,
get_args_str
(
odp2
));
}
...
...
@@ -504,7 +537,7 @@ static void output_module16( DLLSPEC *spec )
entry_point
->
name
=
NULL
;
entry_point
->
link_name
=
xstrdup
(
spec
->
init_func
);
entry_point
->
export_name
=
NULL
;
entry_point
->
u
.
func
.
arg_types
[
0
]
=
0
;
entry_point
->
u
.
func
.
nb_args
=
0
;
assert
(
!
spec
->
ordinals
[
0
]
);
spec
->
ordinals
[
0
]
=
entry_point
;
}
...
...
@@ -654,28 +687,36 @@ static void output_module16( DLLSPEC *spec )
for
(
i
=
0
;
i
<
nb_funcs
;
i
++
)
{
unsigned
int
arg_types
[
2
];
int
nop_words
,
argsize
=
0
;
int
nop_words
,
pos
,
argsize
=
0
;
if
(
typelist
[
i
]
->
type
==
TYPE_PASCAL
)
argsize
=
get_function_argsize
(
typelist
[
i
]
);
/* build the arg types bit fields */
arg_types
[
0
]
=
arg_types
[
1
]
=
0
;
for
(
j
=
0
;
typelist
[
i
]
->
u
.
func
.
arg_types
[
j
];
j
++
)
for
(
j
=
pos
=
0
;
j
<
typelist
[
i
]
->
u
.
func
.
nb_args
&&
pos
<
20
;
j
++
,
pos
++
)
{
int
type
=
0
;
switch
(
typelist
[
i
]
->
u
.
func
.
arg_type
s
[
j
])
switch
(
typelist
[
i
]
->
u
.
func
.
arg
s
[
j
])
{
case
'w'
:
type
=
ARG_WORD
;
break
;
case
's'
:
type
=
ARG_SWORD
;
break
;
case
'l'
:
type
=
ARG_LONG
;
break
;
case
'p'
:
type
=
ARG_PTR
;
break
;
case
't'
:
type
=
ARG_STR
;
break
;
case
'T'
:
type
=
ARG_SEGSTR
;
break
;
case
ARG_WORD
:
type
=
ARG16_WORD
;
break
;
case
ARG_SWORD
:
type
=
ARG16_SWORD
;
break
;
case
ARG_SEGPTR
:
type
=
ARG16_LONG
;
break
;
case
ARG_SEGSTR
:
type
=
ARG16_SEGSTR
;
break
;
case
ARG_LONG
:
type
=
ARG16_LONG
;
break
;
case
ARG_PTR
:
type
=
ARG16_PTR
;
break
;
case
ARG_STR
:
type
=
ARG16_STR
;
break
;
case
ARG_WSTR
:
type
=
ARG16_PTR
;
break
;
case
ARG_DOUBLE
:
type
=
ARG16_LONG
;
arg_types
[
pos
/
10
]
|=
type
<<
(
3
*
(
pos
%
10
));
pos
++
;
break
;
}
arg_types
[
j
/
10
]
|=
type
<<
(
3
*
(
j
%
10
));
if
(
pos
<
20
)
arg_types
[
pos
/
10
]
|=
type
<<
(
3
*
(
pos
%
10
));
}
if
(
typelist
[
i
]
->
type
==
TYPE_VARARGS
)
arg_types
[
j
/
10
]
|=
ARG_VARARG
<<
(
3
*
(
j
%
10
));
if
(
typelist
[
i
]
->
type
==
TYPE_VARARGS
&&
pos
<
20
)
arg_types
[
pos
/
10
]
|=
ARG16_VARARG
<<
(
3
*
(
pos
%
10
));
output
(
".L__wine_spec_callfrom16_%s:
\n
"
,
get_callfrom16_name
(
typelist
[
i
])
);
output
(
"
\t
pushl $.L__wine_spec_call16_%s
\n
"
,
get_relay_name
(
typelist
[
i
])
);
...
...
tools/winebuild/spec32.c
View file @
e0188c83
...
...
@@ -81,7 +81,7 @@ int has_relays( DLLSPEC *spec )
static
void
output_relay_debug
(
DLLSPEC
*
spec
)
{
int
i
;
unsigned
int
j
,
args
,
flags
;
unsigned
int
j
,
pos
,
args
,
flags
;
/* first the table of entry point offsets */
...
...
@@ -111,10 +111,15 @@ static void output_relay_debug( DLLSPEC *spec )
if
(
needs_relay
(
odp
))
{
for
(
j
=
0
;
j
<
16
&&
odp
->
u
.
func
.
arg_types
[
j
]
;
j
++
)
for
(
j
=
pos
=
0
;
pos
<
16
&&
j
<
odp
->
u
.
func
.
nb_args
;
j
++
)
{
if
(
odp
->
u
.
func
.
arg_types
[
j
]
==
't'
)
mask
|=
1
<<
(
j
*
2
);
if
(
odp
->
u
.
func
.
arg_types
[
j
]
==
'W'
)
mask
|=
2
<<
(
j
*
2
);
switch
(
odp
->
u
.
func
.
args
[
j
])
{
case
ARG_STR
:
mask
|=
1
<<
(
2
*
pos
++
);
break
;
case
ARG_WSTR
:
mask
|=
2
<<
(
2
*
pos
++
);
break
;
case
ARG_DOUBLE
:
pos
+=
8
/
get_ptr_size
();
break
;
default:
pos
++
;
break
;
}
}
}
output
(
"
\t
.long 0x%08x
\n
"
,
mask
);
...
...
@@ -135,7 +140,7 @@ static void output_relay_debug( DLLSPEC *spec )
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
".L__wine_spec_relay_entry_point_%d:
\n
"
,
i
);
args
=
strlen
(
odp
->
u
.
func
.
arg_types
);
args
=
get_args_size
(
odp
)
/
get_ptr_size
(
);
flags
=
0
;
switch
(
target_cpu
)
...
...
@@ -831,7 +836,7 @@ void output_def_file( DLLSPEC *spec, int include_private )
break
;
case
TYPE_STDCALL
:
{
int
at_param
=
strlen
(
odp
->
u
.
func
.
arg_types
)
*
get_ptr_size
(
);
int
at_param
=
get_args_size
(
odp
);
if
(
!
kill_at
&&
target_cpu
==
CPU_x86
)
output
(
"@%d"
,
at_param
);
if
(
odp
->
flags
&
FLAG_FORWARD
)
{
...
...
tools/winebuild/utils.c
View file @
e0188c83
...
...
@@ -890,6 +890,26 @@ unsigned int get_ptr_size(void)
return
0
;
}
/* return the total size in bytes of the arguments on the stack */
unsigned
int
get_args_size
(
const
ORDDEF
*
odp
)
{
unsigned
int
i
,
size
;
for
(
i
=
size
=
0
;
i
<
odp
->
u
.
func
.
nb_args
;
i
++
)
{
switch
(
odp
->
u
.
func
.
args
[
i
])
{
case
ARG_DOUBLE
:
size
+=
8
;
break
;
default:
size
+=
get_ptr_size
();
break
;
}
}
return
size
;
}
/* return the assembly name for a C symbol */
const
char
*
asm_name
(
const
char
*
sym
)
{
...
...
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