aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2codeview.cc
diff options
context:
space:
mode:
authorMark Harmstone <mark@harmstone.com>2024-05-11 08:24:59 -0600
committerJeff Law <jlaw@ventanamicro.com>2024-05-11 08:24:59 -0600
commit1da83fece2963cfe0df57ac5e85dd1f92427ca70 (patch)
tree0972479372fb2397b1ccac772904881554403b9f /gcc/dwarf2codeview.cc
parent1f129e5e2b74c20a757f2809792af229b551b09b (diff)
downloadgcc-1da83fece2963cfe0df57ac5e85dd1f92427ca70.zip
gcc-1da83fece2963cfe0df57ac5e85dd1f92427ca70.tar.gz
gcc-1da83fece2963cfe0df57ac5e85dd1f92427ca70.tar.bz2
[PATCH v4 4/4] Output S_COMPILE3 symbol in CodeView debug section
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 (DEBUG_S_SYMBOLS): Define. (S_COMPILE3, CV_CFL_80386, CV_CFL_X64): Likewise. (CV_CFL_C, CV_CFL_CXX): Likewise. (SYMBOL_START_LABEL, SYMBOL_END_LABEL): Likewise. (start_processor, language_constant): New functions. (write_compile3_symbol, write_codeview_symbols): Likewise. (codeview_debug_finish): Call write_codeview_symbols.
Diffstat (limited to 'gcc/dwarf2codeview.cc')
-rw-r--r--gcc/dwarf2codeview.cc126
1 files changed, 126 insertions, 0 deletions
diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc
index 9c69ebf..db776d7 100644
--- a/gcc/dwarf2codeview.cc
+++ b/gcc/dwarf2codeview.cc
@@ -39,14 +39,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
@@ -120,6 +131,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;
@@ -592,6 +604,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
@@ -606,6 +731,7 @@ codeview_debug_finish (void)
write_strings_table ();
write_source_files ();
write_line_numbers ();
+ write_codeview_symbols ();
}
#endif