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
6b977352
Commit
6b977352
authored
Nov 06, 2022
by
Rémi Bernon
Committed by
Alexandre Julliard
Nov 08, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winebuild: Implement delay import lib generation without dlltool.
parent
244e8fd3
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
145 additions
and
9 deletions
+145
-9
import.c
tools/winebuild/import.c
+145
-9
No files found.
tools/winebuild/import.c
View file @
6b977352
...
...
@@ -1630,27 +1630,133 @@ static void build_dlltool_import_lib( const char *lib_name, DLLSPEC *spec, struc
/* create a Windows-style import library */
static
void
build_windows_import_lib
(
const
char
*
lib_name
,
DLLSPEC
*
spec
,
struct
strarray
files
)
{
char
*
dll_name
,
*
import_desc
,
*
import_name
;
char
*
dll_name
,
*
import_desc
,
*
import_name
,
*
delay_load
;
struct
strarray
objs
=
empty_strarray
;
int
i
,
total
,
by_name
;
int
is_delay
=
strendswith
(
lib_name
,
".delay.a"
);
const
char
*
name
;
if
(
strendswith
(
lib_name
,
".delay.a"
))
{
if
(
verbose
)
fprintf
(
stderr
,
"Not implemented, falling back to dlltool.
\n
"
);
build_dlltool_import_lib
(
output_file_name
,
spec
,
files
);
return
;
}
/* make sure assemble_files doesn't strip suffixes */
dll_name
=
encode_dll_name
(
spec
->
file_name
);
for
(
i
=
0
;
i
<
strlen
(
dll_name
);
++
i
)
if
(
dll_name
[
i
]
==
'.'
)
dll_name
[
i
]
=
'_'
;
import_desc
=
strmake
(
"__wine_import_%s_desc"
,
dll_name
);
import_name
=
strmake
(
"__wine_import_%s_name"
,
dll_name
);
delay_load
=
strmake
(
"__wine_delay_load_%s"
,
dll_name
);
new_output_as_file
();
if
(
is_delay
)
{
output
(
"
\n\t
.text
\n
"
);
output
(
"
\t
.align %d
\n
"
,
get_alignment
(
get_ptr_size
()
));
output
(
"%s
\n
"
,
asm_globl
(
delay_load
)
);
output
(
"
\t
%s
\n
"
,
func_declaration
(
delay_load
)
);
output_cfi
(
".cfi_startproc"
);
switch
(
target
.
cpu
)
{
case
CPU_i386
:
output
(
"
\t
pushl %%ecx
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset 4"
);
output
(
"
\t
pushl %%edx
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset 4"
);
output
(
"
\t
pushl %%eax
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset 4"
);
output
(
"
\t
pushl $%s
\n
"
,
asm_name
(
import_desc
)
);
output
(
"
\t
calll ___delayLoadHelper2@8
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset -8"
);
output
(
"
\t
popl %%edx
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset -4"
);
output
(
"
\t
popl %%ecx
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset -4"
);
output
(
"
\t
jmp *%%eax
\n
"
);
break
;
case
CPU_x86_64
:
output_cfi
(
".seh_proc %s"
,
asm_name
(
delay_load
)
);
output
(
"
\t
subq $0x48, %%rsp
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset 0x48"
);
output_cfi
(
".seh_stackalloc 0x48"
);
output_cfi
(
".seh_endprologue"
);
output
(
"
\t
movq %%rcx, 0x40(%%rsp)
\n
"
);
output
(
"
\t
movq %%rdx, 0x38(%%rsp)
\n
"
);
output
(
"
\t
movq %%r8, 0x30(%%rsp)
\n
"
);
output
(
"
\t
movq %%r9, 0x28(%%rsp)
\n
"
);
output
(
"
\t
movq %%rax, %%rdx
\n
"
);
output
(
"
\t
leaq %s(%%rip), %%rcx
\n
"
,
asm_name
(
import_desc
)
);
output
(
"
\t
call __delayLoadHelper2
\n
"
);
output
(
"
\t
movq 0x28(%%rsp), %%r9
\n
"
);
output
(
"
\t
movq 0x30(%%rsp), %%r8
\n
"
);
output
(
"
\t
movq 0x38(%%rsp), %%rdx
\n
"
);
output
(
"
\t
movq 0x40(%%rsp), %%rcx
\n
"
);
output
(
"
\t
addq $0x48, %%rsp
\n
"
);
output_cfi
(
".cfi_adjust_cfa_offset -0x48"
);
output
(
"
\t
jmp *%%rax
\n
"
);
output_cfi
(
".seh_endproc"
);
break
;
case
CPU_ARM
:
output
(
"
\t
push {r0-r3, FP, LR}
\n
"
);
output
(
"
\t
mov r1, IP
\n
"
);
output
(
"
\t
ldr r0, 1f
\n
"
);
output
(
"
\t
ldr r0, [r0]
\n
"
);
output
(
"
\t
bl __delayLoadHelper2
\n
"
);
output
(
"
\t
mov IP, r0
\n
"
);
output
(
"
\t
pop {r0-r3, FP, LR}
\n
"
);
output
(
"
\t
bx IP
\n
"
);
output
(
"1:
\t
.long %s
\n
"
,
asm_name
(
import_desc
)
);
break
;
case
CPU_ARM64
:
output
(
"
\t
stp x29, x30, [sp, #-80]!
\n
"
);
output
(
"
\t
mov x29, sp
\n
"
);
output
(
"
\t
stp x0, x1, [sp, #16]
\n
"
);
output
(
"
\t
stp x2, x3, [sp, #32]
\n
"
);
output
(
"
\t
stp x4, x5, [sp, #48]
\n
"
);
output
(
"
\t
stp x6, x7, [sp, #64]
\n
"
);
output
(
"
\t
mov x1, x16
\n
"
);
output
(
"
\t
adrp x0, %s
\n
"
,
asm_name
(
import_desc
)
);
output
(
"
\t
add x0, x0, #%s
\n
"
,
asm_name
(
import_desc
)
);
output
(
"
\t
bl __delayLoadHelper2
\n
"
);
output
(
"
\t
mov x16, x0
\n
"
);
output
(
"
\t
ldp x0, x1, [sp, #16]
\n
"
);
output
(
"
\t
ldp x2, x3, [sp, #32]
\n
"
);
output
(
"
\t
ldp x4, x5, [sp, #48]
\n
"
);
output
(
"
\t
ldp x6, x7, [sp, #64]
\n
"
);
output
(
"
\t
ldp x29, x30, [sp], #80
\n
"
);
output
(
"
\t
br x16
\n
"
);
break
;
}
output_cfi
(
".cfi_endproc"
);
output_function_size
(
delay_load
);
output_gnu_stack_note
();
output
(
"
\n\t
.data
\n
"
);
output
(
".L__wine_delay_import_handle:
\n
"
);
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
output
(
"
\n\t
.section
\"
.text$2
\"\n
"
);
output
(
"%s
\n
"
,
asm_globl
(
import_desc
)
);
output
(
"
\t
.long 1
\n
"
);
/* DllAttributes */
output_rva
(
"%s"
,
asm_name
(
import_name
)
);
/* DllNameRVA */
output_rva
(
".L__wine_delay_import_handle"
);
/* ModuleHandleRVA */
output_rva
(
".L__wine_import_addrs"
);
/* ImportAddressTableRVA */
output_rva
(
".L__wine_import_names"
);
/* ImportNameTableRVA */
output
(
"
\t
.long 0
\n
"
);
/* BoundImportAddressTableRVA */
output
(
"
\t
.long 0
\n
"
);
/* UnloadInformationTableRVA */
output
(
"
\t
.long 0
\n
"
);
/* TimeDateStamp */
output
(
"
\n\t
.section
\"
.idata$5
\"\n
"
);
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* FirstThunk tail */
output
(
".L__wine_import_addrs:
\n
"
);
output
(
"
\n\t
.section
\"
.idata$4
\"\n
"
);
output
(
"
\t
%s 0
\n
"
,
get_asm_ptr_keyword
()
);
/* OriginalFirstThunk tail */
output
(
".L__wine_import_names:
\n
"
);
/* required to avoid internal linker errors with some binutils versions */
output
(
"
\n\t
.section
\"
.idata$2
\"\n
"
);
}
else
{
output
(
"
\n\t
.section
\"
.idata$2
\"\n
"
);
output
(
"%s
\n
"
,
asm_globl
(
import_desc
)
);
output_rva
(
".L__wine_import_names"
);
/* OriginalFirstThunk */
...
...
@@ -1664,6 +1770,7 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
output
(
"
\n\t
.section
\"
.idata$5
\"\n
"
);
output
(
".L__wine_import_addrs:
\n
"
);
/* FirstThunk head */
}
/* _head suffix to keep this object sections first */
assemble_files
(
strmake
(
"%s_head"
,
dll_name
)
);
...
...
@@ -1722,19 +1829,45 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
{
case
CPU_i386
:
output
(
"
\t
jmp *%s
\n
"
,
asm_name
(
imp_name
)
);
if
(
is_delay
)
{
output
(
".L__wine_delay_import:
\n
"
);
output
(
"
\t
mov $%s,%%eax
\n
"
,
asm_name
(
imp_name
)
);
output
(
"
\t
jmp %s
\n
"
,
asm_name
(
delay_load
)
);
}
break
;
case
CPU_x86_64
:
output
(
"
\t
jmp *%s(%%rip)
\n
"
,
asm_name
(
imp_name
)
);
if
(
is_delay
)
{
output
(
".L__wine_delay_import:
\n
"
);
output
(
"
\t
lea %s(%%rip),%%rax
\n
"
,
asm_name
(
imp_name
)
);
output
(
"
\t
jmp %s
\n
"
,
asm_name
(
delay_load
)
);
}
break
;
case
CPU_ARM
:
output
(
"
\t
ldr IP, 1f
\n
"
);
output
(
"
\t
ldr PC, [IP]
\n
"
);
if
(
is_delay
)
{
output
(
".L__wine_delay_import:
\n
"
);
output
(
"
\t
ldr IP, 1f
\n
"
);
output
(
"
\t
ldr IP, [IP]
\n
"
);
output
(
"
\t
b %s
\n
"
,
asm_name
(
delay_load
)
);
}
output
(
"1:
\t
.long %s
\n
"
,
asm_name
(
imp_name
)
);
break
;
case
CPU_ARM64
:
output
(
"
\t
adrp x16, %s
\n
"
,
arm64_page
(
asm_name
(
imp_name
)
)
);
output
(
"
\t
add x16, x16, #%s
\n
"
,
arm64_pageoff
(
asm_name
(
imp_name
)
)
);
output
(
"
\t
br x16
\n
"
);
if
(
is_delay
)
{
output
(
".L__wine_delay_import:
\n
"
);
output
(
"
\t
adrp x16, %s
\n
"
,
arm64_page
(
asm_name
(
imp_name
)
)
);
output
(
"
\t
add x16, x16, #%s
\n
"
,
arm64_pageoff
(
asm_name
(
imp_name
)
)
);
output
(
"
\t
b %s
\n
"
,
asm_name
(
delay_load
)
);
}
break
;
}
...
...
@@ -1752,7 +1885,9 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
output
(
"
\n\t
.section
\"
.idata$5
\"\n
"
);
output
(
"%s
\n
"
,
asm_globl
(
imp_name
)
);
if
(
by_name
)
if
(
is_delay
)
output
(
"
\t
%s .L__wine_delay_import
\n
"
,
get_asm_ptr_keyword
()
);
else
if
(
by_name
)
{
output_rva
(
".L__wine_import_name"
);
if
(
get_ptr_size
()
==
8
)
output
(
"
\t
.long 0
\n
"
);
...
...
@@ -1790,6 +1925,7 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec, struc
free
(
import_desc
);
free
(
import_name
);
free
(
delay_load
);
free
(
dll_name
);
output_static_lib
(
output_file_name
,
files
,
1
);
...
...
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