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
>

Reply via email to