From f08649c02d8ca0b788e9d2663738e42744e6d10d Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Wed, 17 Dec 2014 16:25:49 +0000 Subject: [PATCH] Add a few debug utilities for DWARF expressions * dwarf2out.c (print_loc_descr): New. (print_dw_val): New. (print_attribute): New. (print_loc_descr): New. (print_die): Use print_dw_val. (debug_dwarf_loc_descr): New. * dwarf2out.h (debug_dwarf_loc_descr): New declaration. From-SVN: r218826 --- gcc/ChangeLog | 10 ++ gcc/dwarf2out.c | 278 ++++++++++++++++++++++++++++++------------------ gcc/dwarf2out.h | 1 + 3 files changed, 187 insertions(+), 102 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e76f7cacec..ac8eb959db0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-12-17 Pierre-Marie de Rodat + + * dwarf2out.c (print_loc_descr): New. + (print_dw_val): New. + (print_attribute): New. + (print_loc_descr): New. + (print_die): Use print_dw_val. + (debug_dwarf_loc_descr): New. + * dwarf2out.h (debug_dwarf_loc_descr): New declaration. + 2014-12-17 Pierre-Marie de Rodat * dwarf2out.c (gen_type_die_with_usage): Enable the array lang-hook diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 4e24f686f0a..71e940f6b4d 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -5370,6 +5370,173 @@ print_signature (FILE *outfile, char *sig) fprintf (outfile, "%02x", sig[i] & 0xff); } +static void print_loc_descr (dw_loc_descr_ref, FILE *); + +/* Print the value associated to the VAL DWARF value node to OUTFILE. If + RECURSE, output location descriptor operations. */ + +static void +print_dw_val (dw_val_node *val, bool recurse, FILE *outfile) +{ + switch (val->val_class) + { + case dw_val_class_addr: + fprintf (outfile, "address"); + break; + case dw_val_class_offset: + fprintf (outfile, "offset"); + break; + case dw_val_class_loc: + fprintf (outfile, "location descriptor"); + if (val->v.val_loc == NULL) + fprintf (outfile, " -> \n"); + else if (recurse) + { + fprintf (outfile, ":\n"); + print_indent += 4; + print_loc_descr (val->v.val_loc, outfile); + print_indent -= 4; + } + else + fprintf (outfile, " (%p)\n", (void *) val->v.val_loc); + break; + case dw_val_class_loc_list: + fprintf (outfile, "location list -> label:%s", + val->v.val_loc_list->ll_symbol); + break; + case dw_val_class_range_list: + fprintf (outfile, "range list"); + break; + case dw_val_class_const: + fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, val->v.val_int); + break; + case dw_val_class_unsigned_const: + fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, val->v.val_unsigned); + break; + case dw_val_class_const_double: + fprintf (outfile, "constant ("HOST_WIDE_INT_PRINT_DEC","\ + HOST_WIDE_INT_PRINT_UNSIGNED")", + val->v.val_double.high, + val->v.val_double.low); + break; + case dw_val_class_wide_int: + { + int i = val->v.val_wide->get_len (); + fprintf (outfile, "constant ("); + gcc_assert (i > 0); + if (val->v.val_wide->elt (i - 1) == 0) + fprintf (outfile, "0x"); + fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, + val->v.val_wide->elt (--i)); + while (--i >= 0) + fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, + val->v.val_wide->elt (i)); + fprintf (outfile, ")"); + break; + } + case dw_val_class_vec: + fprintf (outfile, "floating-point or vector constant"); + break; + case dw_val_class_flag: + fprintf (outfile, "%u", val->v.val_flag); + break; + case dw_val_class_die_ref: + if (val->v.val_die_ref.die != NULL) + { + dw_die_ref die = val->v.val_die_ref.die; + + if (die->comdat_type_p) + { + fprintf (outfile, "die -> signature: "); + print_signature (outfile, + die->die_id.die_type_node->signature); + } + else if (die->die_id.die_symbol) + fprintf (outfile, "die -> label: %s", die->die_id.die_symbol); + else + fprintf (outfile, "die -> %ld", die->die_offset); + fprintf (outfile, " (%p)", (void *) die); + } + else + fprintf (outfile, "die -> "); + break; + case dw_val_class_vms_delta: + fprintf (outfile, "delta: @slotcount(%s-%s)", + val->v.val_vms_delta.lbl2, val->v.val_vms_delta.lbl1); + break; + case dw_val_class_lbl_id: + case dw_val_class_lineptr: + case dw_val_class_macptr: + case dw_val_class_high_pc: + fprintf (outfile, "label: %s", val->v.val_lbl_id); + break; + case dw_val_class_str: + if (val->v.val_str->str != NULL) + fprintf (outfile, "\"%s\"", val->v.val_str->str); + else + fprintf (outfile, ""); + break; + case dw_val_class_file: + fprintf (outfile, "\"%s\" (%d)", val->v.val_file->filename, + val->v.val_file->emitted_number); + break; + case dw_val_class_data8: + { + int i; + + for (i = 0; i < 8; i++) + fprintf (outfile, "%02x", val->v.val_data8[i]); + break; + } + default: + break; + } +} + +/* Likewise, for a DIE attribute. */ + +static void +print_attribute (dw_attr_ref a, bool recurse, FILE *outfile) +{ + print_dw_val (&a->dw_attr_val, recurse, outfile); +} + + +/* Print the list of operands in the LOC location description to OUTFILE. This + routine is a debugging aid only. */ + +static void +print_loc_descr (dw_loc_descr_ref loc, FILE *outfile) +{ + dw_loc_descr_ref l = loc; + + if (loc == NULL) + { + print_spaces (outfile); + fprintf (outfile, "\n"); + return; + } + + for (l = loc; l != NULL; l = l->dw_loc_next) + { + print_spaces (outfile); + fprintf (outfile, "(%p) %s", + (void *) l, + dwarf_stack_op_name (l->dw_loc_opc)); + if (l->dw_loc_oprnd1.val_class != dw_val_class_none) + { + fprintf (outfile, " "); + print_dw_val (&l->dw_loc_oprnd1, false, outfile); + } + if (l->dw_loc_oprnd2.val_class != dw_val_class_none) + { + fprintf (outfile, ", "); + print_dw_val (&l->dw_loc_oprnd2, false, outfile); + } + fprintf (outfile, "\n"); + } +} + /* Print the information associated with a given DIE, and its children. This routine is a debugging aid only. */ @@ -5402,108 +5569,7 @@ print_die (dw_die_ref die, FILE *outfile) print_spaces (outfile); fprintf (outfile, " %s: ", dwarf_attr_name (a->dw_attr)); - switch (AT_class (a)) - { - case dw_val_class_addr: - fprintf (outfile, "address"); - break; - case dw_val_class_offset: - fprintf (outfile, "offset"); - break; - case dw_val_class_loc: - fprintf (outfile, "location descriptor"); - break; - case dw_val_class_loc_list: - fprintf (outfile, "location list -> label:%s", - AT_loc_list (a)->ll_symbol); - break; - case dw_val_class_range_list: - fprintf (outfile, "range list"); - break; - case dw_val_class_const: - fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, AT_int (a)); - break; - case dw_val_class_unsigned_const: - fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, AT_unsigned (a)); - break; - case dw_val_class_const_double: - fprintf (outfile, "constant ("HOST_WIDE_INT_PRINT_DEC","\ - HOST_WIDE_INT_PRINT_UNSIGNED")", - a->dw_attr_val.v.val_double.high, - a->dw_attr_val.v.val_double.low); - break; - case dw_val_class_wide_int: - { - int i = a->dw_attr_val.v.val_wide->get_len (); - fprintf (outfile, "constant ("); - gcc_assert (i > 0); - if (a->dw_attr_val.v.val_wide->elt (i - 1) == 0) - fprintf (outfile, "0x"); - fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, - a->dw_attr_val.v.val_wide->elt (--i)); - while (--i >= 0) - fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, - a->dw_attr_val.v.val_wide->elt (i)); - fprintf (outfile, ")"); - break; - } - case dw_val_class_vec: - fprintf (outfile, "floating-point or vector constant"); - break; - case dw_val_class_flag: - fprintf (outfile, "%u", AT_flag (a)); - break; - case dw_val_class_die_ref: - if (AT_ref (a) != NULL) - { - if (AT_ref (a)->comdat_type_p) - { - fprintf (outfile, "die -> signature: "); - print_signature (outfile, - AT_ref (a)->die_id.die_type_node->signature); - } - else if (AT_ref (a)->die_id.die_symbol) - fprintf (outfile, "die -> label: %s", - AT_ref (a)->die_id.die_symbol); - else - fprintf (outfile, "die -> %ld", AT_ref (a)->die_offset); - fprintf (outfile, " (%p)", (void *) AT_ref (a)); - } - else - fprintf (outfile, "die -> "); - break; - case dw_val_class_vms_delta: - fprintf (outfile, "delta: @slotcount(%s-%s)", - AT_vms_delta2 (a), AT_vms_delta1 (a)); - break; - case dw_val_class_lbl_id: - case dw_val_class_lineptr: - case dw_val_class_macptr: - case dw_val_class_high_pc: - fprintf (outfile, "label: %s", AT_lbl (a)); - break; - case dw_val_class_str: - if (AT_string (a) != NULL) - fprintf (outfile, "\"%s\"", AT_string (a)); - else - fprintf (outfile, ""); - break; - case dw_val_class_file: - fprintf (outfile, "\"%s\" (%d)", AT_file (a)->filename, - AT_file (a)->emitted_number); - break; - case dw_val_class_data8: - { - int i; - - for (i = 0; i < 8; i++) - fprintf (outfile, "%02x", a->dw_attr_val.v.val_data8[i]); - break; - } - default: - break; - } - + print_attribute (a, true, outfile); fprintf (outfile, "\n"); } @@ -5517,6 +5583,14 @@ print_die (dw_die_ref die, FILE *outfile) fprintf (outfile, "\n"); } +/* Print the list of operations in the LOC location description. */ + +DEBUG_FUNCTION void +debug_dwarf_loc_descr (dw_loc_descr_ref loc) +{ + print_loc_descr (loc, stderr); +} + /* Print the information collected for a given DIE. */ DEBUG_FUNCTION void diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index a8d68bb1155..a61f5870488 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -254,6 +254,7 @@ extern void dwarf2out_emit_cfi (dw_cfi_ref cfi); extern void debug_dwarf (void); struct die_struct; extern void debug_dwarf_die (struct die_struct *); +extern void debug_dwarf_loc_descr (dw_loc_descr_ref); extern void debug (die_struct &ref); extern void debug (die_struct *ptr); extern void dwarf2out_set_demangle_name_func (const char *(*) (const char *)); -- 2.30.2