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
492ac292
Commit
492ac292
authored
Feb 17, 2004
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for building a dll from a .def file for cases where we
don't want to write a full .spec. Renamed --spec option to --dll for consistency.
parent
14743a0f
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
510 additions
and
307 deletions
+510
-307
Make.rules.in
Make.rules.in
+1
-1
Makedll.rules.in
dlls/Makedll.rules.in
+1
-1
Makefile.in
dlls/gdi/Makefile.in
+1
-1
Makefile.in
dlls/kernel/Makefile.in
+1
-1
Makefile.in
dlls/shell32/Makefile.in
+2
-2
Makefile.in
dlls/user/Makefile.in
+3
-3
build.h
tools/winebuild/build.h
+7
-3
import.c
tools/winebuild/import.c
+85
-197
main.c
tools/winebuild/main.c
+41
-43
parser.c
tools/winebuild/parser.c
+284
-49
utils.c
tools/winebuild/utils.c
+77
-0
winebuild.man.in
tools/winebuild/winebuild.man.in
+7
-6
No files found.
Make.rules.in
View file @
492ac292
...
...
@@ -129,7 +129,7 @@ LINTS = $(C_SRCS:.c=.ln)
$(WINDRES) -i $< -o $@
.spec.spec.c:
$(WINEBUILD) $(DEFS) -o $@ --main-module $(MODULE) --
spec
$<
$(WINEBUILD) $(DEFS) -o $@ --main-module $(MODULE) --
dll
$<
.spec.spec.def:
$(WINEBUILD) $(DEFS) -o $@ --def $<
...
...
dlls/Makedll.rules.in
View file @
492ac292
...
...
@@ -27,7 +27,7 @@ all: $(MODULE)$(DLLEXT) $(SUBDIRS)
# Rules for .so files
$(MAINSPEC).c: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) $(WINEBUILD)
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --
spec
$(SRCDIR)/$(MAINSPEC) $(DLLMODE:%=--mode %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
$(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --
dll
$(SRCDIR)/$(MAINSPEC) $(DLLMODE:%=--mode %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
$(MODULE).so: $(MAINSPEC).o $(ALL_OBJS) Makefile.in
$(LDDLL) $(MAINSPEC).o $(ALL_OBJS) -o $@ -L$(DLLDIR) $(ALL_LIBS) -lc
...
...
dlls/gdi/Makefile.in
View file @
492ac292
...
...
@@ -76,7 +76,7 @@ EXTRASUBDIRS = \
# Special rules for 16-bit resource and spec files
gdi.exe.spec.c
:
gdi.exe.spec version16.res
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--heap
65520
--main-module
$(MODULE)
--res
version16.res
--
spec
$(SRCDIR)
/gdi.exe.spec
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--heap
65520
--main-module
$(MODULE)
--res
version16.res
--
dll
$(SRCDIR)
/gdi.exe.spec
version16.res
:
version16.rc
$(LDPATH)
$(RC16)
$(RC16FLAGS)
-fo
$@
$(SRCDIR)
/version16.rc
...
...
dlls/kernel/Makefile.in
View file @
492ac292
...
...
@@ -113,7 +113,7 @@ relay16asm.s: $(WINEBUILD)
# Special rules for 16-bit resource and spec files
krnl386.exe.spec.c
:
krnl386.exe.spec version16.res
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--dll-name
kernel
--main-module
$(MODULE)
--res
version16.res
--
spec
$(SRCDIR)
/krnl386.exe.spec
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--dll-name
kernel
--main-module
$(MODULE)
--res
version16.res
--
dll
$(SRCDIR)
/krnl386.exe.spec
version16.res
:
version16.rc
$(LDPATH)
$(RC16)
$(RC16FLAGS)
-fo
$@
$(SRCDIR)
/version16.rc
...
...
dlls/shell32/Makefile.in
View file @
492ac292
...
...
@@ -72,10 +72,10 @@ version16.res: version16.rc
$(LDPATH)
$(RC16)
$(RC16FLAGS)
-fo
$@
$(SRCDIR)
/version16.rc
shell.spec.c
:
shell.spec version16.res
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--main-module
$(MODULE)
--res
version16.res
--
spec
$(SRCDIR)
/shell.spec
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--main-module
$(MODULE)
--res
version16.res
--
dll
$(SRCDIR)
/shell.spec
authors.c
:
$(TOPSRCDIR)/AUTHORS
(
L
ANG
=
C
;
echo
'const char * const SHELL_Authors[] = {'
&&
\
(
L
C_ALL
=
C
;
echo
'const char * const SHELL_Authors[] = {'
&&
\
sed
-e
'1,2d'
-e
's/\(.*\)/ \"\1\",/'
$(TOPSRCDIR)
/AUTHORS
&&
\
echo
' 0 };'
)
>
$@
||
(
$(RM)
$@
&&
false
)
...
...
dlls/user/Makefile.in
View file @
492ac292
...
...
@@ -168,13 +168,13 @@ EXTRASUBDIRS = \
# Special rules for 16-bit resource and spec files
user.exe.spec.c
:
user.exe.spec resources/version16.res
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--heap
65520
--main-module
$(MODULE)
--res
resources/version16.res
--
spec
$(SRCDIR)
/user.exe.spec
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--heap
65520
--main-module
$(MODULE)
--res
resources/version16.res
--
dll
$(SRCDIR)
/user.exe.spec
display.drv.spec.c
:
display.drv.spec resources/display.res
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--main-module
$(MODULE)
--res
resources/display.res
--
spec
$(SRCDIR)
/display.drv.spec
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--main-module
$(MODULE)
--res
resources/display.res
--
dll
$(SRCDIR)
/display.drv.spec
mouse.drv.spec.c
:
mouse.drv.spec resources/mouse.res
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--main-module
$(MODULE)
--res
resources/mouse.res
--
spec
$(SRCDIR)
/mouse.drv.spec
$(WINEBUILD)
$(DEFS)
$(DLLFLAGS)
-o
$@
--main-module
$(MODULE)
--res
resources/mouse.res
--
dll
$(SRCDIR)
/mouse.drv.spec
resources/display.res
:
resources/display.rc
$(LDPATH)
$(RC16)
$(RC16FLAGS)
-fo
$@
$(SRCDIR)
/resources/display.rc
...
...
tools/winebuild/build.h
View file @
492ac292
...
...
@@ -68,7 +68,6 @@ typedef struct
typedef
struct
{
int
n_args
;
char
arg_types
[
21
];
}
ORD_FUNCTION
;
...
...
@@ -170,6 +169,9 @@ extern FILE *open_input_file( const char *srcdir, const char *name );
extern
void
close_input_file
(
FILE
*
file
);
extern
void
dump_bytes
(
FILE
*
outfile
,
const
unsigned
char
*
data
,
int
len
,
const
char
*
label
,
int
constant
);
extern
int
remove_stdcall_decoration
(
char
*
name
);
extern
DLLSPEC
*
alloc_dll_spec
(
void
);
extern
void
free_dll_spec
(
DLLSPEC
*
spec
);
extern
const
char
*
make_c_identifier
(
const
char
*
str
);
extern
int
get_alignment
(
int
alignBoundary
);
...
...
@@ -184,7 +186,6 @@ extern void load_res16_file( const char *name, DLLSPEC *spec );
extern
int
output_res16_data
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
int
output_res16_directory
(
unsigned
char
*
buffer
,
DLLSPEC
*
spec
);
extern
void
output_dll_init
(
FILE
*
outfile
,
const
char
*
constructor
,
const
char
*
destructor
);
extern
int
parse_debug_channels
(
const
char
*
srcdir
,
const
char
*
filename
);
extern
void
BuildRelays16
(
FILE
*
outfile
);
extern
void
BuildRelays32
(
FILE
*
outfile
);
...
...
@@ -192,7 +193,10 @@ extern void BuildSpec16File( FILE *outfile, DLLSPEC *spec );
extern
void
BuildSpec32File
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
BuildDef32File
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
BuildDebugFile
(
FILE
*
outfile
,
const
char
*
srcdir
,
char
**
argv
);
extern
int
ParseTopLevel
(
FILE
*
file
,
DLLSPEC
*
spec
);
extern
int
parse_spec_file
(
FILE
*
file
,
DLLSPEC
*
spec
);
extern
int
parse_def_file
(
FILE
*
file
,
DLLSPEC
*
spec
);
extern
int
parse_debug_channels
(
const
char
*
srcdir
,
const
char
*
filename
);
/* global variables */
...
...
tools/winebuild/import.c
View file @
492ac292
/*
* DLL imports support
*
* Copyright 2000 Alexandre Julliard
*
2000 Eric Pouech
* Copyright 2000
, 2004
Alexandre Julliard
*
Copyright
2000 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -32,20 +32,13 @@
#include "build.h"
struct
func
{
char
*
name
;
/* function name */
int
ordinal
;
/* function ordinal */
int
ord_only
;
/* non-zero if function is imported by ordinal */
};
struct
import
{
char
*
dll
;
/* dll name
*/
DLLSPEC
*
spec
;
/* description of the imported dll
*/
int
delay
;
/* delay or not dll loading ? */
struct
func
*
exports
;
/* functions exported from this dll */
ORDDEF
*
*
exports
;
/* functions exported from this dll */
int
nb_exports
;
/* number of exported functions */
struct
func
*
imports
;
/* functions we want to import from this dll */
ORDDEF
*
*
imports
;
/* functions we want to import from this dll */
int
nb_imports
;
/* number of imported functions */
};
...
...
@@ -143,7 +136,10 @@ static int name_cmp( const void *name, const void *entry )
/* compare function names; helper for resolve_imports */
static
int
func_cmp
(
const
void
*
func1
,
const
void
*
func2
)
{
return
strcmp
(
((
struct
func
*
)
func1
)
->
name
,
((
struct
func
*
)
func2
)
->
name
);
const
ORDDEF
*
odp1
=
*
(
const
ORDDEF
**
)
func1
;
const
ORDDEF
*
odp2
=
*
(
const
ORDDEF
**
)
func2
;
return
strcmp
(
odp1
->
name
?
odp1
->
name
:
odp1
->
export_name
,
odp2
->
name
?
odp2
->
name
:
odp2
->
export_name
);
}
/* locate a symbol in a (sorted) list */
...
...
@@ -159,14 +155,15 @@ inline static const char *find_symbol( const char *name, char **table, int size
}
/* locate an export in a (sorted) export list */
inline
static
struct
func
*
find_export
(
const
char
*
name
,
struct
func
*
table
,
int
size
)
inline
static
ORDDEF
*
find_export
(
const
char
*
name
,
ORDDEF
*
*
table
,
int
size
)
{
struct
func
func
,
*
res
=
NULL
;
ORDDEF
func
,
*
odp
,
*
*
res
=
NULL
;
func
.
name
=
(
char
*
)
name
;
func
.
ordinal
=
-
1
;
if
(
table
)
res
=
bsearch
(
&
func
,
table
,
size
,
sizeof
(
*
table
),
func_cmp
);
return
res
;
odp
=
&
func
;
if
(
table
)
res
=
bsearch
(
&
odp
,
table
,
size
,
sizeof
(
*
table
),
func_cmp
);
return
res
?
*
res
:
NULL
;
}
/* sort a symbol table */
...
...
@@ -179,13 +176,9 @@ inline static void sort_symbols( char **table, int size )
/* free an import structure */
static
void
free_imports
(
struct
import
*
imp
)
{
int
i
;
for
(
i
=
0
;
i
<
imp
->
nb_exports
;
i
++
)
free
(
imp
->
exports
[
i
].
name
);
for
(
i
=
0
;
i
<
imp
->
nb_imports
;
i
++
)
free
(
imp
->
imports
[
i
].
name
);
free
(
imp
->
exports
);
free
(
imp
->
imports
);
free
(
imp
->
dll
);
free
_dll_spec
(
imp
->
spec
);
free
(
imp
);
}
...
...
@@ -202,7 +195,7 @@ static int is_already_imported( const char *name )
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
strcmp
(
dll_imports
[
i
]
->
dll
,
name
))
return
1
;
if
(
!
strcmp
(
dll_imports
[
i
]
->
spec
->
file_name
,
name
))
return
1
;
}
return
0
;
}
...
...
@@ -241,152 +234,40 @@ static char *open_library( const char *name )
return
fullname
;
}
/* skip whitespace until the next token */
static
char
*
skip_whitespace
(
char
*
p
)
{
while
(
*
p
&&
isspace
(
*
p
))
p
++
;
if
(
!*
p
||
*
p
==
';'
)
p
=
NULL
;
return
p
;
}
/* skip to the start of the next token, null terminating the current one */
static
char
*
next_token
(
char
*
p
)
{
while
(
*
p
&&
!
isspace
(
*
p
))
p
++
;
if
(
*
p
)
*
p
++
=
0
;
return
skip_whitespace
(
p
);
}
/* remove the @nn suffix from stdcall names */
static
char
*
remove_stdcall_decoration
(
char
*
buffer
)
{
char
*
p
=
buffer
+
strlen
(
buffer
)
-
1
;
while
(
p
>
buffer
&&
isdigit
(
*
p
))
p
--
;
if
(
p
>
buffer
&&
*
p
==
'@'
)
*
p
=
0
;
return
buffer
;
}
/* read in the list of exported symbols of an import library */
static
int
read_import_lib
(
const
char
*
name
,
struct
import
*
imp
)
{
FILE
*
f
;
char
buffer
[
1024
];
char
*
fullname
;
int
size
;
int
i
,
ret
;
DLLSPEC
*
spec
=
imp
->
spec
;
imp
->
exports
=
NULL
;
imp
->
nb_exports
=
size
=
0
;
imp
->
nb_exports
=
0
;
fullname
=
open_library
(
name
);
f
=
open_input_file
(
NULL
,
fullname
);
free
(
fullname
);
while
(
fgets
(
buffer
,
sizeof
(
buffer
),
f
))
{
char
*
name
,
*
flags
;
int
ordinal
=
0
,
ord_only
=
0
;
char
*
p
=
buffer
+
strlen
(
buffer
)
-
1
;
if
(
p
<
buffer
)
goto
next
;
if
(
*
p
==
'\n'
)
*
p
--
=
0
;
p
=
buffer
;
if
(
!
(
p
=
skip_whitespace
(
p
)))
goto
next
;
name
=
p
;
p
=
next_token
(
name
);
if
(
!
strcmp
(
name
,
"LIBRARY"
))
{
if
(
!
p
)
{
error
(
"Expected name after LIBRARY
\n
"
);
goto
next
;
}
name
=
p
;
p
=
next_token
(
name
);
if
(
p
)
{
error
(
"Garbage after LIBRARY statement
\n
"
);
goto
next
;
}
if
(
is_already_imported
(
name
))
{
close_input_file
(
f
);
return
0
;
/* ignore this dll */
}
free
(
imp
->
dll
);
imp
->
dll
=
xstrdup
(
name
);
goto
next
;
}
if
(
!
strcmp
(
name
,
"EXPORTS"
))
goto
next
;
ret
=
parse_def_file
(
f
,
spec
);
close_input_file
(
f
);
if
(
!
ret
)
return
0
;
if
(
is_already_imported
(
spec
->
file_name
))
return
0
;
/* check for ordinal */
if
(
!
p
)
{
error
(
"Expected ordinal after function name
\n
"
);
goto
next
;
}
if
(
*
p
!=
'@'
||
!
isdigit
(
p
[
1
]))
{
error
(
"Expected ordinal after function name '%s'
\n
"
,
name
);
goto
next
;
}
ordinal
=
strtol
(
p
+
1
,
&
p
,
10
);
if
(
ordinal
>=
MAX_ORDINALS
)
{
error
(
"Invalid ordinal number %d
\n
"
,
ordinal
);
goto
next
;
}
imp
->
exports
=
xmalloc
(
spec
->
nb_entry_points
*
sizeof
(
*
imp
->
exports
)
);
/* check for optional flags */
while
(
p
&&
(
p
=
skip_whitespace
(
p
)))
{
flags
=
p
;
p
=
next_token
(
flags
);
if
(
!
strcmp
(
flags
,
"NONAME"
))
{
ord_only
=
1
;
if
(
!
ordinal
)
{
error
(
"Invalid ordinal number %d
\n
"
,
ordinal
);
goto
next
;
}
}
else
if
(
!
strcmp
(
flags
,
"CONSTANT"
)
||
!
strcmp
(
flags
,
"DATA"
))
{
/* we don't support importing non-function entry points */
goto
next
;
}
else
if
(
!
strcmp
(
flags
,
"PRIVATE"
))
{
/* function must not be imported */
goto
next
;
}
else
{
error
(
"Garbage after ordinal declaration
\n
"
);
goto
next
;
}
}
for
(
i
=
0
;
i
<
spec
->
nb_entry_points
;
i
++
)
{
ORDDEF
*
odp
=
&
spec
->
entry_points
[
i
];
if
(
imp
->
nb_exports
==
size
)
{
size
+=
128
;
imp
->
exports
=
xrealloc
(
imp
->
exports
,
size
*
sizeof
(
*
imp
->
exports
)
);
}
if
((
p
=
strchr
(
name
,
'='
)))
*
p
=
0
;
remove_stdcall_decoration
(
name
);
imp
->
exports
[
imp
->
nb_exports
].
name
=
xstrdup
(
name
);
imp
->
exports
[
imp
->
nb_exports
].
ordinal
=
ordinal
;
imp
->
exports
[
imp
->
nb_exports
].
ord_only
=
ord_only
;
imp
->
nb_exports
++
;
next:
current_line
++
;
if
(
odp
->
type
!=
TYPE_STDCALL
&&
odp
->
type
!=
TYPE_CDECL
)
continue
;
if
(
odp
->
flags
&
FLAG_PRIVATE
)
continue
;
imp
->
exports
[
imp
->
nb_exports
++
]
=
odp
;
}
close_input_file
(
f
);
imp
->
exports
=
xrealloc
(
imp
->
exports
,
imp
->
nb_exports
*
sizeof
(
*
imp
->
exports
)
);
if
(
imp
->
nb_exports
)
qsort
(
imp
->
exports
,
imp
->
nb_exports
,
sizeof
(
*
imp
->
exports
),
func_cmp
);
return
!
nb_errors
;
return
1
;
}
/* add a dll to the list of imports */
...
...
@@ -407,11 +288,11 @@ void add_import_dll( const char *name, int delay )
}
imp
=
xmalloc
(
sizeof
(
*
imp
)
);
imp
->
dll
=
fullname
;
imp
->
delay
=
delay
;
imp
->
imports
=
NULL
;
imp
->
nb_imports
=
0
;
imp
->
spec
=
alloc_dll_spec
()
;
imp
->
spec
->
file_name
=
fullname
;
imp
->
delay
=
delay
;
imp
->
imports
=
NULL
;
imp
->
nb_imports
=
0
;
if
(
delay
)
nb_delayed
++
;
if
(
read_import_lib
(
name
,
imp
))
...
...
@@ -489,13 +370,10 @@ void add_ignore_symbol( const char *name )
}
/* add a function to the list of imports from a given dll */
static
void
add_import_func
(
struct
import
*
imp
,
const
struct
func
*
func
)
static
void
add_import_func
(
struct
import
*
imp
,
ORDDEF
*
func
)
{
imp
->
imports
=
xrealloc
(
imp
->
imports
,
(
imp
->
nb_imports
+
1
)
*
sizeof
(
*
imp
->
imports
)
);
imp
->
imports
[
imp
->
nb_imports
].
name
=
xstrdup
(
func
->
name
);
imp
->
imports
[
imp
->
nb_imports
].
ordinal
=
func
->
ordinal
;
imp
->
imports
[
imp
->
nb_imports
].
ord_only
=
func
->
ord_only
;
imp
->
nb_imports
++
;
imp
->
imports
[
imp
->
nb_imports
++
]
=
func
;
total_imports
++
;
if
(
imp
->
delay
)
total_delayed
++
;
}
...
...
@@ -613,15 +491,16 @@ static void add_extra_undef_symbols( const DLLSPEC *spec )
static
int
check_unused
(
const
struct
import
*
imp
,
const
DLLSPEC
*
spec
)
{
int
i
;
size_t
len
=
strlen
(
imp
->
dll
);
const
char
*
p
=
strchr
(
imp
->
dll
,
'.'
);
if
(
p
&&
!
strcasecmp
(
p
,
".dll"
))
len
=
p
-
imp
->
dll
;
const
char
*
file_name
=
imp
->
spec
->
file_name
;
size_t
len
=
strlen
(
file_name
);
const
char
*
p
=
strchr
(
file_name
,
'.'
);
if
(
p
&&
!
strcasecmp
(
p
,
".dll"
))
len
=
p
-
file_name
;
for
(
i
=
spec
->
base
;
i
<=
spec
->
limit
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
i
];
if
(
!
odp
||
!
(
odp
->
flags
&
FLAG_FORWARD
))
continue
;
if
(
!
strncasecmp
(
odp
->
link_name
,
imp
->
dll
,
len
)
&&
if
(
!
strncasecmp
(
odp
->
link_name
,
file_name
,
len
)
&&
odp
->
link_name
[
len
]
==
'.'
)
return
0
;
/* found a forward, it is used */
}
...
...
@@ -724,10 +603,10 @@ int resolve_imports( DLLSPEC *spec )
for
(
j
=
0
;
j
<
nb_undef_symbols
;
j
++
)
{
struct
func
*
func
=
find_export
(
undef_symbols
[
j
],
imp
->
exports
,
imp
->
nb_exports
);
if
(
func
)
ORDDEF
*
odp
=
find_export
(
undef_symbols
[
j
],
imp
->
exports
,
imp
->
nb_exports
);
if
(
odp
)
{
add_import_func
(
imp
,
func
);
add_import_func
(
imp
,
odp
);
free
(
undef_symbols
[
j
]
);
undef_symbols
[
j
]
=
NULL
;
}
...
...
@@ -736,7 +615,7 @@ int resolve_imports( DLLSPEC *spec )
if
(
!
remove_symbol_holes
()
&&
check_unused
(
imp
,
spec
))
{
/* the dll is not used, get rid of it */
warning
(
"%s imported but no symbols used
\n
"
,
imp
->
dll
);
warning
(
"%s imported but no symbols used
\n
"
,
imp
->
spec
->
file_name
);
remove_import_dll
(
i
);
i
--
;
}
...
...
@@ -772,7 +651,7 @@ static int output_immediate_imports( FILE *outfile )
{
if
(
dll_imports
[
i
]
->
delay
)
continue
;
fprintf
(
outfile
,
" { 0, 0, 0,
\"
%s
\"
, &imports.data[%d] },
\n
"
,
dll_imports
[
i
]
->
dll
,
j
);
dll_imports
[
i
]
->
spec
->
file_name
,
j
);
j
+=
dll_imports
[
i
]
->
nb_imports
+
1
;
}
...
...
@@ -784,18 +663,18 @@ static int output_immediate_imports( FILE *outfile )
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
dll_imports
[
i
]
->
delay
)
continue
;
fprintf
(
outfile
,
" /* %s */
\n
"
,
dll_imports
[
i
]
->
dll
);
fprintf
(
outfile
,
" /* %s */
\n
"
,
dll_imports
[
i
]
->
spec
->
file_name
);
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
)
{
struct
func
*
import
=
&
dll_imports
[
i
]
->
imports
[
j
];
if
(
!
import
->
ord_only
)
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
if
(
!
(
odp
->
flags
&
FLAG_NONAME
)
)
{
unsigned
short
ord
=
import
->
ordinal
;
unsigned
short
ord
=
odp
->
ordinal
;
fprintf
(
outfile
,
"
\"\\
%03o
\\
%03o%s
\"
,
\n
"
,
*
(
unsigned
char
*
)
&
ord
,
*
((
unsigned
char
*
)
&
ord
+
1
),
import
->
name
);
*
(
unsigned
char
*
)
&
ord
,
*
((
unsigned
char
*
)
&
ord
+
1
),
odp
->
name
);
}
else
fprintf
(
outfile
,
" (char *)%d,
\n
"
,
import
->
ordinal
);
fprintf
(
outfile
,
" (char *)%d,
\n
"
,
odp
->
ordinal
);
}
fprintf
(
outfile
,
" 0,
\n
"
);
}
...
...
@@ -811,13 +690,14 @@ static int output_immediate_imports( FILE *outfile )
if
(
dll_imports
[
i
]
->
delay
)
continue
;
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
,
pos
+=
4
)
{
struct
func
*
import
=
&
dll_imports
[
i
]
->
imports
[
j
];
fprintf
(
outfile
,
"
\"\\
t"
__ASM_FUNC
(
"%s"
)
"
\\
n
\"\n
"
,
import
->
name
);
fprintf
(
outfile
,
"
\"\\
t.globl "
__ASM_NAME
(
"%s"
)
"
\\
n
\"\n
"
,
import
->
name
);
fprintf
(
outfile
,
"
\"
"
__ASM_NAME
(
"%s"
)
":
\\
n
\\
t"
,
import
->
name
);
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
const
char
*
name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
fprintf
(
outfile
,
"
\"\\
t"
__ASM_FUNC
(
"%s"
)
"
\\
n
\"\n
"
,
name
);
fprintf
(
outfile
,
"
\"\\
t.globl "
__ASM_NAME
(
"%s"
)
"
\\
n
\"\n
"
,
name
);
fprintf
(
outfile
,
"
\"
"
__ASM_NAME
(
"%s"
)
":
\\
n
\\
t"
,
name
);
#if defined(__i386__)
if
(
strstr
(
import
->
name
,
"__wine_call_from_16"
))
if
(
strstr
(
name
,
"__wine_call_from_16"
))
fprintf
(
outfile
,
".byte 0x2e
\\
n
\\
tjmp *(imports+%d)
\\
n
\\
tnop
\\
n"
,
pos
);
else
fprintf
(
outfile
,
"jmp *(imports+%d)
\\
n
\\
tmovl %%esi,%%esi
\\
n"
,
pos
);
...
...
@@ -886,8 +766,9 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
fprintf
(
outfile
,
"static void *__wine_delay_imp_%d_hmod;
\n
"
,
i
);
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
)
{
fprintf
(
outfile
,
"void __wine_delay_imp_%d_%s();
\n
"
,
i
,
dll_imports
[
i
]
->
imports
[
j
].
name
);
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
const
char
*
name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
fprintf
(
outfile
,
"void __wine_delay_imp_%d_%s();
\n
"
,
i
,
name
);
}
}
fprintf
(
outfile
,
"
\n
"
);
...
...
@@ -910,31 +791,33 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
fprintf
(
outfile
,
" { 0,
\"
%s
\"
, &__wine_delay_imp_%d_hmod, &delay_imports.IAT[%d], &delay_imports.INT[%d], 0, 0, 0 },
\n
"
,
dll_imports
[
i
]
->
dll
,
i
,
j
,
j
);
dll_imports
[
i
]
->
spec
->
file_name
,
i
,
j
,
j
);
j
+=
dll_imports
[
i
]
->
nb_imports
;
}
fprintf
(
outfile
,
" },
\n
{
\n
"
);
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
fprintf
(
outfile
,
" /* %s */
\n
"
,
dll_imports
[
i
]
->
dll
);
fprintf
(
outfile
,
" /* %s */
\n
"
,
dll_imports
[
i
]
->
spec
->
file_name
);
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
)
{
fprintf
(
outfile
,
" &__wine_delay_imp_%d_%s,
\n
"
,
i
,
dll_imports
[
i
]
->
imports
[
j
].
name
);
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
const
char
*
name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
fprintf
(
outfile
,
" &__wine_delay_imp_%d_%s,
\n
"
,
i
,
name
);
}
}
fprintf
(
outfile
,
" },
\n
{
\n
"
);
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
fprintf
(
outfile
,
" /* %s */
\n
"
,
dll_imports
[
i
]
->
dll
);
fprintf
(
outfile
,
" /* %s */
\n
"
,
dll_imports
[
i
]
->
spec
->
file_name
);
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
)
{
struct
func
*
import
=
&
dll_imports
[
i
]
->
imports
[
j
];
if
(
import
->
ord_only
)
fprintf
(
outfile
,
" (char *)%d,
\n
"
,
import
->
ordinal
);
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
if
(
!
odp
->
name
)
fprintf
(
outfile
,
" (char *)%d,
\n
"
,
odp
->
ordinal
);
else
fprintf
(
outfile
,
"
\"
%s
\"
,
\n
"
,
import
->
name
);
fprintf
(
outfile
,
"
\"
%s
\"
,
\n
"
,
odp
->
name
);
}
}
fprintf
(
outfile
,
" }
\n
};
\n\n
"
);
...
...
@@ -1059,7 +942,10 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
)
{
char
buffer
[
128
];
sprintf
(
buffer
,
"__wine_delay_imp_%d_%s"
,
i
,
dll_imports
[
i
]
->
imports
[
j
].
name
);
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
const
char
*
name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
sprintf
(
buffer
,
"__wine_delay_imp_%d_%s"
,
i
,
name
);
fprintf
(
outfile
,
"
\"\\
t"
__ASM_FUNC
(
"%s"
)
"
\\
n
\"\n
"
,
buffer
);
fprintf
(
outfile
,
"
\"
"
__ASM_NAME
(
"%s"
)
":
\\
n
\"\n
"
,
buffer
);
#if defined(__i386__)
...
...
@@ -1088,12 +974,14 @@ static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
,
pos
+=
4
)
{
struct
func
*
import
=
&
dll_imports
[
i
]
->
imports
[
j
];
fprintf
(
outfile
,
"
\"\\
t"
__ASM_FUNC
(
"%s"
)
"
\\
n
\"\n
"
,
import
->
name
);
fprintf
(
outfile
,
"
\"\\
t.globl "
__ASM_NAME
(
"%s"
)
"
\\
n
\"\n
"
,
import
->
name
);
fprintf
(
outfile
,
"
\"
"
__ASM_NAME
(
"%s"
)
":
\\
n
\\
t
\"
"
,
import
->
name
);
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
const
char
*
name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
fprintf
(
outfile
,
"
\"\\
t"
__ASM_FUNC
(
"%s"
)
"
\\
n
\"\n
"
,
name
);
fprintf
(
outfile
,
"
\"\\
t.globl "
__ASM_NAME
(
"%s"
)
"
\\
n
\"\n
"
,
name
);
fprintf
(
outfile
,
"
\"
"
__ASM_NAME
(
"%s"
)
":
\\
n
\\
t
\"
"
,
name
);
#if defined(__i386__)
if
(
strstr
(
import
->
name
,
"__wine_call_from_16"
))
if
(
strstr
(
name
,
"__wine_call_from_16"
))
fprintf
(
outfile
,
"
\"
.byte 0x2e
\\
n
\\
tjmp *(delay_imports+%d)
\\
n
\\
tnop
\\
n
\"
"
,
pos
);
else
fprintf
(
outfile
,
"
\"
jmp *(delay_imports+%d)
\\
n
\\
tmovl %%esi,%%esi
\\
n
\"
"
,
pos
);
...
...
tools/winebuild/main.c
View file @
492ac292
...
...
@@ -56,17 +56,17 @@ char **lib_path = NULL;
char
*
input_file_name
=
NULL
;
const
char
*
output_file_name
=
NULL
;
static
FILE
*
input_file
;
static
FILE
*
output_file
;
static
const
char
*
current_src_dir
;
static
int
nb_res_files
;
static
char
**
res_files
;
static
char
*
spec_file_name
;
/* execution mode */
enum
exec_mode_values
{
MODE_NONE
,
MODE_
SPEC
,
MODE_
DLL
,
MODE_EXE
,
MODE_DEF
,
MODE_DEBUG
,
...
...
@@ -87,7 +87,10 @@ static void set_dll_file_name( const char *name, DLLSPEC *spec )
if
((
p
=
strrchr
(
name
,
'/'
)))
name
=
p
+
1
;
spec
->
file_name
=
xmalloc
(
strlen
(
name
)
+
5
);
strcpy
(
spec
->
file_name
,
name
);
if
((
p
=
strrchr
(
spec
->
file_name
,
'.'
))
&&
!
strcmp
(
p
,
".spec"
))
*
p
=
0
;
if
((
p
=
strrchr
(
spec
->
file_name
,
'.'
)))
{
if
(
!
strcmp
(
p
,
".spec"
)
||
!
strcmp
(
p
,
".def"
))
*
p
=
0
;
}
if
(
!
strchr
(
spec
->
file_name
,
'.'
))
strcat
(
spec
->
file_name
,
".dll"
);
}
...
...
@@ -126,7 +129,7 @@ static const char usage_str[] =
" --version Print the version and exit
\n
"
" -w --warnings Turn on warnings
\n
"
"
\n
Mode options:
\n
"
" --
spec=FILE.SPEC Build a .c file from a spec
file
\n
"
" --
dll=FILE Build a .c file from a .spec or .def
file
\n
"
" --def=FILE.SPEC Build a .def file from a spec file
\n
"
" --exe=NAME Build a .c file for the named executable
\n
"
" --debug [FILES] Build a .c file with the debug channels declarations
\n
"
...
...
@@ -136,7 +139,7 @@ static const char usage_str[] =
enum
long_options_values
{
LONG_OPT_
SPEC
=
1
,
LONG_OPT_
DLL
=
1
,
LONG_OPT_DEF
,
LONG_OPT_EXE
,
LONG_OPT_DEBUG
,
...
...
@@ -149,13 +152,14 @@ static const char short_options[] = "C:D:F:H:I:K:L:M:N:d:e:f:hi:kl:m:o:r:w";
static
const
struct
option
long_options
[]
=
{
{
"
spec"
,
1
,
0
,
LONG_OPT_SPEC
},
{
"
dll"
,
1
,
0
,
LONG_OPT_DLL
},
{
"def"
,
1
,
0
,
LONG_OPT_DEF
},
{
"exe"
,
1
,
0
,
LONG_OPT_EXE
},
{
"debug"
,
0
,
0
,
LONG_OPT_DEBUG
},
{
"relay16"
,
0
,
0
,
LONG_OPT_RELAY16
},
{
"relay32"
,
0
,
0
,
LONG_OPT_RELAY32
},
{
"version"
,
0
,
0
,
LONG_OPT_VERSION
},
{
"spec"
,
1
,
0
,
LONG_OPT_DLL
},
/* for backwards compatibility */
/* aliases for short options */
{
"source-dir"
,
1
,
0
,
'C'
},
{
"delay-lib"
,
1
,
0
,
'd'
},
...
...
@@ -287,14 +291,14 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
case
'w'
:
display_warnings
=
1
;
break
;
case
LONG_OPT_
SPEC
:
set_exec_mode
(
MODE_
SPEC
);
input_file
=
open_input_file
(
NULL
,
optarg
);
case
LONG_OPT_
DLL
:
set_exec_mode
(
MODE_
DLL
);
spec_file_name
=
xstrdup
(
optarg
);
set_dll_file_name
(
optarg
,
spec
);
break
;
case
LONG_OPT_DEF
:
set_exec_mode
(
MODE_DEF
);
input_file
=
open_input_file
(
NULL
,
optarg
);
spec_file_name
=
xstrdup
(
optarg
);
set_dll_file_name
(
optarg
,
spec
);
break
;
case
LONG_OPT_EXE
:
...
...
@@ -357,65 +361,59 @@ static void load_resources( char *argv[], DLLSPEC *spec )
}
}
static
int
parse_input_file
(
DLLSPEC
*
spec
)
{
FILE
*
input_file
=
open_input_file
(
NULL
,
spec_file_name
);
char
*
extension
=
strrchr
(
spec_file_name
,
'.'
);
if
(
extension
&&
!
strcmp
(
extension
,
".def"
))
return
parse_def_file
(
input_file
,
spec
);
else
return
parse_spec_file
(
input_file
,
spec
);
close_input_file
(
input_file
);
}
/*******************************************************************
* main
*/
int
main
(
int
argc
,
char
**
argv
)
{
DLLSPEC
spec
;
spec
.
file_name
=
NULL
;
spec
.
dll_name
=
NULL
;
spec
.
owner_name
=
NULL
;
spec
.
init_func
=
NULL
;
spec
.
type
=
SPEC_WIN32
;
spec
.
mode
=
SPEC_MODE_DLL
;
spec
.
base
=
MAX_ORDINALS
;
spec
.
limit
=
0
;
spec
.
stack_size
=
0
;
spec
.
heap_size
=
0
;
spec
.
nb_entry_points
=
0
;
spec
.
alloc_entry_points
=
0
;
spec
.
nb_names
=
0
;
spec
.
nb_resources
=
0
;
spec
.
entry_points
=
NULL
;
spec
.
names
=
NULL
;
spec
.
ordinals
=
NULL
;
spec
.
resources
=
NULL
;
DLLSPEC
*
spec
=
alloc_dll_spec
();
output_file
=
stdout
;
argv
=
parse_options
(
argc
,
argv
,
&
spec
);
argv
=
parse_options
(
argc
,
argv
,
spec
);
switch
(
exec_mode
)
{
case
MODE_
SPEC
:
load_resources
(
argv
,
&
spec
);
if
(
!
ParseTopLevel
(
input_file
,
&
spec
))
break
;
switch
(
spec
.
type
)
case
MODE_
DLL
:
load_resources
(
argv
,
spec
);
if
(
!
parse_input_file
(
spec
))
break
;
switch
(
spec
->
type
)
{
case
SPEC_WIN16
:
if
(
argv
[
0
])
fatal_error
(
"file argument '%s' not allowed in this mode
\n
"
,
argv
[
0
]
);
BuildSpec16File
(
output_file
,
&
spec
);
BuildSpec16File
(
output_file
,
spec
);
break
;
case
SPEC_WIN32
:
read_undef_symbols
(
argv
);
BuildSpec32File
(
output_file
,
&
spec
);
BuildSpec32File
(
output_file
,
spec
);
break
;
default:
assert
(
0
);
}
break
;
case
MODE_EXE
:
if
(
spec
.
type
==
SPEC_WIN16
)
fatal_error
(
"Cannot build 16-bit exe files
\n
"
);
load_resources
(
argv
,
&
spec
);
if
(
spec
->
type
==
SPEC_WIN16
)
fatal_error
(
"Cannot build 16-bit exe files
\n
"
);
load_resources
(
argv
,
spec
);
read_undef_symbols
(
argv
);
BuildSpec32File
(
output_file
,
&
spec
);
BuildSpec32File
(
output_file
,
spec
);
break
;
case
MODE_DEF
:
if
(
argv
[
0
])
fatal_error
(
"file argument '%s' not allowed in this mode
\n
"
,
argv
[
0
]
);
if
(
spec
.
type
==
SPEC_WIN16
)
fatal_error
(
"Cannot yet build .def file for 16-bit dlls
\n
"
);
if
(
!
ParseTopLevel
(
input_file
,
&
spec
))
break
;
BuildDef32File
(
output_file
,
&
spec
);
if
(
spec
->
type
==
SPEC_WIN16
)
fatal_error
(
"Cannot yet build .def file for 16-bit dlls
\n
"
);
if
(
!
parse_input_file
(
spec
))
break
;
BuildDef32File
(
output_file
,
spec
);
break
;
case
MODE_DEBUG
:
BuildDebugFile
(
output_file
,
current_src_dir
,
argv
);
...
...
tools/winebuild/parser.c
View file @
492ac292
...
...
@@ -3,7 +3,7 @@
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Martin von Loewis
* Copyright 1995, 1996, 1997 Alexandre Julliard
* Copyright 1995, 1996, 1997
, 2004
Alexandre Julliard
* Copyright 1997 Eric Youngdale
* Copyright 1999 Ulrich Weigand
*
...
...
@@ -43,6 +43,9 @@ static char TokenBuffer[512];
static
char
*
ParseNext
=
ParseBuffer
;
static
FILE
*
input_file
;
static
const
char
*
separator_chars
;
static
const
char
*
comment_chars
;
static
const
char
*
const
TypeNames
[
TYPE_NBTYPES
]
=
{
"variable"
,
/* TYPE_VARIABLE */
...
...
@@ -76,7 +79,12 @@ static int IsNumberString(const char *s)
inline
static
int
is_token_separator
(
char
ch
)
{
return
(
ch
==
'('
||
ch
==
')'
||
ch
==
'-'
);
return
strchr
(
separator_chars
,
ch
)
!=
NULL
;
}
inline
static
int
is_token_comment
(
char
ch
)
{
return
strchr
(
comment_chars
,
ch
)
!=
NULL
;
}
/* get the next line from the input file, or return 0 if at eof */
...
...
@@ -109,7 +117,7 @@ static const char * GetToken( int allow_eol )
else
break
;
}
if
((
*
p
==
'\0'
)
||
(
*
p
==
'#'
))
if
((
*
p
==
'\0'
)
||
is_token_comment
(
*
p
))
{
if
(
!
allow_eol
)
error
(
"Declaration not terminated properly
\n
"
);
return
NULL
;
...
...
@@ -146,11 +154,11 @@ static ORDDEF *add_entry_point( DLLSPEC *spec )
}
/*******************************************************************
*
ParseV
ariable
*
parse_spec_v
ariable
*
* Parse a variable definition.
* Parse a variable definition
in a .spec file
.
*/
static
int
ParseV
ariable
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
static
int
parse_spec_v
ariable
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
{
char
*
endptr
;
int
*
value_array
;
...
...
@@ -208,11 +216,11 @@ static int ParseVariable( ORDDEF *odp, DLLSPEC *spec )
/*******************************************************************
*
ParseExportFunction
*
parse_spec_export
*
* Parse a
function definition
.
* Parse a
n exported function definition in a .spec file
.
*/
static
int
ParseExportFunction
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
static
int
parse_spec_export
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
{
const
char
*
token
;
unsigned
int
i
;
...
...
@@ -330,11 +338,11 @@ static int ParseExportFunction( ORDDEF *odp, DLLSPEC *spec )
/*******************************************************************
*
ParseE
quate
*
parse_spec_e
quate
*
* Parse an 'equate' definition.
* Parse an 'equate' definition
in a .spec file
.
*/
static
int
ParseE
quate
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
static
int
parse_spec_e
quate
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
{
char
*
endptr
;
int
value
;
...
...
@@ -358,11 +366,11 @@ static int ParseEquate( ORDDEF *odp, DLLSPEC *spec )
/*******************************************************************
*
ParseS
tub
*
parse_spec_s
tub
*
* Parse a 'stub' definition
.
* Parse a 'stub' definition
in a .spec file
*/
static
int
ParseS
tub
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
static
int
parse_spec_s
tub
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
{
odp
->
u
.
func
.
arg_types
[
0
]
=
'\0'
;
odp
->
link_name
=
xstrdup
(
""
);
...
...
@@ -371,11 +379,11 @@ static int ParseStub( ORDDEF *odp, DLLSPEC *spec )
/*******************************************************************
*
ParseE
xtern
*
parse_spec_e
xtern
*
* Parse an 'extern' definition.
* Parse an 'extern' definition
in a .spec file
.
*/
static
int
ParseE
xtern
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
static
int
parse_spec_e
xtern
(
ORDDEF
*
odp
,
DLLSPEC
*
spec
)
{
const
char
*
token
;
...
...
@@ -403,11 +411,11 @@ static int ParseExtern( ORDDEF *odp, DLLSPEC *spec )
/*******************************************************************
*
ParseF
lags
*
parse_spec_f
lags
*
* Parse the optional flags for an entry point
* Parse the optional flags for an entry point
in a .spec file.
*/
static
const
char
*
ParseF
lags
(
ORDDEF
*
odp
)
static
const
char
*
parse_spec_f
lags
(
ORDDEF
*
odp
)
{
unsigned
int
i
;
const
char
*
token
;
...
...
@@ -429,26 +437,13 @@ static const char *ParseFlags( ORDDEF *odp )
return
token
;
}
/*******************************************************************
* fix_export_name
*
* Fix an exported function name by removing a possible @xx suffix
*/
static
void
fix_export_name
(
char
*
name
)
{
char
*
p
,
*
end
=
strrchr
(
name
,
'@'
);
if
(
!
end
||
!
end
[
1
]
||
end
==
name
)
return
;
/* make sure all the rest is digits */
for
(
p
=
end
+
1
;
*
p
;
p
++
)
if
(
!
isdigit
(
*
p
))
return
;
*
end
=
0
;
}
/*******************************************************************
*
ParseO
rdinal
*
parse_spec_o
rdinal
*
* Parse an ordinal definition.
* Parse an ordinal definition
in a .spec file
.
*/
static
int
ParseO
rdinal
(
int
ordinal
,
DLLSPEC
*
spec
)
static
int
parse_spec_o
rdinal
(
int
ordinal
,
DLLSPEC
*
spec
)
{
const
char
*
token
;
...
...
@@ -468,32 +463,32 @@ static int ParseOrdinal( int ordinal, DLLSPEC *spec )
}
if
(
!
(
token
=
GetToken
(
0
)))
goto
error
;
if
(
*
token
==
'-'
&&
!
(
token
=
ParseF
lags
(
odp
)))
goto
error
;
if
(
*
token
==
'-'
&&
!
(
token
=
parse_spec_f
lags
(
odp
)))
goto
error
;
odp
->
name
=
xstrdup
(
token
);
fix_export_name
(
odp
->
name
);
remove_stdcall_decoration
(
odp
->
name
);
odp
->
lineno
=
current_line
;
odp
->
ordinal
=
ordinal
;
switch
(
odp
->
type
)
{
case
TYPE_VARIABLE
:
if
(
!
ParseV
ariable
(
odp
,
spec
))
goto
error
;
if
(
!
parse_spec_v
ariable
(
odp
,
spec
))
goto
error
;
break
;
case
TYPE_PASCAL
:
case
TYPE_STDCALL
:
case
TYPE_VARARGS
:
case
TYPE_CDECL
:
if
(
!
ParseExportFunction
(
odp
,
spec
))
goto
error
;
if
(
!
parse_spec_export
(
odp
,
spec
))
goto
error
;
break
;
case
TYPE_ABS
:
if
(
!
ParseE
quate
(
odp
,
spec
))
goto
error
;
if
(
!
parse_spec_e
quate
(
odp
,
spec
))
goto
error
;
break
;
case
TYPE_STUB
:
if
(
!
ParseS
tub
(
odp
,
spec
))
goto
error
;
if
(
!
parse_spec_s
tub
(
odp
,
spec
))
goto
error
;
break
;
case
TYPE_EXTERN
:
if
(
!
ParseE
xtern
(
odp
,
spec
))
goto
error
;
if
(
!
parse_spec_e
xtern
(
odp
,
spec
))
goto
error
;
break
;
default:
assert
(
0
);
...
...
@@ -641,17 +636,20 @@ static void assign_ordinals( DLLSPEC *spec )
/*******************************************************************
*
ParseTopLevel
*
parse_spec_file
*
* Parse a spec file.
* Parse a
.
spec file.
*/
int
ParseTopLevel
(
FILE
*
file
,
DLLSPEC
*
spec
)
int
parse_spec_file
(
FILE
*
file
,
DLLSPEC
*
spec
)
{
const
char
*
token
;
input_file
=
file
;
current_line
=
0
;
comment_chars
=
"#;"
;
separator_chars
=
"()-"
;
while
(
get_next_line
())
{
if
(
!
(
token
=
GetToken
(
1
)))
continue
;
...
...
@@ -662,11 +660,11 @@ int ParseTopLevel( FILE *file, DLLSPEC *spec )
error
(
"'@' ordinals not supported for Win16
\n
"
);
continue
;
}
if
(
!
ParseO
rdinal
(
-
1
,
spec
))
continue
;
if
(
!
parse_spec_o
rdinal
(
-
1
,
spec
))
continue
;
}
else
if
(
IsNumberString
(
token
))
{
if
(
!
ParseO
rdinal
(
atoi
(
token
),
spec
))
continue
;
if
(
!
parse_spec_o
rdinal
(
atoi
(
token
),
spec
))
continue
;
}
else
{
...
...
@@ -684,6 +682,243 @@ int ParseTopLevel( FILE *file, DLLSPEC *spec )
/*******************************************************************
* parse_def_library
*
* Parse a LIBRARY declaration in a .def file.
*/
static
int
parse_def_library
(
DLLSPEC
*
spec
)
{
const
char
*
token
=
GetToken
(
1
);
if
(
!
token
)
return
1
;
if
(
strcmp
(
token
,
"BASE"
))
{
free
(
spec
->
file_name
);
spec
->
file_name
=
xstrdup
(
token
);
if
(
!
(
token
=
GetToken
(
1
)))
return
1
;
}
if
(
strcmp
(
token
,
"BASE"
))
{
error
(
"Expected library name or BASE= declaration, got '%s'
\n
"
,
token
);
return
0
;
}
if
(
!
(
token
=
GetToken
(
0
)))
return
0
;
if
(
strcmp
(
token
,
"="
))
{
error
(
"Expected '=' after BASE, got '%s'
\n
"
,
token
);
return
0
;
}
if
(
!
(
token
=
GetToken
(
0
)))
return
0
;
/* FIXME: do something with base address */
return
1
;
}
/*******************************************************************
* parse_def_stack_heap_size
*
* Parse a STACKSIZE or HEAPSIZE declaration in a .def file.
*/
static
int
parse_def_stack_heap_size
(
int
is_stack
,
DLLSPEC
*
spec
)
{
const
char
*
token
=
GetToken
(
0
);
char
*
end
;
unsigned
long
size
;
if
(
!
token
)
return
0
;
size
=
strtoul
(
token
,
&
end
,
0
);
if
(
*
end
)
{
error
(
"Invalid number '%s'
\n
"
,
token
);
return
0
;
}
if
(
is_stack
)
spec
->
stack_size
=
size
/
1024
;
else
spec
->
heap_size
=
size
/
1024
;
if
(
!
(
token
=
GetToken
(
1
)))
return
1
;
if
(
strcmp
(
token
,
","
))
{
error
(
"Expected ',' after size, got '%s'
\n
"
,
token
);
return
0
;
}
if
(
!
(
token
=
GetToken
(
0
)))
return
0
;
/* FIXME: do something with reserve size */
return
1
;
}
/*******************************************************************
* parse_def_export
*
* Parse an export declaration in a .def file.
*/
static
int
parse_def_export
(
char
*
name
,
DLLSPEC
*
spec
)
{
int
i
,
args
;
const
char
*
token
=
GetToken
(
1
);
ORDDEF
*
odp
=
add_entry_point
(
spec
);
memset
(
odp
,
0
,
sizeof
(
*
odp
)
);
odp
->
lineno
=
current_line
;
odp
->
ordinal
=
-
1
;
odp
->
name
=
name
;
args
=
remove_stdcall_decoration
(
odp
->
name
);
if
(
args
==
-
1
)
odp
->
type
=
TYPE_CDECL
;
else
{
odp
->
type
=
TYPE_STDCALL
;
args
/=
sizeof
(
int
);
if
(
args
>=
sizeof
(
odp
->
u
.
func
.
arg_types
))
{
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'
;
}
/* check for optional internal name */
if
(
token
&&
!
strcmp
(
token
,
"="
))
{
if
(
!
(
token
=
GetToken
(
0
)))
goto
error
;
odp
->
link_name
=
xstrdup
(
token
);
remove_stdcall_decoration
(
odp
->
link_name
);
token
=
GetToken
(
1
);
}
/* check for optional ordinal */
if
(
token
&&
token
[
0
]
==
'@'
)
{
int
ordinal
;
if
(
!
IsNumberString
(
token
+
1
))
{
error
(
"Expected number after '@', got '%s'
\n
"
,
token
+
1
);
goto
error
;
}
ordinal
=
atoi
(
token
+
1
);
if
(
!
ordinal
)
{
error
(
"Ordinal 0 is not valid
\n
"
);
goto
error
;
}
if
(
ordinal
>=
MAX_ORDINALS
)
{
error
(
"Ordinal number %d too large
\n
"
,
ordinal
);
goto
error
;
}
if
(
ordinal
>
spec
->
limit
)
spec
->
limit
=
ordinal
;
if
(
ordinal
<
spec
->
base
)
spec
->
base
=
ordinal
;
odp
->
ordinal
=
ordinal
;
token
=
GetToken
(
1
);
}
/* check for other optional keywords */
if
(
token
&&
!
strcmp
(
token
,
"NONAME"
))
{
if
(
odp
->
ordinal
==
-
1
)
{
error
(
"NONAME requires an ordinal
\n
"
);
goto
error
;
}
odp
->
export_name
=
odp
->
name
;
odp
->
name
=
NULL
;
odp
->
flags
|=
FLAG_NONAME
;
token
=
GetToken
(
1
);
}
if
(
token
&&
!
strcmp
(
token
,
"PRIVATE"
))
{
odp
->
flags
|=
FLAG_PRIVATE
;
token
=
GetToken
(
1
);
}
if
(
token
&&
!
strcmp
(
token
,
"DATA"
))
{
odp
->
type
=
TYPE_EXTERN
;
token
=
GetToken
(
1
);
}
if
(
token
)
{
error
(
"Garbage text '%s' found at end of export declaration
\n
"
,
token
);
goto
error
;
}
return
1
;
error:
spec
->
nb_entry_points
--
;
free
(
odp
->
name
);
return
0
;
}
/*******************************************************************
* parse_def_file
*
* Parse a .def file.
*/
int
parse_def_file
(
FILE
*
file
,
DLLSPEC
*
spec
)
{
const
char
*
token
;
int
in_exports
=
0
;
input_file
=
file
;
current_line
=
0
;
comment_chars
=
";"
;
separator_chars
=
",="
;
while
(
get_next_line
())
{
if
(
!
(
token
=
GetToken
(
1
)))
continue
;
if
(
!
strcmp
(
token
,
"LIBRARY"
)
||
!
strcmp
(
token
,
"NAME"
))
{
if
(
!
parse_def_library
(
spec
))
continue
;
goto
end_of_line
;
}
else
if
(
!
strcmp
(
token
,
"STACKSIZE"
))
{
if
(
!
parse_def_stack_heap_size
(
1
,
spec
))
continue
;
goto
end_of_line
;
}
else
if
(
!
strcmp
(
token
,
"HEAPSIZE"
))
{
if
(
!
parse_def_stack_heap_size
(
0
,
spec
))
continue
;
goto
end_of_line
;
}
else
if
(
!
strcmp
(
token
,
"EXPORTS"
))
{
in_exports
=
1
;
if
(
!
(
token
=
GetToken
(
1
)))
continue
;
}
else
if
(
!
strcmp
(
token
,
"IMPORTS"
))
{
in_exports
=
0
;
if
(
!
(
token
=
GetToken
(
1
)))
continue
;
}
else
if
(
!
strcmp
(
token
,
"SECTIONS"
))
{
in_exports
=
0
;
if
(
!
(
token
=
GetToken
(
1
)))
continue
;
}
if
(
!
in_exports
)
continue
;
/* ignore this line */
if
(
!
parse_def_export
(
xstrdup
(
token
),
spec
))
continue
;
end_of_line:
if
((
token
=
GetToken
(
1
)))
error
(
"Syntax error near '%s'
\n
"
,
token
);
}
current_line
=
0
;
/* no longer parsing the input file */
assign_names
(
spec
);
assign_ordinals
(
spec
);
return
!
nb_errors
;
}
/*******************************************************************
* add_debug_channel
*/
static
void
add_debug_channel
(
const
char
*
name
)
...
...
tools/winebuild/utils.c
View file @
492ac292
...
...
@@ -210,6 +210,83 @@ void close_input_file( FILE *file )
/*******************************************************************
* remove_stdcall_decoration
*
* Remove a possible @xx suffix from a function name.
* Return the numerical value of the suffix, or -1 if none.
*/
int
remove_stdcall_decoration
(
char
*
name
)
{
char
*
p
,
*
end
=
strrchr
(
name
,
'@'
);
if
(
!
end
||
!
end
[
1
]
||
end
==
name
)
return
-
1
;
/* make sure all the rest is digits */
for
(
p
=
end
+
1
;
*
p
;
p
++
)
if
(
!
isdigit
(
*
p
))
return
-
1
;
*
end
=
0
;
return
atoi
(
end
+
1
);
}
/*******************************************************************
* alloc_dll_spec
*
* Create a new dll spec file descriptor
*/
DLLSPEC
*
alloc_dll_spec
(
void
)
{
DLLSPEC
*
spec
;
spec
=
xmalloc
(
sizeof
(
*
spec
)
);
spec
->
file_name
=
NULL
;
spec
->
dll_name
=
NULL
;
spec
->
owner_name
=
NULL
;
spec
->
init_func
=
NULL
;
spec
->
type
=
SPEC_WIN32
;
spec
->
mode
=
SPEC_MODE_DLL
;
spec
->
base
=
MAX_ORDINALS
;
spec
->
limit
=
0
;
spec
->
stack_size
=
0
;
spec
->
heap_size
=
0
;
spec
->
nb_entry_points
=
0
;
spec
->
alloc_entry_points
=
0
;
spec
->
nb_names
=
0
;
spec
->
nb_resources
=
0
;
spec
->
entry_points
=
NULL
;
spec
->
names
=
NULL
;
spec
->
ordinals
=
NULL
;
spec
->
resources
=
NULL
;
return
spec
;
}
/*******************************************************************
* free_dll_spec
*
* Free dll spec file descriptor
*/
void
free_dll_spec
(
DLLSPEC
*
spec
)
{
int
i
;
for
(
i
=
0
;
i
<
spec
->
nb_entry_points
;
i
++
)
{
ORDDEF
*
odp
=
&
spec
->
entry_points
[
i
];
free
(
odp
->
name
);
free
(
odp
->
export_name
);
free
(
odp
->
link_name
);
}
free
(
spec
->
file_name
);
free
(
spec
->
dll_name
);
free
(
spec
->
owner_name
);
free
(
spec
->
init_func
);
free
(
spec
->
entry_points
);
free
(
spec
->
names
);
free
(
spec
->
ordinals
);
free
(
spec
->
resources
);
free
(
spec
);
}
/*******************************************************************
* make_c_identifier
*
* Map a string to a valid C identifier.
...
...
tools/winebuild/winebuild.man.in
View file @
492ac292
...
...
@@ -19,10 +19,11 @@ option can be specified, as described in the \fBOPTIONS\fR section.
You have to specify exactly one of the following options, depending on
what you want winebuild to generate.
.TP
.BI \--spec=\ file.spec
Build a C file from a spec file (see \fBSPEC FILE SYNTAX\fR for
details). The resulting C file must be compiled and linked to the
other object files to build a working Wine dll.
.BI \--dll=\ filename
Build a C file from a .spec file (see \fBSPEC FILE SYNTAX\fR for
details), or from a standard Windows .def file. The resulting C file
must be compiled and linked to the other object files to build a
working Wine dll.
.br
In that mode, the
.I input files
...
...
@@ -34,7 +35,7 @@ other dlls.
.TP
.BI \--exe=\ name
Build a C file for the named executable. This is basically the same as
the --
spec
mode except that it doesn't require a .spec file as input,
the --
dll
mode except that it doesn't require a .spec file as input,
since an executable doesn't export functions. The resulting C file
must be compiled and linked to the other object files to build a
working Wine executable, and all the other object files must be listed
...
...
@@ -130,7 +131,7 @@ imported from it is actually called).
.BI \-M,\ --main-module= module
Specify that we are building a 16-bit dll, that will ultimately be
linked together with the 32-bit dll specified in \fImodule\fR. Only
meaningful in \fB--
spec
\fR mode.
meaningful in \fB--
dll
\fR mode.
.TP
.BI \-m,\ --mode= mode
Set the executable or dll mode, which can be one of the following:
...
...
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