Alexandre Julliard : winebuild: Add a --builtin option to mark PE files as builtins.

Alexandre Julliard julliard at winehq.org
Wed Dec 18 15:51:09 CST 2019


Module: wine
Branch: master
Commit: 9dc348a071fc626f85c3d3d7b40425712bde1e2c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9dc348a071fc626f85c3d3d7b40425712bde1e2c

Author: Alexandre Julliard <julliard at 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 at 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




More information about the wine-cvs mailing list