From: Jacek Caban Subject: [PATCH 4/4] winegcc: Support delayload on LLVM toolchain. Message-Id: <9ac0efbb-f8b2-470e-359d-9e7dce075df2@codeweavers.com> Date: Mon, 7 Oct 2019 18:54:41 +0200 We use -Wl,-Xlink=-delayload instead of -Wl,-delayload because the later causes only warning on binutils ld, so we can't easily use it to detect if the feature is present. Signed-off-by: Jacek Caban --- This is the main remaining problem with llvm-mingw builds. On top of that, unpatched Wine can be build with llvm-mingw paired with git llvm version. CROSSCFLAGS="-fno-builtin-exp2" configure argument is still required to work around wine crt limitations. I use CROSSCFLAGS="-g -fno-builtin-exp2 -Wno-incompatible-library-redeclaration" for better experience. tools/winegcc/winegcc.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index f0a87492db..9ea44d9117 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -346,7 +346,7 @@ static strarray* get_translator(struct options *opts) return strarray_fromstring( str, " " ); } -static int try_link( const strarray *prefix, const strarray *link_tool, const char *cflags ) +static int try_link( const strarray *prefix, const strarray *link_tool, const char *cflags, const char *code ) { const char *in = get_temp_file( "try_link", ".c" ); const char *out = get_temp_file( "try_link", ".out" ); @@ -355,7 +355,7 @@ static int try_link( const strarray *prefix, const strarray *link_tool, const ch int sout = -1, serr = -1; int ret; - create_file( in, 0644, "int main(void){return 1;}\n" ); + create_file( in, 0644, code ? code : "int main(void){return 1;}\n" ); strarray_add( link, "-o" ); strarray_add( link, out ); @@ -466,12 +466,12 @@ static strarray *get_link_args( struct options *opts, const char *output_name ) default: if (opts->image_base) { - if (!try_link( opts->prefix, link_args, strmake("-Wl,-Ttext-segment=%s", opts->image_base)) ) + if (!try_link( opts->prefix, link_args, strmake("-Wl,-Ttext-segment=%s", opts->image_base), NULL) ) strarray_add( flags, strmake("-Wl,-Ttext-segment=%s", opts->image_base) ); else opts->prelink = PRELINK; } - if (!try_link( opts->prefix, link_args, "-Wl,-z,max-page-size=0x1000")) + if (!try_link( opts->prefix, link_args, "-Wl,-z,max-page-size=0x1000", NULL)) strarray_add( flags, "-Wl,-z,max-page-size=0x1000"); break; } @@ -484,16 +484,16 @@ static strarray *get_link_args( struct options *opts, const char *output_name ) strarray_add( flags, "-Wl,--no-wchar-size-warning" ); /* Try all options first - this is likely to succeed on modern compilers */ - if (!try_link( opts->prefix, link_args, "-Wl,-z,defs -Wl,-init,__wine_spec_init,-fini,_wine_spec_fini" )) + if (!try_link( opts->prefix, link_args, "-Wl,-z,defs -Wl,-init,__wine_spec_init,-fini,_wine_spec_fini", NULL )) { strarray_add( flags, "-Wl,-z,defs" ); strarray_add( flags, "-Wl,-init,__wine_spec_init,-fini,__wine_spec_fini" ); } else /* otherwise figure out which ones are allowed */ { - if (!try_link( opts->prefix, link_args, "-Wl,-z,defs" )) + if (!try_link( opts->prefix, link_args, "-Wl,-z,defs", NULL )) strarray_add( flags, "-Wl,-z,defs" ); - if (!try_link( opts->prefix, link_args, "-Wl,-init,__wine_spec_init,-fini,_wine_spec_fini" )) + if (!try_link( opts->prefix, link_args, "-Wl,-init,__wine_spec_init,-fini,_wine_spec_fini", NULL )) strarray_add( flags, "-Wl,-init,__wine_spec_init,-fini,__wine_spec_fini" ); } @@ -990,6 +990,7 @@ static void build(struct options* opts) const char *output_name, *spec_file, *lang; int generate_app_loader = 1; const char* crt_lib = NULL; + int use_delay_importlibs = 0; int fake_module = 0; int is_pe = (opts->target_platform == PLATFORM_WINDOWS || opts->target_platform == PLATFORM_CYGWIN); unsigned int j; @@ -1048,6 +1049,16 @@ static void build(struct options* opts) strarray_addall(lib_dirs, opts->lib_dirs); } + if (opts->delayloads->size && is_pe) + { + link_args = get_translator( opts ); + use_delay_importlibs = try_link(opts->prefix, link_args, + "-shared -nostartfiles -nodefaultlibs -Wl,-Xlink=-delayload:test.dll", + "void __stdcall DllMainCRTStartup(int i, int j, int k) {}\n" + "void __stdcall __delayLoadHelper2(int i, int j) {}\n"); + strarray_free(link_args); + } + /* mark the files with their appropriate type */ spec_file = lang = 0; files = strarray_alloc(); @@ -1099,7 +1110,7 @@ static void build(struct options* opts) else if (file[1] == 'l') { const char *delay_lib = NULL; - if (is_pe) + if (use_delay_importlibs) { unsigned int i; for (i = 0; i < opts->delayloads->size; i++) @@ -1252,6 +1263,12 @@ static void build(struct options* opts) strarray_add(link_args, spec_o_name); + if (is_pe && !use_delay_importlibs) + { + for (j = 0; j < opts->delayloads->size; j++) + strarray_add(spec_args, strmake("-Wl,-Xlink=-delayload:%s", opts->delayloads->base[j])); + } + for ( j = 0; j < files->size; j++ ) { const char* name = files->base[j] + 2;