This adds support for `CROSSDEBUG="dwarf pdb"` (or the equivalent `CROSSCFLAGS`) to enable embedding DWARF debug info alongside PDB files, as well as `CROSSDEBUG="split-dwarf pdb"` to generate both split DWARF and PDB files from a single Clang-based build. This makes it easier to produce a Wine build that can be debugged using both Windows and Unix tools.
From: Jacek Caban jacek@codeweavers.com
This enables generating both PDB and split DWARF from a single build. --- tools/winegcc/winegcc.c | 46 +++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/tools/winegcc/winegcc.c b/tools/winegcc/winegcc.c index a657d8d6229..402eb41e3f2 100644 --- a/tools/winegcc/winegcc.c +++ b/tools/winegcc/winegcc.c @@ -140,7 +140,7 @@ static const char* app_loader_template = ;
static const char *output_file_name; -static const char *output_debug_file; +static struct strarray output_debug_files; static const char *output_implib; static const char *output; static int keep_generated = 0; @@ -207,9 +207,11 @@ static struct strarray delayimports;
static void cleanup_output_files(void) { + unsigned int i; if (output_file_name) unlink( output_file_name ); - if (output_debug_file) unlink( output_debug_file ); if (output_implib) unlink( output_implib ); + for (i = 0; i < output_debug_files.count; i++) + unlink( output_debug_files.str[i] ); }
static void clean_temp_files(void) @@ -499,6 +501,7 @@ static struct strarray get_link_args( const char *output_name ) { struct strarray link_args = get_translator(); struct strarray flags = empty_strarray; + unsigned int i;
strarray_addall( &link_args, linker_args );
@@ -562,8 +565,11 @@ static struct strarray get_link_args( const char *output_name ) if (entry_point) strarray_add( &flags, strmake( "-Wl,--entry,%s%s", target.cpu == CPU_i386 ? "_" : "", entry_point ));
- if (output_debug_file && strendswith(output_debug_file, ".pdb")) - strarray_add(&link_args, strmake("-Wl,--pdb=%s", output_debug_file)); + for (i = 0; i < output_debug_files.count; i++) + { + if (!strendswith(output_debug_files.str[i], ".pdb")) continue; + strarray_add(&link_args, strmake("-Wl,--pdb=%s", output_debug_files.str[i])); + }
if (use_build_id) strarray_add( &link_args, "-Wl,--build-id"); @@ -604,15 +610,20 @@ static struct strarray get_link_args( const char *output_name ) else strarray_add( &flags, strmake("-Wl,-subsystem:%s", is_gui_app ? "windows" : "console" ));
- if (output_debug_file && strendswith(output_debug_file, ".pdb")) + for (i = 0; i < output_debug_files.count; i++) { - strarray_add(&link_args, "-Wl,-debug"); - strarray_add(&link_args, strmake("-Wl,-pdb:%s", output_debug_file)); + if (strendswith(output_debug_files.str[i], ".pdb")) + { + strarray_add(&link_args, "-Wl,-debug"); + strarray_add(&link_args, strmake("-Wl,-pdb:%s", output_debug_files.str[i])); + } + else strarray_add( &link_args, "-Wl,-debug:dwarf" ); } - else if (strip) + + if (strip) strarray_add( &link_args, "-s" ); - else - strarray_add(&link_args, "-Wl,-debug:dwarf"); + else if (!output_debug_files.count) + strarray_add( &link_args, "-Wl,-debug:dwarf" );
if (use_build_id) strarray_add( &link_args, "-Wl,-build-id"); @@ -1459,15 +1470,18 @@ static void build(struct strarray input_files, const char *output)
spawn(link_args, 0);
- if (output_debug_file && !strendswith(output_debug_file, ".pdb")) + for (i = 0; i < output_debug_files.count; i++) { - struct strarray tool, objcopy = build_tool_name(target_alias, tool_objcopy); + struct strarray tool, objcopy; + + if (strendswith(output_debug_files.str[i], ".pdb")) continue; + objcopy = build_tool_name(target_alias, tool_objcopy);
tool = empty_strarray; strarray_addall( &tool, objcopy ); strarray_add(&tool, "--only-keep-debug"); strarray_add(&tool, output_file_name); - strarray_add(&tool, output_debug_file); + strarray_add(&tool, output_debug_files.str[i]); spawn(tool, 1);
tool = empty_strarray; @@ -1479,7 +1493,7 @@ static void build(struct strarray input_files, const char *output) tool = empty_strarray; strarray_addall( &tool, objcopy ); strarray_add(&tool, "--add-gnu-debuglink"); - strarray_add(&tool, output_debug_file); + strarray_add(&tool, output_debug_files.str[i]); strarray_add(&tool, output_file_name); spawn(tool, 0); } @@ -1930,7 +1944,7 @@ int main(int argc, char **argv) } if (!strcmp(Wl.str[j], "--debug-file") && j < Wl.count - 1) { - output_debug_file = xstrdup( Wl.str[++j] ); + strarray_add( &output_debug_files, xstrdup( Wl.str[++j] )); continue; } if (!strcmp(Wl.str[j], "--whole-archive") || @@ -2068,7 +2082,7 @@ int main(int argc, char **argv) else compile(file_args, output, compile_only);
output_file_name = NULL; - output_debug_file = NULL; + output_debug_files.count = 0; output_implib = NULL; return 0; }
From: Jacek Caban jacek@codeweavers.com
--- tools/makedep.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/tools/makedep.c b/tools/makedep.c index ad06868fdab..7cfc6ff5106 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -2444,16 +2444,19 @@ static struct strarray remove_warning_flags( struct strarray flags )
/******************************************************************* - * get_debug_file + * get_debug_files */ -static const char *get_debug_file( struct makefile *make, const char *name, unsigned int arch ) +static void output_debug_files( struct makefile *make, const char *name, unsigned int arch ) { const char *debug_file = NULL; - if (!debug_flags[arch]) return NULL; + if (!debug_flags[arch]) return; if (!strcmp( debug_flags[arch], "pdb" )) debug_file = strmake( "%s.pdb", get_base_name( name )); else if (!strncmp( debug_flags[arch], "split", 5 )) debug_file = strmake( "%s.debug", name ); - if (debug_file) strarray_add( &make->debug_files, debug_file ); - return debug_file; + if (debug_file) + { + strarray_add( &make->debug_files, debug_file ); + output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file ))); + } }
@@ -3137,7 +3140,7 @@ static void output_source_testdll( struct makefile *make, struct incl_file *sour struct strarray dll_flags = empty_strarray; struct strarray default_imports = empty_strarray; struct strarray all_libs, dep_libs; - const char *dll_name, *obj_name, *res_name, *output_rsrc, *output_file, *debug_file, *ext = ".dll"; + const char *dll_name, *obj_name, *res_name, *output_rsrc, *output_file, *ext = ".dll"; struct incl_file *spec_file = find_src_file( make, strmake( "%s.spec", obj )); unsigned int arch, link_arch;
@@ -3194,8 +3197,7 @@ static void output_source_testdll( struct makefile *make, struct incl_file *sour output_filename( obj_name ); if (hybrid_obj_name) output_filename( hybrid_obj_name ); if (res_name) output_filename( res_name ); - if ((debug_file = get_debug_file( make, dll_name, link_arch ))) - output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file ))); + output_debug_files( make, dll_name, link_arch ); output_filenames( all_libs ); output_filename( arch_make_variable( "LDFLAGS", link_arch )); output( "\n" ); @@ -3472,7 +3474,6 @@ static void output_module( struct makefile *make, unsigned int arch ) struct strarray dep_libs = empty_strarray; struct strarray imports = make->imports; const char *module_name; - const char *debug_file; char *spec_file = NULL; unsigned int i, link_arch;
@@ -3546,8 +3547,7 @@ static void output_module( struct makefile *make, unsigned int arch ) output_filenames_obj_dir( make, make->object_files[arch] ); if (link_arch != arch) output_filenames_obj_dir( make, make->object_files[link_arch] ); output_filenames_obj_dir( make, make->res_files[arch] ); - debug_file = get_debug_file( make, module_name, link_arch ); - if (debug_file) output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file ))); + output_debug_files( make, module_name, link_arch ); output_filenames( all_libs ); output_filename( arch_make_variable( "LDFLAGS", link_arch )); output( "\n" ); @@ -3661,7 +3661,6 @@ static void output_test_module( struct makefile *make, unsigned int arch ) struct strarray dep_libs = empty_strarray; struct strarray all_libs = empty_strarray; struct makefile *parent = get_parent_makefile( make ); - const char *debug_file; unsigned int link_arch;
if (!get_link_arch( make, arch, &link_arch )) return; @@ -3677,8 +3676,7 @@ static void output_test_module( struct makefile *make, unsigned int arch ) output_filenames_obj_dir( make, make->object_files[arch] ); if (link_arch != arch) output_filenames_obj_dir( make, make->object_files[link_arch] ); output_filenames_obj_dir( make, make->res_files[arch] ); - if ((debug_file = get_debug_file( make, testmodule, arch ))) - output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file ))); + output_debug_files( make, testmodule, arch ); output_filenames( all_libs ); output_filename( arch_make_variable( "LDFLAGS", link_arch )); output( "\n" );
From: Jacek Caban jacek@codeweavers.com
--- configure.ac | 28 ++++++++++++++++++---------- tools/makedep.c | 19 +++++++++++-------- 2 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/configure.ac b/configure.ac index 056d18b378b..cae44286dc4 100644 --- a/configure.ac +++ b/configure.ac @@ -587,13 +587,18 @@ This is an error since --enable-archs=$wine_arch was requested.])]) wine_crossdebug=$CROSSDEBUG if test -z "$wine_crossdebug" then + ac_g_flag_seen="" for ac_flag in $CFLAGS; do case $ac_flag in - -gdwarf*) wine_crossdebug=dwarf ;; - -gcodeview) wine_crossdebug=pdb ;; - -g) wine_crossdebug=${wine_crossdebug:-dwarf} ;; + -gdwarf*) AS_VAR_APPEND(wine_crossdebug, " dwarf") ;; + -gcodeview) AS_VAR_APPEND(wine_crossdebug, " pdb") ;; + -g) ac_g_flag_seen=$ac_flag ;; esac done + if test -n "$ac_g_flag_seen" -a -z "$wine_crossdebug" + then + wine_crossdebug=dwarf + fi fi
ac_debug_format_seen="" @@ -604,13 +609,16 @@ This is an error since --enable-archs=$wine_arch was requested.])]) done if test "x$ac_debug_format_seen" = x then - case $wine_crossdebug in - *dwarf) dnl clang emits a warning without -Wl,-debug:dwarf, so ensure linker option is present - WINE_TRY_PE_CFLAGS([-Wl,-debug:dwarf],[AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -Wl,-debug:dwarf"]) - CFLAGS="$CFLAGS -Wl,-debug:dwarf"]) - WINE_TRY_PE_CFLAGS([-gdwarf-4]) ;; - pdb) WINE_TRY_PE_CFLAGS([-gcodeview]) ;; - esac + for wine_debug_format in $wine_crossdebug + do + case $wine_debug_format in + *dwarf) dnl clang emits a warning without -Wl,-debug:dwarf, so ensure linker option is present + WINE_TRY_PE_CFLAGS([-Wl,-debug:dwarf],[AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -Wl,-debug:dwarf"]) + CFLAGS="$CFLAGS -Wl,-debug:dwarf"]) + WINE_TRY_PE_CFLAGS([-gdwarf-4]) ;; + pdb) WINE_TRY_PE_CFLAGS([-gcodeview]) ;; + esac + done fi AS_VAR_SET([${wine_arch}_DEBUG],[$wine_crossdebug])
diff --git a/tools/makedep.c b/tools/makedep.c index 7cfc6ff5106..bf20cbc16e3 100644 --- a/tools/makedep.c +++ b/tools/makedep.c @@ -168,7 +168,7 @@ static const char *arch_dirs[MAX_ARCHS]; static const char *arch_pe_dirs[MAX_ARCHS]; static const char *arch_install_dirs[MAX_ARCHS]; static const char *strip_progs[MAX_ARCHS]; -static const char *debug_flags[MAX_ARCHS]; +static struct strarray debug_flags[MAX_ARCHS]; static const char *delay_load_flags[MAX_ARCHS]; static struct strarray target_flags[MAX_ARCHS]; static struct strarray extra_cflags[MAX_ARCHS]; @@ -2448,12 +2448,15 @@ static struct strarray remove_warning_flags( struct strarray flags ) */ static void output_debug_files( struct makefile *make, const char *name, unsigned int arch ) { - const char *debug_file = NULL; - if (!debug_flags[arch]) return; - if (!strcmp( debug_flags[arch], "pdb" )) debug_file = strmake( "%s.pdb", get_base_name( name )); - else if (!strncmp( debug_flags[arch], "split", 5 )) debug_file = strmake( "%s.debug", name ); - if (debug_file) + unsigned int i; + + for (i = 0; i < debug_flags[arch].count; i++) { + const char *debug_file = NULL; + const char *flag = debug_flags[arch].str[i]; + if (!strcmp( flag, "pdb" )) debug_file = strmake( "%s.pdb", get_base_name( name )); + else if (!strncmp( flag, "split", 5 )) debug_file = strmake( "%s.debug", name ); + if (!debug_file) continue; strarray_add( &make->debug_files, debug_file ); output_filename( strmake( "-Wl,--debug-file,%s", obj_dir_path( make, debug_file ))); } @@ -4730,13 +4733,13 @@ int main( int argc, char *argv[] ) disabled_dirs[arch] = get_expanded_arch_var_array( top_makefile, "DISABLED_SUBDIRS", arch ); if (!is_multiarch( arch )) continue; delay_load_flags[arch] = get_expanded_arch_var( top_makefile, "DELAYLOADFLAG", arch ); - debug_flags[arch] = get_expanded_arch_var( top_makefile, "DEBUG", arch ); + debug_flags[arch] = get_expanded_arch_var_array( top_makefile, "DEBUG", arch ); }
if (unix_lib_supported) { delay_load_flags[0] = "-Wl,-delayload,"; - debug_flags[0] = NULL; + debug_flags[0].count = 0; }
top_makefile->src_dir = root_src_dir;