Module: wine Branch: master Commit: 9dc348a071fc626f85c3d3d7b40425712bde1e2c URL: https://source.winehq.org/git/wine.git/?a=commit;h=9dc348a071fc626f85c3d3d7b...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Dec 18 21:05:27 2019 +0100
winebuild: Add a --builtin option to mark PE files as builtins.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
tools/winebuild/build.h | 1 + tools/winebuild/main.c | 17 ++++++++++++++--- tools/winebuild/spec32.c | 35 ++++++++++++++++++++++++++++++++--- tools/winebuild/winebuild.man.in | 4 ++++ 4 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index 2b67d305e8..29cd997b96 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -320,6 +320,7 @@ extern void output_spec16_file( DLLSPEC *spec ); 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 add_16bit_exports( DLLSPEC *spec32, DLLSPEC *spec16 ); extern int parse_spec_file( FILE *file, DLLSPEC *spec ); diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index f4abb55081..ca8f8af03a 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -113,6 +113,7 @@ enum exec_mode_values MODE_EXE, MODE_DEF, MODE_IMPLIB, + MODE_BUILTIN, MODE_RESOURCES };
@@ -291,11 +292,12 @@ static const char usage_str[] = " --version Print the version and exit\n" " -w, --warnings Turn on warnings\n" "\nMode options:\n" -" --dll Build a .c file from a .spec or .def file\n" +" --dll Build a library from a .spec file and object files\n" " --def Build a .def file from a .spec file\n" -" --exe Build a .c file for an executable\n" +" --exe Build an executable from object files\n" " --implib Build an import library\n" -" --resources Build a .o file for the resource files\n\n" +" --builtin Mark a library as a Wine builtin\n" +" --resources Build a .o or .res file for the resource files\n\n" "The mode options are mutually exclusive; you must specify one and only one.\n\n";
enum long_options_values @@ -304,6 +306,7 @@ enum long_options_values LONG_OPT_DEF, LONG_OPT_EXE, LONG_OPT_IMPLIB, + LONG_OPT_BUILTIN, LONG_OPT_ASCMD, LONG_OPT_CCCMD, LONG_OPT_EXTERNAL_SYMS, @@ -326,6 +329,7 @@ static const struct option long_options[] = { "def", 0, 0, LONG_OPT_DEF }, { "exe", 0, 0, LONG_OPT_EXE }, { "implib", 0, 0, LONG_OPT_IMPLIB }, + { "builtin", 0, 0, LONG_OPT_BUILTIN }, { "as-cmd", 1, 0, LONG_OPT_ASCMD }, { "cc-cmd", 1, 0, LONG_OPT_CCCMD }, { "external-symbols", 0, 0, LONG_OPT_EXTERNAL_SYMS }, @@ -494,6 +498,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec ) case LONG_OPT_IMPLIB: set_exec_mode( MODE_IMPLIB ); break; + case LONG_OPT_BUILTIN: + set_exec_mode( MODE_BUILTIN ); + break; case LONG_OPT_ASCMD: as_command = strarray_fromstring( optarg, " " ); break; @@ -677,6 +684,10 @@ int main(int argc, char **argv) if (!parse_input_file( spec )) break; output_import_lib( spec, argv ); break; + case MODE_BUILTIN: + if (!argv[0]) fatal_error( "missing file argument for --builtin option\n" ); + make_builtin_files( argv ); + break; case MODE_RESOURCES: load_resources( argv, spec ); output_res_o_file( spec ); diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index f2567e8a92..ecfe4c5011 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -48,6 +48,9 @@
int needs_get_pc_thunk = 0;
+static const char builtin_signature[32] = "Wine builtin DLL"; +static const char fakedll_signature[32] = "Wine placeholder DLL"; + /* check if entry point needs a relay thunk */ static inline int needs_relay( const ORDDEF *odp ) { @@ -790,12 +793,11 @@ void output_fake_module( DLLSPEC *spec ) static const unsigned char exe_code_section[] = { 0xb8, 0x01, 0x00, 0x00, 0x00, /* movl $1,%eax */ 0xc2, 0x04, 0x00 }; /* ret $4 */
- static const char fakedll_signature[] = "Wine placeholder DLL"; const unsigned int page_size = get_page_size(); const unsigned int section_align = page_size; const unsigned int file_align = 0x200; const unsigned int reloc_size = 8; - const unsigned int lfanew = (0x40 + sizeof(fakedll_signature) + 15) & ~15; + const unsigned int lfanew = 0x40 + sizeof(fakedll_signature); const unsigned int nb_sections = 2 + (spec->nb_resources != 0); const unsigned int text_size = (spec->characteristics & IMAGE_FILE_DLL) ? sizeof(dll_code_section) : sizeof(exe_code_section); @@ -837,7 +839,6 @@ void output_fake_module( DLLSPEC *spec ) put_dword( lfanew );
put_data( fakedll_signature, sizeof(fakedll_signature) ); - align_output( 16 );
put_dword( 0x4550 ); /* Signature */ switch(target_cpu) @@ -1062,3 +1063,31 @@ void output_def_file( DLLSPEC *spec, int import_only ) if (!total) warning( "%s: Import library doesn't export anything\n", spec->file_name ); if (spec32) free_dll_spec( spec32 ); } + + +/******************************************************************* + * make_builtin_files + */ +void make_builtin_files( char *argv[] ) +{ + int i, fd; + struct + { + unsigned short e_magic; + unsigned short unused[29]; + unsigned int e_lfanew; + } header; + + for (i = 0; argv[i]; i++) + { + if ((fd = open( argv[i], O_RDWR | O_BINARY )) == -1) fatal_perror( "Cannot open %s", argv[i] ); + if (read( fd, &header, sizeof(header) ) == sizeof(header) && !memcmp( &header.e_magic, "MZ", 2 )) + { + if (header.e_lfanew < sizeof(header) + sizeof(builtin_signature)) + fatal_error( "%s: Not enough space (%x) for Wine signature\n", argv[i], header.e_lfanew ); + write( fd, builtin_signature, sizeof(builtin_signature) ); + } + else fatal_error( "%s: Unrecognized file format\n", argv[i] ); + close( fd ); + } +} diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index 367121544d..4da48ffa81 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -51,6 +51,10 @@ Build a .a import library from a spec file. The .spec file is specified via the \fB-E\fR option. If the output library name ends in .delay.a, a delayed import library is built. .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