From: Mark Harmstone <mark@harmstone.com>
To: gcc-patches@gcc.gnu.org
Cc: Mark Harmstone <mark@harmstone.com>
Subject: [PATCH 04/11] Handle pointers for CodeView
Date: Tue, 18 Jun 2024 01:17:06 +0100 [thread overview]
Message-ID: <20240618001713.24034-5-mark@harmstone.com> (raw)
In-Reply-To: <20240618001713.24034-1-mark@harmstone.com>
Translates DW_TAG_pointer_type DIEs into LF_POINTER symbols, which get
output into the .debug$T section.
gcc/
* dwarf2codeview.cc (FIRST_TYPE): Define.
(struct codeview_custom_type): New structure.
(custom_types, last_custom_type): New variables.
(get_type_num): Prototype.
(write_lf_pointer, write_custom_types): New functions.
(codeview_debug_finish): Call write_custom_types.
(add_custom_type, get_type_num_pointer_type): New functions.
(get_type_num): Handle DW_TAG_pointer_type DIEs.
* dwarf2codeview.h (T_VOID): Define.
(CV_POINTER_32, CV_POINTER_64): Likewise.
(T_32PVOID, T_64PVOID): Likewise.
(CV_PTR_NEAR32, CV_PTR64, LF_POINTER): Likewise.
---
gcc/dwarf2codeview.cc | 179 +++++++++++++++++++++++++++++++++++++++++-
gcc/dwarf2codeview.h | 13 +++
2 files changed, 188 insertions(+), 4 deletions(-)
diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc
index 5006a176260..51401f2d5bc 100644
--- a/gcc/dwarf2codeview.cc
+++ b/gcc/dwarf2codeview.cc
@@ -56,6 +56,8 @@ along with GCC; see the file COPYING3. If not see
#define CV_CFL_C 0x00
#define CV_CFL_CXX 0x01
+#define FIRST_TYPE 0x1000
+
#define LINE_LABEL "Lcvline"
#define END_FUNC_LABEL "Lcvendfunc"
#define SYMBOL_START_LABEL "Lcvsymstart"
@@ -168,6 +170,22 @@ struct die_hasher : free_ptr_hash <codeview_type>
}
};
+struct codeview_custom_type
+{
+ struct codeview_custom_type *next;
+ uint32_t num;
+ uint16_t kind;
+
+ union
+ {
+ struct
+ {
+ uint32_t base_type;
+ uint32_t attributes;
+ } lf_pointer;
+ };
+};
+
static unsigned int line_label_num;
static unsigned int func_label_num;
static unsigned int sym_label_num;
@@ -181,6 +199,9 @@ static const char* last_filename;
static uint32_t last_file_id;
static codeview_symbol *sym, *last_sym;
static hash_table<die_hasher> *types_htab;
+static codeview_custom_type *custom_types, *last_custom_type;
+
+static uint32_t get_type_num (dw_die_ref type);
/* Record new line number against the current function. */
@@ -845,6 +866,71 @@ write_codeview_symbols (void)
asm_fprintf (asm_out_file, "%LLcv_syms_end:\n");
}
+/* Write an LF_POINTER type. */
+
+static void
+write_lf_pointer (codeview_custom_type *t)
+{
+ /* This is lf_pointer in binutils and lfPointer in Microsoft's cvinfo.h:
+
+ struct lf_pointer
+ {
+ uint16_t size;
+ uint16_t kind;
+ uint32_t base_type;
+ uint32_t attributes;
+ } ATTRIBUTE_PACKED;
+ */
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
+ t->num, t->num);
+
+ asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, t->kind);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_pointer.base_type);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_pointer.attributes);
+ putc ('\n', asm_out_file);
+
+ asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
+}
+
+/* Write the .debug$T section, which contains all of our custom type
+ definitions. */
+
+static void
+write_custom_types (void)
+{
+ targetm.asm_out.named_section (".debug$T", 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);
+
+ while (custom_types)
+ {
+ codeview_custom_type *n = custom_types->next;
+
+ switch (custom_types->kind)
+ {
+ case LF_POINTER:
+ write_lf_pointer (custom_types);
+ break;
+ }
+
+ free (custom_types);
+ custom_types = n;
+ }
+}
+
/* Finish CodeView debug info emission. */
void
@@ -861,6 +947,9 @@ codeview_debug_finish (void)
write_line_numbers ();
write_codeview_symbols ();
+ if (custom_types)
+ write_custom_types ();
+
if (types_htab)
delete types_htab;
}
@@ -993,10 +1082,88 @@ get_type_num_base_type (dw_die_ref type)
}
}
-/* Process a DIE representing a type definition and return its number. If
- it's something we can't handle, return 0. We keep a hash table so that
- we're not adding the same type multiple times - though if we do it's not
- disastrous, as ld will deduplicate everything for us. */
+/* Add a new codeview_custom_type to our singly-linked custom_types list. */
+
+static void
+add_custom_type (codeview_custom_type *ct)
+{
+ uint32_t num;
+
+ if (last_custom_type)
+ {
+ num = last_custom_type->num + 1;
+ last_custom_type->next = ct;
+ }
+ else
+ {
+ num = FIRST_TYPE;
+ custom_types = ct;
+ }
+
+ last_custom_type = ct;
+
+ ct->num = num;
+}
+
+/* Process a DW_TAG_pointer_type DIE. If this is a pointer to a builtin
+ type, return the predefined constant for this. Otherwise, add a new
+ LF_POINTER type and return its number. */
+
+static uint32_t
+get_type_num_pointer_type (dw_die_ref type)
+{
+ uint32_t base_type_num, byte_size;
+ dw_die_ref base_type;
+ codeview_custom_type *ct;
+
+ byte_size = get_AT_unsigned (type, DW_AT_byte_size);
+ if (byte_size != 4 && byte_size != 8)
+ return 0;
+
+ base_type = get_AT_ref (type, DW_AT_type);
+
+ /* If DW_AT_type is not set, this must be a void pointer. */
+ if (!base_type)
+ return byte_size == 4 ? T_32PVOID : T_64PVOID;
+
+ base_type_num = get_type_num (base_type);
+ if (base_type_num == 0)
+ return 0;
+
+ /* Pointers to builtin types have predefined type numbers, with the top byte
+ determining the pointer size - 0x0400 for a 32-bit pointer and 0x0600
+ for 64-bit. */
+ if (base_type_num < FIRST_TYPE && !(base_type_num & 0xff00))
+ {
+ if (byte_size == 4)
+ return CV_POINTER_32 | base_type_num;
+ else
+ return CV_POINTER_64 | base_type_num;
+ }
+
+ ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
+
+ ct->next = NULL;
+ ct->kind = LF_POINTER;
+ ct->lf_pointer.base_type = base_type_num;
+
+ if (byte_size == 4)
+ ct->lf_pointer.attributes = CV_PTR_NEAR32;
+ else
+ ct->lf_pointer.attributes = CV_PTR_64;
+
+ ct->lf_pointer.attributes |= byte_size << 13;
+
+ add_custom_type (ct);
+
+ return ct->num;
+}
+
+/* Process a DIE representing a type definition, add a CodeView type if
+ necessary, and return its number. If it's something we can't handle, return
+ 0. We keep a hash table so that we're not adding the same type multiple
+ times - though if we do it's not disastrous, as ld will deduplicate
+ everything for us. */
static uint32_t
get_type_num (dw_die_ref type)
@@ -1030,6 +1197,10 @@ get_type_num (dw_die_ref type)
t->num = get_type_num (get_AT_ref (type, DW_AT_type));
break;
+ case DW_TAG_pointer_type:
+ t->num = get_type_num_pointer_type (type);
+ break;
+
default:
t->num = 0;
break;
diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h
index 7d8a4c161f4..0af4c98250f 100644
--- a/gcc/dwarf2codeview.h
+++ b/gcc/dwarf2codeview.h
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
/* Constants for in-built types. */
+#define T_VOID 0x0003
#define T_CHAR 0x0010
#define T_SHORT 0x0011
#define T_LONG 0x0012
@@ -46,6 +47,18 @@ along with GCC; see the file COPYING3. If not see
#define T_CHAR32 0x007b
#define T_CHAR8 0x007c
+#define CV_POINTER_32 0x0400
+#define CV_POINTER_64 0x0600
+#define T_32PVOID (T_VOID | CV_POINTER_32)
+#define T_64PVOID (T_VOID | CV_POINTER_64)
+
+/* LF_POINTER attributes. */
+#define CV_PTR_NEAR32 0x0a
+#define CV_PTR_64 0x0c
+
+/* Constants for type definitions. */
+#define LF_POINTER 0x1002
+
/* Debug Format Interface. Used in dwarf2out.cc. */
extern void codeview_debug_finish (void);
--
2.44.2
next prev parent reply other threads:[~2024-06-18 0:17 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-18 0:17 [PATCH 00/11] CodeView variables and type system Mark Harmstone
2024-06-18 0:17 ` [PATCH 01/11] Output CodeView data about variables Mark Harmstone
2024-06-23 23:50 ` Jeff Law
2024-06-18 0:17 ` [PATCH 02/11] Handle CodeView base types Mark Harmstone
2024-06-24 0:18 ` Jeff Law
2024-06-18 0:17 ` [PATCH 03/11] Handle typedefs for CodeView Mark Harmstone
2024-06-24 0:30 ` Jeff Law
2024-06-18 0:17 ` Mark Harmstone [this message]
2024-06-24 3:31 ` [PATCH 04/11] Handle pointers " Jeff Law
2024-06-18 0:17 ` [PATCH 05/11] Handle const and varible modifiers " Mark Harmstone
2024-06-24 3:39 ` Jeff Law
2024-06-25 2:49 ` Mark Harmstone
2024-06-25 5:42 ` Jeff Law
2024-06-18 0:17 ` [PATCH 06/11] Handle enums " Mark Harmstone
2024-06-24 3:49 ` Jeff Law
2024-06-18 0:17 ` [PATCH 07/11] Handle structs and classes " Mark Harmstone
2024-06-25 5:40 ` Jeff Law
2024-06-18 0:17 ` [PATCH 08/11] Handle unions " Mark Harmstone
2024-06-25 23:29 ` Jeff Law
2024-06-18 0:17 ` [PATCH 09/11] Handle arrays " Mark Harmstone
2024-06-25 23:32 ` Jeff Law
2024-06-18 0:17 ` [PATCH 10/11] Handle bitfields " Mark Harmstone
2024-06-26 2:21 ` Jeff Law
2024-06-18 0:17 ` [PATCH 11/11] Handle subroutine types in CodeView Mark Harmstone
2024-06-26 2:27 ` Jeff Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240618001713.24034-5-mark@harmstone.com \
--to=mark@harmstone.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).