<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Have the winebuild -spec.o include an undefined .globl referencing any<o:p></o:p></p>
<p class="MsoNormal">symbol we know the winecrt0 entry point will eventually reference,<o:p></o:p></p>
<p class="MsoNormal">so ld knows about what it needs before scanning library archives.<o:p></o:p></p>
<p class="MsoNormal">---<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">wine.exe.so files set __wine_spec_exe_entry as the entry point,<o:p></o:p></p>
<p class="MsoNormal">rather than main. Therefore the linker is not initially looking for main,<o:p></o:p></p>
<p class="MsoNormal">and will pass over any objects in lib.a archives that might provide it.<o:p></o:p></p>
<p class="MsoNormal">When libwinecrt0.a is reached, it finds __wine_spec_exe_entry and learns<o:p></o:p></p>
<p class="MsoNormal">that this wants main, but this rescan will prefer the winecrt0 definition<o:p></o:p></p>
<p class="MsoNormal">(in terms of WinMain) to rescanning earlier libraries.<o:p></o:p></p>
<p class="MsoNormal">Only a direct .o file (which is never passed over) can override this,<o:p></o:p></p>
<p class="MsoNormal">so libraries like -lgtest_main do not work as intended.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h<o:p></o:p></p>
<p class="MsoNormal">index e1d2e5edf8..66b15167a3 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/tools/winebuild/build.h<o:p></o:p></p>
<p class="MsoNormal">+++ b/tools/winebuild/build.h<o:p></o:p></p>
<p class="MsoNormal">@@ -136,6 +136,7 @@ typedef struct<o:p></o:p></p>
<p class="MsoNormal">     int              subsystem;          /* subsystem id */<o:p></o:p></p>
<p class="MsoNormal">     int              subsystem_major;    /* subsystem version major number */<o:p></o:p></p>
<p class="MsoNormal">     int              subsystem_minor;    /* subsystem version minor number */<o:p></o:p></p>
<p class="MsoNormal">+    int              unicode_app;        /* default to unicode entry point */<o:p></o:p></p>
<p class="MsoNormal">     ORDDEF          *entry_points;       /* dll entry points */<o:p></o:p></p>
<p class="MsoNormal">     ORDDEF         **names;              /* array of entry point names (points into entry_points) */<o:p></o:p></p>
<p class="MsoNormal">     ORDDEF         **ordinals;           /* array of dll ordinals (points into entry_points) */<o:p></o:p></p>
<p class="MsoNormal">@@ -297,6 +298,7 @@ extern void output_gnu_stack_note(void);<o:p></o:p></p>
<p class="MsoNormal">extern void add_import_dll( const char *name, const char *filename );<o:p></o:p></p>
<p class="MsoNormal">extern void add_delayed_import( const char *name );<o:p></o:p></p>
<p class="MsoNormal">extern void add_extra_ld_symbol( const char *name );<o:p></o:p></p>
<p class="MsoNormal">+extern void add_spec_extra_ld_symbol( const char *name );<o:p></o:p></p>
<p class="MsoNormal">extern void read_undef_symbols( DLLSPEC *spec, char **argv );<o:p></o:p></p>
<p class="MsoNormal">extern void resolve_imports( DLLSPEC *spec );<o:p></o:p></p>
<p class="MsoNormal">extern int is_undefined( const char *name );<o:p></o:p></p>
<p class="MsoNormal">diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c<o:p></o:p></p>
<p class="MsoNormal">index 0e5e1627dd..68137b0f4c 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/tools/winebuild/main.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/tools/winebuild/main.c<o:p></o:p></p>
<p class="MsoNormal">@@ -396,8 +396,25 @@ static const char *get_default_entry_point( const DLLSPEC *spec )<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     if (spec->characteristics & IMAGE_FILE_DLL) return "DllMain";<o:p></o:p></p>
<p class="MsoNormal">     if (spec->subsystem == IMAGE_SUBSYSTEM_NATIVE) return "DriverEntry";<o:p></o:p></p>
<p class="MsoNormal">-    if (spec->type == SPEC_WIN16) return "__wine_spec_exe16_entry";<o:p></o:p></p>
<p class="MsoNormal">-    return "__wine_spec_exe_entry";<o:p></o:p></p>
<p class="MsoNormal">+    if (spec->type == SPEC_WIN16) {<o:p></o:p></p>
<p class="MsoNormal">+        add_spec_extra_ld_symbol("WinMain16");<o:p></o:p></p>
<p class="MsoNormal">+        return "__wine_spec_exe16_entry";<o:p></o:p></p>
<p class="MsoNormal">+    }<o:p></o:p></p>
<p class="MsoNormal">+    if (spec->unicode_app) {<o:p></o:p></p>
<p class="MsoNormal">+        /* __wine_spec_exe_wentry always calls wmain */<o:p></o:p></p>
<p class="MsoNormal">+        add_spec_extra_ld_symbol("wmain");<o:p></o:p></p>
<p class="MsoNormal">+        if(spec->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {<o:p></o:p></p>
<p class="MsoNormal">+            add_spec_extra_ld_symbol("wWinMain");<o:p></o:p></p>
<p class="MsoNormal">+        }<o:p></o:p></p>
<p class="MsoNormal">+        return "__wine_spec_exe_wentry";<o:p></o:p></p>
<p class="MsoNormal">+    } else {<o:p></o:p></p>
<p class="MsoNormal">+        /* __wine_spec_exe_entry always calls main */<o:p></o:p></p>
<p class="MsoNormal">+        add_spec_extra_ld_symbol("main");<o:p></o:p></p>
<p class="MsoNormal">+        if(spec->subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) {<o:p></o:p></p>
<p class="MsoNormal">+            add_spec_extra_ld_symbol("WinMain");<o:p></o:p></p>
<p class="MsoNormal">+        }<o:p></o:p></p>
<p class="MsoNormal">+        return "__wine_spec_exe_entry";<o:p></o:p></p>
<p class="MsoNormal">+    }<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> /* parse options from the argv array and remove all the recognized ones */<o:p></o:p></p>
<p class="MsoNormal">@@ -448,6 +465,7 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec )<o:p></o:p></p>
<p class="MsoNormal">             else if (!strcmp( optarg, "thumb" )) thumb_mode = 1;<o:p></o:p></p>
<p class="MsoNormal">             else if (!strcmp( optarg, "no-cygwin" )) use_msvcrt = 1;<o:p></o:p></p>
<p class="MsoNormal">             else if (!strcmp( optarg, "unix" )) unix_lib = 1;<o:p></o:p></p>
<p class="MsoNormal">+            else if (!strcmp( optarg, "unicode" )) spec->unicode_app = 1;<o:p></o:p></p>
<p class="MsoNormal">             else if (!strncmp( optarg, "cpu=", 4 )) cpu_option = xstrdup( optarg + 4 );<o:p></o:p></p>
<p class="MsoNormal">             else if (!strncmp( optarg, "fpu=", 4 )) fpu_option = xstrdup( optarg + 4 );<o:p></o:p></p>
<p class="MsoNormal">             else if (!strncmp( optarg, "arch=", 5 )) arch_option = xstrdup( optarg + 5 );<o:p></o:p></p>
<p class="MsoNormal">diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c<o:p></o:p></p>
<p class="MsoNormal">index c85249b2a9..7fccb0c4f6 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/tools/winebuild/spec32.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/tools/winebuild/spec32.c<o:p></o:p></p>
<p class="MsoNormal">@@ -50,6 +50,13 @@ int needs_get_pc_thunk = 0;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> static const char builtin_signature[32] = "Wine builtin DLL";<o:p></o:p></p>
<p class="MsoNormal">static const char fakedll_signature[32] = "Wine placeholder DLL";<o:p></o:p></p>
<p class="MsoNormal">+static struct strarray spec_extra_ld_symbols = { 0 }; /* list of extra symbols that ld should resolve */<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+/* add a symbol to the list of extra symbols that ld must resolve */<o:p></o:p></p>
<p class="MsoNormal">+void add_spec_extra_ld_symbol( const char *name )<o:p></o:p></p>
<p class="MsoNormal">+{<o:p></o:p></p>
<p class="MsoNormal">+    strarray_add( &spec_extra_ld_symbols, name, NULL );<o:p></o:p></p>
<p class="MsoNormal">+}<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal"> /* check if entry point needs a relay thunk */<o:p></o:p></p>
<p class="MsoNormal">static inline int needs_relay( const ORDDEF *odp )<o:p></o:p></p>
<p class="MsoNormal">@@ -602,6 +609,7 @@ void output_exports( DLLSPEC *spec )<o:p></o:p></p>
<p class="MsoNormal">void output_module( DLLSPEC *spec )<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">     int machine = 0;<o:p></o:p></p>
<p class="MsoNormal">+    int i;<o:p></o:p></p>
<p class="MsoNormal">     unsigned int page_size = get_page_size();<o:p></o:p></p>
<p class="MsoNormal">     const char *data_dirs[16] = { NULL };<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">@@ -680,6 +688,10 @@ void output_module( DLLSPEC *spec )<o:p></o:p></p>
<p class="MsoNormal">     output( "\t.long 0\n" );              /* SizeOfCode */<o:p></o:p></p>
<p class="MsoNormal">     output( "\t.long 0\n" );              /* SizeOfInitializedData */<o:p></o:p></p>
<p class="MsoNormal">     output( "\t.long 0\n" );              /* SizeOfUninitializedData */<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">+    for (i = 0; i < spec_extra_ld_symbols.count; i++)<o:p></o:p></p>
<p class="MsoNormal">+        output( "\t.globl %s\n", asm_name(spec_extra_ld_symbols.str[i]) );<o:p></o:p></p>
<p class="MsoNormal">+<o:p></o:p></p>
<p class="MsoNormal">     /* note: we expand the AddressOfEntryPoint field on 64-bit by overwriting the BaseOfCode field */<o:p></o:p></p>
<p class="MsoNormal">     output( "\t%s %s\n",                  /* AddressOfEntryPoint */<o:p></o:p></p>
<p class="MsoNormal">             get_asm_ptr_keyword(), spec->init_func ? asm_name(spec->init_func) : "0" );<o:p></o:p></p>
<p class="MsoNormal">diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c<o:p></o:p></p>
<p class="MsoNormal">index 29c1b0549d..3c2b029b40 100644<o:p></o:p></p>
<p class="MsoNormal">--- a/tools/winegcc/winegcc.c<o:p></o:p></p>
<p class="MsoNormal">+++ b/tools/winegcc/winegcc.c<o:p></o:p></p>
<p class="MsoNormal">@@ -1228,8 +1228,6 @@ static void build(struct options* opts)<o:p></o:p></p>
<p class="MsoNormal">             entry_point = (is_pe && opts->target_cpu == CPU_x86) ? "DriverEntry@8" : "DriverEntry";<o:p></o:p></p>
<p class="MsoNormal">         else if (opts->use_msvcrt && !opts->shared && !opts->win16_app)<o:p></o:p></p>
<p class="MsoNormal">             entry_point = opts->unicode_app ? "wmainCRTStartup" : "mainCRTStartup";<o:p></o:p></p>
<p class="MsoNormal">-        else if (!is_pe && !opts->shared && opts->unicode_app)<o:p></o:p></p>
<p class="MsoNormal">-            entry_point = "__wine_spec_exe_wentry";<o:p></o:p></p>
<p class="MsoNormal">     }<o:p></o:p></p>
<p class="MsoNormal">     else entry_point = opts->entry_point;<o:p></o:p></p>
<p class="MsoNormal"><o:p></o:p></p>
<p class="MsoNormal">@@ -1241,6 +1239,8 @@ static void build(struct options* opts)<o:p></o:p></p>
<p class="MsoNormal">     spec_o_name = get_temp_file(output_name, ".spec.o");<o:p></o:p></p>
<p class="MsoNormal">     if (opts->force_pointer_size)<o:p></o:p></p>
<p class="MsoNormal">         strarray_add(spec_args, strmake("-m%u", 8 * opts->force_pointer_size ));<o:p></o:p></p>
<p class="MsoNormal">+    if(opts->unicode_app)<o:p></o:p></p>
<p class="MsoNormal">+        strarray_add(spec_args, "-municode");<o:p></o:p></p>
<p class="MsoNormal">     strarray_add(spec_args, "-D_REENTRANT");<o:p></o:p></p>
<p class="MsoNormal">     if (opts->pic && !is_pe) strarray_add(spec_args, "-fPIC");<o:p></o:p></p>
<p class="MsoNormal">     strarray_add(spec_args, opts->shared ? "--dll" : "--exe");<o:p></o:p></p>
</div>
</body>
</html>