From patchwork Mon Aug 19 01:15:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 1973631 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=U/ojcm6n; 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 4WnF7T3Zbcz1yXg for ; Mon, 19 Aug 2024 11:17:09 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4CDC2384DEFC for ; Mon, 19 Aug 2024 01:17:07 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.burntcomma.com (mail2.burntcomma.com [217.169.27.34]) by sourceware.org (Postfix) with ESMTPS id 47139386182F for ; Mon, 19 Aug 2024 01:15:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 47139386182F 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 47139386182F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.169.27.34 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724030143; cv=none; b=ThhcUyLw3h+EINn1qd8gvPhBIR2lx4l1F86KNIfoa26fg2DiuMGaUKzsIciH9POdivVxwOB3iDgombc88AWiA9C2em1PPq5nm9Z35vRW/cIOuYjf4QeNWDeSBauLab8DtTkS0SIaJnWI1/f7tKs507ORdZwdRtmADhD8c+6nXbQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724030143; c=relaxed/simple; bh=tNWWgw1xXovOKLFu8JMmj5xTYqtpFGRX/t/tVQQeiCw=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:Mime-Version; b=XDpOmmdyqPu+MFLl6yfbz5pnKVs7dx2wXMywYP95pTfNX2JevhySlz0wmm9Rej2e4UHkImz3fYjFhT8OZAxMbqdYra/weH24eNQ7YOq4E5+h6Brb2CbZQcJ55iLO3ijGgE4T43okojMVkYrSSjjarif4W+vudUuiGsUWbebz9mY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from localhost.localdomain (mail2.burntcomma.com [217.169.27.34]) (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 BC050A06A7; Mon, 19 Aug 2024 02:15:34 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmstone.com; s=mail; t=1724030135; bh=SrCmrM6FeEs4vsMprOikZttivW5wKT99h9lnoK+zifI=; h=From:To:Cc:Subject:Date; b=U/ojcm6nBCb6snvOleAF3NgGz02MXGGBucxFc4tEeLpIEEyRv3s7/mSeTi9przBLm gesWRizRucRLrfhB/YdR3ZtxlDI5YAt6K6Bp1JrJlmhTigcsQ52fE0KmvJnjmgKY+B 9GIwx0VFQX8A79/ptWXa5rl22sEoCrL5L84p0e30= From: Mark Harmstone To: gcc-patches@gcc.gnu.org Cc: Mark Harmstone Subject: [PATCH 1/4] Write CodeView information about enregistered optimized variables Date: Mon, 19 Aug 2024 02:15:27 +0100 Message-ID: <20240819011530.25488-1-mark@harmstone.com> Mime-Version: 1.0 X-Spam-Status: No, score=-11.9 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 Enable variable tracking when outputting CodeView debug information, and make it so that we issue debug symbols for optimized variables in registers. This consists of S_LOCAL symbols, which give the name and the type of local variables, followed by S_DEFRANGE_REGISTER symbols for the register and the code for which this applies. gcc/ * dwarf2codeview.cc (enum cv_sym_type): Add S_LOCAL and S_DEFRANGE_REGISTER. (write_s_local): New function. (write_defrange_register): New function. (write_optimized_local_variable_loc): New function. (write_optimized_local_variable): New function. (write_optimized_function_vars): New function. (write_function): Call write_optimized_function_vars if variable tracking enabled. * dwarf2out.cc (typedef var_loc_view): Move to dwarf2out.h. (struct dw_loc_list_struct): Likewise. * dwarf2out.h (typedef var_loc_view): Move from dwarf2out.cc. (struct dw_loc_list_struct): Likewise. * opts.cc (finish_options): Enable variable tracking for CodeView. --- gcc/dwarf2codeview.cc | 316 +++++++++++++++++++++++++++++++++++++++++- gcc/dwarf2out.cc | 37 ----- gcc/dwarf2out.h | 37 +++++ gcc/opts.cc | 2 +- 4 files changed, 353 insertions(+), 39 deletions(-) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index e01515a0ec4..15253978968 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -77,6 +77,8 @@ enum cv_sym_type { S_GDATA32 = 0x110d, S_REGREL32 = 0x1111, S_COMPILE3 = 0x113c, + S_LOCAL = 0x113e, + S_DEFRANGE_REGISTER = 0x1141, S_LPROC32_ID = 0x1146, S_GPROC32_ID = 0x1147, S_PROC_ID_END = 0x114f @@ -1946,6 +1948,56 @@ end: free (s->data_symbol.name); } +/* Write an S_LOCAL symbol, representing an optimized variable. This is then + followed by various S_DEFRANGE_* symbols, which describe how to find the + value of a variable and the range for which this is valid. */ + +static void +write_s_local (dw_die_ref die) +{ + unsigned int label_num = ++sym_label_num; + const char *name = get_AT_string (die, DW_AT_name); + uint32_t type; + + /* This is struct LOCALSYM in Microsoft's cvinfo.h: + + struct LOCALSYM { + uint16_t reclen; + uint16_t rectyp; + uint32_t typind; + uint16_t flags; + char name[]; + }; + */ + + 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_LOCAL); + putc ('\n', asm_out_file); + + type = get_type_num (get_AT_ref (die, DW_AT_type), false, false); + + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, type); + 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); + + ASM_OUTPUT_ASCII (asm_out_file, name, strlen (name) + 1); + + ASM_OUTPUT_ALIGN (asm_out_file, 2); + + targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num); +} + /* Write an S_LDATA32 symbol, representing a static variable within a function. This symbol can also appear outside of a function block - see write_data_symbol. */ @@ -2278,6 +2330,194 @@ write_fbreg_variable (dw_die_ref die, dw_loc_descr_ref loc_ref, targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num); } +/* Write an S_DEFRANGE_REGISTER symbol, which describes a range for which an + S_LOCAL variable is held in a certain register. */ + +static void +write_defrange_register (dw_loc_descr_ref expr, rtx range_start, rtx range_end) +{ + unsigned int label_num = ++sym_label_num; + uint16_t regno; + + /* This is defrange_register in binutils and DEFRANGESYMREGISTER in + Microsoft's cvinfo.h: + + struct lvar_addr_range + { + uint32_t offset; + uint16_t section; + uint16_t length; + } ATTRIBUTE_PACKED; + + struct lvar_addr_gap { + uint16_t offset; + uint16_t length; + } ATTRIBUTE_PACKED; + + struct defrange_register + { + uint16_t size; + uint16_t kind; + uint16_t reg; + uint16_t attributes; + struct lvar_addr_range range; + struct lvar_addr_gap gaps[]; + } ATTRIBUTE_PACKED; + */ + + if (expr->dw_loc_opc == DW_OP_regx) + regno = dwarf_reg_to_cv (expr->dw_loc_oprnd1.v.val_int); + else + regno = dwarf_reg_to_cv (expr->dw_loc_opc - DW_OP_reg0); + + if (regno == 0) + return; + + 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_DEFRANGE_REGISTER); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, regno); + 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); + + asm_fprintf (asm_out_file, "\t.secrel32 "); + output_addr_const (asm_out_file, range_start); + fputc ('\n', asm_out_file); + + asm_fprintf (asm_out_file, "\t.secidx "); + output_addr_const (asm_out_file, range_start); + fputc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + output_addr_const (asm_out_file, range_end); + fputs (" - ", asm_out_file); + output_addr_const (asm_out_file, range_start); + putc ('\n', asm_out_file); + + targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num); +} + +/* Try to write an S_DEFRANGE_* symbol for the given DWARF location. */ + +static void +write_optimized_local_variable_loc (dw_loc_descr_ref expr, rtx range_start, + rtx range_end) +{ + if (expr->dw_loc_next) + return; + + if (!range_start) + return; + + if (!range_end) + return; + + switch (expr->dw_loc_opc) + { + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + case DW_OP_regx: + write_defrange_register (expr, range_start, range_end); + break; + + default: + break; + } +} + +/* Write an optimized local variable, given by an S_LOCAL symbol followed by + any number of S_DEFRANGE_* symbols. We can't mix and match optimized and + unoptimized variables in the same function, so even if it stays in the same + place for the whole block we need to write an S_LOCAL. */ + +static void +write_optimized_local_variable (dw_die_ref die, rtx block_start, rtx block_end) +{ + dw_attr_node *loc; + dw_loc_list_ref loc_list; + + loc = get_AT (die, DW_AT_location); + if (!loc) + return; + + switch (loc->dw_attr_val.val_class) + { + case dw_val_class_loc_list: + loc_list = loc->dw_attr_val.v.val_loc_list; + + write_s_local (die); + + while (loc_list) + { + rtx range_start = NULL, range_end = NULL; + + if (loc_list->begin) + range_start = gen_rtx_SYMBOL_REF (Pmode, loc_list->begin); + + if (loc_list->end) + range_end = gen_rtx_SYMBOL_REF (Pmode, loc_list->end); + + write_optimized_local_variable_loc (loc_list->expr, range_start, + range_end); + + loc_list = loc_list->dw_loc_next; + } + break; + + case dw_val_class_loc: + write_s_local (die); + + write_optimized_local_variable_loc (loc->dw_attr_val.v.val_loc, + block_start, block_end); + break; + + default: + break; + } +} + /* Write a symbol representing an unoptimized variable within a function, if we're able to translate the DIE's DW_AT_location into its CodeView equivalent. */ @@ -2517,6 +2757,77 @@ write_unoptimized_function_vars (dw_die_ref die, dw_loc_descr_ref fbloc) while (c != first_child); } +/* Write the variables in an optimized function or block. There's no S_BLOCK32s + here, with the range determining the lifetime of a variable. Unfortunately + for us CodeView is much less expressive than DWARF when it comes to variable + locations, so some degree of "optimized out"s is inevitable. */ + +static void +write_optimized_function_vars (dw_die_ref die, rtx block_start, rtx block_end) +{ + dw_die_ref first_child, c; + + first_child = dw_get_die_child (die); + + if (!first_child) + return; + + c = first_child; + do + { + c = dw_get_die_sib (c); + + switch (dw_get_die_tag (c)) + { + case DW_TAG_formal_parameter: + case DW_TAG_variable: + write_optimized_local_variable (c, block_start, block_end); + break; + + case DW_TAG_lexical_block: + { + dw_attr_node *loc_low, *loc_high; + const char *label_low, *label_high; + rtx rtx_low, rtx_high; + + loc_low = get_AT (die, DW_AT_low_pc); + if (!loc_low) + break; + + if (loc_low->dw_attr_val.val_class != dw_val_class_lbl_id) + break; + + label_low = loc_low->dw_attr_val.v.val_lbl_id; + if (!label_low) + break; + + rtx_low = gen_rtx_SYMBOL_REF (Pmode, label_low); + + loc_high = get_AT (die, DW_AT_high_pc); + if (!loc_high) + break; + + if (loc_high->dw_attr_val.val_class != dw_val_class_high_pc) + break; + + label_high = loc_high->dw_attr_val.v.val_lbl_id; + if (!label_high) + break; + + rtx_high = gen_rtx_SYMBOL_REF (Pmode, label_high); + + write_optimized_function_vars (c, rtx_low, rtx_high); + + break; + } + + default: + break; + } + } + while (c != first_child); +} + /* Write an S_GPROC32_ID symbol, representing a global function, or an S_LPROC32_ID symbol, for a static function. */ @@ -2648,7 +2959,10 @@ write_function (codeview_symbol *s) if (frame_base && frame_base->dw_attr_val.val_class == dw_val_class_loc) fbloc = frame_base->dw_attr_val.v.val_loc; - write_unoptimized_function_vars (s->function.die, fbloc); + if (flag_var_tracking) + write_optimized_function_vars (s->function.die, rtx_low, rtx_high); + else + write_unoptimized_function_vars (s->function.die, fbloc); /* Output the S_PROC_ID_END record. */ diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index d5144714c6e..79f76935121 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -1362,43 +1362,6 @@ struct GTY((for_user)) addr_table_entry { GTY ((desc ("%1.kind"))) addr; }; -typedef unsigned int var_loc_view; - -/* Location lists are ranges + location descriptions for that range, - so you can track variables that are in different places over - their entire life. */ -typedef struct GTY(()) dw_loc_list_struct { - dw_loc_list_ref dw_loc_next; - const char *begin; /* Label and addr_entry for start of range */ - addr_table_entry *begin_entry; - const char *end; /* Label for end of range */ - addr_table_entry *end_entry; - char *ll_symbol; /* Label for beginning of location list. - Only on head of list. */ - char *vl_symbol; /* Label for beginning of view list. Ditto. */ - const char *section; /* Section this loclist is relative to */ - dw_loc_descr_ref expr; - var_loc_view vbegin, vend; - hashval_t hash; - /* True if all addresses in this and subsequent lists are known to be - resolved. */ - bool resolved_addr; - /* True if this list has been replaced by dw_loc_next. */ - bool replaced; - /* True if it has been emitted into .debug_loc* / .debug_loclists* - section. */ - unsigned char emitted : 1; - /* True if hash field is index rather than hash value. */ - unsigned char num_assigned : 1; - /* True if .debug_loclists.dwo offset has been emitted for it already. */ - unsigned char offset_emitted : 1; - /* True if note_variable_value_in_expr has been called on it. */ - unsigned char noted_variable_value : 1; - /* True if the range should be emitted even if begin and end - are the same. */ - bool force; -} dw_loc_list_node; - static dw_loc_descr_ref int_loc_descriptor (poly_int64); static dw_loc_descr_ref uint_loc_descriptor (unsigned HOST_WIDE_INT); diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index a424981b911..f8270c8601f 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -235,6 +235,43 @@ struct GTY(()) dw_discr_value { struct addr_table_entry; +typedef unsigned int var_loc_view; + +/* Location lists are ranges + location descriptions for that range, + so you can track variables that are in different places over + their entire life. */ +typedef struct GTY(()) dw_loc_list_struct { + dw_loc_list_ref dw_loc_next; + const char *begin; /* Label and addr_entry for start of range */ + addr_table_entry *begin_entry; + const char *end; /* Label for end of range */ + addr_table_entry *end_entry; + char *ll_symbol; /* Label for beginning of location list. + Only on head of list. */ + char *vl_symbol; /* Label for beginning of view list. Ditto. */ + const char *section; /* Section this loclist is relative to */ + dw_loc_descr_ref expr; + var_loc_view vbegin, vend; + hashval_t hash; + /* True if all addresses in this and subsequent lists are known to be + resolved. */ + bool resolved_addr; + /* True if this list has been replaced by dw_loc_next. */ + bool replaced; + /* True if it has been emitted into .debug_loc* / .debug_loclists* + section. */ + unsigned char emitted : 1; + /* True if hash field is index rather than hash value. */ + unsigned char num_assigned : 1; + /* True if .debug_loclists.dwo offset has been emitted for it already. */ + unsigned char offset_emitted : 1; + /* True if note_variable_value_in_expr has been called on it. */ + unsigned char noted_variable_value : 1; + /* True if the range should be emitted even if begin and end + are the same. */ + bool force; +} dw_loc_list_node; + /* The dw_val_node describes an attribute's value, as it is represented internally. */ diff --git a/gcc/opts.cc b/gcc/opts.cc index 0b7b137c376..317b586be58 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -1408,7 +1408,7 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* We know which debug output will be used so we can set flag_var_tracking and flag_var_tracking_uninit if the user has not specified them. */ if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL - || !dwarf_debuginfo_p (opts) + || (!dwarf_debuginfo_p (opts) && !codeview_debuginfo_p ()) /* We have not yet initialized debug hooks so match that to check whether we're only doing DWARF2_LINENO_DEBUGGING_INFO. */ #ifndef DWARF2_DEBUGGING_INFO From patchwork Mon Aug 19 01:15:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 1973628 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=pte/Hn1g; 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 4WnF6L6ydLz1yXg for ; Mon, 19 Aug 2024 11:16:09 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0E8CA386482E for ; Mon, 19 Aug 2024 01:16:07 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.burntcomma.com (mail2.burntcomma.com [217.169.27.34]) by sourceware.org (Postfix) with ESMTPS id 4B07F386183A for ; Mon, 19 Aug 2024 01:15:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4B07F386183A 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 4B07F386183A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.169.27.34 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724030143; cv=none; b=awUQy+Z8iHkT96nSj5oxSovA2mkznRVJ+MxogljAMpmEtyRN1o6RANQf/AmYuvZ/8o6J87dlI2rQ2nM4QaDm1EwHq7Jk+NeGydVDL9cZ23+B75vzlAagxvst5w1oRvM1EPFA77cJ8QmaFL0kp3jXMVrIxEaAbxgZwfZnbbx5yqE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724030143; c=relaxed/simple; bh=+Qiwa5276A7gWIC4iRa91wZTxtrfKdTkjO/ziQ33g6g=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:Mime-Version; b=Oy3Q5V5S0FD5YzjJBO2279EFNRm4onN31O880DHHyn3Ciz8hnnfKB2/KoU/mPmCFfNDqV6iu6dF96yHE44v8iaJPtKZkOgBT7jhCy66F4LJU7xSGRUKPpzkqDmblqTsxT0Bq7viwBWJ3dWMVPTiU+G4FOgHm1PBBZ1L7pOOwLcU= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from localhost.localdomain (mail2.burntcomma.com [217.169.27.34]) (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 343AAA06A8; Mon, 19 Aug 2024 02:15:38 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmstone.com; s=mail; t=1724030138; bh=UQUN9PRl8ho3PgdorWWAJ4u/ITbY+3XUnPPDNoqEcE4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=pte/Hn1gOGUPgD5mwV8aYoIDjtsAmzAeyI0BDq4Y3nIQwL7hN+2HMy+fGKrlNCM31 uJYWgaiiY84PjgWk4r4DCnALNl2IL1PylNf+PPv8AfJGtG5prvLbDNRp/q6DsER7SN AEZ6g0Q2QE2k3dOqS1OY/6xrGuKYwIdob4Nk+SOk= From: Mark Harmstone To: gcc-patches@gcc.gnu.org Cc: Mark Harmstone Subject: [PATCH 2/4] Write CodeView information about optimized stack variables Date: Mon, 19 Aug 2024 02:15:28 +0100 Message-ID: <20240819011530.25488-2-mark@harmstone.com> In-Reply-To: <20240819011530.25488-1-mark@harmstone.com> References: <20240819011530.25488-1-mark@harmstone.com> Mime-Version: 1.0 X-Spam-Status: No, score=-11.8 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 Outputs S_DEFRANGE_REGISTER_REL symbols for optimized local variables that are on the stack, consisting of the stack register, the offset, and the code range for which this applies. gcc/ * dwarf2codeview.cc (enum cv_sym_type): Add S_DEFRANGE_REGISTER_REL. (write_defrange_register_rel): New function. (write_optimized_local_variable_loc): Add fbloc param, and call write_defrange_register_rel. (write_optimized_local_variable): Add fbloc param. (write_optimized_function_vars): Add fbloc param. --- gcc/dwarf2codeview.cc | 128 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 119 insertions(+), 9 deletions(-) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index 15253978968..74bbf6bc1d7 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -79,6 +79,7 @@ enum cv_sym_type { S_COMPILE3 = 0x113c, S_LOCAL = 0x113e, S_DEFRANGE_REGISTER = 0x1141, + S_DEFRANGE_REGISTER_REL = 0x1145, S_LPROC32_ID = 0x1146, S_GPROC32_ID = 0x1147, S_PROC_ID_END = 0x114f @@ -2409,10 +2410,113 @@ write_defrange_register (dw_loc_descr_ref expr, rtx range_start, rtx range_end) targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num); } +/* Write an S_DEFRANGE_REGISTER_REL symbol, which describes a range for which + an S_LOCAL variable is held in memory given by the value of a certain + register plus an offset. */ + +static void +write_defrange_register_rel (dw_loc_descr_ref expr, dw_loc_descr_ref fbloc, + rtx range_start, rtx range_end) +{ + unsigned int label_num = ++sym_label_num; + uint16_t regno; + int offset; + + /* This is defrange_register_rel in binutils and DEFRANGESYMREGISTERREL in + Microsoft's cvinfo.h: + + struct lvar_addr_range + { + uint32_t offset; + uint16_t section; + uint16_t length; + } ATTRIBUTE_PACKED; + + struct lvar_addr_gap { + uint16_t offset; + uint16_t length; + } ATTRIBUTE_PACKED; + + struct defrange_register_rel + { + uint16_t size; + uint16_t kind; + uint16_t reg; + uint16_t offset_parent; + uint32_t offset_register; + struct lvar_addr_range range; + struct lvar_addr_gap gaps[]; + } ATTRIBUTE_PACKED; + */ + + if (!fbloc) + return; + + if (fbloc->dw_loc_opc >= DW_OP_breg0 && fbloc->dw_loc_opc <= DW_OP_breg31) + { + regno = dwarf_reg_to_cv (fbloc->dw_loc_opc - DW_OP_breg0); + offset = fbloc->dw_loc_oprnd1.v.val_int; + } + else if (fbloc->dw_loc_opc == DW_OP_bregx) + { + regno = dwarf_reg_to_cv (fbloc->dw_loc_oprnd1.v.val_int); + offset = fbloc->dw_loc_oprnd2.v.val_int; + } + else + { + return; + } + + if (expr->dw_loc_oprnd1.val_class != dw_val_class_unsigned_const) + return; + + offset += expr->dw_loc_oprnd1.v.val_int; + + 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_DEFRANGE_REGISTER_REL); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + fprint_whex (asm_out_file, regno); + 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, offset); + putc ('\n', asm_out_file); + + asm_fprintf (asm_out_file, "\t.secrel32 "); + output_addr_const (asm_out_file, range_start); + fputc ('\n', asm_out_file); + + asm_fprintf (asm_out_file, "\t.secidx "); + output_addr_const (asm_out_file, range_start); + fputc ('\n', asm_out_file); + + fputs (integer_asm_op (2, false), asm_out_file); + output_addr_const (asm_out_file, range_end); + fputs (" - ", asm_out_file); + output_addr_const (asm_out_file, range_start); + putc ('\n', asm_out_file); + + targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num); +} + /* Try to write an S_DEFRANGE_* symbol for the given DWARF location. */ static void -write_optimized_local_variable_loc (dw_loc_descr_ref expr, rtx range_start, +write_optimized_local_variable_loc (dw_loc_descr_ref expr, + dw_loc_descr_ref fbloc, rtx range_start, rtx range_end) { if (expr->dw_loc_next) @@ -2462,6 +2566,10 @@ write_optimized_local_variable_loc (dw_loc_descr_ref expr, rtx range_start, write_defrange_register (expr, range_start, range_end); break; + case DW_OP_fbreg: + write_defrange_register_rel (expr, fbloc, range_start, range_end); + break; + default: break; } @@ -2473,7 +2581,8 @@ write_optimized_local_variable_loc (dw_loc_descr_ref expr, rtx range_start, place for the whole block we need to write an S_LOCAL. */ static void -write_optimized_local_variable (dw_die_ref die, rtx block_start, rtx block_end) +write_optimized_local_variable (dw_die_ref die, dw_loc_descr_ref fbloc, + rtx block_start, rtx block_end) { dw_attr_node *loc; dw_loc_list_ref loc_list; @@ -2499,8 +2608,8 @@ write_optimized_local_variable (dw_die_ref die, rtx block_start, rtx block_end) if (loc_list->end) range_end = gen_rtx_SYMBOL_REF (Pmode, loc_list->end); - write_optimized_local_variable_loc (loc_list->expr, range_start, - range_end); + write_optimized_local_variable_loc (loc_list->expr, fbloc, + range_start, range_end); loc_list = loc_list->dw_loc_next; } @@ -2509,7 +2618,7 @@ write_optimized_local_variable (dw_die_ref die, rtx block_start, rtx block_end) case dw_val_class_loc: write_s_local (die); - write_optimized_local_variable_loc (loc->dw_attr_val.v.val_loc, + write_optimized_local_variable_loc (loc->dw_attr_val.v.val_loc, fbloc, block_start, block_end); break; @@ -2763,7 +2872,8 @@ write_unoptimized_function_vars (dw_die_ref die, dw_loc_descr_ref fbloc) locations, so some degree of "optimized out"s is inevitable. */ static void -write_optimized_function_vars (dw_die_ref die, rtx block_start, rtx block_end) +write_optimized_function_vars (dw_die_ref die, dw_loc_descr_ref fbloc, + rtx block_start, rtx block_end) { dw_die_ref first_child, c; @@ -2781,7 +2891,7 @@ write_optimized_function_vars (dw_die_ref die, rtx block_start, rtx block_end) { case DW_TAG_formal_parameter: case DW_TAG_variable: - write_optimized_local_variable (c, block_start, block_end); + write_optimized_local_variable (c, fbloc, block_start, block_end); break; case DW_TAG_lexical_block: @@ -2816,7 +2926,7 @@ write_optimized_function_vars (dw_die_ref die, rtx block_start, rtx block_end) rtx_high = gen_rtx_SYMBOL_REF (Pmode, label_high); - write_optimized_function_vars (c, rtx_low, rtx_high); + write_optimized_function_vars (c, fbloc, rtx_low, rtx_high); break; } @@ -2960,7 +3070,7 @@ write_function (codeview_symbol *s) fbloc = frame_base->dw_attr_val.v.val_loc; if (flag_var_tracking) - write_optimized_function_vars (s->function.die, rtx_low, rtx_high); + write_optimized_function_vars (s->function.die, fbloc, rtx_low, rtx_high); else write_unoptimized_function_vars (s->function.die, fbloc); From patchwork Mon Aug 19 01:15:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 1973630 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=XiYJpfKG; 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 4WnF6Q4mFJz1yXg for ; Mon, 19 Aug 2024 11:16:14 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 826D7384DB45 for ; Mon, 19 Aug 2024 01:16:12 +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 7719B3850203 for ; Mon, 19 Aug 2024 01:15:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7719B3850203 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 7719B3850203 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=1724030143; cv=none; b=EIDVRRLRiz7/rVazkxAWnn8pjijmOy/YzdNSA+DyasdJ6BE8F7/hH+NRwUv3LS1pRC/o2vGWXXaG8jrwFP97fo7ziRR5Pea5nenuqqmIc+K9dETGhBbQYH1f/G442/0U23cfEOdXGCQ9nBi3R7rPFT161mQEf631KLir5D5AflM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724030143; c=relaxed/simple; bh=V059OkQNIHDoHSm3ByC82xWETxdo/MFYJGoTJaqaO9w=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:Mime-Version; b=OEnYSWWuxWJ8exagEKTk+sJGP69+1AcTALw2kejUU7nOR18fsQv/Tts69LjV9omDSyg+XnIUEhutUeOkua7C8doCBX3ls73Xeu0u+IBgFxukZ2L+k+f2km1qySipo76p27Jry3O5J6cztxDUSMCh6WW0Th7yrJD1BBjEt23D54Y= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from localhost.localdomain (mail2.burntcomma.com [217.169.27.34]) (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 64A66A06A9; Mon, 19 Aug 2024 02:15:39 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmstone.com; s=mail; t=1724030139; bh=XzhHb/0Si3VCcPwZpnuPDRUkZ66ezKy9aiAbg0sgTOY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=XiYJpfKGH5e7uvxSZstyR0Dw14HbLjs418AHVPOEuvgeN/aHmW6pFZM1PsQpG27Gt CEymkkqRA7t5dh0Hh8r1ZBOwQX5sLxwl4dD6Bw4r1T0nbwNsKA1X/1Izmb3lsfyzei HgJpnh3DlNiMg/CKF6eFkiscKOxERTG1dCVjV7gk= From: Mark Harmstone To: gcc-patches@gcc.gnu.org Cc: Mark Harmstone Subject: [PATCH 3/4] Write CodeView S_FRAMEPROC symbols Date: Mon, 19 Aug 2024 02:15:29 +0100 Message-ID: <20240819011530.25488-3-mark@harmstone.com> In-Reply-To: <20240819011530.25488-1-mark@harmstone.com> References: <20240819011530.25488-1-mark@harmstone.com> Mime-Version: 1.0 X-Spam-Status: No, score=-11.9 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 Write S_FRAMEPROC symbols, which aren't very useful but seem to be necessary for Microsoft debuggers to function properly. These symbols come after S_LOCAL symbols for optimized variables, but before S_REGISTER and S_REGREL32 for unoptimized variables. gcc/ * dwarf2codeview.cc (enum cv_sym_type): Add S_FRAMEPROC. (write_s_frameproc): New function. (write_function): Call write_s_frameproc. --- gcc/dwarf2codeview.cc | 80 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index 74bbf6bc1d7..88310504cf7 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -71,6 +71,7 @@ along with GCC; see the file COPYING3. If not see enum cv_sym_type { S_END = 0x0006, + S_FRAMEPROC = 0x1012, S_BLOCK32 = 0x1103, S_REGISTER = 0x1106, S_LDATA32 = 0x110c, @@ -2822,6 +2823,74 @@ write_s_end (void) targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num); } +/* Write the S_FRAMEPROC symbol, which is supposed to give information about + the function frame. It doesn't seem to be really used in modern versions of + MSVC, which is why we zero-out everything here. You still need to write it + though, otherwise windbg won't necessarily show all the local variables. */ + +static void +write_s_frameproc (void) +{ + unsigned int label_num = ++sym_label_num; + + /* This is struct FRAMEPROCSYM in Microsoft's cvinfo.h: + + struct frameprocsym + { + uint16_t size; + uint16_t kind; + uint32_t frame_size; + uint32_t padding_size; + uint32_t padding_offset; + uint32_t saved_registers_size; + uint32_t exception_handler_offset; + uint16_t exception_handler_section; + uint32_t flags; + } 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_FRAMEPROC); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, 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, 0); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, 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, 0); + putc ('\n', asm_out_file); + + fputs (integer_asm_op (4, false), asm_out_file); + fprint_whex (asm_out_file, 0); + 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, 0); + putc ('\n', asm_out_file); + + targetm.asm_out.internal_label (asm_out_file, SYMBOL_END_LABEL, label_num); +} + /* Loop through the DIEs in an unoptimized function, writing out any variables or blocks that we encounter. */ @@ -3070,9 +3139,16 @@ write_function (codeview_symbol *s) fbloc = frame_base->dw_attr_val.v.val_loc; if (flag_var_tracking) - write_optimized_function_vars (s->function.die, fbloc, rtx_low, rtx_high); + { + write_optimized_function_vars (s->function.die, fbloc, rtx_low, + rtx_high); + write_s_frameproc (); + } else - write_unoptimized_function_vars (s->function.die, fbloc); + { + write_s_frameproc (); + write_unoptimized_function_vars (s->function.die, fbloc); + } /* Output the S_PROC_ID_END record. */ From patchwork Mon Aug 19 01:15:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 1973629 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=19fgfX2b; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; 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 [8.43.85.97]) (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 4WnF6P363Gz1yf6 for ; Mon, 19 Aug 2024 11:16:09 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6E6E93864837 for ; Mon, 19 Aug 2024 01:16:07 +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 74690386183D for ; Mon, 19 Aug 2024 01:15:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 74690386183D 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 74690386183D 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=1724030143; cv=none; b=ltD/go34NHLpLGqFC12ZEpKV9LdxRInPj5RVUTziHq0Vzp8c4uh5LrgtkVWEjEpSG1wDIrO9XdNfWlYtx2T3qNjGrZB0P9LarOtiQSGXl69n5HZWLJiu43UhyhKVOZo6qT+CMiAWxJ+q/brdlqFo6ElE16RMU8dhz6tpy6IIS5w= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1724030143; c=relaxed/simple; bh=9JdjhLGFRNNoPY6OvbzmjGcXSadVE9xiEa/l9bDR4qo=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:Mime-Version; b=TeA8SNu1n1w8ApxiwiDbHdXSxARpVxsRRSewxHcMGWc6pnCPfmmNYkNeCYndktDbMUagB8tDmAYUnl7N1HeJrhC4/2C61yyuf/mHUPJRlHcaRP1V4vYf2BCF1i/qX8bgbtrS89Gb0nLuWfawBoMyC6NTf4xP3IPqRN780cpPEBo= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from localhost.localdomain (mail2.burntcomma.com [217.169.27.34]) (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 1BABAA06AA; Mon, 19 Aug 2024 02:15:40 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=harmstone.com; s=mail; t=1724030140; bh=QpulloVTMrqk0g6JH0PLgUpswR77Dd/5uAQUgYbWiqg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=19fgfX2buT88sLhPHrOwloRz7PrG6Og9zYWmR0NDa0e5dvF5XK5+yRvuJjnNVZA1J A/QU8HV8KGv2QS/Vdu1x73HRo8C6CpzJskqCUOQIDxTMLJq6VCLrck2C6yAs/6aZ5C CAkCT51N+aCPq+88U9dyYFStGojaySgaXvZm/rH0= From: Mark Harmstone To: gcc-patches@gcc.gnu.org Cc: Mark Harmstone Subject: [PATCH 4/4] Write CodeView information about static locals in optimized code Date: Mon, 19 Aug 2024 02:15:30 +0100 Message-ID: <20240819011530.25488-4-mark@harmstone.com> In-Reply-To: <20240819011530.25488-1-mark@harmstone.com> References: <20240819011530.25488-1-mark@harmstone.com> Mime-Version: 1.0 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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 Write CodeView S_LDATA32 symbols for static locals in optimized code. We have to handle these separately, as they come after the S_FRAMEPROC, plus you can't have S_BLOCK32 symbols like you can in unoptimized code. gcc/ * dwarf2codeview.cc (write_optimized_static_local_vars): New function. (write_function): Call write_optimized_static_local_vars. --- gcc/dwarf2codeview.cc | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index 88310504cf7..e4c67f921cd 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -3007,6 +3007,62 @@ write_optimized_function_vars (dw_die_ref die, dw_loc_descr_ref fbloc, while (c != first_child); } +/* There's no way to mark the range of a static local variable in an optimized + function: there's no S_DEFRANGE_* symbol for this, and you can't have + S_BLOCK32 symbols. So instead we have to loop through after the S_FRAMEPROC + has been written, and write the S_LDATA32s at the end. */ + +static void +write_optimized_static_local_vars (dw_die_ref die) +{ + dw_die_ref first_child, c; + + first_child = dw_get_die_child (die); + + if (!first_child) + return; + + c = first_child; + do + { + c = dw_get_die_sib (c); + + switch (dw_get_die_tag (c)) + { + case DW_TAG_variable: + { + dw_attr_node *loc; + dw_loc_descr_ref loc_ref; + + loc = get_AT (c, DW_AT_location); + if (!loc) + break; + + if (loc->dw_attr_val.val_class != dw_val_class_loc) + break; + + loc_ref = loc->dw_attr_val.v.val_loc; + if (!loc_ref) + break; + + if (loc_ref->dw_loc_opc != DW_OP_addr) + break; + + write_local_s_ldata32 (c, loc_ref); + break; + } + + case DW_TAG_lexical_block: + write_optimized_static_local_vars (c); + break; + + default: + break; + } + } + while (c != first_child); +} + /* Write an S_GPROC32_ID symbol, representing a global function, or an S_LPROC32_ID symbol, for a static function. */ @@ -3143,6 +3199,7 @@ write_function (codeview_symbol *s) write_optimized_function_vars (s->function.die, fbloc, rtx_low, rtx_high); write_s_frameproc (); + write_optimized_static_local_vars (s->function.die); } else {