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
71580499
Commit
71580499
authored
Aug 11, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winebuild: Added output() function to properly deal with write errors.
parent
05001b1c
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1154 additions
and
1148 deletions
+1154
-1148
build.h
tools/winebuild/build.h
+18
-15
import.c
tools/winebuild/import.c
+256
-256
main.c
tools/winebuild/main.c
+8
-8
relay.c
tools/winebuild/relay.c
+409
-415
res16.c
tools/winebuild/res16.c
+26
-26
res32.c
tools/winebuild/res32.c
+30
-30
spec16.c
tools/winebuild/spec16.c
+210
-210
spec32.c
tools/winebuild/spec32.c
+172
-173
utils.c
tools/winebuild/utils.c
+25
-15
No files found.
tools/winebuild/build.h
View file @
71580499
...
...
@@ -154,11 +154,13 @@ extern void error( const char *msg, ... )
__attribute__
((
__format__
(
__printf__
,
1
,
2
)));
extern
void
warning
(
const
char
*
msg
,
...
)
__attribute__
((
__format__
(
__printf__
,
1
,
2
)));
extern
int
output
(
const
char
*
format
,
...
)
__attribute__
((
__format__
(
__printf__
,
1
,
2
)));
extern
char
*
get_temp_file_name
(
const
char
*
prefix
,
const
char
*
suffix
);
extern
void
output_standard_file_header
(
FILE
*
outfile
);
extern
void
output_standard_file_header
(
void
);
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
void
*
buffer
,
unsigned
int
size
);
extern
void
dump_bytes
(
const
void
*
buffer
,
unsigned
int
size
);
extern
int
remove_stdcall_decoration
(
char
*
name
);
extern
void
assemble_file
(
const
char
*
src_file
,
const
char
*
obj_file
);
extern
DLLSPEC
*
alloc_dll_spec
(
void
);
...
...
@@ -176,8 +178,8 @@ extern const char *get_asm_string_keyword(void);
extern
const
char
*
get_asm_short_keyword
(
void
);
extern
const
char
*
get_asm_rodata_section
(
void
);
extern
const
char
*
get_asm_string_section
(
void
);
extern
void
output_function_size
(
FILE
*
outfile
,
const
char
*
name
);
extern
void
output_gnu_stack_note
(
FILE
*
outfile
);
extern
void
output_function_size
(
const
char
*
name
);
extern
void
output_gnu_stack_note
(
void
);
extern
void
add_import_dll
(
const
char
*
name
,
const
char
*
filename
);
extern
void
add_delayed_import
(
const
char
*
name
);
...
...
@@ -187,20 +189,20 @@ extern void read_undef_symbols( DLLSPEC *spec, char **argv );
extern
int
resolve_imports
(
DLLSPEC
*
spec
);
extern
int
has_imports
(
void
);
extern
int
has_relays
(
DLLSPEC
*
spec
);
extern
void
output_get_pc_thunk
(
FILE
*
outfile
);
extern
void
output_stubs
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
output_imports
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
output_get_pc_thunk
(
void
);
extern
void
output_stubs
(
DLLSPEC
*
spec
);
extern
void
output_imports
(
DLLSPEC
*
spec
);
extern
int
load_res32_file
(
const
char
*
name
,
DLLSPEC
*
spec
);
extern
void
output_resources
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
output_resources
(
DLLSPEC
*
spec
);
extern
void
load_res16_file
(
const
char
*
name
,
DLLSPEC
*
spec
);
extern
void
output_res16_data
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
output_res16_directory
(
FILE
*
outfile
,
DLLSPEC
*
spec
,
const
char
*
header_name
);
extern
void
output_res16_data
(
DLLSPEC
*
spec
);
extern
void
output_res16_directory
(
DLLSPEC
*
spec
,
const
char
*
header_name
);
extern
void
BuildRelays16
(
FILE
*
outfile
);
extern
void
BuildRelays32
(
FILE
*
outfile
);
extern
void
BuildSpec16File
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
BuildSpec32File
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
BuildDef32File
(
FILE
*
outfile
,
DLLSPEC
*
spec
);
extern
void
BuildRelays16
(
void
);
extern
void
BuildRelays32
(
void
);
extern
void
BuildSpec16File
(
DLLSPEC
*
spec
);
extern
void
BuildSpec32File
(
DLLSPEC
*
spec
);
extern
void
BuildDef32File
(
DLLSPEC
*
spec
);
extern
int
parse_spec_file
(
FILE
*
file
,
DLLSPEC
*
spec
);
extern
int
parse_def_file
(
FILE
*
file
,
DLLSPEC
*
spec
);
...
...
@@ -219,6 +221,7 @@ extern int link_ext_symbols;
extern
char
*
input_file_name
;
extern
char
*
spec_file_name
;
extern
FILE
*
output_file
;
extern
const
char
*
output_file_name
;
extern
char
**
lib_path
;
...
...
tools/winebuild/import.c
View file @
71580499
...
...
@@ -592,99 +592,99 @@ int resolve_imports( DLLSPEC *spec )
}
/* output the get_pc thunk if needed */
void
output_get_pc_thunk
(
FILE
*
outfile
)
void
output_get_pc_thunk
(
void
)
{
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
(
"
\n\t
.text
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"%s:
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"
\t
popl %%eax
\n
"
);
output
(
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
ret
\n
"
);
output_function_size
(
"__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
)
static
void
output_import_thunk
(
const
char
*
name
,
const
char
*
table
,
int
pos
)
{
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
name
)
);
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
output
(
"%s
\n
"
,
asm_globl
(
name
)
);
switch
(
target_cpu
)
{
case
CPU_x86
:
if
(
!
UsePIC
)
{
fprintf
(
outfile
,
"
\t
jmp *(%s+%d)
\n
"
,
table
,
pos
);
output
(
"
\t
jmp *(%s+%d)
\n
"
,
table
,
pos
);
}
else
{
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:
\t
jmp *%s+%d-1b(%%eax)
\n
"
,
table
,
pos
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:
\t
jmp *%s+%d-1b(%%eax)
\n
"
,
table
,
pos
);
}
break
;
case
CPU_x86_64
:
fprintf
(
outfile
,
"
\t
jmpq *%s+%d(%%rip)
\n
"
,
table
,
pos
);
output
(
"
\t
jmpq *%s+%d(%%rip)
\n
"
,
table
,
pos
);
break
;
case
CPU_SPARC
:
if
(
!
UsePIC
)
{
fprintf
(
outfile
,
"
\t
sethi %%hi(%s+%d), %%g1
\n
"
,
table
,
pos
);
fprintf
(
outfile
,
"
\t
ld [%%g1+%%lo(%s+%d)], %%g1
\n
"
,
table
,
pos
);
fprintf
(
outfile
,
"
\t
jmp %%g1
\n
"
);
fprintf
(
outfile
,
"
\t
nop
\n
"
);
output
(
"
\t
sethi %%hi(%s+%d), %%g1
\n
"
,
table
,
pos
);
output
(
"
\t
ld [%%g1+%%lo(%s+%d)], %%g1
\n
"
,
table
,
pos
);
output
(
"
\t
jmp %%g1
\n
"
);
output
(
"
\t
nop
\n
"
);
}
else
{
/* Hmpf. Stupid sparc assembler always interprets global variable
names as GOT offsets, so we have to do it the long way ... */
fprintf
(
outfile
,
"
\t
save %%sp, -96, %%sp
\n
"
);
fprintf
(
outfile
,
"0:
\t
call 1f
\n
"
);
fprintf
(
outfile
,
"
\t
nop
\n
"
);
fprintf
(
outfile
,
"1:
\t
sethi %%hi(%s+%d-0b), %%g1
\n
"
,
table
,
pos
);
fprintf
(
outfile
,
"
\t
or %%g1, %%lo(%s+%d-0b), %%g1
\n
"
,
table
,
pos
);
fprintf
(
outfile
,
"
\t
ld [%%g1+%%o7], %%g1
\n
"
);
fprintf
(
outfile
,
"
\t
jmp %%g1
\n
"
);
fprintf
(
outfile
,
"
\t
restore
\n
"
);
output
(
"
\t
save %%sp, -96, %%sp
\n
"
);
output
(
"0:
\t
call 1f
\n
"
);
output
(
"
\t
nop
\n
"
);
output
(
"1:
\t
sethi %%hi(%s+%d-0b), %%g1
\n
"
,
table
,
pos
);
output
(
"
\t
or %%g1, %%lo(%s+%d-0b), %%g1
\n
"
,
table
,
pos
);
output
(
"
\t
ld [%%g1+%%o7], %%g1
\n
"
);
output
(
"
\t
jmp %%g1
\n
"
);
output
(
"
\t
restore
\n
"
);
}
break
;
case
CPU_ALPHA
:
fprintf
(
outfile
,
"
\t
lda $0,%s
\n
"
,
table
);
fprintf
(
outfile
,
"
\t
lda $0,%d($0)
\n
"
,
pos
);
fprintf
(
outfile
,
"
\t
jmp $31,($0)
\n
"
);
output
(
"
\t
lda $0,%s
\n
"
,
table
);
output
(
"
\t
lda $0,%d($0)
\n
"
,
pos
);
output
(
"
\t
jmp $31,($0)
\n
"
);
break
;
case
CPU_POWERPC
:
fprintf
(
outfile
,
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
9
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
8
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
7
),
ppc_reg
(
1
)
);
output
(
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
output
(
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
9
),
ppc_reg
(
1
)
);
output
(
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
output
(
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
8
),
ppc_reg
(
1
)
);
output
(
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
output
(
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
7
),
ppc_reg
(
1
)
);
if
(
target_platform
==
PLATFORM_APPLE
)
{
fprintf
(
outfile
,
"
\t
lis %s, ha16(%s+%d)
\n
"
,
ppc_reg
(
9
),
table
,
pos
);
fprintf
(
outfile
,
"
\t
la %s, lo16(%s+%d)(%s)
\n
"
,
ppc_reg
(
8
),
table
,
pos
,
ppc_reg
(
9
)
);
output
(
"
\t
lis %s, ha16(%s+%d)
\n
"
,
ppc_reg
(
9
),
table
,
pos
);
output
(
"
\t
la %s, lo16(%s+%d)(%s)
\n
"
,
ppc_reg
(
8
),
table
,
pos
,
ppc_reg
(
9
)
);
}
else
{
fprintf
(
outfile
,
"
\t
lis %s, (%s+%d)@h
\n
"
,
ppc_reg
(
9
),
table
,
pos
);
fprintf
(
outfile
,
"
\t
la %s, (%s+%d)@l(%s)
\n
"
,
ppc_reg
(
8
),
table
,
pos
,
ppc_reg
(
9
)
);
output
(
"
\t
lis %s, (%s+%d)@h
\n
"
,
ppc_reg
(
9
),
table
,
pos
);
output
(
"
\t
la %s, (%s+%d)@l(%s)
\n
"
,
ppc_reg
(
8
),
table
,
pos
,
ppc_reg
(
9
)
);
}
fprintf
(
outfile
,
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
7
),
ppc_reg
(
8
)
);
fprintf
(
outfile
,
"
\t
mtctr %s
\n
"
,
ppc_reg
(
7
)
);
fprintf
(
outfile
,
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
7
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
addi %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
8
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
addi %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
9
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
addi %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
fprintf
(
outfile
,
"
\t
bctr
\n
"
);
output
(
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
7
),
ppc_reg
(
8
)
);
output
(
"
\t
mtctr %s
\n
"
,
ppc_reg
(
7
)
);
output
(
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
7
),
ppc_reg
(
1
)
);
output
(
"
\t
addi %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
output
(
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
8
),
ppc_reg
(
1
)
);
output
(
"
\t
addi %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
output
(
"
\t
lwz %s, 0(%s)
\n
"
,
ppc_reg
(
9
),
ppc_reg
(
1
)
);
output
(
"
\t
addi %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
)
);
output
(
"
\t
bctr
\n
"
);
break
;
}
output_function_size
(
outfile
,
name
);
output_function_size
(
name
);
}
/* check if we need an import directory */
...
...
@@ -694,7 +694,7 @@ int has_imports(void)
}
/* output the import table of a Win32 module */
static
void
output_immediate_imports
(
FILE
*
outfile
)
static
void
output_immediate_imports
(
void
)
{
int
i
,
j
;
const
char
*
dll_name
;
...
...
@@ -703,10 +703,10 @@ static void output_immediate_imports( FILE *outfile )
/* main import header */
fprintf
(
outfile
,
"
\n
/* import table */
\n
"
);
fprintf
(
outfile
,
"
\n\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
".L__wine_spec_imports:
\n
"
);
output
(
"
\n
/* import table */
\n
"
);
output
(
"
\n\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
".L__wine_spec_imports:
\n
"
);
/* list of dlls */
...
...
@@ -714,23 +714,23 @@ static void output_immediate_imports( FILE *outfile )
{
if
(
dll_imports
[
i
]
->
delay
)
continue
;
dll_name
=
make_c_identifier
(
dll_imports
[
i
]
->
spec
->
file_name
);
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* OriginalFirstThunk */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* ForwarderChain */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_import_name_%s-.L__wine_spec_rva_base
\n
"
,
/* Name */
output
(
"
\t
.long 0
\n
"
);
/* OriginalFirstThunk */
output
(
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
output
(
"
\t
.long 0
\n
"
);
/* ForwarderChain */
output
(
"
\t
.long .L__wine_spec_import_name_%s-.L__wine_spec_rva_base
\n
"
,
/* Name */
dll_name
);
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_import_data_ptrs+%d-.L__wine_spec_rva_base
\n
"
,
/* FirstThunk */
output
(
"
\t
.long .L__wine_spec_import_data_ptrs+%d-.L__wine_spec_rva_base
\n
"
,
/* FirstThunk */
j
*
get_ptr_size
()
);
j
+=
dll_imports
[
i
]
->
nb_imports
+
1
;
}
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* OriginalFirstThunk */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* ForwarderChain */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* Name */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* FirstThunk */
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
".L__wine_spec_import_data_ptrs:
\n
"
);
output
(
"
\t
.long 0
\n
"
);
/* OriginalFirstThunk */
output
(
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
output
(
"
\t
.long 0
\n
"
);
/* ForwarderChain */
output
(
"
\t
.long 0
\n
"
);
/* Name */
output
(
"
\t
.long 0
\n
"
);
/* FirstThunk */
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
".L__wine_spec_import_data_ptrs:
\n
"
);
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
dll_imports
[
i
]
->
delay
)
continue
;
...
...
@@ -739,19 +739,19 @@ static void output_immediate_imports( FILE *outfile )
{
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
if
(
!
(
odp
->
flags
&
FLAG_NONAME
))
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_import_data_%s_%s-.L__wine_spec_rva_base
\n
"
,
output
(
"
\t
%s .L__wine_spec_import_data_%s_%s-.L__wine_spec_rva_base
\n
"
,
get_asm_ptr_keyword
(),
dll_name
,
odp
->
name
);
else
{
if
(
get_ptr_size
()
==
8
)
fprintf
(
outfile
,
"
\t
.quad 0x800000000000%04x
\n
"
,
odp
->
ordinal
);
output
(
"
\t
.quad 0x800000000000%04x
\n
"
,
odp
->
ordinal
);
else
fprintf
(
outfile
,
"
\t
.long 0x8000%04x
\n
"
,
odp
->
ordinal
);
output
(
"
\t
.long 0x8000%04x
\n
"
,
odp
->
ordinal
);
}
}
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
}
fprintf
(
outfile
,
".L__wine_spec_imports_end:
\n
"
);
output
(
".L__wine_spec_imports_end:
\n
"
);
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
...
...
@@ -762,10 +762,10 @@ static void output_immediate_imports( FILE *outfile )
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
if
(
!
(
odp
->
flags
&
FLAG_NONAME
))
{
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
2
)
);
fprintf
(
outfile
,
".L__wine_spec_import_data_%s_%s:
\n
"
,
dll_name
,
odp
->
name
);
fprintf
(
outfile
,
"
\t
%s %d
\n
"
,
get_asm_short_keyword
(),
odp
->
ordinal
);
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
odp
->
name
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
2
)
);
output
(
".L__wine_spec_import_data_%s_%s:
\n
"
,
dll_name
,
odp
->
name
);
output
(
"
\t
%s %d
\n
"
,
get_asm_short_keyword
(),
odp
->
ordinal
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
odp
->
name
);
}
}
}
...
...
@@ -774,13 +774,13 @@ static void output_immediate_imports( FILE *outfile )
{
if
(
dll_imports
[
i
]
->
delay
)
continue
;
dll_name
=
make_c_identifier
(
dll_imports
[
i
]
->
spec
->
file_name
);
fprintf
(
outfile
,
".L__wine_spec_import_name_%s:
\n\t
%s
\"
%s
\"\n
"
,
output
(
".L__wine_spec_import_name_%s:
\n\t
%s
\"
%s
\"\n
"
,
dll_name
,
get_asm_string_keyword
(),
dll_imports
[
i
]
->
spec
->
file_name
);
}
}
/* output the import thunks of a Win32 module */
static
void
output_immediate_import_thunks
(
FILE
*
outfile
)
static
void
output_immediate_import_thunks
(
void
)
{
int
i
,
j
,
pos
;
int
nb_imm
=
nb_imports
-
nb_delayed
;
...
...
@@ -788,10 +788,10 @@ static void output_immediate_import_thunks( FILE *outfile )
if
(
!
nb_imm
)
return
;
fprintf
(
outfile
,
"
\n
/* immediate import thunks */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
8
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
asm_name
(
import_thunks
));
output
(
"
\n
/* immediate import thunks */
\n\n
"
);
output
(
"
\t
.text
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
8
)
);
output
(
"%s:
\n
"
,
asm_name
(
import_thunks
));
for
(
i
=
pos
=
0
;
i
<
nb_imports
;
i
++
)
{
...
...
@@ -799,56 +799,56 @@ static void output_immediate_import_thunks( FILE *outfile )
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
,
pos
+=
get_ptr_size
())
{
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
output_import_thunk
(
o
utfile
,
o
dp
->
name
?
odp
->
name
:
odp
->
export_name
,
output_import_thunk
(
odp
->
name
?
odp
->
name
:
odp
->
export_name
,
".L__wine_spec_import_data_ptrs"
,
pos
);
}
pos
+=
get_ptr_size
();
}
output_function_size
(
outfile
,
import_thunks
);
output_function_size
(
import_thunks
);
}
/* output the delayed import table of a Win32 module */
static
void
output_delayed_imports
(
FILE
*
outfile
,
const
DLLSPEC
*
spec
)
static
void
output_delayed_imports
(
const
DLLSPEC
*
spec
)
{
int
i
,
j
,
mod
;
if
(
!
nb_delayed
)
return
;
fprintf
(
outfile
,
"
\n
/* delayed imports */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
"__wine_spec_delay_imports"
)
);
output
(
"
\n
/* delayed imports */
\n\n
"
);
output
(
"
\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
"%s
\n
"
,
asm_globl
(
"__wine_spec_delay_imports"
)
);
/* list of dlls */
for
(
i
=
j
=
mod
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* grAttrs */
fprintf
(
outfile
,
"
\t
%s .L__wine_delay_name_%d
\n
"
,
/* szName */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* grAttrs */
output
(
"
\t
%s .L__wine_delay_name_%d
\n
"
,
/* szName */
get_asm_ptr_keyword
(),
i
);
fprintf
(
outfile
,
"
\t
%s .L__wine_delay_modules+%d
\n
"
,
/* phmod */
output
(
"
\t
%s .L__wine_delay_modules+%d
\n
"
,
/* phmod */
get_asm_ptr_keyword
(),
mod
*
get_ptr_size
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_delay_IAT+%d
\n
"
,
/* pIAT */
output
(
"
\t
%s .L__wine_delay_IAT+%d
\n
"
,
/* pIAT */
get_asm_ptr_keyword
(),
j
*
get_ptr_size
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_delay_INT+%d
\n
"
,
/* pINT */
output
(
"
\t
%s .L__wine_delay_INT+%d
\n
"
,
/* pINT */
get_asm_ptr_keyword
(),
j
*
get_ptr_size
()
);
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pBoundIAT */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pUnloadIAT */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* dwTimeStamp */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pBoundIAT */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pUnloadIAT */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* dwTimeStamp */
j
+=
dll_imports
[
i
]
->
nb_imports
;
mod
++
;
}
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* grAttrs */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* szName */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* phmod */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pIAT */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pINT */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pBoundIAT */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pUnloadIAT */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* dwTimeStamp */
fprintf
(
outfile
,
"
\n
.L__wine_delay_IAT:
\n
"
);
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* grAttrs */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* szName */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* phmod */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pIAT */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pINT */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pBoundIAT */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* pUnloadIAT */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* dwTimeStamp */
output
(
"
\n
.L__wine_delay_IAT:
\n
"
);
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
...
...
@@ -856,12 +856,12 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
const
char
*
name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
fprintf
(
outfile
,
"
\t
%s .L__wine_delay_imp_%d_%s
\n
"
,
output
(
"
\t
%s .L__wine_delay_imp_%d_%s
\n
"
,
get_asm_ptr_keyword
(),
i
,
name
);
}
}
fprintf
(
outfile
,
"
\n
.L__wine_delay_INT:
\n
"
);
output
(
"
\n
.L__wine_delay_INT:
\n
"
);
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
...
...
@@ -869,24 +869,24 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
if
(
!
odp
->
name
)
fprintf
(
outfile
,
"
\t
%s %d
\n
"
,
get_asm_ptr_keyword
(),
odp
->
ordinal
);
output
(
"
\t
%s %d
\n
"
,
get_asm_ptr_keyword
(),
odp
->
ordinal
);
else
fprintf
(
outfile
,
"
\t
%s .L__wine_delay_data_%d_%s
\n
"
,
output
(
"
\t
%s .L__wine_delay_data_%d_%s
\n
"
,
get_asm_ptr_keyword
(),
i
,
odp
->
name
);
}
}
fprintf
(
outfile
,
"
\n
.L__wine_delay_modules:
\n
"
);
output
(
"
\n
.L__wine_delay_modules:
\n
"
);
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
dll_imports
[
i
]
->
delay
)
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
if
(
dll_imports
[
i
]
->
delay
)
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
}
for
(
i
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
fprintf
(
outfile
,
".L__wine_delay_name_%d:
\n
"
,
i
);
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
output
(
".L__wine_delay_name_%d:
\n
"
,
i
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
dll_imports
[
i
]
->
spec
->
file_name
);
}
...
...
@@ -897,15 +897,15 @@ static void output_delayed_imports( FILE *outfile, const DLLSPEC *spec )
{
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
if
(
!
odp
->
name
)
continue
;
fprintf
(
outfile
,
".L__wine_delay_data_%d_%s:
\n
"
,
i
,
odp
->
name
);
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
odp
->
name
);
output
(
".L__wine_delay_data_%d_%s:
\n
"
,
i
,
odp
->
name
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
odp
->
name
);
}
}
output_function_size
(
outfile
,
"__wine_spec_delay_imports"
);
output_function_size
(
"__wine_spec_delay_imports"
);
}
/* output the delayed import thunks of a Win32 module */
static
void
output_delayed_import_thunks
(
FILE
*
outfile
,
const
DLLSPEC
*
spec
)
static
void
output_delayed_import_thunks
(
const
DLLSPEC
*
spec
)
{
int
i
,
idx
,
j
,
pos
,
extra_stack_storage
=
0
;
static
const
char
delayed_import_loaders
[]
=
"__wine_spec_delayed_import_loaders"
;
...
...
@@ -913,105 +913,105 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
if
(
!
nb_delayed
)
return
;
fprintf
(
outfile
,
"
\n
/* delayed import thunks */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
8
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
asm_name
(
delayed_import_loaders
));
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
"__wine_delay_load_asm"
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
output
(
"
\n
/* delayed import thunks */
\n\n
"
);
output
(
"
\t
.text
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
8
)
);
output
(
"%s:
\n
"
,
asm_name
(
delayed_import_loaders
));
output
(
"
\t
%s
\n
"
,
func_declaration
(
"__wine_delay_load_asm"
)
);
output
(
"%s:
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
switch
(
target_cpu
)
{
case
CPU_x86
:
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
jmp *%%eax
\n
"
);
output
(
"
\t
pushl %%ecx
\n
"
);
output
(
"
\t
pushl %%edx
\n
"
);
output
(
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
output
(
"
\t
popl %%edx
\n
"
);
output
(
"
\t
popl %%ecx
\n
"
);
output
(
"
\t
jmp *%%eax
\n
"
);
break
;
case
CPU_x86_64
:
fprintf
(
outfile
,
"
\t
pushq %%rdi
\n
"
);
fprintf
(
outfile
,
"
\t
pushq %%rsi
\n
"
);
fprintf
(
outfile
,
"
\t
pushq %%rdx
\n
"
);
fprintf
(
outfile
,
"
\t
pushq %%rcx
\n
"
);
fprintf
(
outfile
,
"
\t
pushq %%r8
\n
"
);
fprintf
(
outfile
,
"
\t
pushq %%r9
\n
"
);
fprintf
(
outfile
,
"
\t
subq $8,%%rsp
\n
"
);
fprintf
(
outfile
,
"
\t
movq %%r11,%%rdi
\n
"
);
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
fprintf
(
outfile
,
"
\t
addq $8,%%rsp
\n
"
);
fprintf
(
outfile
,
"
\t
popq %%r9
\n
"
);
fprintf
(
outfile
,
"
\t
popq %%r8
\n
"
);
fprintf
(
outfile
,
"
\t
popq %%rcx
\n
"
);
fprintf
(
outfile
,
"
\t
popq %%rdx
\n
"
);
fprintf
(
outfile
,
"
\t
popq %%rsi
\n
"
);
fprintf
(
outfile
,
"
\t
popq %%rdi
\n
"
);
fprintf
(
outfile
,
"
\t
jmp *%%rax
\n
"
);
output
(
"
\t
pushq %%rdi
\n
"
);
output
(
"
\t
pushq %%rsi
\n
"
);
output
(
"
\t
pushq %%rdx
\n
"
);
output
(
"
\t
pushq %%rcx
\n
"
);
output
(
"
\t
pushq %%r8
\n
"
);
output
(
"
\t
pushq %%r9
\n
"
);
output
(
"
\t
subq $8,%%rsp
\n
"
);
output
(
"
\t
movq %%r11,%%rdi
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
output
(
"
\t
addq $8,%%rsp
\n
"
);
output
(
"
\t
popq %%r9
\n
"
);
output
(
"
\t
popq %%r8
\n
"
);
output
(
"
\t
popq %%rcx
\n
"
);
output
(
"
\t
popq %%rdx
\n
"
);
output
(
"
\t
popq %%rsi
\n
"
);
output
(
"
\t
popq %%rdi
\n
"
);
output
(
"
\t
jmp *%%rax
\n
"
);
break
;
case
CPU_SPARC
:
fprintf
(
outfile
,
"
\t
save %%sp, -96, %%sp
\n
"
);
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
fprintf
(
outfile
,
"
\t
mov %%g1, %%o0
\n
"
);
fprintf
(
outfile
,
"
\t
jmp %%o0
\n
"
);
fprintf
(
outfile
,
"
\t
restore
\n
"
);
output
(
"
\t
save %%sp, -96, %%sp
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
output
(
"
\t
mov %%g1, %%o0
\n
"
);
output
(
"
\t
jmp %%o0
\n
"
);
output
(
"
\t
restore
\n
"
);
break
;
case
CPU_ALPHA
:
fprintf
(
outfile
,
"
\t
jsr $26,%s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
fprintf
(
outfile
,
"
\t
jmp $31,($0)
\n
"
);
output
(
"
\t
jsr $26,%s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
output
(
"
\t
jmp $31,($0)
\n
"
);
break
;
case
CPU_POWERPC
:
if
(
target_platform
==
PLATFORM_APPLE
)
extra_stack_storage
=
56
;
/* Save all callee saved registers into a stackframe. */
fprintf
(
outfile
,
"
\t
stwu %s, -%d(%s)
\n
"
,
ppc_reg
(
1
),
48
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
3
),
4
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
4
),
8
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
5
),
12
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
6
),
16
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
7
),
20
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
8
),
24
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
9
),
28
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
10
),
32
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
11
),
36
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
12
),
40
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stwu %s, -%d(%s)
\n
"
,
ppc_reg
(
1
),
48
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
3
),
4
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
4
),
8
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
5
),
12
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
6
),
16
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
7
),
20
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
8
),
24
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
9
),
28
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
10
),
32
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
11
),
36
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
12
),
40
+
extra_stack_storage
,
ppc_reg
(
1
));
/* r0 -> r3 (arg1) */
fprintf
(
outfile
,
"
\t
mr %s, %s
\n
"
,
ppc_reg
(
3
),
ppc_reg
(
0
));
output
(
"
\t
mr %s, %s
\n
"
,
ppc_reg
(
3
),
ppc_reg
(
0
));
/* save return address */
fprintf
(
outfile
,
"
\t
mflr %s
\n
"
,
ppc_reg
(
0
));
fprintf
(
outfile
,
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
0
),
44
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
mflr %s
\n
"
,
ppc_reg
(
0
));
output
(
"
\t
stw %s, %d(%s)
\n
"
,
ppc_reg
(
0
),
44
+
extra_stack_storage
,
ppc_reg
(
1
));
/* Call the __wine_delay_load function, arg1 is arg1. */
fprintf
(
outfile
,
"
\t
bl %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
output
(
"
\t
bl %s
\n
"
,
asm_name
(
"__wine_spec_delay_load"
)
);
/* Load return value from call into ctr register */
fprintf
(
outfile
,
"
\t
mtctr %s
\n
"
,
ppc_reg
(
3
));
output
(
"
\t
mtctr %s
\n
"
,
ppc_reg
(
3
));
/* restore all saved registers and drop stackframe. */
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
3
),
4
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
4
),
8
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
5
),
12
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
6
),
16
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
7
),
20
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
8
),
24
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
9
),
28
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
10
),
32
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
11
),
36
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
12
),
40
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
3
),
4
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
4
),
8
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
5
),
12
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
6
),
16
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
7
),
20
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
8
),
24
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
9
),
28
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
10
),
32
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
11
),
36
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
12
),
40
+
extra_stack_storage
,
ppc_reg
(
1
));
/* Load return value from call into return register */
fprintf
(
outfile
,
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
0
),
44
+
extra_stack_storage
,
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
mtlr %s
\n
"
,
ppc_reg
(
0
));
fprintf
(
outfile
,
"
\t
addi %s, %s, %d
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
),
48
+
extra_stack_storage
);
output
(
"
\t
lwz %s, %d(%s)
\n
"
,
ppc_reg
(
0
),
44
+
extra_stack_storage
,
ppc_reg
(
1
));
output
(
"
\t
mtlr %s
\n
"
,
ppc_reg
(
0
));
output
(
"
\t
addi %s, %s, %d
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
),
48
+
extra_stack_storage
);
/* branch to ctr register. */
fprintf
(
outfile
,
"
\t
bctr
\n
"
);
output
(
"
\t
bctr
\n
"
);
break
;
}
output_function_size
(
outfile
,
"__wine_delay_load_asm"
);
fprintf
(
outfile
,
"
\n
"
);
output_function_size
(
"__wine_delay_load_asm"
);
output
(
"
\n
"
);
for
(
i
=
idx
=
0
;
i
<
nb_imports
;
i
++
)
{
...
...
@@ -1021,25 +1021,25 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
const
char
*
name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
fprintf
(
outfile
,
".L__wine_delay_imp_%d_%s:
\n
"
,
i
,
name
);
output
(
".L__wine_delay_imp_%d_%s:
\n
"
,
i
,
name
);
switch
(
target_cpu
)
{
case
CPU_x86
:
fprintf
(
outfile
,
"
\t
movl $%d, %%eax
\n
"
,
(
idx
<<
16
)
|
j
);
fprintf
(
outfile
,
"
\t
jmp %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
output
(
"
\t
movl $%d, %%eax
\n
"
,
(
idx
<<
16
)
|
j
);
output
(
"
\t
jmp %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
break
;
case
CPU_x86_64
:
fprintf
(
outfile
,
"
\t
movq $%d,%%r11
\n
"
,
(
idx
<<
16
)
|
j
);
fprintf
(
outfile
,
"
\t
jmp %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
output
(
"
\t
movq $%d,%%r11
\n
"
,
(
idx
<<
16
)
|
j
);
output
(
"
\t
jmp %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
break
;
case
CPU_SPARC
:
fprintf
(
outfile
,
"
\t
set %d, %%g1
\n
"
,
(
idx
<<
16
)
|
j
);
fprintf
(
outfile
,
"
\t
b,a %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
output
(
"
\t
set %d, %%g1
\n
"
,
(
idx
<<
16
)
|
j
);
output
(
"
\t
b,a %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
break
;
case
CPU_ALPHA
:
fprintf
(
outfile
,
"
\t
lda $0,%d($31)
\n
"
,
j
);
fprintf
(
outfile
,
"
\t
ldah $0,%d($0)
\n
"
,
idx
);
fprintf
(
outfile
,
"
\t
jmp $31,%s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
output
(
"
\t
lda $0,%d($31)
\n
"
,
j
);
output
(
"
\t
ldah $0,%d($0)
\n
"
,
idx
);
output
(
"
\t
jmp $31,%s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
break
;
case
CPU_POWERPC
:
switch
(
target_platform
)
...
...
@@ -1047,24 +1047,24 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
case
PLATFORM_APPLE
:
/* On Darwin we can use r0 and r2 */
/* Upper part in r2 */
fprintf
(
outfile
,
"
\t
lis %s, %d
\n
"
,
ppc_reg
(
2
),
idx
);
output
(
"
\t
lis %s, %d
\n
"
,
ppc_reg
(
2
),
idx
);
/* Lower part + r2 -> r0, Note we can't use r0 directly */
fprintf
(
outfile
,
"
\t
addi %s, %s, %d
\n
"
,
ppc_reg
(
0
),
ppc_reg
(
2
),
j
);
fprintf
(
outfile
,
"
\t
b %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
output
(
"
\t
addi %s, %s, %d
\n
"
,
ppc_reg
(
0
),
ppc_reg
(
2
),
j
);
output
(
"
\t
b %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
break
;
default:
/* On linux we can't use r2 since r2 is not a scratch register (hold the TOC) */
/* Save r13 on the stack */
fprintf
(
outfile
,
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
13
),
ppc_reg
(
1
));
output
(
"
\t
addi %s, %s, -0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
));
output
(
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
13
),
ppc_reg
(
1
));
/* Upper part in r13 */
fprintf
(
outfile
,
"
\t
lis %s, %d
\n
"
,
ppc_reg
(
13
),
idx
);
output
(
"
\t
lis %s, %d
\n
"
,
ppc_reg
(
13
),
idx
);
/* Lower part + r13 -> r0, Note we can't use r0 directly */
fprintf
(
outfile
,
"
\t
addi %s, %s, %d
\n
"
,
ppc_reg
(
0
),
ppc_reg
(
13
),
j
);
output
(
"
\t
addi %s, %s, %d
\n
"
,
ppc_reg
(
0
),
ppc_reg
(
13
),
j
);
/* Restore r13 */
fprintf
(
outfile
,
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
13
),
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
addic %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
));
fprintf
(
outfile
,
"
\t
b %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
output
(
"
\t
stw %s, 0(%s)
\n
"
,
ppc_reg
(
13
),
ppc_reg
(
1
));
output
(
"
\t
addic %s, %s, 0x4
\n
"
,
ppc_reg
(
1
),
ppc_reg
(
1
));
output
(
"
\t
b %s
\n
"
,
asm_name
(
"__wine_delay_load_asm"
)
);
break
;
}
break
;
...
...
@@ -1072,25 +1072,25 @@ static void output_delayed_import_thunks( FILE *outfile, const DLLSPEC *spec )
}
idx
++
;
}
output_function_size
(
outfile
,
delayed_import_loaders
);
output_function_size
(
delayed_import_loaders
);
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
"%s:
\n
"
,
asm_name
(
delayed_import_thunks
));
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
"%s:
\n
"
,
asm_name
(
delayed_import_thunks
));
for
(
i
=
pos
=
0
;
i
<
nb_imports
;
i
++
)
{
if
(
!
dll_imports
[
i
]
->
delay
)
continue
;
for
(
j
=
0
;
j
<
dll_imports
[
i
]
->
nb_imports
;
j
++
,
pos
+=
get_ptr_size
())
{
ORDDEF
*
odp
=
dll_imports
[
i
]
->
imports
[
j
];
output_import_thunk
(
o
utfile
,
o
dp
->
name
?
odp
->
name
:
odp
->
export_name
,
output_import_thunk
(
odp
->
name
?
odp
->
name
:
odp
->
export_name
,
".L__wine_delay_IAT"
,
pos
);
}
}
output_function_size
(
outfile
,
delayed_import_thunks
);
output_function_size
(
delayed_import_thunks
);
}
/* output import stubs for exported entry points that link to external symbols */
static
void
output_external_link_imports
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
static
void
output_external_link_imports
(
DLLSPEC
*
spec
)
{
unsigned
int
i
,
pos
;
...
...
@@ -1105,25 +1105,25 @@ static void output_external_link_imports( FILE *outfile, DLLSPEC *spec )
remove_name
(
&
ext_link_imports
,
i
--
);
}
fprintf
(
outfile
,
"
\n
/* external link thunks */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
".L__wine_spec_external_links:
\n
"
);
output
(
"
\n
/* external link thunks */
\n\n
"
);
output
(
"
\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
".L__wine_spec_external_links:
\n
"
);
for
(
i
=
0
;
i
<
ext_link_imports
.
count
;
i
++
)
fprintf
(
outfile
,
"
\t
%s %s
\n
"
,
get_asm_ptr_keyword
(),
asm_name
(
ext_link_imports
.
names
[
i
])
);
output
(
"
\t
%s %s
\n
"
,
get_asm_ptr_keyword
(),
asm_name
(
ext_link_imports
.
names
[
i
])
);
fprintf
(
outfile
,
"
\n\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
"%s:
\n
"
,
asm_name
(
"__wine_spec_external_link_thunks"
)
);
output
(
"
\n\t
.text
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
"%s:
\n
"
,
asm_name
(
"__wine_spec_external_link_thunks"
)
);
for
(
i
=
pos
=
0
;
i
<
ext_link_imports
.
count
;
i
++
)
{
char
buffer
[
256
];
sprintf
(
buffer
,
"__wine_spec_ext_link_%s"
,
ext_link_imports
.
names
[
i
]
);
output_import_thunk
(
outfile
,
buffer
,
".L__wine_spec_external_links"
,
pos
);
output_import_thunk
(
buffer
,
".L__wine_spec_external_links"
,
pos
);
pos
+=
get_ptr_size
();
}
output_function_size
(
outfile
,
"__wine_spec_external_link_thunks"
);
output_function_size
(
"__wine_spec_external_link_thunks"
);
}
/*******************************************************************
...
...
@@ -1131,15 +1131,15 @@ static void output_external_link_imports( FILE *outfile, DLLSPEC *spec )
*
* Output the functions for stub entry points
*/
void
output_stubs
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
void
output_stubs
(
DLLSPEC
*
spec
)
{
const
char
*
name
,
*
exp_name
;
int
i
,
pos
;
if
(
!
has_stubs
(
spec
))
return
;
fprintf
(
outfile
,
"
\n
/* stub functions */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
output
(
"
\n
/* stub functions */
\n\n
"
);
output
(
"
\t
.text
\n
"
);
for
(
i
=
pos
=
0
;
i
<
spec
->
nb_entry_points
;
i
++
)
{
...
...
@@ -1148,64 +1148,64 @@ void output_stubs( FILE *outfile, DLLSPEC *spec )
name
=
get_stub_name
(
odp
,
spec
);
exp_name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
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
subl $4,%%esp
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
output
(
"%s:
\n
"
,
asm_name
(
name
)
);
output
(
"
\t
subl $4,%%esp
\n
"
);
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:"
);
if
(
exp_name
)
{
fprintf
(
outfile
,
"
\t
leal .L__wine_stub_strings+%d-1b(%%eax),%%ecx
\n
"
,
pos
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
output
(
"
\t
leal .L__wine_stub_strings+%d-1b(%%eax),%%ecx
\n
"
,
pos
);
output
(
"
\t
pushl %%ecx
\n
"
);
pos
+=
strlen
(
exp_name
)
+
1
;
}
else
fprintf
(
outfile
,
"
\t
pushl $%d
\n
"
,
odp
->
ordinal
);
fprintf
(
outfile
,
"
\t
leal .L__wine_spec_file_name-1b(%%eax),%%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
output
(
"
\t
pushl $%d
\n
"
,
odp
->
ordinal
);
output
(
"
\t
leal .L__wine_spec_file_name-1b(%%eax),%%ecx
\n
"
);
output
(
"
\t
pushl %%ecx
\n
"
);
}
else
{
if
(
exp_name
)
{
fprintf
(
outfile
,
"
\t
pushl $.L__wine_stub_strings+%d
\n
"
,
pos
);
output
(
"
\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 $.L__wine_spec_file_name
\n
"
);
output
(
"
\t
pushl $%d
\n
"
,
odp
->
ordinal
);
output
(
"
\t
pushl $.L__wine_spec_file_name
\n
"
);
}
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_unimplemented_stub"
)
);
output_function_size
(
outfile
,
name
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_unimplemented_stub"
)
);
output_function_size
(
name
);
}
if
(
pos
)
{
fprintf
(
outfile
,
"
\t
%s
\n
"
,
get_asm_string_section
()
);
fprintf
(
outfile
,
".L__wine_stub_strings:
\n
"
);
output
(
"
\t
%s
\n
"
,
get_asm_string_section
()
);
output
(
".L__wine_stub_strings:
\n
"
);
for
(
i
=
0
;
i
<
spec
->
nb_entry_points
;
i
++
)
{
ORDDEF
*
odp
=
&
spec
->
entry_points
[
i
];
if
(
odp
->
type
!=
TYPE_STUB
)
continue
;
exp_name
=
odp
->
name
?
odp
->
name
:
odp
->
export_name
;
if
(
exp_name
)
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
exp_name
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
exp_name
);
}
}
}
/* output the import and delayed import tables of a Win32 module */
void
output_imports
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
void
output_imports
(
DLLSPEC
*
spec
)
{
output_immediate_imports
(
outfile
);
output_delayed_imports
(
outfile
,
spec
);
output_immediate_import_thunks
(
outfile
);
output_delayed_import_thunks
(
outfile
,
spec
);
output_external_link_imports
(
outfile
,
spec
);
output_immediate_imports
();
output_delayed_imports
(
spec
);
output_immediate_import_thunks
();
output_delayed_import_thunks
(
spec
);
output_external_link_imports
(
spec
);
if
(
nb_imports
||
ext_link_imports
.
count
||
has_stubs
(
spec
)
||
has_relays
(
spec
))
output_get_pc_thunk
(
outfile
);
output_get_pc_thunk
();
}
tools/winebuild/main.c
View file @
71580499
...
...
@@ -75,6 +75,7 @@ char **lib_path = NULL;
char
*
input_file_name
=
NULL
;
char
*
spec_file_name
=
NULL
;
FILE
*
output_file
=
NULL
;
const
char
*
output_file_name
=
NULL
;
static
const
char
*
output_file_source_name
;
...
...
@@ -82,7 +83,6 @@ char *as_command = NULL;
char
*
ld_command
=
NULL
;
char
*
nm_command
=
NULL
;
static
FILE
*
output_file
;
static
int
nb_res_files
;
static
char
**
res_files
;
...
...
@@ -597,11 +597,11 @@ int main(int argc, char **argv)
case
SPEC_WIN16
:
if
(
argv
[
0
])
fatal_error
(
"file argument '%s' not allowed in this mode
\n
"
,
argv
[
0
]
);
BuildSpec16File
(
output_file
,
spec
);
BuildSpec16File
(
spec
);
break
;
case
SPEC_WIN32
:
read_undef_symbols
(
spec
,
argv
);
BuildSpec32File
(
output_file
,
spec
);
BuildSpec32File
(
spec
);
break
;
default:
assert
(
0
);
}
...
...
@@ -613,22 +613,22 @@ int main(int argc, char **argv)
load_import_libs
(
argv
);
if
(
spec_file_name
&&
!
parse_input_file
(
spec
))
break
;
read_undef_symbols
(
spec
,
argv
);
BuildSpec32File
(
output_file
,
spec
);
BuildSpec32File
(
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
(
!
spec_file_name
)
fatal_error
(
"missing .spec file
\n
"
);
if
(
!
parse_input_file
(
spec
))
break
;
BuildDef32File
(
output_file
,
spec
);
BuildDef32File
(
spec
);
break
;
case
MODE_RELAY16
:
if
(
argv
[
0
])
fatal_error
(
"file argument '%s' not allowed in this mode
\n
"
,
argv
[
0
]
);
BuildRelays16
(
output_file
);
BuildRelays16
();
break
;
case
MODE_RELAY32
:
if
(
argv
[
0
])
fatal_error
(
"file argument '%s' not allowed in this mode
\n
"
,
argv
[
0
]
);
BuildRelays32
(
output_file
);
BuildRelays32
();
break
;
default:
usage
(
1
);
...
...
@@ -637,7 +637,7 @@ int main(int argc, char **argv)
if
(
nb_errors
)
exit
(
1
);
if
(
output_file_name
)
{
fclose
(
output_file
);
if
(
fclose
(
output_file
)
<
0
)
fatal_perror
(
"fclose"
);
if
(
output_file_source_name
)
assemble_file
(
output_file_source_name
,
output_file_name
);
output_file_name
=
NULL
;
}
...
...
tools/winebuild/relay.c
View file @
71580499
...
...
@@ -50,11 +50,11 @@
/* fix this if the ntdll_thread_regs structure is changed */
#define GS_OFFSET 0x1b0
/* STRUCTOFFSET(TEB,SpareBytes1) + STRUCTOFFSET(ntdll_thread_regs,gs) */
static
void
function_header
(
FILE
*
outfile
,
const
char
*
name
)
static
void
function_header
(
const
char
*
name
)
{
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
name
)
);
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
output
(
"%s
\n
"
,
asm_globl
(
name
)
);
}
...
...
@@ -125,74 +125,73 @@ static void function_header( FILE *outfile, const char *name )
* (sp-20) long saved edx
* (sp-24) long saved previous stack
*/
static
void
BuildCallFrom16Core
(
FILE
*
outfile
,
int
reg_func
,
int
thunk
)
static
void
BuildCallFrom16Core
(
int
reg_func
,
int
thunk
)
{
/* Function header */
if
(
thunk
)
function_header
(
outfile
,
"__wine_call_from_16_thunk"
);
else
if
(
reg_func
)
function_header
(
outfile
,
"__wine_call_from_16_regs"
);
else
function_header
(
outfile
,
"__wine_call_from_16"
);
if
(
thunk
)
function_header
(
"__wine_call_from_16_thunk"
);
else
if
(
reg_func
)
function_header
(
"__wine_call_from_16_regs"
);
else
function_header
(
"__wine_call_from_16"
);
/* Create STACK16FRAME (except STACK32FRAME link) */
fprintf
(
outfile
,
"
\t
pushw %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
pushw %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
pushw %%es
\n
"
);
fprintf
(
outfile
,
"
\t
pushw %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
output
(
"
\t
pushw %%gs
\n
"
);
output
(
"
\t
pushw %%fs
\n
"
);
output
(
"
\t
pushw %%es
\n
"
);
output
(
"
\t
pushw %%ds
\n
"
);
output
(
"
\t
pushl %%ebp
\n
"
);
output
(
"
\t
pushl %%ecx
\n
"
);
output
(
"
\t
pushl %%edx
\n
"
);
/* Save original EFlags register */
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
pushfl
\n
"
);
if
(
reg_func
)
output
(
"
\t
pushfl
\n
"
);
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
call 1f
\n
"
);
fprintf
(
outfile
,
"1:
\t
popl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x2e
\n\t
movl %s-1b(%%ecx),%%edx
\n
"
,
asm_name
(
"CallTo16_DataSelector"
)
);
output
(
"
\t
call 1f
\n
"
);
output
(
"1:
\t
popl %%ecx
\n
"
);
output
(
"
\t
.byte 0x2e
\n\t
movl %s-1b(%%ecx),%%edx
\n
"
,
asm_name
(
"CallTo16_DataSelector"
)
);
}
else
fprintf
(
outfile
,
"
\t
.byte 0x2e
\n\t
movl %s,%%edx
\n
"
,
asm_name
(
"CallTo16_DataSelector"
)
);
output
(
"
\t
.byte 0x2e
\n\t
movl %s,%%edx
\n
"
,
asm_name
(
"CallTo16_DataSelector"
)
);
/* Load 32-bit segment registers */
fprintf
(
outfile
,
"
\t
movw %%dx, %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%dx, %%es
\n
"
);
output
(
"
\t
movw %%dx, %%ds
\n
"
);
output
(
"
\t
movw %%dx, %%es
\n
"
);
if
(
UsePIC
)
fprintf
(
outfile
,
"
\t
movw %s-1b(%%ecx), %%fs
\n
"
,
asm_name
(
"CallTo16_TebSelector"
)
);
output
(
"
\t
movw %s-1b(%%ecx), %%fs
\n
"
,
asm_name
(
"CallTo16_TebSelector"
)
);
else
fprintf
(
outfile
,
"
\t
movw %s, %%fs
\n
"
,
asm_name
(
"CallTo16_TebSelector"
)
);
output
(
"
\t
movw %s, %%fs
\n
"
,
asm_name
(
"CallTo16_TebSelector"
)
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
mov (%d),%%gs
\n
"
,
GS_OFFSET
);
output
(
"
\t
.byte 0x64
\n\t
mov (%d),%%gs
\n
"
,
GS_OFFSET
);
/* Translate STACK16FRAME base to flat offset in %edx */
fprintf
(
outfile
,
"
\t
movw %%ss, %%dx
\n
"
);
fprintf
(
outfile
,
"
\t
andl $0xfff8, %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
shrl $1, %%edx
\n
"
);
output
(
"
\t
movw %%ss, %%dx
\n
"
);
output
(
"
\t
andl $0xfff8, %%edx
\n
"
);
output
(
"
\t
shrl $1, %%edx
\n
"
);
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
addl wine_ldt_copy_ptr-1b(%%ecx),%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movl (%%edx), %%edx
\n
"
);
output
(
"
\t
addl wine_ldt_copy_ptr-1b(%%ecx),%%edx
\n
"
);
output
(
"
\t
movl (%%edx), %%edx
\n
"
);
}
else
fprintf
(
outfile
,
"
\t
movl %s(%%edx), %%edx
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
leal %d(%%ebp,%%edx), %%edx
\n
"
,
reg_func
?
0
:
-
4
);
output
(
"
\t
movl %s(%%edx), %%edx
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
output
(
"
\t
movzwl %%sp, %%ebp
\n
"
);
output
(
"
\t
leal %d(%%ebp,%%edx), %%edx
\n
"
,
reg_func
?
0
:
-
4
);
/* Get saved flags into %ecx */
if
(
reg_func
)
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
if
(
reg_func
)
output
(
"
\t
popl %%ecx
\n
"
);
/* Get the 32-bit stack pointer from the TEB and complete STACK16FRAME */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl (%d), %%ebp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
output
(
"
\t
.byte 0x64
\n\t
movl (%d), %%ebp
\n
"
,
STACKOFFSET
);
output
(
"
\t
pushl %%ebp
\n
"
);
/* Switch stacks */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw %%ss, (%d)
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw %%sp, (%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
pushl %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ss
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ebp, %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
addl $%d, %%ebp
\n
"
,
STACK32OFFSET
(
ebp
)
);
output
(
"
\t
.byte 0x64
\n\t
movw %%ss, (%d)
\n
"
,
STACKOFFSET
+
2
);
output
(
"
\t
.byte 0x64
\n\t
movw %%sp, (%d)
\n
"
,
STACKOFFSET
);
output
(
"
\t
pushl %%ds
\n
"
);
output
(
"
\t
popl %%ss
\n
"
);
output
(
"
\t
movl %%ebp, %%esp
\n
"
);
output
(
"
\t
addl $%d, %%ebp
\n
"
,
STACK32OFFSET
(
ebp
)
);
/* At this point:
...
...
@@ -209,32 +208,32 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk )
if
(
thunk
)
{
/* Set up registers as expected and call thunk */
fprintf
(
outfile
,
"
\t
leal %d(%%edx), %%ebx
\n
"
,
(
int
)
sizeof
(
STACK16FRAME
)
-
22
);
fprintf
(
outfile
,
"
\t
leal -4(%%esp), %%ebp
\n
"
);
output
(
"
\t
leal %d(%%edx), %%ebx
\n
"
,
(
int
)
sizeof
(
STACK16FRAME
)
-
22
);
output
(
"
\t
leal -4(%%esp), %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
call *%d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
output
(
"
\t
call *%d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
/* Switch stack back */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d), %%esp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
output
(
"
\t
.byte 0x64
\n\t
movzwl (%d), %%esp
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
/* Restore registers and return directly to caller */
fprintf
(
outfile
,
"
\t
addl $8, %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%es
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
addl $20, %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
xorb %%ch, %%ch
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
addw %%cx, %%sp
\n
"
);
fprintf
(
outfile
,
"
\t
push %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
output
(
"
\t
addl $8, %%esp
\n
"
);
output
(
"
\t
popl %%ebp
\n
"
);
output
(
"
\t
popw %%ds
\n
"
);
output
(
"
\t
popw %%es
\n
"
);
output
(
"
\t
popw %%fs
\n
"
);
output
(
"
\t
popw %%gs
\n
"
);
output
(
"
\t
addl $20, %%esp
\n
"
);
output
(
"
\t
xorb %%ch, %%ch
\n
"
);
output
(
"
\t
popl %%ebx
\n
"
);
output
(
"
\t
addw %%cx, %%sp
\n
"
);
output
(
"
\t
push %%ebx
\n
"
);
output
(
"
\t
.byte 0x66
\n
"
);
output
(
"
\t
lret
\n
"
);
return
;
}
...
...
@@ -243,132 +242,131 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk )
/* Build register CONTEXT */
if
(
reg_func
)
{
fprintf
(
outfile
,
"
\t
subl $%d, %%esp
\n
"
,
(
int
)
sizeof
(
CONTEXT86
)
);
fprintf
(
outfile
,
"
\t
movl %%ecx, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %%ebx, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
movl %%esi, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
movl %%edi, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ebp
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ecx
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
edx
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ds
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
es
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
fs
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
gs
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
cs
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
addl $%d, %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
output
(
"
\t
subl $%d, %%esp
\n
"
,
(
int
)
sizeof
(
CONTEXT86
)
);
output
(
"
\t
movl %%ecx, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
output
(
"
\t
movl %%ebx, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
output
(
"
\t
movl %%esi, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
output
(
"
\t
movl %%edi, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
output
(
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ebp
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
output
(
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ecx
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
output
(
"
\t
movl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
edx
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
output
(
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ds
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
output
(
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
es
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
output
(
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
fs
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
output
(
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
gs
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
output
(
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
cs
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
output
(
"
\t
movzwl %d(%%edx), %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
output
(
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
+
2
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
output
(
"
\t
.byte 0x64
\n\t
movzwl (%d), %%eax
\n
"
,
STACKOFFSET
);
output
(
"
\t
addl $%d, %%eax
\n
"
,
STACK16OFFSET
(
ip
)
);
output
(
"
\t
movl %%eax, %d(%%esp)
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
#if 0
fprintf( outfile,
"\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
output(
"\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
#endif
/* Push address of CONTEXT86 structure -- popped by the relay routine */
fprintf
(
outfile
,
"
\t
movl %%esp,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
andl $~15,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
subl $4,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
movl %%esp,%%eax
\n
"
);
output
(
"
\t
andl $~15,%%esp
\n
"
);
output
(
"
\t
subl $4,%%esp
\n
"
);
output
(
"
\t
pushl %%eax
\n
"
);
}
else
{
fprintf
(
outfile
,
"
\t
subl $8,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
andl $~15,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
addl $8,%%esp
\n
"
);
output
(
"
\t
subl $8,%%esp
\n
"
);
output
(
"
\t
andl $~15,%%esp
\n
"
);
output
(
"
\t
addl $8,%%esp
\n
"
);
}
/* Call relay routine (which will call the API entry point) */
fprintf
(
outfile
,
"
\t
leal %d(%%edx), %%eax
\n
"
,
(
int
)
sizeof
(
STACK16FRAME
)
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
fprintf
(
outfile
,
"
\t
call *%d(%%edx)
\n
"
,
STACK16OFFSET
(
relay
)
);
output
(
"
\t
leal %d(%%edx), %%eax
\n
"
,
(
int
)
sizeof
(
STACK16FRAME
)
);
output
(
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
pushl %d(%%edx)
\n
"
,
STACK16OFFSET
(
entry_point
)
);
output
(
"
\t
call *%d(%%edx)
\n
"
,
STACK16OFFSET
(
relay
)
);
if
(
reg_func
)
{
fprintf
(
outfile
,
"
\t
leal -%d(%%ebp), %%ebx
\n
"
,
(
int
)
sizeof
(
CONTEXT
)
+
STACK32OFFSET
(
ebp
)
);
output
(
"
\t
leal -%d(%%ebp), %%ebx
\n
"
,
(
int
)
sizeof
(
CONTEXT
)
+
STACK32OFFSET
(
ebp
)
);
/* Switch stack back */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d), %%esp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
output
(
"
\t
.byte 0x64
\n\t
movzwl (%d), %%esp
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
/* Get return address to CallFrom16 stub */
fprintf
(
outfile
,
"
\t
addw $%d, %%sp
\n
"
,
STACK16OFFSET
(
callfrom_ip
)
-
4
);
fprintf
(
outfile
,
"
\t
popl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
output
(
"
\t
addw $%d, %%sp
\n
"
,
STACK16OFFSET
(
callfrom_ip
)
-
4
);
output
(
"
\t
popl %%eax
\n
"
);
output
(
"
\t
popl %%edx
\n
"
);
/* Restore all registers from CONTEXT */
fprintf
(
outfile
,
"
\t
movw %d(%%ebx), %%ss
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%esp
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
fprintf
(
outfile
,
"
\t
addl $4, %%esp
\n
"
);
/* room for final return address */
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
fprintf
(
outfile
,
"
\t
pushl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
popl %%es
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
fprintf
(
outfile
,
"
\t
popl %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
fprintf
(
outfile
,
"
\t
popl %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ebx), %%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
popl %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popfl
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
output
(
"
\t
movw %d(%%ebx), %%ss
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
output
(
"
\t
movl %d(%%ebx), %%esp
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
output
(
"
\t
addl $4, %%esp
\n
"
);
/* room for final return address */
output
(
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
output
(
"
\t
pushw %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
output
(
"
\t
pushl %%edx
\n
"
);
output
(
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
output
(
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
output
(
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
output
(
"
\t
popl %%es
\n
"
);
output
(
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
output
(
"
\t
popl %%fs
\n
"
);
output
(
"
\t
pushl %d(%%ebx)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
output
(
"
\t
popl %%gs
\n
"
);
output
(
"
\t
movl %d(%%ebx), %%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
output
(
"
\t
movl %d(%%ebx), %%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
output
(
"
\t
movl %d(%%ebx), %%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
output
(
"
\t
movl %d(%%ebx), %%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
output
(
"
\t
movl %d(%%ebx), %%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
output
(
"
\t
movl %d(%%ebx), %%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
output
(
"
\t
movl %d(%%ebx), %%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
output
(
"
\t
popl %%ds
\n
"
);
output
(
"
\t
popfl
\n
"
);
output
(
"
\t
lret
\n
"
);
}
else
{
/* Switch stack back */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movzwl (%d), %%esp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
movw (%d), %%ss
\n
"
,
STACKOFFSET
+
2
);
output
(
"
\t
.byte 0x64
\n\t
movzwl (%d), %%esp
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
/* Restore registers */
fprintf
(
outfile
,
"
\t
popl %%edx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%es
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%gs
\n
"
);
output
(
"
\t
popl %%edx
\n
"
);
output
(
"
\t
popl %%ecx
\n
"
);
output
(
"
\t
popl %%ebp
\n
"
);
output
(
"
\t
popw %%ds
\n
"
);
output
(
"
\t
popw %%es
\n
"
);
output
(
"
\t
popw %%fs
\n
"
);
output
(
"
\t
popw %%gs
\n
"
);
/* Return to return stub which will return to caller */
fprintf
(
outfile
,
"
\t
lret $12
\n
"
);
output
(
"
\t
lret $12
\n
"
);
}
if
(
thunk
)
output_function_size
(
outfile
,
"__wine_call_from_16_thunk"
);
else
if
(
reg_func
)
output_function_size
(
outfile
,
"__wine_call_from_16_regs"
);
else
output_function_size
(
outfile
,
"__wine_call_from_16"
);
if
(
thunk
)
output_function_size
(
"__wine_call_from_16_thunk"
);
else
if
(
reg_func
)
output_function_size
(
"__wine_call_from_16_regs"
);
else
output_function_size
(
"__wine_call_from_16"
);
}
...
...
@@ -391,44 +389,44 @@ static void BuildCallFrom16Core( FILE *outfile, int reg_func, int thunk )
* or else set to default values. The target routine address is either
* given directly or taken from the CONTEXT86.
*/
static
void
BuildCallTo16Core
(
FILE
*
outfile
,
int
reg_func
)
static
void
BuildCallTo16Core
(
int
reg_func
)
{
const
char
*
name
=
reg_func
?
"wine_call_to_16_regs"
:
"wine_call_to_16"
;
/* Function header */
function_header
(
outfile
,
name
);
function_header
(
name
);
/* Function entry sequence */
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp, %%ebp
\n
"
);
output
(
"
\t
pushl %%ebp
\n
"
);
output
(
"
\t
movl %%esp, %%ebp
\n
"
);
/* Save the 32-bit registers */
fprintf
(
outfile
,
"
\t
pushl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
mov %%gs,(%d)
\n
"
,
GS_OFFSET
);
output
(
"
\t
pushl %%ebx
\n
"
);
output
(
"
\t
pushl %%esi
\n
"
);
output
(
"
\t
pushl %%edi
\n
"
);
output
(
"
\t
.byte 0x64
\n\t
mov %%gs,(%d)
\n
"
,
GS_OFFSET
);
/* Setup exception frame */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
pushl (%d)
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
pushl 16(%%ebp)
\n
"
);
/* handler */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
pushl (0)
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl %%esp,(0)
\n
"
);
output
(
"
\t
.byte 0x64
\n\t
pushl (%d)
\n
"
,
STACKOFFSET
);
output
(
"
\t
pushl 16(%%ebp)
\n
"
);
/* handler */
output
(
"
\t
.byte 0x64
\n\t
pushl (0)
\n
"
);
output
(
"
\t
.byte 0x64
\n\t
movl %%esp,(0)
\n
"
);
/* Call the actual CallTo16 routine (simulate a lcall) */
fprintf
(
outfile
,
"
\t
pushl %%cs
\n
"
);
fprintf
(
outfile
,
"
\t
call .L%s
\n
"
,
name
);
output
(
"
\t
pushl %%cs
\n
"
);
output
(
"
\t
call .L%s
\n
"
,
name
);
/* Remove exception frame */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (0)
\n
"
);
fprintf
(
outfile
,
"
\t
addl $4, %%esp
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
popl (0)
\n
"
);
output
(
"
\t
addl $4, %%esp
\n
"
);
output
(
"
\t
.byte 0x64
\n\t
popl (%d)
\n
"
,
STACKOFFSET
);
if
(
!
reg_func
)
{
/* Convert return value */
fprintf
(
outfile
,
"
\t
andl $0xffff,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
shll $16,%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
orl %%edx,%%eax
\n
"
);
output
(
"
\t
andl $0xffff,%%eax
\n
"
);
output
(
"
\t
shll $16,%%edx
\n
"
);
output
(
"
\t
orl %%edx,%%eax
\n
"
);
}
else
{
...
...
@@ -442,94 +440,94 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
* at the cost of a somewhat less efficient return path.]
*/
fprintf
(
outfile
,
"
\t
movl %d(%%esp), %%edi
\n
"
,
STACK32OFFSET
(
target
)
-
STACK32OFFSET
(
edi
));
output
(
"
\t
movl %d(%%esp), %%edi
\n
"
,
STACK32OFFSET
(
target
)
-
STACK32OFFSET
(
edi
));
/* everything above edi has been popped already */
fprintf
(
outfile
,
"
\t
movl %%eax, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %%ebx, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
movl %%ecx, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %%edx, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
fprintf
(
outfile
,
"
\t
movl %%ebp, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
movl %%esi, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
output
(
"
\t
movl %%eax, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
output
(
"
\t
movl %%ebx, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
output
(
"
\t
movl %%ecx, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
output
(
"
\t
movl %%edx, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
output
(
"
\t
movl %%ebp, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
output
(
"
\t
movl %%esi, %d(%%edi)
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
/* The return glue code saved %esp into %esi */
}
/* Restore the 32-bit registers */
fprintf
(
outfile
,
"
\t
popl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
output
(
"
\t
popl %%edi
\n
"
);
output
(
"
\t
popl %%esi
\n
"
);
output
(
"
\t
popl %%ebx
\n
"
);
/* Function exit sequence */
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
ret $12
\n
"
);
output
(
"
\t
popl %%ebp
\n
"
);
output
(
"
\t
ret $12
\n
"
);
/* Start of the actual CallTo16 routine */
fprintf
(
outfile
,
".L%s:
\n
"
,
name
);
output
(
".L%s:
\n
"
,
name
);
/* Switch to the 16-bit stack */
fprintf
(
outfile
,
"
\t
movl %%esp,%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%ss
\n
"
,
STACKOFFSET
+
2
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movw (%d),%%sp
\n
"
,
STACKOFFSET
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl %%edx,(%d)
\n
"
,
STACKOFFSET
);
output
(
"
\t
movl %%esp,%%edx
\n
"
);
output
(
"
\t
.byte 0x64
\n\t
movw (%d),%%ss
\n
"
,
STACKOFFSET
+
2
);
output
(
"
\t
.byte 0x64
\n\t
movw (%d),%%sp
\n
"
,
STACKOFFSET
);
output
(
"
\t
.byte 0x64
\n\t
movl %%edx,(%d)
\n
"
,
STACKOFFSET
);
/* Make %bp point to the previous stackframe (built by CallFrom16) */
fprintf
(
outfile
,
"
\t
movzwl %%sp,%%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
leal %d(%%ebp),%%ebp
\n
"
,
STACK16OFFSET
(
bp
)
);
output
(
"
\t
movzwl %%sp,%%ebp
\n
"
);
output
(
"
\t
leal %d(%%ebp),%%ebp
\n
"
,
STACK16OFFSET
(
bp
)
);
/* Add the specified offset to the new sp */
fprintf
(
outfile
,
"
\t
subw %d(%%edx), %%sp
\n
"
,
STACK32OFFSET
(
nb_args
)
);
output
(
"
\t
subw %d(%%edx), %%sp
\n
"
,
STACK32OFFSET
(
nb_args
)
);
if
(
reg_func
)
{
/* Push the called routine address */
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%edx
\n
"
,
STACK32OFFSET
(
target
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
fprintf
(
outfile
,
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
output
(
"
\t
movl %d(%%edx),%%edx
\n
"
,
STACK32OFFSET
(
target
)
);
output
(
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
output
(
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
/* Get the registers */
fprintf
(
outfile
,
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
popl %%es
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
fprintf
(
outfile
,
"
\t
popl %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
fprintf
(
outfile
,
"
\t
popl %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%edx),%%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
output
(
"
\t
pushw %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
output
(
"
\t
pushl %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
output
(
"
\t
popl %%es
\n
"
);
output
(
"
\t
pushl %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
output
(
"
\t
popl %%fs
\n
"
);
output
(
"
\t
pushl %d(%%edx)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
output
(
"
\t
popl %%gs
\n
"
);
output
(
"
\t
movl %d(%%edx),%%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
output
(
"
\t
movl %d(%%edx),%%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
output
(
"
\t
movl %d(%%edx),%%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
output
(
"
\t
movl %d(%%edx),%%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
output
(
"
\t
movl %d(%%edx),%%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
output
(
"
\t
movl %d(%%edx),%%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
output
(
"
\t
movl %d(%%edx),%%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
/* Get the 16-bit ds */
fprintf
(
outfile
,
"
\t
popw %%ds
\n
"
);
output
(
"
\t
popw %%ds
\n
"
);
}
else
/* not a register function */
{
/* Push the called routine address */
fprintf
(
outfile
,
"
\t
pushl %d(%%edx)
\n
"
,
STACK32OFFSET
(
target
)
);
output
(
"
\t
pushl %d(%%edx)
\n
"
,
STACK32OFFSET
(
target
)
);
/* Set %fs and %gs to the value saved by the last CallFrom16 */
fprintf
(
outfile
,
"
\t
pushw %d(%%ebp)
\n
"
,
STACK16OFFSET
(
fs
)
-
STACK16OFFSET
(
bp
)
);
fprintf
(
outfile
,
"
\t
popw %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
pushw %d(%%ebp)
\n
"
,
STACK16OFFSET
(
gs
)
-
STACK16OFFSET
(
bp
)
);
fprintf
(
outfile
,
"
\t
popw %%gs
\n
"
);
output
(
"
\t
pushw %d(%%ebp)
\n
"
,
STACK16OFFSET
(
fs
)
-
STACK16OFFSET
(
bp
)
);
output
(
"
\t
popw %%fs
\n
"
);
output
(
"
\t
pushw %d(%%ebp)
\n
"
,
STACK16OFFSET
(
gs
)
-
STACK16OFFSET
(
bp
)
);
output
(
"
\t
popw %%gs
\n
"
);
/* Set %ds and %es (and %ax just in case) equal to %ss */
fprintf
(
outfile
,
"
\t
movw %%ss,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%ds
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%es
\n
"
);
output
(
"
\t
movw %%ss,%%ax
\n
"
);
output
(
"
\t
movw %%ax,%%ds
\n
"
);
output
(
"
\t
movw %%ax,%%es
\n
"
);
}
/* Jump to the called routine */
fprintf
(
outfile
,
"
\t
.byte 0x66
\n
"
);
fprintf
(
outfile
,
"
\t
lret
\n
"
);
output
(
"
\t
.byte 0x66
\n
"
);
output
(
"
\t
lret
\n
"
);
/* Function footer */
output_function_size
(
outfile
,
name
);
output_function_size
(
name
);
}
...
...
@@ -538,34 +536,34 @@ static void BuildCallTo16Core( FILE *outfile, int reg_func )
*
* Build the return code for 16-bit callbacks
*/
static
void
BuildRet16Func
(
FILE
*
outfile
)
static
void
BuildRet16Func
(
void
)
{
function_header
(
outfile
,
"__wine_call_to_16_ret"
);
function_header
(
"__wine_call_to_16_ret"
);
/* Save %esp into %esi */
fprintf
(
outfile
,
"
\t
movl %%esp,%%esi
\n
"
);
output
(
"
\t
movl %%esp,%%esi
\n
"
);
/* Restore 32-bit segment registers */
fprintf
(
outfile
,
"
\t
.byte 0x2e
\n\t
movl %s"
,
asm_name
(
"CallTo16_DataSelector"
)
);
fprintf
(
outfile
,
"-%s,%%edi
\n
"
,
asm_name
(
"__wine_call16_start"
)
);
fprintf
(
outfile
,
"
\t
movw %%di,%%ds
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%di,%%es
\n
"
);
output
(
"
\t
.byte 0x2e
\n\t
movl %s"
,
asm_name
(
"CallTo16_DataSelector"
)
);
output
(
"-%s,%%edi
\n
"
,
asm_name
(
"__wine_call16_start"
)
);
output
(
"
\t
movw %%di,%%ds
\n
"
);
output
(
"
\t
movw %%di,%%es
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x2e
\n\t
mov %s"
,
asm_name
(
"CallTo16_TebSelector"
)
);
fprintf
(
outfile
,
"-%s,%%fs
\n
"
,
asm_name
(
"__wine_call16_start"
)
);
output
(
"
\t
.byte 0x2e
\n\t
mov %s"
,
asm_name
(
"CallTo16_TebSelector"
)
);
output
(
"-%s,%%fs
\n
"
,
asm_name
(
"__wine_call16_start"
)
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
mov (%d),%%gs
\n
"
,
GS_OFFSET
);
output
(
"
\t
.byte 0x64
\n\t
mov (%d),%%gs
\n
"
,
GS_OFFSET
);
/* Restore the 32-bit stack */
fprintf
(
outfile
,
"
\t
movw %%di,%%ss
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
movl (%d),%%esp
\n
"
,
STACKOFFSET
);
output
(
"
\t
movw %%di,%%ss
\n
"
);
output
(
"
\t
.byte 0x64
\n\t
movl (%d),%%esp
\n
"
,
STACKOFFSET
);
/* Return to caller */
fprintf
(
outfile
,
"
\t
lret
\n
"
);
output_function_size
(
outfile
,
"__wine_call_to_16_ret"
);
output
(
"
\t
lret
\n
"
);
output_function_size
(
"__wine_call_to_16_ret"
);
}
...
...
@@ -659,77 +657,77 @@ static void BuildRet16Func( FILE *outfile )
* (ebp+4) ret addr
* (ebp) ebp
*/
static
void
BuildCallTo32CBClient
(
FILE
*
outfile
,
BOOL
isEx
)
static
void
BuildCallTo32CBClient
(
BOOL
isEx
)
{
function_header
(
outfile
,
isEx
?
"CALL32_CBClientEx"
:
"CALL32_CBClient"
);
function_header
(
isEx
?
"CALL32_CBClientEx"
:
"CALL32_CBClient"
);
/* Entry code */
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp,%%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ebx
\n
"
);
output
(
"
\t
pushl %%ebp
\n
"
);
output
(
"
\t
movl %%esp,%%ebp
\n
"
);
output
(
"
\t
pushl %%edi
\n
"
);
output
(
"
\t
pushl %%esi
\n
"
);
output
(
"
\t
pushl %%ebx
\n
"
);
/* Get pointer to temporary area and save the 32-bit stack pointer */
fprintf
(
outfile
,
"
\t
movl 16(%%ebp), %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
leal -8(%%esp), %%eax
\n
"
);
output
(
"
\t
movl 16(%%ebp), %%ebx
\n
"
);
output
(
"
\t
leal -8(%%esp), %%eax
\n
"
);
if
(
!
isEx
)
fprintf
(
outfile
,
"
\t
movl %%eax, -8(%%ebx)
\n
"
);
output
(
"
\t
movl %%eax, -8(%%ebx)
\n
"
);
else
fprintf
(
outfile
,
"
\t
movl %%eax, 12(%%ebx)
\n
"
);
output
(
"
\t
movl %%eax, 12(%%ebx)
\n
"
);
/* Set up registers and call CBClient relay stub (simulating a far call) */
fprintf
(
outfile
,
"
\t
movl 20(%%ebp), %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
movl (%%esi), %%esi
\n
"
);
output
(
"
\t
movl 20(%%ebp), %%esi
\n
"
);
output
(
"
\t
movl (%%esi), %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
movl 8(%%ebp), %%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl 12(%%ebp), %%ebp
\n
"
);
output
(
"
\t
movl 8(%%ebp), %%eax
\n
"
);
output
(
"
\t
movl 12(%%ebp), %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%cs
\n
"
);
fprintf
(
outfile
,
"
\t
call *%%eax
\n
"
);
output
(
"
\t
pushl %%cs
\n
"
);
output
(
"
\t
call *%%eax
\n
"
);
/* Return new esi value to caller */
fprintf
(
outfile
,
"
\t
movl 32(%%esp), %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esi, (%%edi)
\n
"
);
output
(
"
\t
movl 32(%%esp), %%edi
\n
"
);
output
(
"
\t
movl %%esi, (%%edi)
\n
"
);
/* Return argument size to caller */
if
(
isEx
)
{
fprintf
(
outfile
,
"
\t
movl 36(%%esp), %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%ebp, (%%ebx)
\n
"
);
output
(
"
\t
movl 36(%%esp), %%ebx
\n
"
);
output
(
"
\t
movl %%ebp, (%%ebx)
\n
"
);
}
/* Restore registers and return */
fprintf
(
outfile
,
"
\t
popl %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%esi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%edi
\n
"
);
fprintf
(
outfile
,
"
\t
popl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
output_function_size
(
outfile
,
isEx
?
"CALL32_CBClientEx"
:
"CALL32_CBClient"
);
output
(
"
\t
popl %%ebx
\n
"
);
output
(
"
\t
popl %%esi
\n
"
);
output
(
"
\t
popl %%edi
\n
"
);
output
(
"
\t
popl %%ebp
\n
"
);
output
(
"
\t
ret
\n
"
);
output_function_size
(
isEx
?
"CALL32_CBClientEx"
:
"CALL32_CBClient"
);
/* '16-bit' return stub */
function_header
(
outfile
,
isEx
?
"CALL32_CBClientEx_Ret"
:
"CALL32_CBClient_Ret"
);
function_header
(
isEx
?
"CALL32_CBClientEx_Ret"
:
"CALL32_CBClient_Ret"
);
if
(
!
isEx
)
{
fprintf
(
outfile
,
"
\t
movzwl %%sp, %%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
lssl %%ss:-16(%%ebx), %%esp
\n
"
);
output
(
"
\t
movzwl %%sp, %%ebx
\n
"
);
output
(
"
\t
lssl %%ss:-16(%%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
"
);
output
(
"
\t
movzwl %%bp, %%ebx
\n
"
);
output
(
"
\t
subw %%bp, %%sp
\n
"
);
output
(
"
\t
movzwl %%sp, %%ebp
\n
"
);
output
(
"
\t
lssl %%ss:-12(%%ebx), %%esp
\n
"
);
}
fprintf
(
outfile
,
"
\t
lret
\n
"
);
output_function_size
(
outfile
,
isEx
?
"CALL32_CBClientEx_Ret"
:
"CALL32_CBClient_Ret"
);
output
(
"
\t
lret
\n
"
);
output_function_size
(
isEx
?
"CALL32_CBClientEx_Ret"
:
"CALL32_CBClient_Ret"
);
}
...
...
@@ -758,114 +756,114 @@ static void BuildCallTo32CBClient( FILE *outfile, BOOL isEx )
* pointer on return (with the return address and arguments already
* removed).
*/
static
void
BuildCallFrom32Regs
(
FILE
*
outfile
)
static
void
BuildCallFrom32Regs
(
void
)
{
static
const
int
STACK_SPACE
=
128
+
sizeof
(
CONTEXT86
);
/* Function header */
function_header
(
outfile
,
"__wine_call_from_32_regs"
);
function_header
(
"__wine_call_from_32_regs"
);
/* Allocate some buffer space on the stack */
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp,%%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
leal -%d(%%esp), %%esp
\n
"
,
STACK_SPACE
+
4
/* for context arg */
);
output
(
"
\t
pushl %%ebp
\n
"
);
output
(
"
\t
movl %%esp,%%ebp
\n
"
);
output
(
"
\t
leal -%d(%%esp), %%esp
\n
"
,
STACK_SPACE
+
4
/* for context arg */
);
/* Build the context structure */
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 8(%%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
);
fprintf
(
outfile
,
"
\t
movl %%esi,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Esi
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movl %%edi,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Edi
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
xorl %%eax,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movw %%cs,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movw %%es,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movw %%fs,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movw %%gs,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movw %%ss,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movw %%ds,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
-
STACK_SPACE
);
fprintf
(
outfile
,
"
\t
movw %%ax,%%es
\n
"
);
/* set %es equal to %ds just in case */
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 12(%%ebp),%%eax
\n
"
);
/* Get %eip at time of call */
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Eip
)
-
STACK_SPACE
);
output
(
"
\t
pushfl
\n
"
);
output
(
"
\t
popl %%eax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
-
STACK_SPACE
);
output
(
"
\t
movl 0(%%ebp),%%eax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Ebp
)
-
STACK_SPACE
);
output
(
"
\t
movl 8(%%ebp),%%eax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Eax
)
-
STACK_SPACE
);
output
(
"
\t
movl %%ebx,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Ebx
)
-
STACK_SPACE
);
output
(
"
\t
movl %%ecx,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Ecx
)
-
STACK_SPACE
);
output
(
"
\t
movl %%edx,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Edx
)
-
STACK_SPACE
);
output
(
"
\t
movl %%esi,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Esi
)
-
STACK_SPACE
);
output
(
"
\t
movl %%edi,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Edi
)
-
STACK_SPACE
);
output
(
"
\t
xorl %%eax,%%eax
\n
"
);
output
(
"
\t
movw %%cs,%%ax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
-
STACK_SPACE
);
output
(
"
\t
movw %%es,%%ax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
-
STACK_SPACE
);
output
(
"
\t
movw %%fs,%%ax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
-
STACK_SPACE
);
output
(
"
\t
movw %%gs,%%ax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
-
STACK_SPACE
);
output
(
"
\t
movw %%ss,%%ax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
-
STACK_SPACE
);
output
(
"
\t
movw %%ds,%%ax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
-
STACK_SPACE
);
output
(
"
\t
movw %%ax,%%es
\n
"
);
/* set %es equal to %ds just in case */
output
(
"
\t
movl $0x%x,%%eax
\n
"
,
CONTEXT86_FULL
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
ContextFlags
)
-
STACK_SPACE
);
output
(
"
\t
movl 12(%%ebp),%%eax
\n
"
);
/* Get %eip at time of call */
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Eip
)
-
STACK_SPACE
);
/* Transfer the arguments */
fprintf
(
outfile
,
"
\t
movl 4(%%ebp),%%ebx
\n
"
);
/* get relay code addr */
fprintf
(
outfile
,
"
\t
movzbl 4(%%ebx),%%ecx
\n
"
);
/* fetch number of args to copy */
fprintf
(
outfile
,
"
\t
subl %%ecx,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
andl $~15,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
leal 16(%%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
jz 1f
\n
"
);
fprintf
(
outfile
,
"
\t
cld
\n
"
);
fprintf
(
outfile
,
"
\t
rep
\n\t
movsl
\n
"
);
/* copy args */
fprintf
(
outfile
,
"1:
\t
leal %d(%%ebp),%%eax
\n
"
,
-
STACK_SPACE
);
/* get addr of context struct */
fprintf
(
outfile
,
"
\t
movl %%eax,(%%edi)
\n
"
);
/* and pass it as extra arg */
fprintf
(
outfile
,
"
\t
movzbl 5(%%ebx),%%eax
\n
"
);
/* fetch number of args to remove */
fprintf
(
outfile
,
"
\t
leal 16(%%ebp,%%eax),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Esp
)
-
STACK_SPACE
);
output
(
"
\t
movl 4(%%ebp),%%ebx
\n
"
);
/* get relay code addr */
output
(
"
\t
movzbl 4(%%ebx),%%ecx
\n
"
);
/* fetch number of args to copy */
output
(
"
\t
subl %%ecx,%%esp
\n
"
);
output
(
"
\t
andl $~15,%%esp
\n
"
);
output
(
"
\t
leal 16(%%ebp),%%esi
\n
"
);
/* get %esp at time of call */
output
(
"
\t
movl %%esp,%%edi
\n
"
);
output
(
"
\t
shrl $2,%%ecx
\n
"
);
output
(
"
\t
jz 1f
\n
"
);
output
(
"
\t
cld
\n
"
);
output
(
"
\t
rep
\n\t
movsl
\n
"
);
/* copy args */
output
(
"1:
\t
leal %d(%%ebp),%%eax
\n
"
,
-
STACK_SPACE
);
/* get addr of context struct */
output
(
"
\t
movl %%eax,(%%edi)
\n
"
);
/* and pass it as extra arg */
output
(
"
\t
movzbl 5(%%ebx),%%eax
\n
"
);
/* fetch number of args to remove */
output
(
"
\t
leal 16(%%ebp,%%eax),%%eax
\n
"
);
output
(
"
\t
movl %%eax,%d(%%ebp)
\n
"
,
CONTEXTOFFSET
(
Esp
)
-
STACK_SPACE
);
/* Call the entry point */
fprintf
(
outfile
,
"
\t
addl (%%ebx),%%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
call *%%ebx
\n
"
);
fprintf
(
outfile
,
"
\t
leal -%d(%%ebp),%%ecx
\n
"
,
STACK_SPACE
);
output
(
"
\t
addl (%%ebx),%%ebx
\n
"
);
output
(
"
\t
call *%%ebx
\n
"
);
output
(
"
\t
leal -%d(%%ebp),%%ecx
\n
"
,
STACK_SPACE
);
/* Restore the context structure */
fprintf
(
outfile
,
"2:
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
fprintf
(
outfile
,
"
\t
popl %%es
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
fprintf
(
outfile
,
"
\t
popl %%fs
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
fprintf
(
outfile
,
"
\t
popl %%gs
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
fprintf
(
outfile
,
"
\t
popl %%ss
\n
"
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%esp
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
fprintf
(
outfile
,
"
\t
movl %d(%%ecx),%%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
fprintf
(
outfile
,
"
\t
popl %%ds
\n
"
);
fprintf
(
outfile
,
"
\t
iret
\n
"
);
output_function_size
(
outfile
,
"__wine_call_from_32_regs"
);
function_header
(
outfile
,
"__wine_call_from_32_restore_regs"
);
fprintf
(
outfile
,
"
\t
movl 4(%%esp),%%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
jmp 2b
\n
"
);
output_function_size
(
outfile
,
"__wine_call_from_32_restore_regs"
);
output
(
"2:
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegEs
)
);
output
(
"
\t
popl %%es
\n
"
);
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegFs
)
);
output
(
"
\t
popl %%fs
\n
"
);
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegGs
)
);
output
(
"
\t
popl %%gs
\n
"
);
output
(
"
\t
movl %d(%%ecx),%%edi
\n
"
,
CONTEXTOFFSET
(
Edi
)
);
output
(
"
\t
movl %d(%%ecx),%%esi
\n
"
,
CONTEXTOFFSET
(
Esi
)
);
output
(
"
\t
movl %d(%%ecx),%%edx
\n
"
,
CONTEXTOFFSET
(
Edx
)
);
output
(
"
\t
movl %d(%%ecx),%%ebx
\n
"
,
CONTEXTOFFSET
(
Ebx
)
);
output
(
"
\t
movl %d(%%ecx),%%eax
\n
"
,
CONTEXTOFFSET
(
Eax
)
);
output
(
"
\t
movl %d(%%ecx),%%ebp
\n
"
,
CONTEXTOFFSET
(
Ebp
)
);
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegSs
)
);
output
(
"
\t
popl %%ss
\n
"
);
output
(
"
\t
movl %d(%%ecx),%%esp
\n
"
,
CONTEXTOFFSET
(
Esp
)
);
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
EFlags
)
);
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegCs
)
);
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
Eip
)
);
output
(
"
\t
pushl %d(%%ecx)
\n
"
,
CONTEXTOFFSET
(
SegDs
)
);
output
(
"
\t
movl %d(%%ecx),%%ecx
\n
"
,
CONTEXTOFFSET
(
Ecx
)
);
output
(
"
\t
popl %%ds
\n
"
);
output
(
"
\t
iret
\n
"
);
output_function_size
(
"__wine_call_from_32_regs"
);
function_header
(
"__wine_call_from_32_restore_regs"
);
output
(
"
\t
movl 4(%%esp),%%ecx
\n
"
);
output
(
"
\t
jmp 2b
\n
"
);
output_function_size
(
"__wine_call_from_32_restore_regs"
);
}
...
...
@@ -885,38 +883,34 @@ static void BuildCallFrom32Regs( FILE *outfile )
* On entry to function, fs register points to a valid TEB.
* On exit from function, stack will be popped.
*/
static
void
BuildPendingEventCheck
(
FILE
*
outfile
)
static
void
BuildPendingEventCheck
(
void
)
{
/* Function header */
function_header
(
outfile
,
"DPMI_PendingEventCheck"
);
function_header
(
"DPMI_PendingEventCheck"
);
/* Check for pending events. */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
vm86_pending
)
);
fprintf
(
outfile
,
"
\t
je %s
\n
"
,
asm_name
(
"DPMI_PendingEventCheck_Cleanup"
)
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
dpmi_vif
)
);
fprintf
(
outfile
,
"
\t
je %s
\n
"
,
asm_name
(
"DPMI_PendingEventCheck_Cleanup"
)
);
output
(
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
vm86_pending
)
);
output
(
"
\t
je %s
\n
"
,
asm_name
(
"DPMI_PendingEventCheck_Cleanup"
)
);
output
(
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
dpmi_vif
)
);
output
(
"
\t
je %s
\n
"
,
asm_name
(
"DPMI_PendingEventCheck_Cleanup"
)
);
/* Process pending events. */
fprintf
(
outfile
,
"
\t
sti
\n
"
);
output
(
"
\t
sti
\n
"
);
/* Start cleanup. Restore fs register. */
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
"DPMI_PendingEventCheck_Cleanup"
)
);
fprintf
(
outfile
,
"
\t
popw %%fs
\n
"
);
output
(
"%s
\n
"
,
asm_globl
(
"DPMI_PendingEventCheck_Cleanup"
)
);
output
(
"
\t
popw %%fs
\n
"
);
/* Return from function. */
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
"DPMI_PendingEventCheck_Return"
)
);
fprintf
(
outfile
,
"
\t
iret
\n
"
);
output
(
"%s
\n
"
,
asm_globl
(
"DPMI_PendingEventCheck_Return"
)
);
output
(
"
\t
iret
\n
"
);
output_function_size
(
outfile
,
"DPMI_PendingEventCheck"
);
output_function_size
(
"DPMI_PendingEventCheck"
);
}
...
...
@@ -925,59 +919,59 @@ static void BuildPendingEventCheck( FILE *outfile )
*
* Build all the 16-bit relay callbacks
*/
void
BuildRelays16
(
FILE
*
outfile
)
void
BuildRelays16
(
void
)
{
if
(
target_cpu
!=
CPU_x86
)
{
fprintf
(
outfile
,
"/* File not used with this architecture. Do not edit! */
\n\n
"
);
output
(
"/* File not used with this architecture. Do not edit! */
\n\n
"
);
return
;
}
/* File header */
fprintf
(
outfile
,
"/* File generated automatically. Do not edit! */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
output
(
"/* File generated automatically. Do not edit! */
\n\n
"
);
output
(
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"%s:
\n\n
"
,
asm_name
(
"__wine_spec_thunk_text_16"
)
);
output
(
"%s:
\n\n
"
,
asm_name
(
"__wine_spec_thunk_text_16"
)
);
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
"__wine_call16_start"
)
);
output
(
"%s
\n
"
,
asm_globl
(
"__wine_call16_start"
)
);
/* Standard CallFrom16 routine */
BuildCallFrom16Core
(
outfile
,
FALSE
,
FALSE
);
BuildCallFrom16Core
(
FALSE
,
FALSE
);
/* Register CallFrom16 routine */
BuildCallFrom16Core
(
outfile
,
TRUE
,
FALSE
);
BuildCallFrom16Core
(
TRUE
,
FALSE
);
/* C16ThkSL CallFrom16 routine */
BuildCallFrom16Core
(
outfile
,
FALSE
,
TRUE
);
BuildCallFrom16Core
(
FALSE
,
TRUE
);
/* Standard CallTo16 routine */
BuildCallTo16Core
(
outfile
,
0
);
BuildCallTo16Core
(
0
);
/* Register CallTo16 routine */
BuildCallTo16Core
(
outfile
,
1
);
BuildCallTo16Core
(
1
);
/* Standard CallTo16 return stub */
BuildRet16Func
(
outfile
);
BuildRet16Func
();
/* CBClientThunkSL routine */
BuildCallTo32CBClient
(
outfile
,
FALSE
);
BuildCallTo32CBClient
(
FALSE
);
/* CBClientThunkSLEx routine */
BuildCallTo32CBClient
(
outfile
,
TRUE
);
BuildCallTo32CBClient
(
TRUE
);
/* Pending DPMI events check stub */
BuildPendingEventCheck
(
outfile
);
BuildPendingEventCheck
();
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
"__wine_call16_end"
)
);
output_function_size
(
outfile
,
"__wine_spec_thunk_text_16"
);
output
(
"%s
\n
"
,
asm_globl
(
"__wine_call16_end"
)
);
output_function_size
(
"__wine_spec_thunk_text_16"
);
/* Declare the return address and data selector variables */
fprintf
(
outfile
,
"
\n\t
.data
\n\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"%s
\n\t
.long 0
\n
"
,
asm_globl
(
"CallTo16_DataSelector"
)
);
fprintf
(
outfile
,
"%s
\n\t
.long 0
\n
"
,
asm_globl
(
"CallTo16_TebSelector"
)
);
if
(
UsePIC
)
fprintf
(
outfile
,
"wine_ldt_copy_ptr:
\t
.long %s
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
output_gnu_stack_note
(
outfile
);
output
(
"
\n\t
.data
\n\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"%s
\n\t
.long 0
\n
"
,
asm_globl
(
"CallTo16_DataSelector"
)
);
output
(
"%s
\n\t
.long 0
\n
"
,
asm_globl
(
"CallTo16_TebSelector"
)
);
if
(
UsePIC
)
output
(
"wine_ldt_copy_ptr:
\t
.long %s
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
output_gnu_stack_note
();
}
/*******************************************************************
...
...
@@ -985,23 +979,23 @@ void BuildRelays16( FILE *outfile )
*
* Build all the 32-bit relay callbacks
*/
void
BuildRelays32
(
FILE
*
outfile
)
void
BuildRelays32
(
void
)
{
if
(
target_cpu
!=
CPU_x86
)
{
fprintf
(
outfile
,
"/* File not used with this architecture. Do not edit! */
\n\n
"
);
output
(
"/* File not used with this architecture. Do not edit! */
\n\n
"
);
return
;
}
/* File header */
fprintf
(
outfile
,
"/* File generated automatically. Do not edit! */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"%s:
\n\n
"
,
asm_name
(
"__wine_spec_thunk_text_32"
)
);
output
(
"/* File generated automatically. Do not edit! */
\n\n
"
);
output
(
"
\t
.text
\n
"
);
output
(
"%s:
\n\n
"
,
asm_name
(
"__wine_spec_thunk_text_32"
)
);
/* 32-bit register entry point */
BuildCallFrom32Regs
(
outfile
);
BuildCallFrom32Regs
();
output_function_size
(
outfile
,
"__wine_spec_thunk_text_32"
);
output_gnu_stack_note
(
outfile
);
output_function_size
(
"__wine_spec_thunk_text_32"
);
output_gnu_stack_note
();
}
tools/winebuild/res16.c
View file @
71580499
...
...
@@ -242,16 +242,16 @@ static void free_resource_tree( struct res_tree *tree )
}
/* output a string preceded by its length */
static
void
output_string
(
FILE
*
outfile
,
const
char
*
str
)
static
void
output_string
(
const
char
*
str
)
{
unsigned
int
i
,
len
=
strlen
(
str
);
fprintf
(
outfile
,
"
\t
.byte 0x%02x"
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
fprintf
(
outfile
,
",0x%02x"
,
(
unsigned
char
)
str
[
i
]
);
fprintf
(
outfile
,
" /* %s */
\n
"
,
str
);
output
(
"
\t
.byte 0x%02x"
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
output
(
",0x%02x"
,
(
unsigned
char
)
str
[
i
]
);
output
(
" /* %s */
\n
"
,
str
);
}
/* output the resource data */
void
output_res16_data
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
void
output_res16_data
(
DLLSPEC
*
spec
)
{
const
struct
resource
*
res
;
unsigned
int
i
;
...
...
@@ -260,14 +260,14 @@ void output_res16_data( FILE *outfile, DLLSPEC *spec )
for
(
i
=
0
,
res
=
spec
->
resources
;
i
<
spec
->
nb_resources
;
i
++
,
res
++
)
{
fprintf
(
outfile
,
".L__wine_spec_resource_%u:
\n
"
,
i
);
dump_bytes
(
outfile
,
res
->
data
,
res
->
data_size
);
fprintf
(
outfile
,
".L__wine_spec_resource_%u_end:
\n
"
,
i
);
output
(
".L__wine_spec_resource_%u:
\n
"
,
i
);
dump_bytes
(
res
->
data
,
res
->
data_size
);
output
(
".L__wine_spec_resource_%u_end:
\n
"
,
i
);
}
}
/* output the resource definitions */
void
output_res16_directory
(
FILE
*
outfile
,
DLLSPEC
*
spec
,
const
char
*
header_name
)
void
output_res16_directory
(
DLLSPEC
*
spec
,
const
char
*
header_name
)
{
unsigned
int
i
,
j
;
struct
res_tree
*
tree
;
...
...
@@ -276,38 +276,38 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na
tree
=
build_resource_tree
(
spec
);
fprintf
(
outfile
,
"
\n
.L__wine_spec_ne_rsrctab:
\n
"
);
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* alignment */
output
(
"
\n
.L__wine_spec_ne_rsrctab:
\n
"
);
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* alignment */
/* type and name structures */
for
(
i
=
0
,
type
=
tree
->
types
;
i
<
tree
->
nb_types
;
i
++
,
type
++
)
{
if
(
type
->
type
->
str
)
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab
\n
"
,
output
(
"
\t
%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab
\n
"
,
get_asm_short_keyword
(),
i
);
else
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
type
->
type
->
id
|
0x8000
);
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
type
->
type
->
id
|
0x8000
);
fprintf
(
outfile
,
"
\t
%s %u,0,0
\n
"
,
get_asm_short_keyword
(),
type
->
nb_names
);
output
(
"
\t
%s %u,0,0
\n
"
,
get_asm_short_keyword
(),
type
->
nb_names
);
for
(
j
=
0
,
res
=
type
->
res
;
j
<
type
->
nb_names
;
j
++
,
res
++
)
{
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_resource_%u-%s
\n
"
,
output
(
"
\t
%s .L__wine_spec_resource_%u-%s
\n
"
,
get_asm_short_keyword
(),
res
-
spec
->
resources
,
header_name
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_resource_%u_end-.L__wine_spec_resource_%u
\n
"
,
output
(
"
\t
%s .L__wine_spec_resource_%u_end-.L__wine_spec_resource_%u
\n
"
,
get_asm_short_keyword
(),
res
-
spec
->
resources
,
res
-
spec
->
resources
);
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
res
->
memopt
);
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
res
->
memopt
);
if
(
res
->
name
.
str
)
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab
\n
"
,
output
(
"
\t
%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab
\n
"
,
get_asm_short_keyword
(),
i
,
j
);
else
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
res
->
name
.
id
|
0x8000
);
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
res
->
name
.
id
|
0x8000
);
fprintf
(
outfile
,
"
\t
%s 0,0
\n
"
,
get_asm_short_keyword
()
);
output
(
"
\t
%s 0,0
\n
"
,
get_asm_short_keyword
()
);
}
}
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* terminator */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* terminator */
/* name strings */
...
...
@@ -315,19 +315,19 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na
{
if
(
type
->
type
->
str
)
{
fprintf
(
outfile
,
".L__wine_spec_restype_%u:
\n
"
,
i
);
output_string
(
outfile
,
type
->
type
->
str
);
output
(
".L__wine_spec_restype_%u:
\n
"
,
i
);
output_string
(
type
->
type
->
str
);
}
for
(
j
=
0
,
res
=
type
->
res
;
j
<
type
->
nb_names
;
j
++
,
res
++
)
{
if
(
res
->
name
.
str
)
{
fprintf
(
outfile
,
".L__wine_spec_resname_%u_%u:
\n
"
,
i
,
j
);
output_string
(
outfile
,
res
->
name
.
str
);
output
(
".L__wine_spec_resname_%u_%u:
\n
"
,
i
,
j
);
output_string
(
res
->
name
.
str
);
}
}
}
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
/* names terminator */
output
(
"
\t
.byte 0
\n
"
);
/* names terminator */
free_resource_tree
(
tree
);
}
tools/winebuild/res32.c
View file @
71580499
...
...
@@ -316,29 +316,29 @@ static void free_resource_tree( struct res_tree *tree )
}
/* output a Unicode string */
static
void
output_string
(
FILE
*
outfile
,
const
WCHAR
*
name
)
static
void
output_string
(
const
WCHAR
*
name
)
{
int
i
,
len
=
strlenW
(
name
);
fprintf
(
outfile
,
"
\t
%s 0x%04x"
,
get_asm_short_keyword
(),
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
fprintf
(
outfile
,
",0x%04x"
,
name
[
i
]
);
fprintf
(
outfile
,
" /* "
);
for
(
i
=
0
;
i
<
len
;
i
++
)
fprintf
(
outfile
,
"%c"
,
isprint
((
char
)
name
[
i
])
?
(
char
)
name
[
i
]
:
'?'
);
fprintf
(
outfile
,
" */
\n
"
);
output
(
"
\t
%s 0x%04x"
,
get_asm_short_keyword
(),
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
output
(
",0x%04x"
,
name
[
i
]
);
output
(
" /* "
);
for
(
i
=
0
;
i
<
len
;
i
++
)
output
(
"%c"
,
isprint
((
char
)
name
[
i
])
?
(
char
)
name
[
i
]
:
'?'
);
output
(
" */
\n
"
);
}
/* output a resource directory */
static
inline
void
output_res_dir
(
FILE
*
outfile
,
unsigned
int
nb_names
,
unsigned
int
nb_ids
)
static
inline
void
output_res_dir
(
unsigned
int
nb_names
,
unsigned
int
nb_ids
)
{
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* Characteristics */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
fprintf
(
outfile
,
"
\t
%s 0,0
\n
"
,
/* Major/MinorVersion */
output
(
"
\t
.long 0
\n
"
);
/* Characteristics */
output
(
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
output
(
"
\t
%s 0,0
\n
"
,
/* Major/MinorVersion */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s %u,%u
\n
"
,
/* NumberOfNamed/IdEntries */
output
(
"
\t
%s %u,%u
\n
"
,
/* NumberOfNamed/IdEntries */
get_asm_short_keyword
(),
nb_names
,
nb_ids
);
}
/* output the resource definitions */
void
output_resources
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
void
output_resources
(
DLLSPEC
*
spec
)
{
int
k
,
nb_id_types
;
unsigned
int
i
,
n
,
offset
,
data_offset
;
...
...
@@ -388,19 +388,19 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* output the resource directories */
fprintf
(
outfile
,
"
\n
/* resources */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
".L__wine_spec_resources:
\n
"
);
output
(
"
\n
/* resources */
\n\n
"
);
output
(
"
\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
".L__wine_spec_resources:
\n
"
);
output_res_dir
(
outfile
,
tree
->
nb_types
-
nb_id_types
,
nb_id_types
);
output_res_dir
(
tree
->
nb_types
-
nb_id_types
,
nb_id_types
);
/* dump the type directory */
offset
=
RESDIR_SIZE
(
tree
->
nb_types
);
for
(
i
=
0
,
type
=
tree
->
types
;
i
<
tree
->
nb_types
;
i
++
,
type
++
)
{
fprintf
(
outfile
,
"
\t
.long 0x%08x,0x%08x
\n
"
,
output
(
"
\t
.long 0x%08x,0x%08x
\n
"
,
type
->
name_offset
,
offset
|
0x80000000
);
offset
+=
RESDIR_SIZE
(
type
->
nb_names
);
for
(
n
=
0
,
name
=
type
->
names
;
n
<
type
->
nb_names
;
n
++
,
name
++
)
...
...
@@ -414,22 +414,22 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
for
(
i
=
0
,
type
=
tree
->
types
;
i
<
tree
->
nb_types
;
i
++
,
type
++
)
{
output_res_dir
(
outfile
,
type
->
nb_names
-
type
->
nb_id_names
,
type
->
nb_id_names
);
output_res_dir
(
type
->
nb_names
-
type
->
nb_id_names
,
type
->
nb_id_names
);
offset
+=
RESDIR_SIZE
(
type
->
nb_names
);
for
(
n
=
0
,
name
=
type
->
names
;
n
<
type
->
nb_names
;
n
++
,
name
++
)
{
fprintf
(
outfile
,
"
\t
.long 0x%08x,0x%08x
\n
"
,
output
(
"
\t
.long 0x%08x,0x%08x
\n
"
,
name
->
name_offset
,
offset
|
0x80000000
);
offset
+=
RESDIR_SIZE
(
name
->
nb_languages
);
}
for
(
n
=
0
,
name
=
type
->
names
;
n
<
type
->
nb_names
;
n
++
,
name
++
)
{
output_res_dir
(
outfile
,
0
,
name
->
nb_languages
);
output_res_dir
(
0
,
name
->
nb_languages
);
for
(
k
=
0
,
res
=
name
->
res
;
k
<
name
->
nb_languages
;
k
++
,
res
++
)
{
unsigned
int
entry_offset
=
(
res
-
spec
->
resources
)
*
sizeof
(
IMAGE_RESOURCE_DATA_ENTRY
);
fprintf
(
outfile
,
"
\t
.long 0x%08x,0x%08x
\n
"
,
res
->
lang
,
data_offset
+
entry_offset
);
output
(
"
\t
.long 0x%08x,0x%08x
\n
"
,
res
->
lang
,
data_offset
+
entry_offset
);
}
}
}
...
...
@@ -437,28 +437,28 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* dump the resource data entries */
for
(
i
=
0
,
res
=
spec
->
resources
;
i
<
spec
->
nb_resources
;
i
++
,
res
++
)
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0
\n
"
,
output
(
"
\t
.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0
\n
"
,
i
,
res
->
data_size
);
/* dump the name strings */
for
(
i
=
0
,
type
=
tree
->
types
;
i
<
tree
->
nb_types
;
i
++
,
type
++
)
{
if
(
type
->
type
->
str
)
output_string
(
outfile
,
type
->
type
->
str
);
if
(
type
->
type
->
str
)
output_string
(
type
->
type
->
str
);
for
(
n
=
0
,
name
=
type
->
names
;
n
<
type
->
nb_names
;
n
++
,
name
++
)
if
(
name
->
name
->
str
)
output_string
(
outfile
,
name
->
name
->
str
);
if
(
name
->
name
->
str
)
output_string
(
name
->
name
->
str
);
}
/* resource data */
for
(
i
=
0
,
res
=
spec
->
resources
;
i
<
spec
->
nb_resources
;
i
++
,
res
++
)
{
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
".L__wine_spec_res_%d:
\n
"
,
i
);
dump_bytes
(
outfile
,
res
->
data
,
res
->
data_size
);
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
".L__wine_spec_res_%d:
\n
"
,
i
);
dump_bytes
(
res
->
data
,
res
->
data_size
);
}
fprintf
(
outfile
,
".L__wine_spec_resources_end:
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
output
(
".L__wine_spec_resources_end:
\n
"
);
output
(
"
\t
.byte 0
\n
"
);
free_resource_tree
(
tree
);
}
tools/winebuild/spec16.c
View file @
71580499
...
...
@@ -54,31 +54,31 @@ static inline int is_function( const ORDDEF *odp )
*
* Output entries for individual symbols in the entry table.
*/
static
void
output_entries
(
FILE
*
outfile
,
DLLSPEC
*
spec
,
int
first
,
int
count
)
static
void
output_entries
(
DLLSPEC
*
spec
,
int
first
,
int
count
)
{
int
i
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
first
+
i
];
fprintf
(
outfile
,
"
\t
.byte 0x03
\n
"
);
/* flags: exported & public data */
output
(
"
\t
.byte 0x03
\n
"
);
/* flags: exported & public data */
switch
(
odp
->
type
)
{
case
TYPE_CDECL
:
case
TYPE_PASCAL
:
case
TYPE_VARARGS
:
case
TYPE_STUB
:
fprintf
(
outfile
,
"
\t
%s .L__wine_%s_%u-.L__wine_spec_code_segment
\n
"
,
output
(
"
\t
%s .L__wine_%s_%u-.L__wine_spec_code_segment
\n
"
,
get_asm_short_keyword
(),
make_c_identifier
(
spec
->
dll_name
),
first
+
i
);
break
;
case
TYPE_VARIABLE
:
fprintf
(
outfile
,
"
\t
%s .L__wine_%s_%u-.L__wine_spec_data_segment
\n
"
,
output
(
"
\t
%s .L__wine_%s_%u-.L__wine_spec_data_segment
\n
"
,
get_asm_short_keyword
(),
make_c_identifier
(
spec
->
dll_name
),
first
+
i
);
break
;
case
TYPE_ABS
:
fprintf
(
outfile
,
"
\t
%s 0x%04x /* %s */
\n
"
,
output
(
"
\t
%s 0x%04x /* %s */
\n
"
,
get_asm_short_keyword
(),
odp
->
u
.
abs
.
value
,
odp
->
name
);
break
;
default:
...
...
@@ -91,7 +91,7 @@ static void output_entries( FILE *outfile, DLLSPEC *spec, int first, int count )
/*******************************************************************
* output_entry_table
*/
static
void
output_entry_table
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
static
void
output_entry_table
(
DLLSPEC
*
spec
)
{
int
i
,
prev
=
0
,
prev_sel
=
-
1
,
bundle_count
=
0
;
...
...
@@ -126,10 +126,10 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec )
/* flush previous bundle */
if
(
bundle_count
)
{
fprintf
(
outfile
,
"
\t
/* %s.%d - %s.%d */
\n
"
,
output
(
"
\t
/* %s.%d - %s.%d */
\n
"
,
spec
->
dll_name
,
prev
-
bundle_count
+
1
,
spec
->
dll_name
,
prev
);
fprintf
(
outfile
,
"
\t
.byte 0x%02x,0x%02x
\n
"
,
bundle_count
,
prev_sel
);
output_entries
(
outfile
,
spec
,
prev
-
bundle_count
+
1
,
bundle_count
);
output
(
"
\t
.byte 0x%02x,0x%02x
\n
"
,
bundle_count
,
prev_sel
);
output_entries
(
spec
,
prev
-
bundle_count
+
1
,
bundle_count
);
}
if
(
prev
+
1
!=
i
)
...
...
@@ -137,10 +137,10 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec )
int
skip
=
i
-
(
prev
+
1
);
while
(
skip
>
255
)
{
fprintf
(
outfile
,
"
\t
.byte 0xff,0x00
\n
"
);
output
(
"
\t
.byte 0xff,0x00
\n
"
);
skip
-=
255
;
}
fprintf
(
outfile
,
"
\t
.byte 0x%02x,0x00
\n
"
,
skip
);
output
(
"
\t
.byte 0x%02x,0x00
\n
"
,
skip
);
}
bundle_count
=
0
;
...
...
@@ -153,24 +153,24 @@ static void output_entry_table( FILE *outfile, DLLSPEC *spec )
/* flush last bundle */
if
(
bundle_count
)
{
fprintf
(
outfile
,
"
\t
.byte 0x%02x,0x%02x
\n
"
,
bundle_count
,
prev_sel
);
output_entries
(
outfile
,
spec
,
prev
-
bundle_count
+
1
,
bundle_count
);
output
(
"
\t
.byte 0x%02x,0x%02x
\n
"
,
bundle_count
,
prev_sel
);
output_entries
(
spec
,
prev
-
bundle_count
+
1
,
bundle_count
);
}
fprintf
(
outfile
,
"
\t
.byte 0x00
\n
"
);
output
(
"
\t
.byte 0x00
\n
"
);
}
/*******************************************************************
* output_resident_name
*/
static
void
output_resident_name
(
FILE
*
outfile
,
const
char
*
string
,
int
ordinal
)
static
void
output_resident_name
(
const
char
*
string
,
int
ordinal
)
{
unsigned
int
i
,
len
=
strlen
(
string
);
fprintf
(
outfile
,
"
\t
.byte 0x%02x"
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
fprintf
(
outfile
,
",0x%02x"
,
(
unsigned
char
)
toupper
(
string
[
i
])
);
fprintf
(
outfile
,
" /* %s */
\n
"
,
string
);
fprintf
(
outfile
,
"
\t
%s %u
\n
"
,
get_asm_short_keyword
(),
ordinal
);
output
(
"
\t
.byte 0x%02x"
,
len
);
for
(
i
=
0
;
i
<
len
;
i
++
)
output
(
",0x%02x"
,
(
unsigned
char
)
toupper
(
string
[
i
])
);
output
(
" /* %s */
\n
"
,
string
);
output
(
"
\t
%s %u
\n
"
,
get_asm_short_keyword
(),
ordinal
);
}
...
...
@@ -283,7 +283,7 @@ static int get_function_argsize( const ORDDEF *odp )
* the same as for normal functions, but in addition the CONTEXT86 pointer
* filled with the current register values is passed to the 32-bit routine.
*/
static
void
output_call16_function
(
FILE
*
outfile
,
ORDDEF
*
odp
)
static
void
output_call16_function
(
ORDDEF
*
odp
)
{
char
name
[
256
];
int
i
,
pos
,
stack_words
;
...
...
@@ -293,41 +293,41 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp )
sprintf
(
name
,
".L__wine_spec_call16_%s"
,
get_relay_name
(
odp
)
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
name
);
fprintf
(
outfile
,
"
\t
pushl %%ebp
\n
"
);
fprintf
(
outfile
,
"
\t
movl %%esp,%%ebp
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
output
(
"%s:
\n
"
,
name
);
output
(
"
\t
pushl %%ebp
\n
"
);
output
(
"
\t
movl %%esp,%%ebp
\n
"
);
stack_words
=
2
;
if
(
needs_ldt
)
{
fprintf
(
outfile
,
"
\t
pushl %%esi
\n
"
);
output
(
"
\t
pushl %%esi
\n
"
);
stack_words
++
;
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:
\t
movl wine_ldt_copy_ptr-1b(%%eax),%%esi
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:
\t
movl wine_ldt_copy_ptr-1b(%%eax),%%esi
\n
"
);
}
else
fprintf
(
outfile
,
"
\t
movl $%s,%%esi
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
output
(
"
\t
movl $%s,%%esi
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
}
/* preserve 16-byte stack alignment */
stack_words
+=
strlen
(
args
);
if
((
odp
->
flags
&
FLAG_REGISTER
)
||
(
odp
->
type
==
TYPE_VARARGS
))
stack_words
++
;
if
(
stack_words
%
4
)
fprintf
(
outfile
,
"
\t
subl $%d,%%esp
\n
"
,
16
-
4
*
(
stack_words
%
4
)
);
if
(
stack_words
%
4
)
output
(
"
\t
subl $%d,%%esp
\n
"
,
16
-
4
*
(
stack_words
%
4
)
);
if
(
args
[
0
]
||
odp
->
type
==
TYPE_VARARGS
)
fprintf
(
outfile
,
"
\t
movl 12(%%ebp),%%ecx
\n
"
);
/* args */
output
(
"
\t
movl 12(%%ebp),%%ecx
\n
"
);
/* args */
if
(
odp
->
flags
&
FLAG_REGISTER
)
{
fprintf
(
outfile
,
"
\t
pushl 16(%%ebp)
\n
"
);
/* context */
output
(
"
\t
pushl 16(%%ebp)
\n
"
);
/* context */
}
else
if
(
odp
->
type
==
TYPE_VARARGS
)
{
fprintf
(
outfile
,
"
\t
leal %d(%%ecx),%%eax
\n
"
,
argsize
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
/* va_list16 */
output
(
"
\t
leal %d(%%ecx),%%eax
\n
"
,
argsize
);
output
(
"
\t
pushl %%eax
\n
"
);
/* va_list16 */
}
pos
=
(
odp
->
type
==
TYPE_PASCAL
)
?
0
:
argsize
;
...
...
@@ -337,33 +337,33 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp )
{
case
'w'
:
/* word */
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
2
;
fprintf
(
outfile
,
"
\t
movzwl %d(%%ecx),%%eax
\n
"
,
pos
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
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 */
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
2
;
fprintf
(
outfile
,
"
\t
movswl %d(%%ecx),%%eax
\n
"
,
pos
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
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 */
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
4
;
fprintf
(
outfile
,
"
\t
pushl %d(%%ecx)
\n
"
,
pos
);
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 */
if
(
odp
->
type
!=
TYPE_PASCAL
)
pos
-=
4
;
fprintf
(
outfile
,
"
\t
movzwl %d(%%ecx),%%edx
\n
"
,
pos
+
2
);
/* sel */
fprintf
(
outfile
,
"
\t
shr $3,%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
movzwl %d(%%ecx),%%eax
\n
"
,
pos
);
/* offset */
fprintf
(
outfile
,
"
\t
addl (%%esi,%%edx,4),%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
movzwl %d(%%ecx),%%edx
\n
"
,
pos
+
2
);
/* sel */
output
(
"
\t
shr $3,%%edx
\n
"
);
output
(
"
\t
movzwl %d(%%ecx),%%eax
\n
"
,
pos
);
/* offset */
output
(
"
\t
addl (%%esi,%%edx,4),%%eax
\n
"
);
output
(
"
\t
pushl %%eax
\n
"
);
if
(
odp
->
type
==
TYPE_PASCAL
)
pos
+=
4
;
break
;
...
...
@@ -372,13 +372,13 @@ static void output_call16_function( FILE *outfile, ORDDEF *odp )
}
}
fprintf
(
outfile
,
"
\t
call *8(%%ebp)
\n
"
);
output
(
"
\t
call *8(%%ebp)
\n
"
);
if
(
needs_ldt
)
fprintf
(
outfile
,
"
\t
movl -4(%%ebp),%%esi
\n
"
);
if
(
needs_ldt
)
output
(
"
\t
movl -4(%%ebp),%%esi
\n
"
);
fprintf
(
outfile
,
"
\t
leave
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
output_function_size
(
outfile
,
name
);
output
(
"
\t
leave
\n
"
);
output
(
"
\t
ret
\n
"
);
output_function_size
(
name
);
}
...
...
@@ -450,72 +450,72 @@ static int sort_func_list( ORDDEF **list, int count,
*
* Output the dll initialization code.
*/
static
void
output_init_code
(
FILE
*
outfile
,
const
DLLSPEC
*
spec
,
const
char
*
header_name
)
static
void
output_init_code
(
const
DLLSPEC
*
spec
,
const
char
*
header_name
)
{
char
name
[
80
];
sprintf
(
name
,
".L__wine_spec_%s_init"
,
make_c_identifier
(
spec
->
dll_name
)
);
fprintf
(
outfile
,
"
\n
/* dll initialization code */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.align 4
\n
"
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
name
);
fprintf
(
outfile
,
"subl $4,%%esp
\n
"
);
output
(
"
\n
/* dll initialization code */
\n\n
"
);
output
(
"
\t
.text
\n
"
);
output
(
"
\t
.align 4
\n
"
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
output
(
"%s:
\n
"
,
name
);
output
(
"subl $4,%%esp
\n
"
);
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:
\t
leal .L__wine_spec_file_name-1b(%%eax),%%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
fprintf
(
outfile
,
"
\t
leal %s-1b(%%eax),%%ecx
\n
"
,
header_name
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:
\t
leal .L__wine_spec_file_name-1b(%%eax),%%ecx
\n
"
);
output
(
"
\t
pushl %%ecx
\n
"
);
output
(
"
\t
leal %s-1b(%%eax),%%ecx
\n
"
,
header_name
);
output
(
"
\t
pushl %%ecx
\n
"
);
}
else
{
fprintf
(
outfile
,
"
\t
pushl $.L__wine_spec_file_name
\n
"
);
fprintf
(
outfile
,
"
\t
pushl $%s
\n
"
,
header_name
);
output
(
"
\t
pushl $.L__wine_spec_file_name
\n
"
);
output
(
"
\t
pushl $%s
\n
"
,
header_name
);
}
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_dll_register_16"
)
);
fprintf
(
outfile
,
"
\t
addl $12,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
output_function_size
(
outfile
,
name
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_dll_register_16"
)
);
output
(
"
\t
addl $12,%%esp
\n
"
);
output
(
"
\t
ret
\n
"
);
output_function_size
(
name
);
sprintf
(
name
,
".L__wine_spec_%s_fini"
,
make_c_identifier
(
spec
->
dll_name
)
);
fprintf
(
outfile
,
"
\t
.align 4
\n
"
);
fprintf
(
outfile
,
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
name
);
fprintf
(
outfile
,
"subl $8,%%esp
\n
"
);
output
(
"
\t
.align 4
\n
"
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
name
)
);
output
(
"%s:
\n
"
,
name
);
output
(
"subl $8,%%esp
\n
"
);
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:
\t
leal %s-1b(%%eax),%%ecx
\n
"
,
header_name
);
fprintf
(
outfile
,
"
\t
pushl %%ecx
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:
\t
leal %s-1b(%%eax),%%ecx
\n
"
,
header_name
);
output
(
"
\t
pushl %%ecx
\n
"
);
}
else
{
fprintf
(
outfile
,
"
\t
pushl $%s
\n
"
,
header_name
);
output
(
"
\t
pushl $%s
\n
"
,
header_name
);
}
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_dll_unregister_16"
)
);
fprintf
(
outfile
,
"
\t
addl $12,%%esp
\n
"
);
fprintf
(
outfile
,
"
\t
ret
\n
"
);
output_function_size
(
outfile
,
name
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_dll_unregister_16"
)
);
output
(
"
\t
addl $12,%%esp
\n
"
);
output
(
"
\t
ret
\n
"
);
output_function_size
(
name
);
if
(
target_platform
==
PLATFORM_APPLE
)
{
fprintf
(
outfile
,
"
\t
.mod_init_func
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_%s_init
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
fprintf
(
outfile
,
"
\t
.mod_term_func
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_%s_fini
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
output
(
"
\t
.mod_init_func
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
.long .L__wine_spec_%s_init
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
output
(
"
\t
.mod_term_func
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
.long .L__wine_spec_%s_fini
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
}
else
{
fprintf
(
outfile
,
"
\t
.section
\"
.init
\"
,
\"
ax
\"\n
"
);
fprintf
(
outfile
,
"
\t
call .L__wine_spec_%s_init
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
fprintf
(
outfile
,
"
\t
.section
\"
.fini
\"
,
\"
ax
\"\n
"
);
fprintf
(
outfile
,
"
\t
call .L__wine_spec_%s_fini
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
output
(
"
\t
.section
\"
.init
\"
,
\"
ax
\"\n
"
);
output
(
"
\t
call .L__wine_spec_%s_init
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
output
(
"
\t
.section
\"
.fini
\"
,
\"
ax
\"\n
"
);
output
(
"
\t
call .L__wine_spec_%s_fini
\n
"
,
make_c_identifier
(
spec
->
dll_name
)
);
}
}
...
...
@@ -525,7 +525,7 @@ static void output_init_code( FILE *outfile, const DLLSPEC *spec, const char *he
*
* Build a Win16 assembly file from a spec file.
*/
void
BuildSpec16File
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
void
BuildSpec16File
(
DLLSPEC
*
spec
)
{
ORDDEF
**
typelist
;
int
i
,
j
,
nb_funcs
;
...
...
@@ -533,7 +533,7 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
/* File header */
output_standard_file_header
(
outfile
);
output_standard_file_header
();
if
(
!
spec
->
dll_name
)
/* set default name from file name */
{
...
...
@@ -558,130 +558,130 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
/* Output the module structure */
sprintf
(
header_name
,
"__wine_spec_%s_dos_header"
,
make_c_identifier
(
spec
->
dll_name
)
);
fprintf
(
outfile
,
"
\n
/* module data */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"%s:
\n
"
,
header_name
);
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
/* e_magic */
output
(
"
\n
/* module data */
\n\n
"
);
output
(
"
\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"%s:
\n
"
,
header_name
);
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
/* e_magic */
IMAGE_DOS_SIGNATURE
);
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cblp */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cp */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_crlc */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cparhdr */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_minalloc */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_maxalloc */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_ss */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_sp */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_csum */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_ip */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cs */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_lfarlc */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_ovno */
fprintf
(
outfile
,
"
\t
%s 0,0,0,0
\n
"
,
get_asm_short_keyword
()
);
/* e_res */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_oemid */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_oeminfo */
fprintf
(
outfile
,
"
\t
%s 0,0,0,0,0,0,0,0,0,0
\n
"
,
get_asm_short_keyword
()
);
/* e_res2 */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_ne_header-%s
\n
"
,
header_name
);
/* e_lfanew */
fprintf
(
outfile
,
".L__wine_spec_ne_header:
\n
"
);
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
/* ne_magic */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cblp */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cp */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_crlc */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cparhdr */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_minalloc */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_maxalloc */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_ss */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_sp */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_csum */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_ip */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_cs */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_lfarlc */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_ovno */
output
(
"
\t
%s 0,0,0,0
\n
"
,
get_asm_short_keyword
()
);
/* e_res */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_oemid */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* e_oeminfo */
output
(
"
\t
%s 0,0,0,0,0,0,0,0,0,0
\n
"
,
get_asm_short_keyword
()
);
/* e_res2 */
output
(
"
\t
.long .L__wine_spec_ne_header-%s
\n
"
,
header_name
);
/* e_lfanew */
output
(
".L__wine_spec_ne_header:
\n
"
);
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
/* ne_magic */
IMAGE_OS2_SIGNATURE
);
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
/* ne_ver */
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
/* ne_rev */
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_ne_enttab-.L__wine_spec_ne_header
\n
"
,
/* ne_enttab */
output
(
"
\t
.byte 0
\n
"
);
/* ne_ver */
output
(
"
\t
.byte 0
\n
"
);
/* ne_rev */
output
(
"
\t
%s .L__wine_spec_ne_enttab-.L__wine_spec_ne_header
\n
"
,
/* ne_enttab */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab
\n
"
,
/* ne_cbenttab */
output
(
"
\t
%s .L__wine_spec_ne_enttab_end-.L__wine_spec_ne_enttab
\n
"
,
/* ne_cbenttab */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* ne_crc */
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
/* ne_flags */
output
(
"
\t
.long 0
\n
"
);
/* ne_crc */
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
/* ne_flags */
NE_FFLAGS_SINGLEDATA
|
NE_FFLAGS_LIBMODULE
);
fprintf
(
outfile
,
"
\t
%s 2
\n
"
,
get_asm_short_keyword
()
);
/* ne_autodata */
fprintf
(
outfile
,
"
\t
%s %u
\n
"
,
get_asm_short_keyword
(),
spec
->
heap_size
);
/* ne_heap */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_stack */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* ne_csip */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* ne_sssp */
fprintf
(
outfile
,
"
\t
%s 2
\n
"
,
get_asm_short_keyword
()
);
/* ne_cseg */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cmod */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cbnrestab */
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_ne_segtab-.L__wine_spec_ne_header
\n
"
,
/* ne_segtab */
output
(
"
\t
%s 2
\n
"
,
get_asm_short_keyword
()
);
/* ne_autodata */
output
(
"
\t
%s %u
\n
"
,
get_asm_short_keyword
(),
spec
->
heap_size
);
/* ne_heap */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_stack */
output
(
"
\t
.long 0
\n
"
);
/* ne_csip */
output
(
"
\t
.long 0
\n
"
);
/* ne_sssp */
output
(
"
\t
%s 2
\n
"
,
get_asm_short_keyword
()
);
/* ne_cseg */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cmod */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cbnrestab */
output
(
"
\t
%s .L__wine_spec_ne_segtab-.L__wine_spec_ne_header
\n
"
,
/* ne_segtab */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header
\n
"
,
/* ne_rsrctab */
output
(
"
\t
%s .L__wine_spec_ne_rsrctab-.L__wine_spec_ne_header
\n
"
,
/* ne_rsrctab */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header
\n
"
,
/* ne_restab */
output
(
"
\t
%s .L__wine_spec_ne_restab-.L__wine_spec_ne_header
\n
"
,
/* ne_restab */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header
\n
"
,
/* ne_modtab */
output
(
"
\t
%s .L__wine_spec_ne_modtab-.L__wine_spec_ne_header
\n
"
,
/* ne_modtab */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header
\n
"
,
/* ne_imptab */
output
(
"
\t
%s .L__wine_spec_ne_imptab-.L__wine_spec_ne_header
\n
"
,
/* ne_imptab */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* ne_nrestab */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cmovent */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_align */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cres */
fprintf
(
outfile
,
"
\t
.byte 0x%02x
\n
"
,
NE_OSFLAGS_WINDOWS
);
/* ne_exetyp */
fprintf
(
outfile
,
"
\t
.byte 0x%02x
\n
"
,
NE_AFLAGS_FASTLOAD
);
/* ne_flagsothers */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_pretthunks */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_psegrefbytes */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_swaparea */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_expver */
output
(
"
\t
.long 0
\n
"
);
/* ne_nrestab */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cmovent */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_align */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_cres */
output
(
"
\t
.byte 0x%02x
\n
"
,
NE_OSFLAGS_WINDOWS
);
/* ne_exetyp */
output
(
"
\t
.byte 0x%02x
\n
"
,
NE_AFLAGS_FASTLOAD
);
/* ne_flagsothers */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_pretthunks */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_psegrefbytes */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_swaparea */
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
/* ne_expver */
/* segment table */
fprintf
(
outfile
,
"
\n
.L__wine_spec_ne_segtab:
\n
"
);
output
(
"
\n
.L__wine_spec_ne_segtab:
\n
"
);
/* code segment entry */
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_code_segment-%s
\n
"
,
/* filepos */
output
(
"
\t
%s .L__wine_spec_code_segment-%s
\n
"
,
/* filepos */
get_asm_short_keyword
(),
header_name
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment
\n
"
,
/* size */
output
(
"
\t
%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment
\n
"
,
/* size */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
NE_SEGFLAGS_32BIT
);
/* flags */
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment
\n
"
,
/* minsize */
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
NE_SEGFLAGS_32BIT
);
/* flags */
output
(
"
\t
%s .L__wine_spec_code_segment_end-.L__wine_spec_code_segment
\n
"
,
/* minsize */
get_asm_short_keyword
()
);
/* data segment entry */
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_data_segment-%s
\n
"
,
/* filepos */
output
(
"
\t
%s .L__wine_spec_data_segment-%s
\n
"
,
/* filepos */
get_asm_short_keyword
(),
header_name
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment
\n
"
,
/* size */
output
(
"
\t
%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment
\n
"
,
/* size */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
NE_SEGFLAGS_DATA
);
/* flags */
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment
\n
"
,
/* minsize */
output
(
"
\t
%s 0x%04x
\n
"
,
get_asm_short_keyword
(),
NE_SEGFLAGS_DATA
);
/* flags */
output
(
"
\t
%s .L__wine_spec_data_segment_end-.L__wine_spec_data_segment
\n
"
,
/* minsize */
get_asm_short_keyword
()
);
/* resource directory */
output_res16_directory
(
outfile
,
spec
,
header_name
);
output_res16_directory
(
spec
,
header_name
);
/* resident names table */
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
2
)
);
fprintf
(
outfile
,
".L__wine_spec_ne_restab:
\n
"
);
output_resident_name
(
outfile
,
spec
->
dll_name
,
0
);
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
2
)
);
output
(
".L__wine_spec_ne_restab:
\n
"
);
output_resident_name
(
spec
->
dll_name
,
0
);
for
(
i
=
1
;
i
<=
spec
->
limit
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
i
];
if
(
!
odp
||
!
odp
->
name
[
0
])
continue
;
output_resident_name
(
o
utfile
,
o
dp
->
name
,
i
);
output_resident_name
(
odp
->
name
,
i
);
}
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
output
(
"
\t
.byte 0
\n
"
);
/* imported names table */
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
2
)
);
fprintf
(
outfile
,
".L__wine_spec_ne_modtab:
\n
"
);
fprintf
(
outfile
,
".L__wine_spec_ne_imptab:
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0,0
\n
"
);
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
2
)
);
output
(
".L__wine_spec_ne_modtab:
\n
"
);
output
(
".L__wine_spec_ne_imptab:
\n
"
);
output
(
"
\t
.byte 0,0
\n
"
);
/* entry table */
fprintf
(
outfile
,
"
\n
.L__wine_spec_ne_enttab:
\n
"
);
output_entry_table
(
outfile
,
spec
);
fprintf
(
outfile
,
".L__wine_spec_ne_enttab_end:
\n
"
);
output
(
"
\n
.L__wine_spec_ne_enttab:
\n
"
);
output_entry_table
(
spec
);
output
(
".L__wine_spec_ne_enttab_end:
\n
"
);
/* code segment */
fprintf
(
outfile
,
"
\n\t
.align %d
\n
"
,
get_alignment
(
2
)
);
fprintf
(
outfile
,
".L__wine_spec_code_segment:
\n
"
);
output
(
"
\n\t
.align %d
\n
"
,
get_alignment
(
2
)
);
output
(
".L__wine_spec_code_segment:
\n
"
);
for
(
i
=
0
;
i
<
nb_funcs
;
i
++
)
{
...
...
@@ -709,9 +709,9 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
}
if
(
typelist
[
i
]
->
type
==
TYPE_VARARGS
)
arg_types
[
j
/
10
]
|=
ARG_VARARG
<<
(
3
*
(
j
%
10
));
fprintf
(
outfile
,
".L__wine_spec_callfrom16_%s:
\n
"
,
get_callfrom16_name
(
typelist
[
i
])
);
fprintf
(
outfile
,
"
\t
pushl $.L__wine_spec_call16_%s
\n
"
,
get_relay_name
(
typelist
[
i
])
);
fprintf
(
outfile
,
"
\t
lcall $0,$0
\n
"
);
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
])
);
output
(
"
\t
lcall $0,$0
\n
"
);
if
(
typelist
[
i
]
->
flags
&
FLAG_REGISTER
)
{
...
...
@@ -719,91 +719,91 @@ void BuildSpec16File( FILE *outfile, DLLSPEC *spec )
}
else
if
(
typelist
[
i
]
->
flags
&
FLAG_RET16
)
{
fprintf
(
outfile
,
"
\t
orw %%ax,%%ax
\n
"
);
fprintf
(
outfile
,
"
\t
nop
\n
"
);
/* so that the lretw is aligned */
output
(
"
\t
orw %%ax,%%ax
\n
"
);
output
(
"
\t
nop
\n
"
);
/* so that the lretw is aligned */
nop_words
=
2
;
}
else
{
fprintf
(
outfile
,
"
\t
shld $16,%%eax,%%edx
\n
"
);
fprintf
(
outfile
,
"
\t
orl %%eax,%%eax
\n
"
);
output
(
"
\t
shld $16,%%eax,%%edx
\n
"
);
output
(
"
\t
orl %%eax,%%eax
\n
"
);
nop_words
=
1
;
}
if
(
argsize
)
{
fprintf
(
outfile
,
"
\t
lretw $%u
\n
"
,
argsize
);
output
(
"
\t
lretw $%u
\n
"
,
argsize
);
nop_words
--
;
}
else
fprintf
(
outfile
,
"
\t
lretw
\n
"
);
else
output
(
"
\t
lretw
\n
"
);
if
(
nop_words
)
fprintf
(
outfile
,
"
\t
%s
\n
"
,
nop_sequence
[
nop_words
-
1
]
);
if
(
nop_words
)
output
(
"
\t
%s
\n
"
,
nop_sequence
[
nop_words
-
1
]
);
/* the movl is here so that the code contains only valid instructions, */
/* it's never actually executed, we only care about the arg_types[] values */
fprintf
(
outfile
,
"
\t
%s 0x86c7
\n
"
,
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
.long 0x%08x,0x%08x
\n
"
,
arg_types
[
0
],
arg_types
[
1
]
);
output
(
"
\t
%s 0x86c7
\n
"
,
get_asm_short_keyword
()
);
output
(
"
\t
.long 0x%08x,0x%08x
\n
"
,
arg_types
[
0
],
arg_types
[
1
]
);
}
for
(
i
=
0
;
i
<=
spec
->
limit
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
i
];
if
(
!
odp
||
!
is_function
(
odp
))
continue
;
fprintf
(
outfile
,
".L__wine_%s_%u:
\n
"
,
make_c_identifier
(
spec
->
dll_name
),
i
);
fprintf
(
outfile
,
"
\t
pushw %%bp
\n
"
);
fprintf
(
outfile
,
"
\t
pushl $%s
\n
"
,
output
(
".L__wine_%s_%u:
\n
"
,
make_c_identifier
(
spec
->
dll_name
),
i
);
output
(
"
\t
pushw %%bp
\n
"
);
output
(
"
\t
pushl $%s
\n
"
,
asm_name
(
odp
->
type
==
TYPE_STUB
?
get_stub_name
(
odp
,
spec
)
:
odp
->
link_name
));
fprintf
(
outfile
,
"
\t
callw .L__wine_spec_callfrom16_%s
\n
"
,
get_callfrom16_name
(
odp
)
);
output
(
"
\t
callw .L__wine_spec_callfrom16_%s
\n
"
,
get_callfrom16_name
(
odp
)
);
}
fprintf
(
outfile
,
".L__wine_spec_code_segment_end:
\n
"
);
output
(
".L__wine_spec_code_segment_end:
\n
"
);
/* data segment */
fprintf
(
outfile
,
"
\n
.L__wine_spec_data_segment:
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
\n
"
);
/* instance data */
output
(
"
\n
.L__wine_spec_data_segment:
\n
"
);
output
(
"
\t
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
\n
"
);
/* instance data */
for
(
i
=
0
;
i
<=
spec
->
limit
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
i
];
if
(
!
odp
||
odp
->
type
!=
TYPE_VARIABLE
)
continue
;
fprintf
(
outfile
,
".L__wine_%s_%u:
\n
"
,
make_c_identifier
(
spec
->
dll_name
),
i
);
fprintf
(
outfile
,
"
\t
.long "
);
output
(
".L__wine_%s_%u:
\n
"
,
make_c_identifier
(
spec
->
dll_name
),
i
);
output
(
"
\t
.long "
);
for
(
j
=
0
;
j
<
odp
->
u
.
var
.
n_values
-
1
;
j
++
)
fprintf
(
outfile
,
"0x%08x,"
,
odp
->
u
.
var
.
values
[
j
]
);
fprintf
(
outfile
,
"0x%08x
\n
"
,
odp
->
u
.
var
.
values
[
j
]
);
output
(
"0x%08x,"
,
odp
->
u
.
var
.
values
[
j
]
);
output
(
"0x%08x
\n
"
,
odp
->
u
.
var
.
values
[
j
]
);
}
fprintf
(
outfile
,
".L__wine_spec_data_segment_end:
\n
"
);
output
(
".L__wine_spec_data_segment_end:
\n
"
);
/* resource data */
if
(
spec
->
nb_resources
)
{
fprintf
(
outfile
,
"
\n
.L__wine_spec_resource_data:
\n
"
);
output_res16_data
(
outfile
,
spec
);
output
(
"
\n
.L__wine_spec_resource_data:
\n
"
);
output_res16_data
(
spec
);
}
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
/* make sure the last symbol points to something */
output
(
"
\t
.byte 0
\n
"
);
/* make sure the last symbol points to something */
/* relay functions */
nb_funcs
=
sort_func_list
(
typelist
,
nb_funcs
,
relay_type_compare
);
if
(
nb_funcs
)
{
fprintf
(
outfile
,
"
\n
/* relay functions */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.text
\n
"
);
for
(
i
=
0
;
i
<
nb_funcs
;
i
++
)
output_call16_function
(
outfile
,
typelist
[
i
]
);
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"wine_ldt_copy_ptr:
\n
"
);
fprintf
(
outfile
,
"
\t
.long %s
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
output
(
"
\n
/* relay functions */
\n\n
"
);
output
(
"
\t
.text
\n
"
);
for
(
i
=
0
;
i
<
nb_funcs
;
i
++
)
output_call16_function
(
typelist
[
i
]
);
output
(
"
\t
.data
\n
"
);
output
(
"wine_ldt_copy_ptr:
\n
"
);
output
(
"
\t
.long %s
\n
"
,
asm_name
(
"wine_ldt_copy"
)
);
}
fprintf
(
outfile
,
"
\n\t
%s
\n
"
,
get_asm_string_section
()
);
fprintf
(
outfile
,
".L__wine_spec_file_name:
\n
"
);
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
spec
->
file_name
);
output
(
"
\n\t
%s
\n
"
,
get_asm_string_section
()
);
output
(
".L__wine_spec_file_name:
\n
"
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
spec
->
file_name
);
output_stubs
(
outfile
,
spec
);
output_get_pc_thunk
(
outfile
);
output_init_code
(
outfile
,
spec
,
header_name
);
output_gnu_stack_note
(
outfile
);
output_stubs
(
spec
);
output_get_pc_thunk
();
output_init_code
(
spec
,
header_name
);
output_gnu_stack_note
();
free
(
typelist
);
}
tools/winebuild/spec32.c
View file @
71580499
...
...
@@ -68,30 +68,30 @@ int has_relays( DLLSPEC *spec )
*
* Output entry points for relay debugging
*/
static
void
output_relay_debug
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
static
void
output_relay_debug
(
DLLSPEC
*
spec
)
{
unsigned
int
i
,
j
,
args
,
flags
;
/* first the table of entry point offsets */
fprintf
(
outfile
,
"
\t
%s
\n
"
,
get_asm_rodata_section
()
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
".L__wine_spec_relay_entry_point_offsets:
\n
"
);
output
(
"
\t
%s
\n
"
,
get_asm_rodata_section
()
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
".L__wine_spec_relay_entry_point_offsets:
\n
"
);
for
(
i
=
spec
->
base
;
i
<=
spec
->
limit
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
i
];
if
(
needs_relay
(
odp
))
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points
\n
"
,
i
);
output
(
"
\t
.long .L__wine_spec_relay_entry_point_%d-__wine_spec_relay_entry_points
\n
"
,
i
);
else
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
output
(
"
\t
.long 0
\n
"
);
}
/* then the table of argument types */
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
".L__wine_spec_relay_arg_types:
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
".L__wine_spec_relay_arg_types:
\n
"
);
for
(
i
=
spec
->
base
;
i
<=
spec
->
limit
;
i
++
)
{
...
...
@@ -106,14 +106,14 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
if
(
odp
->
u
.
func
.
arg_types
[
j
]
==
'W'
)
mask
|=
2
<<
(
j
*
2
);
}
}
fprintf
(
outfile
,
"
\t
.long 0x%08x
\n
"
,
mask
);
output
(
"
\t
.long 0x%08x
\n
"
,
mask
);
}
/* then the relay thunks */
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"__wine_spec_relay_entry_points:
\n
"
);
fprintf
(
outfile
,
"
\t
nop
\n
"
);
/* to avoid 0 offset */
output
(
"
\t
.text
\n
"
);
output
(
"__wine_spec_relay_entry_points:
\n
"
);
output
(
"
\t
nop
\n
"
);
/* to avoid 0 offset */
for
(
i
=
spec
->
base
;
i
<=
spec
->
limit
;
i
++
)
{
...
...
@@ -121,39 +121,39 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
if
(
!
needs_relay
(
odp
))
continue
;
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
".L__wine_spec_relay_entry_point_%d:
\n
"
,
i
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
".L__wine_spec_relay_entry_point_%d:
\n
"
,
i
);
if
(
odp
->
flags
&
FLAG_REGISTER
)
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
output
(
"
\t
pushl %%eax
\n
"
);
else
fprintf
(
outfile
,
"
\t
pushl %%esp
\n
"
);
output
(
"
\t
pushl %%esp
\n
"
);
args
=
strlen
(
odp
->
u
.
func
.
arg_types
);
flags
=
0
;
if
(
odp
->
flags
&
FLAG_RET64
)
flags
|=
1
;
if
(
odp
->
type
==
TYPE_STDCALL
)
flags
|=
2
;
fprintf
(
outfile
,
"
\t
pushl $%u
\n
"
,
(
flags
<<
24
)
|
(
args
<<
16
)
|
(
i
-
spec
->
base
)
);
output
(
"
\t
pushl $%u
\n
"
,
(
flags
<<
24
)
|
(
args
<<
16
)
|
(
i
-
spec
->
base
)
);
if
(
UsePIC
)
{
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
fprintf
(
outfile
,
"1:
\t
leal .L__wine_spec_relay_descr-1b(%%eax),%%eax
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
"__wine_spec_get_pc_thunk_eax"
)
);
output
(
"1:
\t
leal .L__wine_spec_relay_descr-1b(%%eax),%%eax
\n
"
);
}
else
fprintf
(
outfile
,
"
\t
movl $.L__wine_spec_relay_descr,%%eax
\n
"
);
fprintf
(
outfile
,
"
\t
pushl %%eax
\n
"
);
else
output
(
"
\t
movl $.L__wine_spec_relay_descr,%%eax
\n
"
);
output
(
"
\t
pushl %%eax
\n
"
);
if
(
odp
->
flags
&
FLAG_REGISTER
)
{
fprintf
(
outfile
,
"
\t
call *8(%%eax)
\n
"
);
output
(
"
\t
call *8(%%eax)
\n
"
);
}
else
{
fprintf
(
outfile
,
"
\t
call *4(%%eax)
\n
"
);
output
(
"
\t
call *4(%%eax)
\n
"
);
if
(
odp
->
type
==
TYPE_STDCALL
)
fprintf
(
outfile
,
"
\t
ret $%u
\n
"
,
args
*
get_ptr_size
()
);
output
(
"
\t
ret $%u
\n
"
,
args
*
get_ptr_size
()
);
else
fprintf
(
outfile
,
"
\t
ret
\n
"
);
output
(
"
\t
ret
\n
"
);
}
}
}
...
...
@@ -163,46 +163,46 @@ static void output_relay_debug( FILE *outfile, DLLSPEC *spec )
*
* Output the export table for a Win32 module.
*/
static
void
output_exports
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
static
void
output_exports
(
DLLSPEC
*
spec
)
{
int
i
,
fwd_size
=
0
;
int
nr_exports
=
spec
->
base
<=
spec
->
limit
?
spec
->
limit
-
spec
->
base
+
1
:
0
;
if
(
!
nr_exports
)
return
;
fprintf
(
outfile
,
"
\n
/* export table */
\n\n
"
);
fprintf
(
outfile
,
"
\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
".L__wine_spec_exports:
\n
"
);
output
(
"
\n
/* export table */
\n\n
"
);
output
(
"
\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
".L__wine_spec_exports:
\n
"
);
/* export directory header */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* Characteristics */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* MajorVersion/MinorVersion */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_exp_names-.L__wine_spec_rva_base
\n
"
);
/* Name */
fprintf
(
outfile
,
"
\t
.long %u
\n
"
,
spec
->
base
);
/* Base */
fprintf
(
outfile
,
"
\t
.long %u
\n
"
,
nr_exports
);
/* NumberOfFunctions */
fprintf
(
outfile
,
"
\t
.long %u
\n
"
,
spec
->
nb_names
);
/* NumberOfNames */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_exports_funcs-.L__wine_spec_rva_base
\n
"
);
/* AddressOfFunctions */
output
(
"
\t
.long 0
\n
"
);
/* Characteristics */
output
(
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
output
(
"
\t
.long 0
\n
"
);
/* MajorVersion/MinorVersion */
output
(
"
\t
.long .L__wine_spec_exp_names-.L__wine_spec_rva_base
\n
"
);
/* Name */
output
(
"
\t
.long %u
\n
"
,
spec
->
base
);
/* Base */
output
(
"
\t
.long %u
\n
"
,
nr_exports
);
/* NumberOfFunctions */
output
(
"
\t
.long %u
\n
"
,
spec
->
nb_names
);
/* NumberOfNames */
output
(
"
\t
.long .L__wine_spec_exports_funcs-.L__wine_spec_rva_base
\n
"
);
/* AddressOfFunctions */
if
(
spec
->
nb_names
)
{
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_exp_name_ptrs-.L__wine_spec_rva_base
\n
"
);
/* AddressOfNames */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_exp_ordinals-.L__wine_spec_rva_base
\n
"
);
/* AddressOfNameOrdinals */
output
(
"
\t
.long .L__wine_spec_exp_name_ptrs-.L__wine_spec_rva_base
\n
"
);
/* AddressOfNames */
output
(
"
\t
.long .L__wine_spec_exp_ordinals-.L__wine_spec_rva_base
\n
"
);
/* AddressOfNameOrdinals */
}
else
{
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* AddressOfNames */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* AddressOfNameOrdinals */
output
(
"
\t
.long 0
\n
"
);
/* AddressOfNames */
output
(
"
\t
.long 0
\n
"
);
/* AddressOfNameOrdinals */
}
/* output the function pointers */
fprintf
(
outfile
,
"
\n
.L__wine_spec_exports_funcs:
\n
"
);
output
(
"
\n
.L__wine_spec_exports_funcs:
\n
"
);
for
(
i
=
spec
->
base
;
i
<=
spec
->
limit
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
i
];
if
(
!
odp
)
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
if
(
!
odp
)
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
else
switch
(
odp
->
type
)
{
case
TYPE_EXTERN
:
...
...
@@ -211,21 +211,21 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
case
TYPE_CDECL
:
if
(
odp
->
flags
&
FLAG_FORWARD
)
{
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_forwards+%u
\n
"
,
get_asm_ptr_keyword
(),
fwd_size
);
output
(
"
\t
%s .L__wine_spec_forwards+%u
\n
"
,
get_asm_ptr_keyword
(),
fwd_size
);
fwd_size
+=
strlen
(
odp
->
link_name
)
+
1
;
}
else
if
(
odp
->
flags
&
FLAG_EXT_LINK
)
{
fprintf
(
outfile
,
"
\t
%s %s_%s
\n
"
,
output
(
"
\t
%s %s_%s
\n
"
,
get_asm_ptr_keyword
(),
asm_name
(
"__wine_spec_ext_link"
),
odp
->
link_name
);
}
else
{
fprintf
(
outfile
,
"
\t
%s %s
\n
"
,
get_asm_ptr_keyword
(),
asm_name
(
odp
->
link_name
)
);
output
(
"
\t
%s %s
\n
"
,
get_asm_ptr_keyword
(),
asm_name
(
odp
->
link_name
)
);
}
break
;
case
TYPE_STUB
:
fprintf
(
outfile
,
"
\t
%s %s
\n
"
,
get_asm_ptr_keyword
(),
output
(
"
\t
%s %s
\n
"
,
get_asm_ptr_keyword
(),
asm_name
(
get_stub_name
(
odp
,
spec
))
);
break
;
default:
...
...
@@ -239,68 +239,68 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
int
namepos
=
strlen
(
spec
->
file_name
)
+
1
;
fprintf
(
outfile
,
"
\n
.L__wine_spec_exp_name_ptrs:
\n
"
);
output
(
"
\n
.L__wine_spec_exp_name_ptrs:
\n
"
);
for
(
i
=
0
;
i
<
spec
->
nb_names
;
i
++
)
{
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base
\n
"
,
namepos
);
output
(
"
\t
.long .L__wine_spec_exp_names+%u-.L__wine_spec_rva_base
\n
"
,
namepos
);
namepos
+=
strlen
(
spec
->
names
[
i
]
->
name
)
+
1
;
}
/* output the function ordinals */
fprintf
(
outfile
,
"
\n
.L__wine_spec_exp_ordinals:
\n
"
);
output
(
"
\n
.L__wine_spec_exp_ordinals:
\n
"
);
for
(
i
=
0
;
i
<
spec
->
nb_names
;
i
++
)
{
fprintf
(
outfile
,
"
\t
%s %d
\n
"
,
output
(
"
\t
%s %d
\n
"
,
get_asm_short_keyword
(),
spec
->
names
[
i
]
->
ordinal
-
spec
->
base
);
}
if
(
spec
->
nb_names
%
2
)
{
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
output
(
"
\t
%s 0
\n
"
,
get_asm_short_keyword
()
);
}
}
/* output the export name strings */
fprintf
(
outfile
,
"
\n
.L__wine_spec_exp_names:
\n
"
);
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
spec
->
file_name
);
output
(
"
\n
.L__wine_spec_exp_names:
\n
"
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
spec
->
file_name
);
for
(
i
=
0
;
i
<
spec
->
nb_names
;
i
++
)
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
spec
->
names
[
i
]
->
name
);
/* output forward strings */
if
(
fwd_size
)
{
fprintf
(
outfile
,
"
\n
.L__wine_spec_forwards:
\n
"
);
output
(
"
\n
.L__wine_spec_forwards:
\n
"
);
for
(
i
=
spec
->
base
;
i
<=
spec
->
limit
;
i
++
)
{
ORDDEF
*
odp
=
spec
->
ordinals
[
i
];
if
(
odp
&&
(
odp
->
flags
&
FLAG_FORWARD
))
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
odp
->
link_name
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
odp
->
link_name
);
}
}
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
".L__wine_spec_exports_end:
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
".L__wine_spec_exports_end:
\n
"
);
/* output relays */
/* we only support relay debugging on i386 */
if
(
target_cpu
!=
CPU_x86
)
{
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
return
;
}
fprintf
(
outfile
,
".L__wine_spec_relay_descr:
\n
"
);
fprintf
(
outfile
,
"
\t
%s 0xdeb90001
\n
"
,
get_asm_ptr_keyword
()
);
/* magic */
fprintf
(
outfile
,
"
\t
%s 0,0
\n
"
,
get_asm_ptr_keyword
()
);
/* relay funcs */
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* private data */
fprintf
(
outfile
,
"
\t
%s __wine_spec_relay_entry_points
\n
"
,
get_asm_ptr_keyword
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_relay_entry_point_offsets
\n
"
,
get_asm_ptr_keyword
()
);
fprintf
(
outfile
,
"
\t
%s .L__wine_spec_relay_arg_types
\n
"
,
get_asm_ptr_keyword
()
);
output
(
".L__wine_spec_relay_descr:
\n
"
);
output
(
"
\t
%s 0xdeb90001
\n
"
,
get_asm_ptr_keyword
()
);
/* magic */
output
(
"
\t
%s 0,0
\n
"
,
get_asm_ptr_keyword
()
);
/* relay funcs */
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* private data */
output
(
"
\t
%s __wine_spec_relay_entry_points
\n
"
,
get_asm_ptr_keyword
()
);
output
(
"
\t
%s .L__wine_spec_relay_entry_point_offsets
\n
"
,
get_asm_ptr_keyword
()
);
output
(
"
\t
%s .L__wine_spec_relay_arg_types
\n
"
,
get_asm_ptr_keyword
()
);
output_relay_debug
(
outfile
,
spec
);
output_relay_debug
(
spec
);
}
...
...
@@ -309,33 +309,33 @@ static void output_exports( FILE *outfile, DLLSPEC *spec )
*
* Output code for calling a dll constructor.
*/
static
void
output_asm_constructor
(
FILE
*
outfile
,
const
char
*
constructor
)
static
void
output_asm_constructor
(
const
char
*
constructor
)
{
if
(
target_platform
==
PLATFORM_APPLE
)
{
/* Mach-O doesn't have an init section */
fprintf
(
outfile
,
"
\n\t
.mod_init_func
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
fprintf
(
outfile
,
"
\t
.long %s
\n
"
,
asm_name
(
constructor
)
);
output
(
"
\n\t
.mod_init_func
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
4
)
);
output
(
"
\t
.long %s
\n
"
,
asm_name
(
constructor
)
);
}
else
{
fprintf
(
outfile
,
"
\n\t
.section
\"
.init
\"
,
\"
ax
\"\n
"
);
output
(
"
\n\t
.section
\"
.init
\"
,
\"
ax
\"\n
"
);
switch
(
target_cpu
)
{
case
CPU_x86
:
case
CPU_x86_64
:
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
constructor
)
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
constructor
)
);
break
;
case
CPU_SPARC
:
fprintf
(
outfile
,
"
\t
call %s
\n
"
,
asm_name
(
constructor
)
);
fprintf
(
outfile
,
"
\t
nop
\n
"
);
output
(
"
\t
call %s
\n
"
,
asm_name
(
constructor
)
);
output
(
"
\t
nop
\n
"
);
break
;
case
CPU_ALPHA
:
fprintf
(
outfile
,
"
\t
jsr $26,%s
\n
"
,
asm_name
(
constructor
)
);
output
(
"
\t
jsr $26,%s
\n
"
,
asm_name
(
constructor
)
);
break
;
case
CPU_POWERPC
:
fprintf
(
outfile
,
"
\t
bl %s
\n
"
,
asm_name
(
constructor
)
);
output
(
"
\t
bl %s
\n
"
,
asm_name
(
constructor
)
);
break
;
}
}
...
...
@@ -347,32 +347,32 @@ static void output_asm_constructor( FILE *outfile, const char *constructor )
*
* Build a Win32 C file from a spec file.
*/
void
BuildSpec32File
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
void
BuildSpec32File
(
DLLSPEC
*
spec
)
{
int
machine
=
0
;
unsigned
int
page_size
=
get_page_size
();
resolve_imports
(
spec
);
output_standard_file_header
(
outfile
);
output_standard_file_header
();
/* Reserve some space for the PE header */
fprintf
(
outfile
,
"
\t
.text
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
page_size
)
);
fprintf
(
outfile
,
"__wine_spec_pe_header:
\n
"
);
output
(
"
\t
.text
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
page_size
)
);
output
(
"__wine_spec_pe_header:
\n
"
);
if
(
target_platform
==
PLATFORM_APPLE
)
fprintf
(
outfile
,
"
\t
.space 65536
\n
"
);
output
(
"
\t
.space 65536
\n
"
);
else
fprintf
(
outfile
,
"
\t
.skip 65536
\n
"
);
output
(
"
\t
.skip 65536
\n
"
);
/* Output the NT header */
fprintf
(
outfile
,
"
\n\t
.data
\n
"
);
fprintf
(
outfile
,
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
"__wine_spec_nt_header"
)
);
fprintf
(
outfile
,
".L__wine_spec_rva_base:
\n
"
);
output
(
"
\n\t
.data
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
())
);
output
(
"%s
\n
"
,
asm_globl
(
"__wine_spec_nt_header"
)
);
output
(
".L__wine_spec_rva_base:
\n
"
);
fprintf
(
outfile
,
"
\t
.long 0x%04x
\n
"
,
IMAGE_NT_SIGNATURE
);
/* Signature */
output
(
"
\t
.long 0x%04x
\n
"
,
IMAGE_NT_SIGNATURE
);
/* Signature */
switch
(
target_cpu
)
{
case
CPU_x86
:
machine
=
IMAGE_FILE_MACHINE_I386
;
break
;
...
...
@@ -381,105 +381,105 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
case
CPU_ALPHA
:
machine
=
IMAGE_FILE_MACHINE_ALPHA
;
break
;
case
CPU_SPARC
:
machine
=
IMAGE_FILE_MACHINE_UNKNOWN
;
break
;
}
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
/* Machine */
output
(
"
\t
%s 0x%04x
\n
"
,
/* Machine */
get_asm_short_keyword
(),
machine
);
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
/* NumberOfSections */
output
(
"
\t
%s 0
\n
"
,
/* NumberOfSections */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* PointerToSymbolTable */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* NumberOfSymbols */
fprintf
(
outfile
,
"
\t
%s %d
\n
"
,
/* SizeOfOptionalHeader */
output
(
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
output
(
"
\t
.long 0
\n
"
);
/* PointerToSymbolTable */
output
(
"
\t
.long 0
\n
"
);
/* NumberOfSymbols */
output
(
"
\t
%s %d
\n
"
,
/* SizeOfOptionalHeader */
get_asm_short_keyword
(),
get_ptr_size
()
==
8
?
IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
:
IMAGE_SIZEOF_NT_OPTIONAL32_HEADER
);
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
/* Characteristics */
output
(
"
\t
%s 0x%04x
\n
"
,
/* Characteristics */
get_asm_short_keyword
(),
spec
->
characteristics
);
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
/* Magic */
output
(
"
\t
%s 0x%04x
\n
"
,
/* Magic */
get_asm_short_keyword
(),
get_ptr_size
()
==
8
?
IMAGE_NT_OPTIONAL_HDR64_MAGIC
:
IMAGE_NT_OPTIONAL_HDR32_MAGIC
);
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
/* MajorLinkerVersion */
fprintf
(
outfile
,
"
\t
.byte 0
\n
"
);
/* MinorLinkerVersion */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* SizeOfCode */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* SizeOfInitializedData */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* SizeOfUninitializedData */
output
(
"
\t
.byte 0
\n
"
);
/* MajorLinkerVersion */
output
(
"
\t
.byte 0
\n
"
);
/* MinorLinkerVersion */
output
(
"
\t
.long 0
\n
"
);
/* SizeOfCode */
output
(
"
\t
.long 0
\n
"
);
/* SizeOfInitializedData */
output
(
"
\t
.long 0
\n
"
);
/* SizeOfUninitializedData */
/* note: we expand the AddressOfEntryPoint field on 64-bit by overwriting the BaseOfCode field */
fprintf
(
outfile
,
"
\t
%s %s
\n
"
,
/* AddressOfEntryPoint */
output
(
"
\t
%s %s
\n
"
,
/* AddressOfEntryPoint */
get_asm_ptr_keyword
(),
asm_name
(
spec
->
init_func
)
);
if
(
get_ptr_size
()
==
4
)
{
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* BaseOfCode */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* BaseOfData */
output
(
"
\t
.long 0
\n
"
);
/* BaseOfCode */
output
(
"
\t
.long 0
\n
"
);
/* BaseOfData */
}
fprintf
(
outfile
,
"
\t
%s __wine_spec_pe_header
\n
"
,
/* ImageBase */
output
(
"
\t
%s __wine_spec_pe_header
\n
"
,
/* ImageBase */
get_asm_ptr_keyword
()
);
fprintf
(
outfile
,
"
\t
.long %u
\n
"
,
page_size
);
/* SectionAlignment */
fprintf
(
outfile
,
"
\t
.long %u
\n
"
,
page_size
);
/* FileAlignment */
fprintf
(
outfile
,
"
\t
%s 1,0
\n
"
,
/* Major/MinorOperatingSystemVersion */
output
(
"
\t
.long %u
\n
"
,
page_size
);
/* SectionAlignment */
output
(
"
\t
.long %u
\n
"
,
page_size
);
/* FileAlignment */
output
(
"
\t
%s 1,0
\n
"
,
/* Major/MinorOperatingSystemVersion */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s 0,0
\n
"
,
/* Major/MinorImageVersion */
output
(
"
\t
%s 0,0
\n
"
,
/* Major/MinorImageVersion */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s %u,%u
\n
"
,
/* Major/MinorSubsystemVersion */
output
(
"
\t
%s %u,%u
\n
"
,
/* Major/MinorSubsystemVersion */
get_asm_short_keyword
(),
spec
->
subsystem_major
,
spec
->
subsystem_minor
);
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* Win32VersionValue */
fprintf
(
outfile
,
"
\t
.long %s-.L__wine_spec_rva_base
\n
"
,
/* SizeOfImage */
output
(
"
\t
.long 0
\n
"
);
/* Win32VersionValue */
output
(
"
\t
.long %s-.L__wine_spec_rva_base
\n
"
,
/* SizeOfImage */
asm_name
(
"_end"
)
);
fprintf
(
outfile
,
"
\t
.long %u
\n
"
,
page_size
);
/* SizeOfHeaders */
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* CheckSum */
fprintf
(
outfile
,
"
\t
%s 0x%04x
\n
"
,
/* Subsystem */
output
(
"
\t
.long %u
\n
"
,
page_size
);
/* SizeOfHeaders */
output
(
"
\t
.long 0
\n
"
);
/* CheckSum */
output
(
"
\t
%s 0x%04x
\n
"
,
/* Subsystem */
get_asm_short_keyword
(),
spec
->
subsystem
);
fprintf
(
outfile
,
"
\t
%s 0
\n
"
,
/* DllCharacteristics */
output
(
"
\t
%s 0
\n
"
,
/* DllCharacteristics */
get_asm_short_keyword
()
);
fprintf
(
outfile
,
"
\t
%s %u,%u
\n
"
,
/* SizeOfStackReserve/Commit */
output
(
"
\t
%s %u,%u
\n
"
,
/* SizeOfStackReserve/Commit */
get_asm_ptr_keyword
(),
(
spec
->
stack_size
?
spec
->
stack_size
:
1024
)
*
1024
,
page_size
);
fprintf
(
outfile
,
"
\t
%s %u,%u
\n
"
,
/* SizeOfHeapReserve/Commit */
output
(
"
\t
%s %u,%u
\n
"
,
/* SizeOfHeapReserve/Commit */
get_asm_ptr_keyword
(),
(
spec
->
heap_size
?
spec
->
heap_size
:
1024
)
*
1024
,
page_size
);
fprintf
(
outfile
,
"
\t
.long 0
\n
"
);
/* LoaderFlags */
fprintf
(
outfile
,
"
\t
.long 16
\n
"
);
/* NumberOfRvaAndSizes */
output
(
"
\t
.long 0
\n
"
);
/* LoaderFlags */
output
(
"
\t
.long 16
\n
"
);
/* NumberOfRvaAndSizes */
if
(
spec
->
base
<=
spec
->
limit
)
/* DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_exports-.L__wine_spec_rva_base,"
output
(
"
\t
.long .L__wine_spec_exports-.L__wine_spec_rva_base,"
".L__wine_spec_exports_end-.L__wine_spec_exports
\n
"
);
else
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
output
(
"
\t
.long 0,0
\n
"
);
if
(
has_imports
())
/* DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_imports-.L__wine_spec_rva_base,"
output
(
"
\t
.long .L__wine_spec_imports-.L__wine_spec_rva_base,"
".L__wine_spec_imports_end-.L__wine_spec_imports
\n
"
);
else
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
output
(
"
\t
.long 0,0
\n
"
);
if
(
spec
->
nb_resources
)
/* DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] */
fprintf
(
outfile
,
"
\t
.long .L__wine_spec_resources-.L__wine_spec_rva_base,"
output
(
"
\t
.long .L__wine_spec_resources-.L__wine_spec_rva_base,"
".L__wine_spec_resources_end-.L__wine_spec_resources
\n
"
);
else
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[3] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[4] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[5] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[6] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[7] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[8] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[9] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[10] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[11] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[12] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[13] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[14] */
fprintf
(
outfile
,
"
\t
.long 0,0
\n
"
);
/* DataDirectory[15] */
fprintf
(
outfile
,
"
\n\t
%s
\n
"
,
get_asm_string_section
()
);
fprintf
(
outfile
,
"%s
\n
"
,
asm_globl
(
"__wine_spec_file_name"
)
);
fprintf
(
outfile
,
".L__wine_spec_file_name:
\n
"
);
fprintf
(
outfile
,
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
spec
->
file_name
);
output
(
"
\t
.long 0,0
\n
"
);
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[3] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[4] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[5] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[6] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[7] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[8] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[9] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[10] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[11] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[12] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[13] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[14] */
output
(
"
\t
.long 0,0
\n
"
);
/* DataDirectory[15] */
output
(
"
\n\t
%s
\n
"
,
get_asm_string_section
()
);
output
(
"%s
\n
"
,
asm_globl
(
"__wine_spec_file_name"
)
);
output
(
".L__wine_spec_file_name:
\n
"
);
output
(
"
\t
%s
\"
%s
\"\n
"
,
get_asm_string_keyword
(),
spec
->
file_name
);
if
(
target_platform
==
PLATFORM_APPLE
)
fprintf
(
outfile
,
"
\t
.lcomm %s,4
\n
"
,
asm_name
(
"_end"
)
);
output_stubs
(
outfile
,
spec
);
output_exports
(
outfile
,
spec
);
output_imports
(
outfile
,
spec
);
output_resources
(
outfile
,
spec
);
output_asm_constructor
(
outfile
,
"__wine_spec_init_ctor"
);
output_gnu_stack_note
(
outfile
);
output
(
"
\t
.lcomm %s,4
\n
"
,
asm_name
(
"_end"
)
);
output_stubs
(
spec
);
output_exports
(
spec
);
output_imports
(
spec
);
output_resources
(
spec
);
output_asm_constructor
(
"__wine_spec_init_ctor"
);
output_gnu_stack_note
();
}
...
...
@@ -488,20 +488,19 @@ void BuildSpec32File( FILE *outfile, DLLSPEC *spec )
*
* Build a Win32 def file from a spec file.
*/
void
BuildDef32File
(
FILE
*
outfile
,
DLLSPEC
*
spec
)
void
BuildDef32File
(
DLLSPEC
*
spec
)
{
const
char
*
name
;
int
i
,
total
;
if
(
spec_file_name
)
fprintf
(
outfile
,
"; File generated automatically from %s; do not edit!
\n\n
"
,
output
(
"; File generated automatically from %s; do not edit!
\n\n
"
,
spec_file_name
);
else
fprintf
(
outfile
,
"; File generated automatically; do not edit!
\n\n
"
);
output
(
"; File generated automatically; do not edit!
\n\n
"
);
fprintf
(
outfile
,
"LIBRARY %s
\n\n
"
,
spec
->
file_name
);
fprintf
(
outfile
,
"EXPORTS
\n
"
);
output
(
"LIBRARY %s
\n\n
"
,
spec
->
file_name
);
output
(
"EXPORTS
\n
"
);
/* Output the exports and relay entry points */
...
...
@@ -520,7 +519,7 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec )
if
(
odp
->
type
==
TYPE_STUB
)
continue
;
fprintf
(
outfile
,
" %s"
,
name
);
output
(
" %s"
,
name
);
switch
(
odp
->
type
)
{
...
...
@@ -531,31 +530,31 @@ void BuildDef32File( FILE *outfile, DLLSPEC *spec )
case
TYPE_CDECL
:
/* try to reduce output */
if
(
strcmp
(
name
,
odp
->
link_name
)
||
(
odp
->
flags
&
FLAG_FORWARD
))
fprintf
(
outfile
,
"=%s"
,
odp
->
link_name
);
output
(
"=%s"
,
odp
->
link_name
);
break
;
case
TYPE_STDCALL
:
{
int
at_param
=
strlen
(
odp
->
u
.
func
.
arg_types
)
*
get_ptr_size
();
if
(
!
kill_at
)
fprintf
(
outfile
,
"@%d"
,
at_param
);
if
(
!
kill_at
)
output
(
"@%d"
,
at_param
);
if
(
odp
->
flags
&
FLAG_FORWARD
)
{
fprintf
(
outfile
,
"=%s"
,
odp
->
link_name
);
output
(
"=%s"
,
odp
->
link_name
);
}
else
if
(
strcmp
(
name
,
odp
->
link_name
))
/* try to reduce output */
{
fprintf
(
outfile
,
"=%s"
,
odp
->
link_name
);
if
(
!
kill_at
)
fprintf
(
outfile
,
"@%d"
,
at_param
);
output
(
"=%s"
,
odp
->
link_name
);
if
(
!
kill_at
)
output
(
"@%d"
,
at_param
);
}
break
;
}
default:
assert
(
0
);
}
fprintf
(
outfile
,
" @%d"
,
odp
->
ordinal
);
if
(
!
odp
->
name
)
fprintf
(
outfile
,
" NONAME"
);
if
(
is_data
)
fprintf
(
outfile
,
" DATA"
);
if
(
odp
->
flags
&
FLAG_PRIVATE
)
fprintf
(
outfile
,
" PRIVATE"
);
fprintf
(
outfile
,
"
\n
"
);
output
(
" @%d"
,
odp
->
ordinal
);
if
(
!
odp
->
name
)
output
(
" NONAME"
);
if
(
is_data
)
output
(
" DATA"
);
if
(
odp
->
flags
&
FLAG_PRIVATE
)
output
(
" PRIVATE"
);
output
(
"
\n
"
);
}
if
(
!
total
)
warning
(
"%s: Import library doesn't export anything
\n
"
,
spec
->
file_name
);
}
tools/winebuild/utils.c
View file @
71580499
...
...
@@ -162,6 +162,18 @@ void warning( const char *msg, ... )
va_end
(
valist
);
}
int
output
(
const
char
*
format
,
...
)
{
int
ret
;
va_list
valist
;
va_start
(
valist
,
format
);
ret
=
vfprintf
(
output_file
,
format
,
valist
);
va_end
(
valist
);
if
(
ret
<
0
)
fatal_perror
(
"Output error"
);
return
ret
;
}
/* get a name for a temp file, automatically cleaned up on exit */
char
*
get_temp_file_name
(
const
char
*
prefix
,
const
char
*
suffix
)
{
...
...
@@ -193,31 +205,29 @@ char *get_temp_file_name( const char *prefix, const char *suffix )
}
/* output a standard header for generated files */
void
output_standard_file_header
(
FILE
*
outfile
)
void
output_standard_file_header
(
void
)
{
if
(
spec_file_name
)
fprintf
(
outfile
,
"/* File generated automatically from %s; do not edit! */
\n
"
,
spec_file_name
);
output
(
"/* File generated automatically from %s; do not edit! */
\n
"
,
spec_file_name
);
else
fprintf
(
outfile
,
"/* File generated automatically; do not edit! */
\n
"
);
fprintf
(
outfile
,
"/* This file can be copied, modified and distributed without restriction. */
\n\n
"
);
output
(
"/* File generated automatically; do not edit! */
\n
"
);
output
(
"/* This file can be copied, modified and distributed without restriction. */
\n\n
"
);
}
/* dump a byte stream into the assembly code */
void
dump_bytes
(
FILE
*
outfile
,
const
void
*
buffer
,
unsigned
int
size
)
void
dump_bytes
(
const
void
*
buffer
,
unsigned
int
size
)
{
unsigned
int
i
;
const
unsigned
char
*
ptr
=
buffer
;
if
(
!
size
)
return
;
fprintf
(
outfile
,
"
\t
.byte "
);
output
(
"
\t
.byte "
);
for
(
i
=
0
;
i
<
size
-
1
;
i
++
,
ptr
++
)
{
if
((
i
%
16
)
==
15
)
fprintf
(
outfile
,
"0x%02x
\n\t
.byte "
,
*
ptr
);
else
fprintf
(
outfile
,
"0x%02x,"
,
*
ptr
);
if
((
i
%
16
)
==
15
)
output
(
"0x%02x
\n\t
.byte "
,
*
ptr
);
else
output
(
"0x%02x,"
,
*
ptr
);
}
fprintf
(
outfile
,
"0x%02x
\n
"
,
*
ptr
);
output
(
"0x%02x
\n
"
,
*
ptr
);
}
...
...
@@ -520,7 +530,7 @@ const char *func_declaration( const char *func )
}
/* output a size declaration for an assembly function */
void
output_function_size
(
FILE
*
outfile
,
const
char
*
name
)
void
output_function_size
(
const
char
*
name
)
{
switch
(
target_platform
)
{
...
...
@@ -528,13 +538,13 @@ void output_function_size( FILE *outfile, const char *name )
case
PLATFORM_WINDOWS
:
break
;
default:
fprintf
(
outfile
,
"
\t
.size %s, .-%s
\n
"
,
name
,
name
);
output
(
"
\t
.size %s, .-%s
\n
"
,
name
,
name
);
break
;
}
}
/* output the GNU note for non-exec stack */
void
output_gnu_stack_note
(
FILE
*
outfile
)
void
output_gnu_stack_note
(
void
)
{
switch
(
target_platform
)
{
...
...
@@ -542,7 +552,7 @@ void output_gnu_stack_note( FILE *outfile )
case
PLATFORM_APPLE
:
break
;
default:
fprintf
(
outfile
,
"
\t
.section .note.GNU-stack,
\"\"
,@progbits
\n
"
);
output
(
"
\t
.section .note.GNU-stack,
\"\"
,@progbits
\n
"
);
break
;
}
}
...
...
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