From patchwork Tue Jun 18 00:17:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 1948912 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; secure) header.d=harmstone.com header.i=@harmstone.com header.a=rsa-sha256 header.s=mail header.b=5ZoLbFNJ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4W36tm1n2Jz20KL for ; Tue, 18 Jun 2024 10:24:00 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 496013882075 for ; Tue, 18 Jun 2024 00:23:58 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.burntcomma.com (mail.burntcomma.com [IPv6:2a02:8012:8cf0:250::6d61:696c]) by sourceware.org (Postfix) with ESMTPS id AB94F3882064 for ; Tue, 18 Jun 2024 00:17:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB94F3882064 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=harmstone.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=harmstone.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AB94F3882064 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a02:8012:8cf0:250::6d61:696c ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1718669921; cv=none; b=jwJNUE6L+iQc4e7c6ARCG+0A3eqQ7ToOmL6k2dyu6gDxXKavRaLEvo5p1/ITf3nf42vuq/ADYiEs9z0JNQLu/sSdSNq+GK1PZrrey5dH0BL79Q1AN9NU2sr6K2kIW07y8Le52iv7pnMZJ7EllW4qz3hKNeSo56aA0a8idfifJi4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1718669921; c=relaxed/simple; bh=699AwdBceK/rxqcppm2QSov6TzoTlZguSeVBWomnv7Y=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:Mime-Version; b=Z75fPIojIdvQzTpIgZ3ejcGp3UdQWM/7uCZNlqSpfejrVf4lYJItJRCJmCW6uQSbHdv4kqYqj45NVR0VTIHJJwnnCdfkLmVpFxQXQQBrM9vX3hKrOjfCUM8wrmk5g6eoo2+ocaVNjxmBac/m1g8ewv35XfLVUVs/gqyUI17NA08= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from localhost.localdomain (beren.burntcomma.com [IPv6:2a02:8012:8cf0:0:b62e:99ff:fee9:ad9f]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (Client did not present a certificate) by mail.burntcomma.com (Postfix) with ESMTPSA id C147A3CF001E; Tue, 18 Jun 2024 01:17:21 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmstone.com; s=mail; t=1718669841; bh=YoJyWpnFE1QEuwIsWwzQHEAAkiTfCS+3GlJHvs5hP+4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=5ZoLbFNJZtniUAA2E2ueYwL8zjyVfrcIrBMgkkrbBFNRhZA7w9V4/5rLJu6tqQb0u 4/dJruceG3cMHfbx6r4Twn9FMsTx407fdXerTE0VLRxgI24E4nPnYnogMFEHQ/x7GE c2HIUhZF2IClG+cismExp2pjwaGRQhYr6NhO30/A= From: Mark Harmstone To: gcc-patches@gcc.gnu.org Cc: Mark Harmstone Subject: [PATCH 06/11] Handle enums for CodeView Date: Tue, 18 Jun 2024 01:17:08 +0100 Message-ID: <20240618001713.24034-7-mark@harmstone.com> In-Reply-To: <20240618001713.24034-1-mark@harmstone.com> References: <20240618001713.24034-1-mark@harmstone.com> Mime-Version: 1.0 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Translates DW_TAG_enumeration_type DIEs into LF_ENUM symbols. gcc/ * dwarf2codeview.cc (MAX_FIELDLIST_SIZE): Define. (struct codeview_integer): New structure. (struct codeview_subtype): Likewise (struct codeview_custom_type): Add lf_fieldlist and lf_enum to union. (write_cv_integer, cv_integer_len): New functions. (write_lf_fieldlist, write_lf_enum): Likewise. (write_custom_types): Call write_lf_fieldlist and write_lf_enum. (add_enum_forward_def): New function. (get_type_num_enumeration_type): Likewise. (get_type_num): Handle DW_TAG_enumeration_type DIEs. * dwarf2codeview.h (LF_FIELDLIST, LF_INDEX, LF_ENUMERATE): Define. (LF_ENUM, LF_CHAR, LF_SHORT, LF_USHORT, LF_LONG): Likewise. (LF_ULONG, LF_QUADWORD, LF_UQUADWORD): Likewise. (CV_ACCESS_PRIVATE, CV_ACCESS_PROTECTED): Likewise. (CV_ACCESS_PUBLIC, CV_PROP_FWDREF): Likewise. --- gcc/dwarf2codeview.cc | 524 ++++++++++++++++++++++++++++++++++++++++++ gcc/dwarf2codeview.h | 17 ++ 2 files changed, 541 insertions(+) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index 05f5f60997e..475a53573e9 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -63,6 +63,11 @@ along with GCC; see the file COPYING3. If not see #define SYMBOL_START_LABEL "Lcvsymstart" #define SYMBOL_END_LABEL "Lcvsymend" +/* There's two bytes available for each type's size, but follow MSVC's lead in + capping the LF_FIELDLIST size at fb00 (minus 8 bytes for the LF_INDEX + pointing to the overflow entry). */ +#define MAX_FIELDLIST_SIZE 0xfaf8 + #define HASH_SIZE 16 struct codeview_string @@ -170,6 +175,31 @@ struct die_hasher : free_ptr_hash } }; +struct codeview_integer +{ + bool neg; + uint64_t num; +}; + +struct codeview_subtype +{ + struct codeview_subtype *next; + uint16_t kind; + + union + { + struct + { + char *name; + struct codeview_integer value; + } lf_enumerate; + struct + { + uint32_t type_num; + } lf_index; + }; +}; + struct codeview_custom_type { struct codeview_custom_type *next; @@ -188,6 +218,20 @@ struct codeview_custom_type uint32_t base_type; uint16_t modifier; } lf_modifier; + struct + { + size_t length; + codeview_subtype *subtypes; + codeview_subtype *last_subtype; + } lf_fieldlist; + struct + { + uint16_t count; + uint16_t properties; + uint32_t underlying_type; + uint32_t fieldlist; + char *name; + } lf_enum; }; }; @@ -978,6 +1022,292 @@ write_lf_modifier (codeview_custom_type *t) asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num); } +/* Write a CodeView extensible integer. If the value is non-negative and + < 0x8000, the value gets written directly as an uint16_t. Otherwise, we + output two bytes for the integer type (LF_CHAR, LF_SHORT, ...), and the + actual value follows. */ + +static size_t +write_cv_integer (codeview_integer *i) +{ + if (i->neg) + { + if (i->num <= 0x80) + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_CHAR); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (1, false), asm_out_file); + fprint_whex (asm_out_file, -i->num); + putc ('\n', asm_out_file); + + return 3; + } + else if (i->num <= 0x8000) + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_SHORT); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, -i->num); + putc ('\n', asm_out_file); + + return 4; + } + else if (i->num <= 0x80000000) + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_LONG); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, -i->num); + putc ('\n', asm_out_file); + + return 6; + } + else + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_QUADWORD); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (8, false), asm_out_file); + fprint_whex (asm_out_file, -i->num); + putc ('\n', asm_out_file); + + return 10; + } + } + else + { + if (i->num <= 0x7fff) + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, i->num); + putc ('\n', asm_out_file); + + return 2; + } + else if (i->num <= 0xffff) + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_USHORT); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, i->num); + putc ('\n', asm_out_file); + + return 4; + } + else if (i->num <= 0xffffffff) + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_ULONG); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, i->num); + putc ('\n', asm_out_file); + + return 6; + } + else + { + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_UQUADWORD); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (8, false), asm_out_file); + fprint_whex (asm_out_file, i->num); + putc ('\n', asm_out_file); + + return 10; + } + } +} + +/* Return the extra size needed for an extensible integer. */ + +static size_t +cv_integer_len (codeview_integer *i) +{ + if (i->neg) + { + if (i->num <= 0x80) + return sizeof (int8_t); + else if (i->num <= 0x8000) + return sizeof (int16_t); + else if (i->num <= 0x80000000) + return sizeof (int32_t); + else + return sizeof (int64_t); + } + else + { + if (i->num <= 0x7fff) + return 0; + else if (i->num <= 0xffff) + return sizeof (uint16_t); + else if (i->num <= 0xffffffff) + return sizeof (uint32_t); + else + return sizeof (uint64_t); + } +} + +/* Write an LF_FIELDLIST type, which is a container for various subtypes. This + has two uses: for the values in an enum, and for the member, operators etc. + for a struct, class, or union. */ + +static void +write_lf_fieldlist (codeview_custom_type *t) +{ + 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); + + while (t->lf_fieldlist.subtypes) + { + codeview_subtype *v = t->lf_fieldlist.subtypes; + codeview_subtype *next = v->next; + size_t name_len, leaf_len; + + switch (v->kind) + { + case LF_ENUMERATE: + /* This is lf_enumerate in binutils and lfEnumerate in Microsoft's + cvinfo.h: + + struct lf_enumerate + { + uint16_t kind; + uint16_t attributes; + uint16_t value; + (then actual value if value >= 0x8000) + char name[]; + } ATTRIBUTE_PACKED; + */ + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_ENUMERATE); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, CV_ACCESS_PUBLIC); + putc ('\n', asm_out_file); + + leaf_len = 4 + write_cv_integer (&v->lf_enumerate.value); + + name_len = strlen (v->lf_enumerate.name) + 1; + ASM_OUTPUT_ASCII (asm_out_file, v->lf_enumerate.name, name_len); + + leaf_len += name_len; + write_cv_padding (4 - (leaf_len % 4)); + + free (v->lf_enumerate.name); + break; + + case LF_INDEX: + /* This is lf_index in binutils and lfIndex in Microsoft's cvinfo.h: + + struct lf_index + { + uint16_t kind; + uint16_t padding; + uint32_t index; + } ATTRIBUTE_PACKED; + */ + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, LF_INDEX); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, 0); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, v->lf_index.type_num); + putc ('\n', asm_out_file); + + break; + } + + t->lf_fieldlist.subtypes = next; + free (v); + } + + asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num); +} + +/* Write an LF_ENUM type. */ + +static void +write_lf_enum (codeview_custom_type *t) +{ + size_t name_len, leaf_len; + + /* This is lf_enum in binutils and lfEnum in Microsoft's cvinfo.h: + + struct lf_enum + { + uint16_t size; + uint16_t kind; + uint16_t num_elements; + uint16_t properties; + uint32_t underlying_type; + uint32_t field_list; + char name[]; + } 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 (2, false), asm_out_file); + fprint_whex (asm_out_file, t->lf_enum.count); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, t->lf_enum.properties); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, t->lf_enum.underlying_type); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, t->lf_enum.fieldlist); + putc ('\n', asm_out_file); + + name_len = strlen (t->lf_enum.name) + 1; + ASM_OUTPUT_ASCII (asm_out_file, t->lf_enum.name, name_len); + + leaf_len = 14 + name_len; + write_cv_padding (4 - (leaf_len % 4)); + + free (t->lf_enum.name); + + 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. */ @@ -1003,6 +1333,14 @@ write_custom_types (void) case LF_MODIFIER: write_lf_modifier (custom_types); break; + + case LF_FIELDLIST: + write_lf_fieldlist (custom_types); + break; + + case LF_ENUM: + write_lf_enum (custom_types); + break; } free (custom_types); @@ -1308,6 +1646,188 @@ get_type_num_volatile_type (dw_die_ref type) return ct->num; } +/* Add a forward declaration for an enum. This is legal from C++11 onwards. */ + +static uint32_t +add_enum_forward_def (dw_die_ref type) +{ + codeview_custom_type *ct; + + ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type)); + + ct->next = NULL; + ct->kind = LF_ENUM; + + ct->lf_enum.count = 0; + ct->lf_enum.properties = CV_PROP_FWDREF; + ct->lf_enum.underlying_type = get_type_num (get_AT_ref (type, DW_AT_type)); + ct->lf_enum.fieldlist = 0; + ct->lf_enum.name = xstrdup (get_AT_string (type, DW_AT_name)); + + add_custom_type (ct); + + return ct->num; +} + +/* Process a DW_TAG_enumeration_type DIE, adding an LF_FIELDLIST and an LF_ENUM + type, returning the number of the latter. */ + +static uint32_t +get_type_num_enumeration_type (dw_die_ref type) +{ + dw_die_ref first_child; + codeview_custom_type *ct; + uint16_t count = 0; + uint32_t last_type; + + if (get_AT_flag (type, DW_AT_declaration)) + return add_enum_forward_def (type); + + /* First, add an LF_FIELDLIST for the enum's values. We don't need to worry + about deduplication here, as ld will take care of that for us. If there's + a lot of entries, add more LF_FIELDLISTs with LF_INDEXes pointing to + the overflow lists. */ + + first_child = dw_get_die_child (type); + + ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type)); + + ct->next = NULL; + ct->kind = LF_FIELDLIST; + ct->lf_fieldlist.length = 0; + ct->lf_fieldlist.subtypes = NULL; + ct->lf_fieldlist.last_subtype = NULL; + + if (first_child) + { + dw_die_ref c; + + c = first_child; + do + { + dw_attr_node *att; + codeview_subtype *el; + size_t el_len; + + c = dw_get_die_sib (c); + + if (dw_get_die_tag (c) != DW_TAG_enumerator) + continue; + + att = get_AT (c, DW_AT_const_value); + if (!att) + continue; + + el = (codeview_subtype *) xmalloc (sizeof (*el)); + el->next = NULL; + el->kind = LF_ENUMERATE; + + switch (AT_class (att)) + { + case dw_val_class_unsigned_const: + case dw_val_class_unsigned_const_implicit: + el->lf_enumerate.value.neg = false; + el->lf_enumerate.value.num = att->dw_attr_val.v.val_unsigned; + break; + + case dw_val_class_const: + case dw_val_class_const_implicit: + if (att->dw_attr_val.v.val_int < 0) + { + el->lf_enumerate.value.neg = true; + el->lf_enumerate.value.num = -att->dw_attr_val.v.val_int; + } + else + { + el->lf_enumerate.value.neg = false; + el->lf_enumerate.value.num = att->dw_attr_val.v.val_int; + } + break; + + default: + free (el); + continue; + } + + el->lf_enumerate.name = xstrdup (get_AT_string (c, DW_AT_name)); + + el_len = 7 + strlen (el->lf_enumerate.name); + el_len += cv_integer_len (&el->lf_enumerate.value); + + if (el_len % 4) + el_len += 4 - (el_len % 4); + + if (ct->lf_fieldlist.length + el_len > MAX_FIELDLIST_SIZE) + { + codeview_subtype *idx; + codeview_custom_type *ct2; + + idx = (codeview_subtype *) xmalloc (sizeof (*idx)); + idx->next = NULL; + idx->kind = LF_INDEX; + idx->lf_index.type_num = 0; + + ct->lf_fieldlist.last_subtype->next = idx; + ct->lf_fieldlist.last_subtype = idx; + + ct2 = (codeview_custom_type *) + xmalloc (sizeof (codeview_custom_type)); + + ct2->next = ct; + ct2->kind = LF_FIELDLIST; + ct2->lf_fieldlist.length = 0; + ct2->lf_fieldlist.subtypes = NULL; + ct2->lf_fieldlist.last_subtype = NULL; + + ct = ct2; + } + + ct->lf_fieldlist.length += el_len; + + if (ct->lf_fieldlist.last_subtype) + ct->lf_fieldlist.last_subtype->next = el; + else + ct->lf_fieldlist.subtypes = el; + + ct->lf_fieldlist.last_subtype = el; + count++; + } + while (c != first_child); + } + + while (ct) + { + codeview_custom_type *ct2; + + ct2 = ct->next; + ct->next = NULL; + + if (ct->lf_fieldlist.last_subtype->kind == LF_INDEX) + ct->lf_fieldlist.last_subtype->lf_index.type_num = last_type; + + add_custom_type (ct); + last_type = ct->num; + + ct = ct2; + } + + /* Now add an LF_ENUM, pointing to the LF_FIELDLIST we just added. */ + + ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type)); + + ct->next = NULL; + ct->kind = LF_ENUM; + ct->lf_enum.count = count; + ct->lf_enum.properties = 0; + ct->lf_enum.underlying_type = get_type_num (get_AT_ref (type, DW_AT_type)); + ct->lf_enum.fieldlist = last_type; + ct->lf_enum.name = xstrdup (get_AT_string (type, DW_AT_name)); + + 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 @@ -1358,6 +1878,10 @@ get_type_num (dw_die_ref type) t->num = get_type_num_volatile_type (type); break; + case DW_TAG_enumeration_type: + t->num = get_type_num_enumeration_type (type); + break; + default: t->num = 0; break; diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h index d48cfbebc32..3f3695625c4 100644 --- a/gcc/dwarf2codeview.h +++ b/gcc/dwarf2codeview.h @@ -63,6 +63,23 @@ along with GCC; see the file COPYING3. If not see /* Constants for type definitions. */ #define LF_MODIFIER 0x1001 #define LF_POINTER 0x1002 +#define LF_FIELDLIST 0x1203 +#define LF_INDEX 0x1404 +#define LF_ENUMERATE 0x1502 +#define LF_ENUM 0x1507 +#define LF_CHAR 0x8000 +#define LF_SHORT 0x8001 +#define LF_USHORT 0x8002 +#define LF_LONG 0x8003 +#define LF_ULONG 0x8004 +#define LF_QUADWORD 0x8009 +#define LF_UQUADWORD 0x800a + +#define CV_ACCESS_PRIVATE 1 +#define CV_ACCESS_PROTECTED 2 +#define CV_ACCESS_PUBLIC 3 + +#define CV_PROP_FWDREF 0x80 /* Debug Format Interface. Used in dwarf2out.cc. */