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
6c4046fe
Commit
6c4046fe
authored
Apr 16, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winebuild: Add --fixup-ctors option to allow intercepting constructors in .so files.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3935acd4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
182 additions
and
5 deletions
+182
-5
build.h
tools/winebuild/build.h
+1
-0
main.c
tools/winebuild/main.c
+12
-1
spec32.c
tools/winebuild/spec32.c
+159
-0
winebuild.man.in
tools/winebuild/winebuild.man.in
+10
-4
No files found.
tools/winebuild/build.h
View file @
6c4046fe
...
...
@@ -321,6 +321,7 @@ extern void output_fake_module16( DLLSPEC *spec16 );
extern
void
output_res_o_file
(
DLLSPEC
*
spec
);
extern
void
output_asm_relays16
(
void
);
extern
void
make_builtin_files
(
char
*
argv
[]
);
extern
void
fixup_constructors
(
char
*
argv
[]
);
extern
void
add_16bit_exports
(
DLLSPEC
*
spec32
,
DLLSPEC
*
spec16
);
extern
int
parse_spec_file
(
FILE
*
file
,
DLLSPEC
*
spec
);
...
...
tools/winebuild/main.c
View file @
6c4046fe
...
...
@@ -115,6 +115,7 @@ enum exec_mode_values
MODE_IMPLIB
,
MODE_STATICLIB
,
MODE_BUILTIN
,
MODE_FIXUP_CTORS
,
MODE_RESOURCES
};
...
...
@@ -301,8 +302,9 @@ static const char usage_str[] =
" --exe Build an executable from object files
\n
"
" --implib Build an import library
\n
"
" --staticlib Build a static library
\n
"
" --builtin Mark a library as a Wine builtin
\n
"
" --resources Build a .o or .res file for the resource files
\n\n
"
" --builtin Mark a library as a Wine builtin
\n
"
" --fixup-ctors Fixup the constructors data after the module has been built
\n
"
"The mode options are mutually exclusive; you must specify one and only one.
\n\n
"
;
enum
long_options_values
...
...
@@ -316,6 +318,7 @@ enum long_options_values
LONG_OPT_CCCMD
,
LONG_OPT_EXTERNAL_SYMS
,
LONG_OPT_FAKE_MODULE
,
LONG_OPT_FIXUP_CTORS
,
LONG_OPT_LARGE_ADDRESS_AWARE
,
LONG_OPT_LDCMD
,
LONG_OPT_NMCMD
,
...
...
@@ -341,6 +344,7 @@ static const struct option long_options[] =
{
"cc-cmd"
,
1
,
0
,
LONG_OPT_CCCMD
},
{
"external-symbols"
,
0
,
0
,
LONG_OPT_EXTERNAL_SYMS
},
{
"fake-module"
,
0
,
0
,
LONG_OPT_FAKE_MODULE
},
{
"fixup-ctors"
,
0
,
0
,
LONG_OPT_FIXUP_CTORS
},
{
"large-address-aware"
,
0
,
0
,
LONG_OPT_LARGE_ADDRESS_AWARE
},
{
"ld-cmd"
,
1
,
0
,
LONG_OPT_LDCMD
},
{
"nm-cmd"
,
1
,
0
,
LONG_OPT_NMCMD
},
...
...
@@ -511,6 +515,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )
case
LONG_OPT_BUILTIN
:
set_exec_mode
(
MODE_BUILTIN
);
break
;
case
LONG_OPT_FIXUP_CTORS
:
set_exec_mode
(
MODE_FIXUP_CTORS
);
break
;
case
LONG_OPT_ASCMD
:
as_command
=
strarray_fromstring
(
optarg
,
" "
);
break
;
...
...
@@ -701,6 +708,10 @@ int main(int argc, char **argv)
if
(
!
argv
[
0
])
fatal_error
(
"missing file argument for --builtin option
\n
"
);
make_builtin_files
(
argv
);
break
;
case
MODE_FIXUP_CTORS
:
if
(
!
argv
[
0
])
fatal_error
(
"missing file argument for --fixup-ctors option
\n
"
);
fixup_constructors
(
argv
);
break
;
case
MODE_RESOURCES
:
load_resources
(
argv
,
spec
);
output_res_o_file
(
spec
);
...
...
tools/winebuild/spec32.c
View file @
6c4046fe
...
...
@@ -1095,3 +1095,162 @@ void make_builtin_files( char *argv[] )
close
(
fd
);
}
}
static
void
fixup_elf32
(
const
char
*
name
,
int
fd
,
void
*
header
,
size_t
header_size
)
{
struct
{
unsigned
char
e_ident
[
16
];
unsigned
short
e_type
;
unsigned
short
e_machine
;
unsigned
int
e_version
;
unsigned
int
e_entry
;
unsigned
int
e_phoff
;
unsigned
int
e_shoff
;
unsigned
int
e_flags
;
unsigned
short
e_ehsize
;
unsigned
short
e_phentsize
;
unsigned
short
e_phnum
;
unsigned
short
e_shentsize
;
unsigned
short
e_shnum
;
unsigned
short
e_shstrndx
;
}
*
elf
=
header
;
struct
{
unsigned
int
p_type
;
unsigned
int
p_offset
;
unsigned
int
p_vaddr
;
unsigned
int
p_paddr
;
unsigned
int
p_filesz
;
unsigned
int
p_memsz
;
unsigned
int
p_flags
;
unsigned
int
p_align
;
}
*
phdr
;
struct
{
unsigned
int
d_tag
;
unsigned
int
d_val
;
}
*
dyn
;
unsigned
int
i
,
size
;
if
(
header_size
<
sizeof
(
*
elf
))
return
;
if
(
elf
->
e_ident
[
6
]
!=
1
/* EV_CURRENT */
)
return
;
size
=
elf
->
e_phnum
*
elf
->
e_phentsize
;
phdr
=
xmalloc
(
size
);
lseek
(
fd
,
elf
->
e_phoff
,
SEEK_SET
);
if
(
read
(
fd
,
phdr
,
size
)
!=
size
)
return
;
for
(
i
=
0
;
i
<
elf
->
e_phnum
;
i
++
)
{
if
(
phdr
->
p_type
==
2
/* PT_DYNAMIC */
)
break
;
phdr
=
(
void
*
)((
char
*
)
phdr
+
elf
->
e_phentsize
);
}
if
(
i
==
elf
->
e_phnum
)
return
;
dyn
=
xmalloc
(
phdr
->
p_filesz
);
lseek
(
fd
,
phdr
->
p_offset
,
SEEK_SET
);
if
(
read
(
fd
,
dyn
,
phdr
->
p_filesz
)
!=
phdr
->
p_filesz
)
return
;
for
(
i
=
0
;
i
<
phdr
->
p_filesz
/
sizeof
(
*
dyn
)
&&
dyn
[
i
].
d_tag
;
i
++
)
{
switch
(
dyn
[
i
].
d_tag
)
{
case
25
:
dyn
[
i
].
d_tag
=
0x60009990
;
break
;
/* DT_INIT_ARRAY */
case
27
:
dyn
[
i
].
d_tag
=
0x60009991
;
break
;
/* DT_INIT_ARRAYSZ */
case
12
:
dyn
[
i
].
d_tag
=
0x60009992
;
break
;
/* DT_INIT */
}
}
lseek
(
fd
,
phdr
->
p_offset
,
SEEK_SET
);
write
(
fd
,
dyn
,
phdr
->
p_filesz
);
}
static
void
fixup_elf64
(
const
char
*
name
,
int
fd
,
void
*
header
,
size_t
header_size
)
{
struct
{
unsigned
char
e_ident
[
16
];
unsigned
short
e_type
;
unsigned
short
e_machine
;
unsigned
int
e_version
;
unsigned
__int64
e_entry
;
unsigned
__int64
e_phoff
;
unsigned
__int64
e_shoff
;
unsigned
int
e_flags
;
unsigned
short
e_ehsize
;
unsigned
short
e_phentsize
;
unsigned
short
e_phnum
;
unsigned
short
e_shentsize
;
unsigned
short
e_shnum
;
unsigned
short
e_shstrndx
;
}
*
elf
=
header
;
struct
{
unsigned
int
p_type
;
unsigned
int
p_flags
;
unsigned
__int64
p_offset
;
unsigned
__int64
p_vaddr
;
unsigned
__int64
p_paddr
;
unsigned
__int64
p_filesz
;
unsigned
__int64
p_memsz
;
unsigned
__int64
p_align
;
}
*
phdr
;
struct
{
unsigned
__int64
d_tag
;
unsigned
__int64
d_val
;
}
*
dyn
;
unsigned
int
i
,
size
;
if
(
header_size
<
sizeof
(
*
elf
))
return
;
if
(
elf
->
e_ident
[
6
]
!=
1
/* EV_CURRENT */
)
return
;
size
=
elf
->
e_phnum
*
elf
->
e_phentsize
;
phdr
=
xmalloc
(
size
);
lseek
(
fd
,
elf
->
e_phoff
,
SEEK_SET
);
if
(
read
(
fd
,
phdr
,
size
)
!=
size
)
return
;
for
(
i
=
0
;
i
<
elf
->
e_phnum
;
i
++
)
{
if
(
phdr
->
p_type
==
2
/* PT_DYNAMIC */
)
break
;
phdr
=
(
void
*
)((
char
*
)
phdr
+
elf
->
e_phentsize
);
}
if
(
i
==
elf
->
e_phnum
)
return
;
dyn
=
xmalloc
(
phdr
->
p_filesz
);
lseek
(
fd
,
phdr
->
p_offset
,
SEEK_SET
);
if
(
read
(
fd
,
dyn
,
phdr
->
p_filesz
)
!=
phdr
->
p_filesz
)
return
;
for
(
i
=
0
;
i
<
phdr
->
p_filesz
/
sizeof
(
*
dyn
)
&&
dyn
[
i
].
d_tag
;
i
++
)
{
switch
(
dyn
[
i
].
d_tag
)
{
case
25
:
dyn
[
i
].
d_tag
=
0x60009990
;
break
;
/* DT_INIT_ARRAY */
case
27
:
dyn
[
i
].
d_tag
=
0x60009991
;
break
;
/* DT_INIT_ARRAYSZ */
case
12
:
dyn
[
i
].
d_tag
=
0x60009992
;
break
;
/* DT_INIT */
}
}
lseek
(
fd
,
phdr
->
p_offset
,
SEEK_SET
);
write
(
fd
,
dyn
,
phdr
->
p_filesz
);
}
/*******************************************************************
* fixup_constructors
*/
void
fixup_constructors
(
char
*
argv
[]
)
{
int
i
,
fd
,
size
;
unsigned
int
header
[
64
];
for
(
i
=
0
;
argv
[
i
];
i
++
)
{
if
((
fd
=
open
(
argv
[
i
],
O_RDWR
|
O_BINARY
))
==
-
1
)
fatal_perror
(
"Cannot open %s"
,
argv
[
i
]
);
size
=
read
(
fd
,
&
header
,
sizeof
(
header
)
);
if
(
size
>
5
)
{
if
(
!
memcmp
(
header
,
"
\177
ELF
\001
"
,
5
))
fixup_elf32
(
argv
[
i
],
fd
,
header
,
size
);
else
if
(
!
memcmp
(
header
,
"
\177
ELF
\002
"
,
5
))
fixup_elf64
(
argv
[
i
],
fd
,
header
,
size
);
}
close
(
fd
);
}
}
tools/winebuild/winebuild.man.in
View file @
6c4046fe
...
...
@@ -54,16 +54,22 @@ in .delay.a, a delayed import library is built.
.BI \--staticlib
Build a .a static library from object files.
.TP
.BI \--builtin
Mark a PE module as a Wine builtin module, by adding the "Wine builtin
DLL" signature string after the DOS header.
.TP
.B \--resources
Generate a .o file containing all the input resources. This is useful
when building with a PE compiler, since the PE binutils cannot handle
multiple resource files as input. For a standard Unix build, the
resource files are automatically included when building the spec file,
so there's no need for an intermediate .o file.
.TP
.BI \--builtin
Mark a PE module as a Wine builtin module, by adding the "Wine builtin
DLL" signature string after the DOS header.
.TP
.BI \--fixup-ctors
Fixup constructors after a module has been built. This should be done
on the final .so module if its code contains constructors, to ensure
that Wine has a chance to initialize the module before the
constructors are executed.
.SH OPTIONS
.TP
.BI \--as-cmd= as-command
...
...
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