On Sat, Mar 20, 2021 at 5:28 PM Mark Harmstone <m...@harmstone.com> wrote:
>
> This is a series of patches to allow gcc to emit debugging information
> in the PE-specific CodeView format, which allows Microsoft debuggers to
> work with mingw EXEs. The format is semi-documented: Microsoft have
> open-sourced some of their header files at
> https://github.com/microsoft/microsoft-pdb, along with a program
> cvdump.exe which outputs the textual form of the data.
>
> This works by adding two new sections to every object file: .debug$T,
> which contains the type definitions, and .debug$S, which is everything
> else (line numbers, file checksums, symbols). The linker then merges
> everything together, resolves any duplicate types etc., and outputs this
> as a PDB file. Obviously this needs linker support to be useful - lld
> does the job, or you can try my binutils patches at
> https://github.com/maharmstone/binutils-gdb/tree/for-gcc.
>
> It also needs support for the asm-pseudo directive .secidx, which
> outputs the IMAGE_REL_AMD64_SECTION / IMAGE_REL_I386_SECTION PE
> relocations. This is likewise not in mainstream binutils - you can
> either try llvm-mc instead of gas, or my binutils repo above.
>
> In terms of debuggers and the like, I've tested this successfully with
> Visual Studio, windbg, radare2, and of course the aforementioned cvdump
> - I don't think there's any other significant tools which use the
>  format.
>
> I've only tested this on x86 and amd64, as I've no idea how you go about
> compiling Windows EXEs for arm or aarch64 with gcc, or if such a thing
> is possible. The other architectures the format provides for are 16-bit
> x86, alpha, mips, m68k, ppc, sh3, arm, aarch64, and ia64 - adding these
> would at the very least require updating the register mapping.
>
> If you're looking to test this, Wine makes a good victim: set
> CROSSCFLAGS to "-gcodeview" when configuring. You probably also want to
> set CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET to "-gcodeview" when
> configuring gcc, to make sure that debugging information gets generated
> for libgcc etc.

I see you're adding another debug format via debug_hooks.  Since the goal is
to make DWARF the only debug interface for the frontends pdbout will be another
road-block towards achieving that (apart from deprecating and removing
stabs & friends).

CTF has already been reworked to be generated off the internal DWARF
representation
(but not yet accepted since that's sth for stage1).  How do CV and
DWARF debug differ
and is emitting CV debug from a DWARF representation possible (I
suppose there might
even exist offline conversion tools?)

Note this was communicated multiple times, but maybe not officially
enough.  I'll see to
add some fat commentary above the debug hooks structure (not sure if
that will help
in practice).

Thanks,
Richard.

> ---
>  gcc/Makefile.in           |  3 ++
>  gcc/common.opt            |  4 +++
>  gcc/config/i386/cygming.h |  1 +
>  gcc/config/i386/x86-64.h  |  2 ++
>  gcc/debug.h               |  1 +
>  gcc/defaults.h            |  3 ++
>  gcc/doc/invoke.texi       |  7 ++++
>  gcc/flag-types.h          |  5 +--
>  gcc/gcc.c                 |  6 ++++
>  gcc/opts.c                |  4 +++
>  gcc/pdbout.c              | 70 +++++++++++++++++++++++++++++++++++++++
>  gcc/pdbout.h              | 23 +++++++++++++
>  gcc/toplev.c              |  4 +++
>  13 files changed, 131 insertions(+), 2 deletions(-)
>  create mode 100644 gcc/pdbout.c
>  create mode 100644 gcc/pdbout.h
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index 543b477ff18..f0249bde720 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -1476,6 +1476,7 @@ OBJS = \
>         opts-global.o \
>         ordered-hash-map-tests.o \
>         passes.o \
> +       pdbout.o \
>         plugin.o \
>         postreload-gcse.o \
>         postreload.o \
> @@ -2637,6 +2638,8 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h 
> $(srcdir)/coretypes.h \
>    $(srcdir)/hsa-common.c \
>    $(srcdir)/calls.c \
>    $(srcdir)/omp-general.h \
> +  $(srcdir)/pdbout.c \
> +  $(srcdir)/pdbout.h \
>    @all_gtfiles@
>
>  # Compute the list of GT header files from the corresponding C sources,
> diff --git a/gcc/common.opt b/gcc/common.opt
> index d33383b523c..80c488c0d70 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -3127,6 +3127,10 @@ gno-pubnames
>  Common Driver Negative(gpubnames) Var(debug_generate_pub_sections, 0) 
> Init(-1)
>  Don't generate DWARF pubnames and pubtypes sections.
>
> +gcodeview
> +Common Driver JoinedOrMissing
> +Generate debug information in CodeView format.
> +
>  gpubnames
>  Common Driver Negative(ggnu-pubnames) Var(debug_generate_pub_sections, 1)
>  Generate DWARF pubnames and pubtypes sections.
> diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
> index 1b1ea7d3d8a..42191b16c99 100644
> --- a/gcc/config/i386/cygming.h
> +++ b/gcc/config/i386/cygming.h
> @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
>  <http://www.gnu.org/licenses/>.  */
>
>  #define DBX_DEBUGGING_INFO 1
> +#define PDB_DEBUGGING_INFO 1
>  #if TARGET_64BIT_DEFAULT || defined (HAVE_GAS_PE_SECREL32_RELOC)
>  #define DWARF2_DEBUGGING_INFO 1
>  #endif
> diff --git a/gcc/config/i386/x86-64.h b/gcc/config/i386/x86-64.h
> index 88db428f592..e84ee6c4026 100644
> --- a/gcc/config/i386/x86-64.h
> +++ b/gcc/config/i386/x86-64.h
> @@ -91,6 +91,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
> If not, see
>  #define DWARF2_DEBUGGING_INFO 1
>  #define DWARF2_UNWIND_INFO 1
>
> +#define PDB_DEBUGGING_INFO 1
> +
>  #undef PREFERRED_DEBUGGING_TYPE
>  #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
>
> diff --git a/gcc/debug.h b/gcc/debug.h
> index 260325920ea..c8f182962dd 100644
> --- a/gcc/debug.h
> +++ b/gcc/debug.h
> @@ -235,6 +235,7 @@ extern const struct gcc_debug_hooks xcoff_debug_hooks;
>  extern const struct gcc_debug_hooks dwarf2_debug_hooks;
>  extern const struct gcc_debug_hooks dwarf2_lineno_debug_hooks;
>  extern const struct gcc_debug_hooks vmsdbg_debug_hooks;
> +extern const struct gcc_debug_hooks pdb_debug_hooks;
>
>  /* Dwarf2 frame information.  */
>
> diff --git a/gcc/defaults.h b/gcc/defaults.h
> index f1a38626624..c6bbb203ef3 100644
> --- a/gcc/defaults.h
> +++ b/gcc/defaults.h
> @@ -922,6 +922,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
> If not, see
>  #elif defined XCOFF_DEBUGGING_INFO
>  #define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
>
> +#elif defined PDB_DEBUGGING_INFO
> +#define PREFERRED_DEBUGGING_TYPE PDB_DEBUG
> +
>  #else
>  /* No debugging format is supported by this target.  */
>  #define PREFERRED_DEBUGGING_TYPE NO_DEBUG
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 527d362533a..f83cec6f5e0 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -435,6 +435,7 @@ Objective-C and Objective-C++ Dialects}.
>  -gstabs  -gstabs+  -gstrict-dwarf  -gno-strict-dwarf @gol
>  -gas-loc-support  -gno-as-loc-support @gol
>  -gas-locview-support  -gno-as-locview-support @gol
> +-gcodeview @gol
>  -gcolumn-info  -gno-column-info @gol
>  -gstatement-frontiers  -gno-statement-frontiers @gol
>  -gvariable-location-views  -gno-variable-location-views @gol
> @@ -8707,6 +8708,12 @@ assembler (GAS) to fail with an error.
>  Produce debugging information in Alpha/VMS debug format (if that is
>  supported).  This is the format used by DEBUG on Alpha/VMS systems.
>
> +@item -gcodeview
> +@opindex gcodeview
> +Produce debugging information in CodeView debug format (if that is
> +supported).  This is the format used by Microsoft Visual C++ on
> +Windows.
> +
>  @item -g@var{level}
>  @itemx -ggdb@var{level}
>  @itemx -gstabs@var{level}
> diff --git a/gcc/flag-types.h b/gcc/flag-types.h
> index b092c563f3d..d4d7bdd5158 100644
> --- a/gcc/flag-types.h
> +++ b/gcc/flag-types.h
> @@ -27,8 +27,9 @@ enum debug_info_type
>    DWARF2_DEBUG,            /* Write Dwarf v2 debug info (using dwarf2out.c). 
>  */
>    XCOFF_DEBUG,     /* Write IBM/Xcoff debug info (using dbxout.c).  */
>    VMS_DEBUG,        /* Write VMS debug info (using vmsdbgout.c).  */
> -  VMS_AND_DWARF2_DEBUG /* Write VMS debug info (using vmsdbgout.c).
> -                          and DWARF v2 debug info (using dwarf2out.c).  */
> +  VMS_AND_DWARF2_DEBUG, /* Write VMS debug info (using vmsdbgout.c).
> +                          and DWARF v2 debug info (using dwarf2out.c).  */
> +  PDB_DEBUG        /* Write CodeView debug info (using pdbout.c).  */
>  };
>
>  enum debug_info_levels
> diff --git a/gcc/gcc.c b/gcc/gcc.c
> index 9f790db0daf..327cb4387db 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -4289,6 +4289,12 @@ driver_handle_option (struct gcc_options *opts,
>        handle_foffload_option (arg);
>        break;
>
> +    case OPT_gcodeview:
> +      /* If we've generated CodeView debugging information, make sure
> +       * linker creates a PDB file for it. */
> +      add_infile ("--pdb=", "*");
> +      break;
> +
>      default:
>        /* Various driver options need no special processing at this
>          point, having been handled in a prescan above or being
> diff --git a/gcc/opts.c b/gcc/opts.c
> index c212a1a57dc..09b91aa2b87 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -2730,6 +2730,10 @@ common_handle_option (struct gcc_options *opts,
>        set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
>        break;
>
> +    case OPT_gcodeview:
> +      set_debug_level (PDB_DEBUG, false, "", opts, opts_set, loc);
> +      break;
> +
>      case OPT_gstabs:
>      case OPT_gstabs_:
>        set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
> diff --git a/gcc/pdbout.c b/gcc/pdbout.c
> new file mode 100644
> index 00000000000..e8f39bb64ea
> --- /dev/null
> +++ b/gcc/pdbout.c
> @@ -0,0 +1,70 @@
> +/* Output CodeView debugging information from GNU compiler.
> + * Copyright (C) 2021 Mark Harmstone
> + *
> + * 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/>.  */
> +
> +/* The CodeView structure is partially documented - definitions of structures
> + * output below can be found at:
> + * https://github.com/microsoft/microsoft-pdb/blob/master/include/cvinfo.h
> + */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "tree.h"
> +#include "debug.h"
> +#include "pdbout.h"
> +
> +const struct gcc_debug_hooks pdb_debug_hooks = {
> +  debug_nothing_charstar,      /* init */
> +  debug_nothing_charstar,      /* finish */
> +  debug_nothing_charstar,      /* early_finish */
> +  debug_nothing_void,          /* assembly_start */
> +  debug_nothing_int_charstar,  /* define */
> +  debug_nothing_int_charstar,  /* undef */
> +  debug_nothing_int_charstar,  /* start_source_file */
> +  debug_nothing_int,           /* end_source_file */
> +  debug_nothing_int_int,       /* begin_block */
> +  debug_nothing_int_int,       /* end_block */
> +  debug_true_const_tree,       /* ignore_block */
> +  debug_nothing_int_int_charstar_int_bool,     /* source_line */
> +  debug_nothing_int_int_charstar,      /* begin_prologue */
> +  debug_nothing_int_charstar,  /* end_prologue */
> +  debug_nothing_int_charstar,  /* begin_epilogue */
> +  debug_nothing_int_charstar,  /* end_epilogue */
> +  debug_nothing_tree,          /* begin_function */
> +  debug_nothing_int,           /* end_function */
> +  debug_nothing_tree,          /* register_main_translation_unit */
> +  debug_nothing_tree,          /* function_decl */
> +  debug_nothing_tree,          /* early_global_decl */
> +  debug_nothing_tree,          /* late_global_decl */
> +  debug_nothing_tree_int,      /* type_decl */
> +  debug_nothing_tree_tree_tree_bool_bool,      /* imported_module_or_decl */
> +  debug_false_tree_charstarstar_uhwistar,      /* die_ref_for_decl */
> +  debug_nothing_tree_charstar_uhwi,    /* register_external_die */
> +  debug_nothing_tree,          /* deferred_inline_function */
> +  debug_nothing_tree,          /* outlining_inline_function */
> +  debug_nothing_rtx_code_label,        /* label */
> +  debug_nothing_int,           /* handle_pch */
> +  debug_nothing_rtx_insn,      /* var_location */
> +  debug_nothing_tree,          /* inline_entry */
> +  debug_nothing_tree,          /* size_function */
> +  debug_nothing_void,          /* switch_text_section */
> +  debug_nothing_tree_tree,     /* set_name */
> +  0,                           /* start_end_main_source_file */
> +  TYPE_SYMTAB_IS_ADDRESS       /* tree_type_symtab_field */
> +};
> diff --git a/gcc/pdbout.h b/gcc/pdbout.h
> new file mode 100644
> index 00000000000..f957cd5eca1
> --- /dev/null
> +++ b/gcc/pdbout.h
> @@ -0,0 +1,23 @@
> +/* CodeView structures and constants
> + * Copyright (c) 2021 Mark Harmstone
> + *
> + * 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_PDBOUT_H
> +#define GCC_PDBOUT_H 1
> +
> +#endif
> diff --git a/gcc/toplev.c b/gcc/toplev.c
> index 5c026feece2..a14a9177ee3 100644
> --- a/gcc/toplev.c
> +++ b/gcc/toplev.c
> @@ -1588,6 +1588,10 @@ process_options (void)
>  #ifdef DWARF2_LINENO_DEBUGGING_INFO
>    else if (write_symbols == DWARF2_DEBUG)
>      debug_hooks = &dwarf2_lineno_debug_hooks;
> +#endif
> +#ifdef PDB_DEBUGGING_INFO
> +  else if (write_symbols == PDB_DEBUG)
> +    debug_hooks = &pdb_debug_hooks;
>  #endif
>    else
>      error_at (UNKNOWN_LOCATION,
> --
> 2.26.2
>

Reply via email to