On Mon, Oct 23, 2023 at 2:57 AM Mark Harmstone <m...@harmstone.com> wrote: > > This patch and the following add initial support for Microsoft's > CodeView debugging format, as used by MSVC, to mingw targets.
A high-level question - it seems there's almost no information in the codeview sections, so is that debug format even inferior to STABS? Is it even used with contemporary toolchains or is DWARF a thing with MSVC? If CodeView is as full-featured as DWARF you are going to run into issues with how we handle LTO given at dwarf2out_finish time all the DWARF for types and declarations is "gone" (to disk). For that post-processing the binary would be much easier. Richard. > Note that you will need a recent version of binutils for this to be > useful. The best way to view the output is to run Microsoft's > cvdump.exe, found in their microsoft-pdb repo on GitHub, against the > object files. > --- > gcc/Makefile.in | 2 + > gcc/config/i386/cygming.h | 2 + > gcc/dwarf2codeview.cc | 50 +++++++++++++++++++ > gcc/dwarf2codeview.h | 30 +++++++++++ > gcc/dwarf2out.cc | 4 ++ > gcc/flag-types.h | 3 ++ > gcc/flags.h | 4 ++ > gcc/opts.cc | 23 +++++++-- > .../gcc.dg/debug/codeview/codeview-1.c | 6 +++ > .../gcc.dg/debug/codeview/codeview.exp | 48 ++++++++++++++++++ > gcc/toplev.cc | 4 ++ > 11 files changed, 171 insertions(+), 5 deletions(-) > create mode 100644 gcc/dwarf2codeview.cc > create mode 100644 gcc/dwarf2codeview.h > create mode 100644 gcc/testsuite/gcc.dg/debug/codeview/codeview-1.c > create mode 100644 gcc/testsuite/gcc.dg/debug/codeview/codeview.exp > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index a25a1e32fbc..d011946379d 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -1428,6 +1428,7 @@ OBJS = \ > dumpfile.o \ > dwarf2asm.o \ > dwarf2cfi.o \ > + dwarf2codeview.o \ > dwarf2ctf.o \ > dwarf2out.o \ > early-remat.o \ > @@ -2794,6 +2795,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h > $(srcdir)/coretypes.h \ > $(srcdir)/dwarf2out.h \ > $(srcdir)/dwarf2asm.cc \ > $(srcdir)/dwarf2cfi.cc \ > + $(srcdir)/dwarf2codeview.cc \ > $(srcdir)/dwarf2ctf.cc \ > $(srcdir)/dwarf2out.cc \ > $(srcdir)/ctfc.h \ > diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h > index d539f8d0699..a141462133b 100644 > --- a/gcc/config/i386/cygming.h > +++ b/gcc/config/i386/cygming.h > @@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see > > #define DWARF2_DEBUGGING_INFO 1 > > +#define CODEVIEW_DEBUGGING_INFO 1 > + > #undef PREFERRED_DEBUGGING_TYPE > #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG > > diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc > new file mode 100644 > index 00000000000..e2bfdf8efeb > --- /dev/null > +++ b/gcc/dwarf2codeview.cc > @@ -0,0 +1,50 @@ > +/* Generate CodeView debugging info from the GCC DWARF. > + Copyright (C) 2023 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +/* See gas/codeview.h in binutils for more about the constants and structs > + listed below. References to Microsoft files refer to Microsoft's PDB > + repository: https://github.com/microsoft/microsoft-pdb. */ > + > +#include "config.h" > +#include "system.h" > +#include "coretypes.h" > +#include "target.h" > +#include "output.h" > +#include "errors.h" > +#include "md5.h" > +#include "function.h" > +#include "version.h" > +#include "tree.h" > +#include "langhooks.h" > +#include "dwarf2out.h" > +#include "dwarf2codeview.h" > + > +#define CV_SIGNATURE_C13 4 > + > +/* Finish CodeView debug info emission. */ > + > +void > +codeview_debug_finish (void) > +{ > + targetm.asm_out.named_section (".debug$S", SECTION_DEBUG, NULL); > + > + fputs (integer_asm_op (4, false), asm_out_file); > + fprint_whex (asm_out_file, CV_SIGNATURE_C13); > + putc ('\n', asm_out_file); > +} > diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h > new file mode 100644 > index 00000000000..efda148eb49 > --- /dev/null > +++ b/gcc/dwarf2codeview.h > @@ -0,0 +1,30 @@ > +/* dwarf2codeview.h - DWARF interface for CodeView generation. > + Copyright (C) 2023 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +#ifndef GCC_DWARF2CODEVIEW_H > +#define GCC_DWARF2CODEVIEW_H 1 > + > +#include "dwarf2out.h" > +#include "flags.h" > + > +/* Debug Format Interface. Used in dwarf2out.cc. */ > + > +extern void codeview_debug_finish (void); > + > +#endif /* GCC_DWARF2CODEVIEW_H */ > diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc > index 0ea73bf782e..557464c4c24 100644 > --- a/gcc/dwarf2out.cc > +++ b/gcc/dwarf2out.cc > @@ -80,6 +80,7 @@ along with GCC; see the file COPYING3. If not see > #include "expr.h" > #include "dwarf2out.h" > #include "dwarf2ctf.h" > +#include "dwarf2codeview.h" > #include "dwarf2asm.h" > #include "toplev.h" > #include "md5.h" > @@ -32207,6 +32208,9 @@ dwarf2out_finish (const char *filename) > || btf_debuginfo_p ()) && lang_GNU_C ()) > ctf_debug_finish (filename); > > + if (codeview_debuginfo_p ()) > + codeview_debug_finish (); > + > /* Skip emitting DWARF if not required. */ > if (!dwarf_debuginfo_p ()) > return; > diff --git a/gcc/flag-types.h b/gcc/flag-types.h > index c1852cd810c..dae1d0a8095 100644 > --- a/gcc/flag-types.h > +++ b/gcc/flag-types.h > @@ -29,6 +29,7 @@ enum debug_info_type > DINFO_TYPE_VMS, /* VMS debug info. */ > DINFO_TYPE_CTF, /* CTF debug info. */ > DINFO_TYPE_BTF, /* BTF debug info. */ > + DINFO_TYPE_CODEVIEW, /* CodeView debug info. */ > DINFO_TYPE_BTF_WITH_CORE, /* BTF debug info with CO-RE relocations. > */ > DINFO_TYPE_MAX = DINFO_TYPE_BTF_WITH_CORE /* Marker only. */ > }; > @@ -42,6 +43,8 @@ enum debug_info_type > #define CTF_DEBUG (1U << DINFO_TYPE_CTF) > /* Write BTF debug info (using btfout.cc). */ > #define BTF_DEBUG (1U << DINFO_TYPE_BTF) > +/* Write CodeView debug info (using dwarf2codeview.cc). */ > +#define CODEVIEW_DEBUG (1U << DINFO_TYPE_CODEVIEW) > /* Write BTF debug info for BPF CO-RE usecase (using btfout.cc). */ > #define BTF_WITH_CORE_DEBUG (1U << DINFO_TYPE_BTF_WITH_CORE) > > diff --git a/gcc/flags.h b/gcc/flags.h > index e4bafa310d6..50036459328 100644 > --- a/gcc/flags.h > +++ b/gcc/flags.h > @@ -53,6 +53,10 @@ extern bool btf_with_core_debuginfo_p (); > > extern bool ctf_debuginfo_p (); > > +/* Return true iff CodeView debug info is enabled. */ > + > +extern bool codeview_debuginfo_p (); > + > /* Return true iff DWARF2 debug info is enabled. */ > > extern bool dwarf_debuginfo_p (struct gcc_options *opts = &global_options); > diff --git a/gcc/opts.cc b/gcc/opts.cc > index 8015cb7556a..f02101ceea3 100644 > --- a/gcc/opts.cc > +++ b/gcc/opts.cc > @@ -50,7 +50,7 @@ static void set_Wstrict_aliasing (struct gcc_options *opts, > int onoff); > > const char *const debug_type_names[] = > { > - "none", "dwarf-2", "vms", "ctf", "btf" > + "none", "dwarf-2", "vms", "ctf", "btf", "codeview" > }; > > /* Bitmasks of fundamental debug info formats indexed by enum > @@ -59,13 +59,13 @@ const char *const debug_type_names[] = > static uint32_t debug_type_masks[] = > { > NO_DEBUG, DWARF2_DEBUG, VMS_DEBUG, > - CTF_DEBUG, BTF_DEBUG > + CTF_DEBUG, BTF_DEBUG, CODEVIEW_DEBUG > }; > > /* Names of the set of debug formats requested by user. Updated and accessed > via debug_set_names. */ > > -static char df_set_names[sizeof "none dwarf-2 vms ctf btf"]; > +static char df_set_names[sizeof "none dwarf-2 vms ctf btf codeview"]; > > /* Get enum debug_info_type of the specified debug format, for error > messages. > Can be used only for individual debug format types. */ > @@ -159,6 +159,14 @@ ctf_debuginfo_p () > return (write_symbols & CTF_DEBUG); > } > > +/* Return TRUE iff CodeView debug info is enabled. */ > + > +bool > +codeview_debuginfo_p () > +{ > + return (write_symbols & CODEVIEW_DEBUG); > +} > + > /* Return TRUE iff dwarf2 debug info is enabled. */ > > bool > @@ -173,7 +181,8 @@ dwarf_debuginfo_p (struct gcc_options *opts) > bool dwarf_based_debuginfo_p () > { > return ((write_symbols & CTF_DEBUG) > - || (write_symbols & BTF_DEBUG)); > + || (write_symbols & BTF_DEBUG) > + || (write_symbols & CODEVIEW_DEBUG)); > } > > /* All flag uses below need to explicitely reference the option sets > @@ -3145,6 +3154,9 @@ common_handle_option (struct gcc_options *opts, > break; > > case OPT_gcodeview: > + set_debug_level (CODEVIEW_DEBUG, false, arg, opts, opts_set, loc); > + if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL) > + opts->x_debug_info_level = DINFO_LEVEL_NORMAL; > break; > > case OPT_gbtf: > @@ -3419,7 +3431,8 @@ set_debug_level (uint32_t dinfo, int extended, const > char *arg, > warning_at (loc, 0, "target system does not support debug > output"); > } > else if ((opts->x_write_symbols & CTF_DEBUG) > - || (opts->x_write_symbols & BTF_DEBUG)) > + || (opts->x_write_symbols & BTF_DEBUG) > + || (opts->x_write_symbols & CODEVIEW_DEBUG)) > { > opts->x_write_symbols |= DWARF2_DEBUG; > opts_set->x_write_symbols |= DWARF2_DEBUG; > diff --git a/gcc/testsuite/gcc.dg/debug/codeview/codeview-1.c > b/gcc/testsuite/gcc.dg/debug/codeview/codeview-1.c > new file mode 100644 > index 00000000000..eb5f14530dc > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/debug/codeview/codeview-1.c > @@ -0,0 +1,6 @@ > +/* { dg-do compile } */ > +/* { dg-options "-gcodeview" } */ > + > +void func(void) > +{ > +} > diff --git a/gcc/testsuite/gcc.dg/debug/codeview/codeview.exp > b/gcc/testsuite/gcc.dg/debug/codeview/codeview.exp > new file mode 100644 > index 00000000000..ff705a4ae78 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/debug/codeview/codeview.exp > @@ -0,0 +1,48 @@ > +# Copyright (C) 2023 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with GCC; see the file COPYING3. If not see > +# <http://www.gnu.org/licenses/>. > + > +# GCC testsuite that uses the `dg.exp' driver. > + > +# Load support procs. > +load_lib gcc-dg.exp > + > +if {![istarget i*86-*-mingw*] > + && ![istarget x86_64-*-mingw*]} { > + return 0 > +} > + > +# If a testcase doesn't have special options, use these. > +global DEFAULT_CFLAGS > +if ![info exists DEFAULT_CFLAGS] then { > + set DEFAULT_CFLAGS " -ansi -pedantic-errors" > +} > + > +# Initialize `dg'. > +dg-init > + > +# Main loop. > +set comp_output [gcc_target_compile \ > + "$srcdir/$subdir/../trivial.c" "trivial.S" assembly \ > + "additional_flags=-gcodeview"] > +if { ! [string match "*: target system does not support the * debug format*" > \ > + $comp_output] } { > + remove-build-file "trivial.S" > + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\] ]] \ > + "" $DEFAULT_CFLAGS > +} > + > +# All done. > +dg-finish > diff --git a/gcc/toplev.cc b/gcc/toplev.cc > index 8af9bf5090e..862583df0f4 100644 > --- a/gcc/toplev.cc > +++ b/gcc/toplev.cc > @@ -1431,6 +1431,10 @@ process_options (bool no_backend) > #ifdef DWARF2_LINENO_DEBUGGING_INFO > else if (write_symbols == DWARF2_DEBUG) > debug_hooks = &dwarf2_lineno_debug_hooks; > +#endif > +#ifdef CODEVIEW_DEBUGGING_INFO > + else if (codeview_debuginfo_p ()) > + debug_hooks = &dwarf2_debug_hooks; > #endif > else > { > -- > 2.41.0 >