* [PATCH 1/5] Remove obsolete debugging formats from names list
@ 2023-10-23 0:55 Mark Harmstone
2023-10-23 0:55 ` [PATCH 2/5] Support for CodeView debugging format Mark Harmstone
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Mark Harmstone @ 2023-10-23 0:55 UTC (permalink / raw)
To: gcc-patches; +Cc: Mark Harmstone
STABS and xcoff have been removed, but are still in debug_type_names,
which ought to match debug_type_masks. This results in the following
minor bug with GCC 13:
$ x86_64-pc-linux-gnu-gcc -gvms -c tmp.c
cc1: error: target system does not support the ‘dwarf-2’ debug format
---
gcc/opts.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gcc/opts.cc b/gcc/opts.cc
index 573dcf8e497..8015cb7556a 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", "stabs", "dwarf-2", "xcoff", "vms", "ctf", "btf"
+ "none", "dwarf-2", "vms", "ctf", "btf"
};
/* Bitmasks of fundamental debug info formats indexed by enum
@@ -65,7 +65,7 @@ static uint32_t debug_type_masks[] =
/* Names of the set of debug formats requested by user. Updated and accessed
via debug_set_names. */
-static char df_set_names[sizeof "none stabs dwarf-2 xcoff vms ctf btf"];
+static char df_set_names[sizeof "none dwarf-2 vms ctf btf"];
/* Get enum debug_info_type of the specified debug format, for error messages.
Can be used only for individual debug format types. */
--
2.41.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/5] Support for CodeView debugging format
2023-10-23 0:55 [PATCH 1/5] Remove obsolete debugging formats from names list Mark Harmstone
@ 2023-10-23 0:55 ` Mark Harmstone
2023-10-26 9:35 ` Richard Biener
2023-10-23 0:55 ` [PATCH 3/5] Output file checksums in CodeView section Mark Harmstone
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Mark Harmstone @ 2023-10-23 0:55 UTC (permalink / raw)
To: gcc-patches; +Cc: Mark Harmstone
This patch and the following add initial support for Microsoft's
CodeView debugging format, as used by MSVC, to mingw targets.
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
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/5] Output file checksums in CodeView section
2023-10-23 0:55 [PATCH 1/5] Remove obsolete debugging formats from names list Mark Harmstone
2023-10-23 0:55 ` [PATCH 2/5] Support for CodeView debugging format Mark Harmstone
@ 2023-10-23 0:55 ` Mark Harmstone
2023-10-23 0:55 ` [PATCH 4/5] Output line numbers " Mark Harmstone
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Mark Harmstone @ 2023-10-23 0:55 UTC (permalink / raw)
To: gcc-patches; +Cc: Mark Harmstone
Outputs the file name and MD5 hash of the main source file into the
CodeView .debug$S section, along with that of any #include'd files.
---
gcc/dwarf2codeview.cc | 254 ++++++++++++++++++++++++++++++++++++++++++
gcc/dwarf2codeview.h | 1 +
gcc/dwarf2out.cc | 3 +
3 files changed, 258 insertions(+)
diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc
index e2bfdf8efeb..d93ba1ed668 100644
--- a/gcc/dwarf2codeview.cc
+++ b/gcc/dwarf2codeview.cc
@@ -37,6 +37,257 @@ along with GCC; see the file COPYING3. If not see
#define CV_SIGNATURE_C13 4
+#define DEBUG_S_STRINGTABLE 0xf3
+#define DEBUG_S_FILECHKSMS 0xf4
+
+#define CHKSUM_TYPE_MD5 1
+
+#define HASH_SIZE 16
+
+struct codeview_string
+{
+ codeview_string *next;
+ uint32_t offset;
+ char *string;
+};
+
+struct string_hasher : free_ptr_hash <struct codeview_string>
+{
+ typedef const char *compare_type;
+
+ static hashval_t hash (const codeview_string *x)
+ {
+ return htab_hash_string (x->string);
+ }
+
+ static bool equal (const codeview_string *x, const char *y)
+ {
+ return !strcmp (x->string, y);
+ }
+
+ static void mark_empty (codeview_string *x)
+ {
+ if (x->string)
+ {
+ free (x->string);
+ x->string = NULL;
+ }
+ }
+
+ static void remove (codeview_string *&x)
+ {
+ free (x->string);
+ }
+};
+
+struct codeview_source_file
+{
+ codeview_source_file *next;
+ unsigned int file_num;
+ uint32_t string_offset;
+ char *filename;
+ uint8_t hash[HASH_SIZE];
+};
+
+static codeview_source_file *files, *last_file;
+static unsigned int num_files;
+static uint32_t string_offset = 1;
+static hash_table<string_hasher> *strings_htab;
+static codeview_string *strings, *last_string;
+
+/* Adds string to the string table, returning its offset. If already present,
+ this returns the offset of the existing string. */
+
+static uint32_t
+add_string (const char *string)
+{
+ codeview_string **slot;
+ codeview_string *s;
+ size_t len;
+
+ if (!strings_htab)
+ strings_htab = new hash_table<string_hasher> (10);
+
+ slot = strings_htab->find_slot_with_hash (string, htab_hash_string (string),
+ INSERT);
+
+ if (*slot)
+ return (*slot)->offset;
+
+ s = (codeview_string *) xmalloc (sizeof (codeview_string));
+ len = strlen (string);
+
+ s->next = NULL;
+
+ s->offset = string_offset;
+ string_offset += len + 1;
+
+ s->string = xstrdup (string);
+
+ if (last_string)
+ last_string->next = s;
+ else
+ strings = s;
+
+ last_string = s;
+
+ *slot = s;
+
+ return s->offset;
+}
+
+/* A new source file has been encountered - record the details and calculate
+ its hash. */
+
+void
+codeview_start_source_file (const char *filename)
+{
+ codeview_source_file *sf;
+ char *path;
+ uint32_t string_offset;
+ FILE *f;
+
+ path = lrealpath (filename);
+ string_offset = add_string (path);
+ free (path);
+
+ sf = files;
+ while (sf)
+ {
+ if (sf->string_offset == string_offset)
+ return;
+
+ sf = sf->next;
+ }
+
+ sf = (codeview_source_file *) xmalloc (sizeof (codeview_source_file));
+ sf->next = NULL;
+ sf->file_num = num_files;
+ sf->string_offset = string_offset;
+ sf->filename = xstrdup (filename);
+
+ f = fopen (filename, "r");
+ if (!f)
+ internal_error ("could not open %s for reading", filename);
+
+ if (md5_stream (f, sf->hash))
+ {
+ fclose (f);
+ internal_error ("md5_stream failed");
+ }
+
+ fclose (f);
+
+ if (last_file)
+ last_file->next = sf;
+ else
+ files = sf;
+
+ last_file = sf;
+ num_files++;
+}
+
+/* Write out the strings table into the .debug$S section. The linker will
+ parse this, and handle the deduplication and hashing for all the object
+ files. */
+
+static void
+write_strings_table (void)
+{
+ codeview_string *string;
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, DEBUG_S_STRINGTABLE);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ asm_fprintf (asm_out_file, "%LLcv_strings_end - %LLcv_strings_start\n");
+
+ asm_fprintf (asm_out_file, "%LLcv_strings_start:\n");
+
+ /* The first entry is always an empty string. */
+ fputs (integer_asm_op (1, false), asm_out_file);
+ fprint_whex (asm_out_file, 0);
+ putc ('\n', asm_out_file);
+
+ string = strings;
+ while (string)
+ {
+ ASM_OUTPUT_ASCII (asm_out_file, string->string,
+ strlen (string->string) + 1);
+
+ string = string->next;
+ }
+
+ delete strings_htab;
+
+ asm_fprintf (asm_out_file, "%LLcv_strings_end:\n");
+
+ ASM_OUTPUT_ALIGN (asm_out_file, 2);
+}
+
+/* Write out the file checksums data into the .debug$S section. */
+
+static void
+write_source_files (void)
+{
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, DEBUG_S_FILECHKSMS);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ asm_fprintf (asm_out_file,
+ "%LLcv_filechksms_end - %LLcv_filechksms_start\n");
+
+ asm_fprintf (asm_out_file, "%LLcv_filechksms_start:\n");
+
+ while (files)
+ {
+ codeview_source_file *next = files->next;
+
+ /* This is struct file_checksum in binutils, or filedata in Microsoft's
+ dumpsym7.cpp:
+
+ struct file_checksum
+ {
+ uint32_t file_id;
+ uint8_t checksum_length;
+ uint8_t checksum_type;
+ } ATTRIBUTE_PACKED;
+
+ followed then by the bytes of the hash, padded to the next 4 bytes.
+ file_id here is actually the offset in the strings table. */
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, files->string_offset);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (1, false), asm_out_file);
+ fprint_whex (asm_out_file, HASH_SIZE);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (1, false), asm_out_file);
+ fprint_whex (asm_out_file, CHKSUM_TYPE_MD5);
+ putc ('\n', asm_out_file);
+
+ for (unsigned int i = 0; i < HASH_SIZE; i++)
+ {
+ fputs (integer_asm_op (1, false), asm_out_file);
+ fprint_whex (asm_out_file, files->hash[i]);
+ putc ('\n', asm_out_file);
+ }
+
+ ASM_OUTPUT_ALIGN (asm_out_file, 2);
+
+ free (files->filename);
+ free (files);
+
+ files = next;
+ }
+
+ asm_fprintf (asm_out_file, "%LLcv_filechksms_end:\n");
+}
+
/* Finish CodeView debug info emission. */
void
@@ -47,4 +298,7 @@ codeview_debug_finish (void)
fputs (integer_asm_op (4, false), asm_out_file);
fprint_whex (asm_out_file, CV_SIGNATURE_C13);
putc ('\n', asm_out_file);
+
+ write_strings_table ();
+ write_source_files ();
}
diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h
index efda148eb49..e2d732bb9b6 100644
--- a/gcc/dwarf2codeview.h
+++ b/gcc/dwarf2codeview.h
@@ -26,5 +26,6 @@ along with GCC; see the file COPYING3. If not see
/* Debug Format Interface. Used in dwarf2out.cc. */
extern void codeview_debug_finish (void);
+extern void codeview_start_source_file (const char *);
#endif /* GCC_DWARF2CODEVIEW_H */
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 557464c4c24..945176a91bc 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -28823,6 +28823,9 @@ dwarf2out_set_ignored_loc (unsigned int line, unsigned int column,
static void
dwarf2out_start_source_file (unsigned int lineno, const char *filename)
{
+ if (codeview_debuginfo_p ())
+ codeview_start_source_file (filename);
+
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
macinfo_entry e;
--
2.41.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/5] Output line numbers in CodeView section
2023-10-23 0:55 [PATCH 1/5] Remove obsolete debugging formats from names list Mark Harmstone
2023-10-23 0:55 ` [PATCH 2/5] Support for CodeView debugging format Mark Harmstone
2023-10-23 0:55 ` [PATCH 3/5] Output file checksums in CodeView section Mark Harmstone
@ 2023-10-23 0:55 ` Mark Harmstone
2023-10-23 0:55 ` [PATCH 5/5] Output S_COMPILE3 symbol in CodeView debug section Mark Harmstone
2023-10-23 7:46 ` [PATCH 1/5] Remove obsolete debugging formats from names list Richard Biener
4 siblings, 0 replies; 8+ messages in thread
From: Mark Harmstone @ 2023-10-23 0:55 UTC (permalink / raw)
To: gcc-patches; +Cc: Mark Harmstone
Outputs the DEBUG_S_LINES block in the CodeView .debug$S section, which
maps between line numbers and addresses.
You'll need a fairly recent version of GAS for the .secidx directive to
be recognized.
---
gcc/dwarf2codeview.cc | 303 ++++++++++++++++++++++++++++++++++++++++++
gcc/dwarf2codeview.h | 3 +
gcc/dwarf2out.cc | 9 ++
gcc/opts.cc | 2 +-
4 files changed, 316 insertions(+), 1 deletion(-)
diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc
index d93ba1ed668..4dfc0300177 100644
--- a/gcc/dwarf2codeview.cc
+++ b/gcc/dwarf2codeview.cc
@@ -37,11 +37,15 @@ along with GCC; see the file COPYING3. If not see
#define CV_SIGNATURE_C13 4
+#define DEBUG_S_LINES 0xf2
#define DEBUG_S_STRINGTABLE 0xf3
#define DEBUG_S_FILECHKSMS 0xf4
#define CHKSUM_TYPE_MD5 1
+#define LINE_LABEL "Lcvline"
+#define END_FUNC_LABEL "Lcvendfunc"
+
#define HASH_SIZE 16
struct codeview_string
@@ -89,11 +93,128 @@ struct codeview_source_file
uint8_t hash[HASH_SIZE];
};
+struct codeview_line
+{
+ codeview_line *next;
+ unsigned int line_no;
+ unsigned int label_num;
+};
+
+struct codeview_line_block
+{
+ codeview_line_block *next;
+ uint32_t file_id;
+ unsigned int num_lines;
+ codeview_line *lines, *last_line;
+};
+
+struct codeview_function
+{
+ codeview_function *next;
+ function *func;
+ unsigned int end_label;
+ codeview_line_block *blocks, *last_block;
+};
+
+static unsigned int line_label_num;
+static unsigned int func_label_num;
static codeview_source_file *files, *last_file;
static unsigned int num_files;
static uint32_t string_offset = 1;
static hash_table<string_hasher> *strings_htab;
static codeview_string *strings, *last_string;
+static codeview_function *funcs, *last_func;
+static const char* last_filename;
+static uint32_t last_file_id;
+
+/* Record new line number against the current function. */
+
+void
+codeview_source_line (unsigned int line_no, const char *filename)
+{
+ codeview_line *l;
+ uint32_t file_id = last_file_id;
+ unsigned int label_num = ++line_label_num;
+
+ targetm.asm_out.internal_label (asm_out_file, LINE_LABEL, label_num);
+
+ if (!last_func || last_func->func != cfun)
+ {
+ codeview_function *f = (codeview_function *)
+ xmalloc (sizeof (codeview_function));
+
+ f->next = NULL;
+ f->func = cfun;
+ f->end_label = 0;
+ f->blocks = f->last_block = NULL;
+
+ if (!funcs)
+ funcs = f;
+ else
+ last_func->next = f;
+
+ last_func = f;
+ }
+
+ if (filename != last_filename)
+ {
+ codeview_source_file *sf = files;
+
+ while (sf)
+ {
+ if (!strcmp (sf->filename, filename))
+ {
+ /* 0x18 is the size of the checksum entry for each file.
+ 0x6 bytes for the header, plus 0x10 bytes for the hash,
+ then padded to a multiple of 4. */
+
+ file_id = sf->file_num * 0x18;
+ last_filename = filename;
+ last_file_id = file_id;
+ break;
+ }
+
+ sf = sf->next;
+ }
+ }
+
+ if (!last_func->last_block || last_func->last_block->file_id != file_id)
+ {
+ codeview_line_block *b;
+
+ b = (codeview_line_block *) xmalloc (sizeof (codeview_line_block));
+
+ b->next = NULL;
+ b->file_id = file_id;
+ b->num_lines = 0;
+ b->lines = b->last_line = NULL;
+
+ if (!last_func->blocks)
+ last_func->blocks = b;
+ else
+ last_func->last_block->next = b;
+
+ last_func->last_block = b;
+ }
+
+ if (last_func->last_block->last_line
+ && last_func->last_block->last_line->line_no == line_no)
+ return;
+
+ l = (codeview_line *) xmalloc (sizeof (codeview_line));
+
+ l->next = NULL;
+ l->line_no = line_no;
+ l->label_num = label_num;
+
+ if (!last_func->last_block->lines)
+ last_func->last_block->lines = l;
+ else
+ last_func->last_block->last_line->next = l;
+
+ last_func->last_block->last_line = l;
+ last_func->last_block->num_lines++;
+}
/* Adds string to the string table, returning its offset. If already present,
this returns the offset of the existing string. */
@@ -288,6 +409,187 @@ write_source_files (void)
asm_fprintf (asm_out_file, "%LLcv_filechksms_end:\n");
}
+/* Write out the line number information for each function into the
+ .debug$S section. */
+
+static void
+write_line_numbers (void)
+{
+ unsigned int func_num = 0;
+
+ while (funcs)
+ {
+ codeview_function *next = funcs->next;
+ unsigned int first_label_num;
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, DEBUG_S_LINES);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ asm_fprintf (asm_out_file, "%LLcv_lines%u_end - %LLcv_lines%u_start\n",
+ func_num, func_num);
+
+ asm_fprintf (asm_out_file, "%LLcv_lines%u_start:\n", func_num);
+
+ /* Output the header (struct cv_lines_header in binutils or
+ CV_DebugSLinesHeader_t in Microsoft's cvinfo.h):
+
+ struct cv_lines_header
+ {
+ uint32_t offset;
+ uint16_t section;
+ uint16_t flags;
+ uint32_t length;
+ };
+ */
+
+ asm_fprintf (asm_out_file, "\t.secrel32\t%L" LINE_LABEL "%u\n",
+ funcs->blocks->lines->label_num);
+ asm_fprintf (asm_out_file, "\t.secidx\t%L" LINE_LABEL "%u\n",
+ funcs->blocks->lines->label_num);
+
+ /* flags */
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, 0);
+ putc ('\n', asm_out_file);
+
+ first_label_num = funcs->blocks->lines->label_num;
+
+ /* length */
+ fputs (integer_asm_op (4, false), asm_out_file);
+ asm_fprintf (asm_out_file,
+ "%L" END_FUNC_LABEL "%u - %L" LINE_LABEL "%u\n",
+ funcs->end_label, first_label_num);
+
+ while (funcs->blocks)
+ {
+ codeview_line_block *next = funcs->blocks->next;
+
+ /* Next comes the blocks, each block being a part of a function
+ within the same source file (struct cv_lines_block in binutils or
+ CV_DebugSLinesFileBlockHeader_t in Microsoft's cvinfo.h):
+
+ struct cv_lines_block
+ {
+ uint32_t file_id;
+ uint32_t num_lines;
+ uint32_t length;
+ };
+ */
+
+ /* file ID */
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, funcs->blocks->file_id);
+ putc ('\n', asm_out_file);
+
+ /* number of lines */
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, funcs->blocks->num_lines);
+ putc ('\n', asm_out_file);
+
+ /* length of code block: (num_lines * sizeof (struct cv_line)) +
+ sizeof (struct cv_lines_block) */
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, (funcs->blocks->num_lines * 0x8) + 0xc);
+ putc ('\n', asm_out_file);
+
+ while (funcs->blocks->lines)
+ {
+ codeview_line *next = funcs->blocks->lines->next;
+
+ /* Finally comes the line number information (struct cv_line in
+ binutils or CV_Line_t in Microsoft's cvinfo.h):
+
+ struct cv_line
+ {
+ uint32_t offset;
+ uint32_t line_no;
+ };
+
+ Strictly speaking line_no is a bitfield: the bottom 24 bits
+ are the line number, and the top bit means "is a statement".
+ */
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ asm_fprintf (asm_out_file,
+ "%L" LINE_LABEL "%u - %L" LINE_LABEL "%u\n",
+ funcs->blocks->lines->label_num, first_label_num);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file,
+ 0x80000000
+ | (funcs->blocks->lines->line_no & 0xffffff));
+ putc ('\n', asm_out_file);
+
+ free (funcs->blocks->lines);
+
+ funcs->blocks->lines = next;
+ }
+
+ free (funcs->blocks);
+
+ funcs->blocks = next;
+ }
+
+ free (funcs);
+
+ asm_fprintf (asm_out_file, "%LLcv_lines%u_end:\n", func_num);
+ func_num++;
+
+ funcs = next;
+ }
+}
+
+/* Treat cold sections as separate functions, for the purposes of line
+ numbers. */
+
+void
+codeview_switch_text_section (void)
+{
+ codeview_function *f;
+
+ if (last_func && last_func->end_label == 0)
+ {
+ unsigned int label_num = ++func_label_num;
+
+ targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL,
+ label_num);
+
+ last_func->end_label = label_num;
+ }
+
+ f = (codeview_function *) xmalloc (sizeof (codeview_function));
+
+ f->next = NULL;
+ f->func = cfun;
+ f->end_label = 0;
+ f->blocks = f->last_block = NULL;
+
+ if (!funcs)
+ funcs = f;
+ else
+ last_func->next = f;
+
+ last_func = f;
+}
+
+/* Mark the end of the current function. */
+
+void
+codeview_end_epilogue (void)
+{
+ if (last_func && last_func->end_label == 0)
+ {
+ unsigned int label_num = ++func_label_num;
+
+ targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL,
+ label_num);
+
+ last_func->end_label = label_num;
+ }
+}
+
/* Finish CodeView debug info emission. */
void
@@ -301,4 +603,5 @@ codeview_debug_finish (void)
write_strings_table ();
write_source_files ();
+ write_line_numbers ();
}
diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h
index e2d732bb9b6..b6421b62d2e 100644
--- a/gcc/dwarf2codeview.h
+++ b/gcc/dwarf2codeview.h
@@ -26,6 +26,9 @@ along with GCC; see the file COPYING3. If not see
/* Debug Format Interface. Used in dwarf2out.cc. */
extern void codeview_debug_finish (void);
+extern void codeview_source_line (unsigned int, const char *);
extern void codeview_start_source_file (const char *);
+extern void codeview_switch_text_section ();
+extern void codeview_end_epilogue (void);
#endif /* GCC_DWARF2CODEVIEW_H */
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 945176a91bc..c0ee99ffd40 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -1253,6 +1253,9 @@ dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
if (dwarf2out_do_cfi_asm ())
fprintf (asm_out_file, "\t.cfi_endproc\n");
+ if (codeview_debuginfo_p ())
+ codeview_end_epilogue ();
+
/* Output a label to mark the endpoint of the code generated for this
function. */
ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
@@ -1306,6 +1309,9 @@ dwarf2out_switch_text_section (void)
}
have_multiple_function_sections = true;
+ if (codeview_debuginfo_p ())
+ codeview_switch_text_section ();
+
if (dwarf2out_do_cfi_asm ())
fprintf (asm_out_file, "\t.cfi_endproc\n");
@@ -28603,6 +28609,9 @@ dwarf2out_source_line (unsigned int line, unsigned int column,
dw_line_info_table *table;
static var_loc_view lvugid;
+ if (codeview_debuginfo_p ())
+ codeview_source_line (line, filename);
+
/* 'line_info_table' information gathering is not needed when the debug
info level is set to the lowest value. Also, the current DWARF-based
debug formats do not use this info. */
diff --git a/gcc/opts.cc b/gcc/opts.cc
index f02101ceea3..6e91b1e0ff9 100644
--- a/gcc/opts.cc
+++ b/gcc/opts.cc
@@ -1364,7 +1364,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
opts->x_debug_nonbind_markers_p
= (opts->x_optimize
&& opts->x_debug_info_level >= DINFO_LEVEL_NORMAL
- && dwarf_debuginfo_p (opts)
+ && (dwarf_debuginfo_p (opts) || codeview_debuginfo_p ())
&& !(opts->x_flag_selective_scheduling
|| opts->x_flag_selective_scheduling2));
--
2.41.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/5] Output S_COMPILE3 symbol in CodeView debug section
2023-10-23 0:55 [PATCH 1/5] Remove obsolete debugging formats from names list Mark Harmstone
` (2 preceding siblings ...)
2023-10-23 0:55 ` [PATCH 4/5] Output line numbers " Mark Harmstone
@ 2023-10-23 0:55 ` Mark Harmstone
2023-10-23 7:46 ` [PATCH 1/5] Remove obsolete debugging formats from names list Richard Biener
4 siblings, 0 replies; 8+ messages in thread
From: Mark Harmstone @ 2023-10-23 0:55 UTC (permalink / raw)
To: gcc-patches; +Cc: Mark Harmstone
Outputs the S_COMPILE3 symbol in the CodeView .debug$S debug section.
The DEBUG_S_SYMBOLS block added here makes up pretty much everything
that isn't data structures or line numbers; we add the S_COMPILE3 symbol
here to start it off.
This is a descriptive bit, the most interesting part of which is the
version of the compiler used.
---
gcc/dwarf2codeview.cc | 126 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc
index 4dfc0300177..a33be036951 100644
--- a/gcc/dwarf2codeview.cc
+++ b/gcc/dwarf2codeview.cc
@@ -37,14 +37,25 @@ along with GCC; see the file COPYING3. If not see
#define CV_SIGNATURE_C13 4
+#define DEBUG_S_SYMBOLS 0xf1
#define DEBUG_S_LINES 0xf2
#define DEBUG_S_STRINGTABLE 0xf3
#define DEBUG_S_FILECHKSMS 0xf4
#define CHKSUM_TYPE_MD5 1
+#define S_COMPILE3 0x113c
+
+#define CV_CFL_80386 0x03
+#define CV_CFL_X64 0xD0
+
+#define CV_CFL_C 0x00
+#define CV_CFL_CXX 0x01
+
#define LINE_LABEL "Lcvline"
#define END_FUNC_LABEL "Lcvendfunc"
+#define SYMBOL_START_LABEL "Lcvsymstart"
+#define SYMBOL_END_LABEL "Lcvsymend"
#define HASH_SIZE 16
@@ -118,6 +129,7 @@ struct codeview_function
static unsigned int line_label_num;
static unsigned int func_label_num;
+static unsigned int sym_label_num;
static codeview_source_file *files, *last_file;
static unsigned int num_files;
static uint32_t string_offset = 1;
@@ -590,6 +602,119 @@ codeview_end_epilogue (void)
}
}
+/* Return the CodeView constant for the selected architecture. */
+
+static uint16_t
+target_processor (void)
+{
+ if (TARGET_64BIT)
+ return CV_CFL_X64;
+ else
+ return CV_CFL_80386;
+}
+
+/* Return the CodeView constant for the language being used. */
+
+static uint32_t
+language_constant (void)
+{
+ const char *language_string = lang_hooks.name;
+
+ if (startswith (language_string, "GNU C++"))
+ return CV_CFL_CXX;
+ else if (startswith (language_string, "GNU C"))
+ return CV_CFL_C;
+
+ return 0;
+}
+
+/* Write a S_COMPILE3 symbol, which records the details of the compiler
+ being used. */
+
+static void
+write_compile3_symbol (void)
+{
+ unsigned int label_num = ++sym_label_num;
+
+ static const char compiler_name[] = "GCC ";
+
+ /* This is struct COMPILESYM3 in binutils and Microsoft's cvinfo.h:
+
+ struct COMPILESYM3
+ {
+ uint16_t length;
+ uint16_t type;
+ uint32_t flags;
+ uint16_t machine;
+ uint16_t frontend_major;
+ uint16_t frontend_minor;
+ uint16_t frontend_build;
+ uint16_t frontend_qfe;
+ uint16_t backend_major;
+ uint16_t backend_minor;
+ uint16_t backend_build;
+ uint16_t backend_qfe;
+ } ATTRIBUTE_PACKED;
+ */
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ asm_fprintf (asm_out_file,
+ "%L" SYMBOL_END_LABEL "%u - %L" SYMBOL_START_LABEL "%u\n",
+ label_num, label_num);
+
+ targetm.asm_out.internal_label (asm_out_file, SYMBOL_START_LABEL, label_num);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, S_COMPILE3);
+ putc ('\n', asm_out_file);
+
+ /* Microsoft has the flags as a bitfield, with the bottom 8 bits being the
+ language constant, and the reset being MSVC-specific stuff. */
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, language_constant ());
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, target_processor ());
+ putc ('\n', asm_out_file);
+
+ /* Write 8 uint16_ts for the frontend and backend versions. As with GAS, we
+ zero these, as it's easier to record the version in the compiler
+ string. */
+ for (unsigned int i = 0; i < 8; i++)
+ {
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, 0);
+ putc ('\n', asm_out_file);
+ }
+
+ ASM_OUTPUT_ASCII (asm_out_file, compiler_name, sizeof (compiler_name) - 1);
+ ASM_OUTPUT_ASCII (asm_out_file, version_string, strlen (version_string) + 1);
+
+ ASM_OUTPUT_ALIGN (asm_out_file, 2);
+
+ targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num);
+}
+
+/* Write the CodeView symbols into the .debug$S section. */
+
+static void
+write_codeview_symbols (void)
+{
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, DEBUG_S_SYMBOLS);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ asm_fprintf (asm_out_file, "%LLcv_syms_end - %LLcv_syms_start\n");
+
+ asm_fprintf (asm_out_file, "%LLcv_syms_start:\n");
+
+ write_compile3_symbol ();
+
+ asm_fprintf (asm_out_file, "%LLcv_syms_end:\n");
+}
+
/* Finish CodeView debug info emission. */
void
@@ -604,4 +729,5 @@ codeview_debug_finish (void)
write_strings_table ();
write_source_files ();
write_line_numbers ();
+ write_codeview_symbols ();
}
--
2.41.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/5] Remove obsolete debugging formats from names list
2023-10-23 0:55 [PATCH 1/5] Remove obsolete debugging formats from names list Mark Harmstone
` (3 preceding siblings ...)
2023-10-23 0:55 ` [PATCH 5/5] Output S_COMPILE3 symbol in CodeView debug section Mark Harmstone
@ 2023-10-23 7:46 ` Richard Biener
4 siblings, 0 replies; 8+ messages in thread
From: Richard Biener @ 2023-10-23 7:46 UTC (permalink / raw)
To: Mark Harmstone; +Cc: gcc-patches
On Mon, Oct 23, 2023 at 2:56 AM Mark Harmstone <mark@harmstone.com> wrote:
>
> STABS and xcoff have been removed, but are still in debug_type_names,
> which ought to match debug_type_masks. This results in the following
> minor bug with GCC 13:
>
> $ x86_64-pc-linux-gnu-gcc -gvms -c tmp.c
> cc1: error: target system does not support the ‘dwarf-2’ debug format
OK for trunk and branch.
Richard.
> ---
> gcc/opts.cc | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/opts.cc b/gcc/opts.cc
> index 573dcf8e497..8015cb7556a 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", "stabs", "dwarf-2", "xcoff", "vms", "ctf", "btf"
> + "none", "dwarf-2", "vms", "ctf", "btf"
> };
>
> /* Bitmasks of fundamental debug info formats indexed by enum
> @@ -65,7 +65,7 @@ static uint32_t debug_type_masks[] =
> /* Names of the set of debug formats requested by user. Updated and accessed
> via debug_set_names. */
>
> -static char df_set_names[sizeof "none stabs dwarf-2 xcoff vms ctf btf"];
> +static char df_set_names[sizeof "none dwarf-2 vms ctf btf"];
>
> /* Get enum debug_info_type of the specified debug format, for error messages.
> Can be used only for individual debug format types. */
> --
> 2.41.0
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/5] Support for CodeView debugging format
2023-10-23 0:55 ` [PATCH 2/5] Support for CodeView debugging format Mark Harmstone
@ 2023-10-26 9:35 ` Richard Biener
2023-10-26 22:23 ` Mark Harmstone
0 siblings, 1 reply; 8+ messages in thread
From: Richard Biener @ 2023-10-26 9:35 UTC (permalink / raw)
To: Mark Harmstone; +Cc: gcc-patches
On Mon, Oct 23, 2023 at 2:57 AM Mark Harmstone <mark@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
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/5] Support for CodeView debugging format
2023-10-26 9:35 ` Richard Biener
@ 2023-10-26 22:23 ` Mark Harmstone
0 siblings, 0 replies; 8+ messages in thread
From: Mark Harmstone @ 2023-10-26 22:23 UTC (permalink / raw)
To: Richard Biener; +Cc: gcc-patches
On 26/10/23 10:35, Richard Biener wrote:
> On Mon, Oct 23, 2023 at 2:57 AM Mark Harmstone <mark@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?
This isn't comprehensive, I'm just adding line number info first. CodeView is as
fully featured as DWARF.
> 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.
Thanks, I'll bear that in mind once I get to coding the bits for type declarations.
Types are stored in the .debug$T section, as opposed to the .debug$S section dealt
with here, so it might turn out that we'll need to deal with the two sections in
different ways.
Mark
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-10-26 22:23 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-23 0:55 [PATCH 1/5] Remove obsolete debugging formats from names list Mark Harmstone
2023-10-23 0:55 ` [PATCH 2/5] Support for CodeView debugging format Mark Harmstone
2023-10-26 9:35 ` Richard Biener
2023-10-26 22:23 ` Mark Harmstone
2023-10-23 0:55 ` [PATCH 3/5] Output file checksums in CodeView section Mark Harmstone
2023-10-23 0:55 ` [PATCH 4/5] Output line numbers " Mark Harmstone
2023-10-23 0:55 ` [PATCH 5/5] Output S_COMPILE3 symbol in CodeView debug section Mark Harmstone
2023-10-23 7:46 ` [PATCH 1/5] Remove obsolete debugging formats from names list Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).