[google/gcc-4_6] Use const offset for DW_AT_high_pc and end of loc list entries (issue6279043)

2012-06-01 Thread Cary Coutant
This patch is for the google/gcc-4_6 branch.

Import pending patch from upstream to generate DW_AT_high_pc as a constant
offset relative to DW_AT_low_pc.  When splitting DWARF info, generate new
format for location list entries using a start symbol and a length.
Together, these changes reduce the size of the .debug_addr section by half.

Tested with GCC test suite and validate_failures.py.


2012-04-27  Mark Wielaard  m...@redhat.com
Cary Coutant  ccout...@google.com

include/
* dwarf2.h (enum dwarf_location_list_entry_type): New enum.

gcc/
* dwarf2out.c (enum dw_val_class): Add dw_val_class_high_pc.
(struct dw_loc_list_struct): Remove end_index.
(add_AT_low_high_pc): New function.
(AT_lbl): Handle dw_val_class_high_pc.
(print_die): Likewise.
(attr_checksum): Likewise.
(attr_checksum_ordered): Likewise.
(same_dw_val_p): Likewise.
(size_of_die): Likewise.
(value_format): Likewise.
(new_loc_list): Remove end_index.
(output_loc_list): Use new DW_LLE_start_length_entry format.
(output_die): Handle dw_val_class_high_pc.
(gen_subprogram_die): Use add_AT_low_high_pc.
(add_high_low_attributes): Likewise.
(index_location_lists): Remove end_index.
(dwarf2out_finish): Use add_AT_low_high_pc.


Index: include/dwarf2.h
===
--- include/dwarf2.h(revision 188123)
+++ include/dwarf2.h(working copy)
@@ -750,6 +750,17 @@ enum dwarf_line_number_x_ops
 DW_LNE_hi_user = 0xff
   };
 
+/* Type codes for location list entries.
+   Extension for Fission.  See http://gcc.gnu.org/wiki/DebugFission.  */
+
+enum dwarf_location_list_entry_type
+  {
+DW_LLE_end_of_list_entry = 0,
+DW_LLE_base_address_selection_entry = 1,
+DW_LLE_start_end_entry = 2,
+DW_LLE_start_length_entry = 3
+  };
+
 /* Call frame information.  */
 enum dwarf_call_frame_info
   {
Index: gcc/dwarf2out.c
===
--- gcc/dwarf2out.c (revision 188123)
+++ gcc/dwarf2out.c (working copy)
@@ -4366,7 +4366,8 @@ enum dw_val_class
   dw_val_class_file,
   dw_val_class_data8,
   dw_val_class_decl_ref,
-  dw_val_class_vms_delta
+  dw_val_class_vms_delta,
+  dw_val_class_high_pc
 };
 
 /* Describe a floating point constant value, or a vector constant value.  */
@@ -4438,8 +4439,7 @@ typedef struct GTY(()) dw_loc_list_struc
   dw_loc_list_ref dw_loc_next;
   const char *begin; /* Label and index for begin address of range */
   unsigned int begin_index;
-  const char *end;  /* Label and index for end address of range */
-  unsigned int end_index;
+  const char *end;  /* Label for end address of range */
   char *ll_symbol; /* Label for beginning of location list.
  Only on head of list */
   const char *section; /* Section this loclist is relative to */
@@ -7566,6 +7566,26 @@ add_AT_data8 (dw_die_ref die, enum dwarf
   add_dwarf_attr (die, attr);
 }
 
+/* Add DW_AT_low_pc and DW_AT_high_pc to a DIE.  */
+static inline void
+add_AT_low_high_pc (dw_die_ref die, const char *lbl_low, const char *lbl_high)
+{
+  dw_attr_node attr;
+
+  attr.dw_attr = DW_AT_low_pc;
+  attr.dw_attr_val.val_class = dw_val_class_lbl_id;
+  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_low);
+  add_dwarf_attr (die, attr);
+
+  attr.dw_attr = DW_AT_high_pc;
+  if (dwarf_version  4)
+attr.dw_attr_val.val_class = dw_val_class_lbl_id;
+  else
+attr.dw_attr_val.val_class = dw_val_class_high_pc;
+  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_high);
+  add_dwarf_attr (die, attr);
+}
+
 /* Hash and equality functions for debug_str_hash.  */
 
 static hashval_t
@@ -8048,7 +8068,8 @@ AT_lbl (dw_attr_ref a)
 {
   gcc_assert (a  (AT_class (a) == dw_val_class_lbl_id
|| AT_class (a) == dw_val_class_lineptr
-   || AT_class (a) == dw_val_class_macptr));
+   || AT_class (a) == dw_val_class_macptr
+   || AT_class (a) == dw_val_class_high_pc));
   return a-dw_attr_val.v.val_lbl_id;
 }
 
@@ -8902,6 +8923,7 @@ print_die (dw_die_ref die, FILE *outfile
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:
@@ -9081,6 +9103,7 @@ attr_checksum (dw_attr_ref at, struct md
 case dw_val_class_lbl_id:
 case dw_val_class_lineptr:
 case dw_val_class_macptr:
+case dw_val_class_high_pc:
   break;
 
 case dw_val_class_file:
@@ -9353,6 +9376,7 @@ attr_checksum_ordered (enum dwarf_tag ta
 case dw_val_class_lbl_id:
 case dw_val_class_lineptr:
 case dw_val_class_macptr:
+case dw_val_class_high_pc:
   break;
 
 case dw_val_class_file:
@@ -9812,6 +9836,7 @@ same_dw_val_p (const dw_val_node *v1, co
 case 

Use const offset for DW_AT_high_pc and end of loc list entries (issue6279043)

2012-06-01 Thread Cary Coutant
This patch is for the google/gcc-4_6 branch.

[Revised to fix an latent bug exposed by changes to the numbering of the
slots in .debug_addr. The location list comparison code had an assertion
that two otherwise equal location expressions would have the same opcode
sizes, but that's not always true with split dwarf because of LEB128
operands to the DW_OP_GNU_addr_index operator.]

Import pending patch from upstream to generate DW_AT_high_pc as a constant
offset relative to DW_AT_low_pc.  When splitting DWARF info, generate new
format for location list entries using a start symbol and a length.
Together, these changes reduce the size of the .debug_addr section by half.

Tested with GCC test suite and validate_failures.py.


2012-04-27  Mark Wielaard  m...@redhat.com
Cary Coutant  ccout...@google.com

include/
* dwarf2.h (enum dwarf_location_list_entry_type): New enum.

gcc/
* dwarf2out.c (enum dw_val_class): Add dw_val_class_high_pc.
(struct dw_loc_list_struct): Remove end_index.
(add_AT_low_high_pc): New function.
(AT_lbl): Handle dw_val_class_high_pc.
(print_die): Likewise.
(attr_checksum): Likewise.
(attr_checksum_ordered): Likewise.
(same_dw_val_p): Likewise.
(size_of_die): Likewise.
(value_format): Likewise.
(new_loc_list): Remove end_index.
(output_loc_list): Use new DW_LLE_start_length_entry format.
(output_die): Handle dw_val_class_high_pc.
(gen_subprogram_die): Use add_AT_low_high_pc.
(add_high_low_attributes): Likewise.
(compare_loc_operands): Relax irrelevant assertion when splitting
DWARF.
(index_location_lists): Remove end_index.
(dwarf2out_finish): Use add_AT_low_high_pc.


Index: include/dwarf2.h
===
--- include/dwarf2.h(revision 188123)
+++ include/dwarf2.h(working copy)
@@ -750,6 +750,17 @@ enum dwarf_line_number_x_ops
 DW_LNE_hi_user = 0xff
   };
 
+/* Type codes for location list entries.
+   Extension for Fission.  See http://gcc.gnu.org/wiki/DebugFission.  */
+
+enum dwarf_location_list_entry_type
+  {
+DW_LLE_end_of_list_entry = 0,
+DW_LLE_base_address_selection_entry = 1,
+DW_LLE_start_end_entry = 2,
+DW_LLE_start_length_entry = 3
+  };
+
 /* Call frame information.  */
 enum dwarf_call_frame_info
   {
Index: gcc/dwarf2out.c
===
--- gcc/dwarf2out.c (revision 188123)
+++ gcc/dwarf2out.c (working copy)
@@ -4366,7 +4366,8 @@ enum dw_val_class
   dw_val_class_file,
   dw_val_class_data8,
   dw_val_class_decl_ref,
-  dw_val_class_vms_delta
+  dw_val_class_vms_delta,
+  dw_val_class_high_pc
 };
 
 /* Describe a floating point constant value, or a vector constant value.  */
@@ -4438,8 +4439,7 @@ typedef struct GTY(()) dw_loc_list_struc
   dw_loc_list_ref dw_loc_next;
   const char *begin; /* Label and index for begin address of range */
   unsigned int begin_index;
-  const char *end;  /* Label and index for end address of range */
-  unsigned int end_index;
+  const char *end;  /* Label for end address of range */
   char *ll_symbol; /* Label for beginning of location list.
  Only on head of list */
   const char *section; /* Section this loclist is relative to */
@@ -7566,6 +7566,26 @@ add_AT_data8 (dw_die_ref die, enum dwarf
   add_dwarf_attr (die, attr);
 }
 
+/* Add DW_AT_low_pc and DW_AT_high_pc to a DIE.  */
+static inline void
+add_AT_low_high_pc (dw_die_ref die, const char *lbl_low, const char *lbl_high)
+{
+  dw_attr_node attr;
+
+  attr.dw_attr = DW_AT_low_pc;
+  attr.dw_attr_val.val_class = dw_val_class_lbl_id;
+  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_low);
+  add_dwarf_attr (die, attr);
+
+  attr.dw_attr = DW_AT_high_pc;
+  if (dwarf_version  4)
+attr.dw_attr_val.val_class = dw_val_class_lbl_id;
+  else
+attr.dw_attr_val.val_class = dw_val_class_high_pc;
+  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_high);
+  add_dwarf_attr (die, attr);
+}
+
 /* Hash and equality functions for debug_str_hash.  */
 
 static hashval_t
@@ -8048,7 +8068,8 @@ AT_lbl (dw_attr_ref a)
 {
   gcc_assert (a  (AT_class (a) == dw_val_class_lbl_id
|| AT_class (a) == dw_val_class_lineptr
-   || AT_class (a) == dw_val_class_macptr));
+   || AT_class (a) == dw_val_class_macptr
+   || AT_class (a) == dw_val_class_high_pc));
   return a-dw_attr_val.v.val_lbl_id;
 }
 
@@ -8902,6 +8923,7 @@ print_die (dw_die_ref die, FILE *outfile
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:
@@ -9081,6 +9103,7 @@ attr_checksum (dw_attr_ref at, struct md
 case dw_val_class_lbl_id:
 case