[google/4.6] Fix problems with -gfission (issue5844043)
This is for the google/gcc-4_6 branch only. This revised patch fixes several problems with -gfission: - Bad index for range list in the compile unit DIE. - DW_AT_ranges attribute for compile unit in the wrong file. - Incorrect size for skeleton type unit DIEs. - Wrote location expression using DW_OP_addr to DWO file. - Emitted skeleton debug section even when there is no debug info. It also addresses a problem with the previous patch that resulted in an ICE when a location expression is removed after creating an addr_table entry for it. Tested: bootstrap, core, mantle, crust (in progress). 2012-03-19 Sterling Augustine saugust...@google.com Cary Coutant ccout...@google.com * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_addr_index. (new_loc_descr): Initialize val_index. (size_of_loc_descr): Add DW_OP_GNU_addr_index. (output_loc_operands): Likewise. (output_loc_operands_raw): Likewise. (build_cfa_loc): Initialize val_index. (new_addr_loc_descr): New function. (add_AT_flag): Initialize val_index. (add_AT_int): Likewise. (add_AT_unsigned): Likewise. (add_AT_double): Likewise. (add_AT_vec): Likewise. (add_AT_data8): Likewise. (add_AT_string): Likewise. (add_AT_die_ref): Likewise. (add_AT_fde_ref): Likewise. (add_AT_loc): Likewise. (add_AT_loc_list): Likewise. (add_addr_table_entry): Change if to assert. (remove_addr_table_entry): New function. (add_AT_addr): Add force_direct parameter; adjust all callers. Initialize val_index. (add_AT_file): Initialize val_index. (add_AT_vms_delta): Likewise. (add_AT_lbl_id): Add force_direct parameter; adjust all callers. Initialize val_index. (add_AT_lineptr): Initialize val_index. (add_AT_macptr): Likewise. (add_AT_offset): Likewise. (add_AT_range_list): Add force_direct parameter; adjust all callers. Initialize val_index. (size_of_die): Check for AT_index. (value_format): Likewise. (output_attr_index_or_value): Likewise. (output_die): Fix format warning. (add_top_level_skeleton_die_attrs): Don't add DW_AT_stmt_list here. (get_skeleton_type_unit): New function. (output_skeleton_debug_sections): Add comp_unit parameter; adjust caller; don't generate debug_skeleton_info_section_label or debug_skeleton_abbrev_section_label here; call get_skeleton_type_unit. (output_comdat_type_unit): Remove assert; call get_skeleton_type_unit. (add_ranges_by_labels): Add force_direct parameter; adjust callers. (address_of_int_loc_descriptor): Initialize val_index. (mem_loc_descriptor): Initialize val_index; call new_addr_loc_descr. (implicit_ptr_descriptor): Don't generate DW_OP_GNU_implicit_pointer when splitting debug info. Initialize val_index. (loc_descriptor): Initialize val_index; call new_addr_loc_descr. (loc_list_from_tree): Likewise. (add_const_value_attribute): Likewise. (dwarf2out_init): Generate debug_skeleton_info_section_label and debug_skeleton_abbrev_section_label here. (output_indirect_string): Check for DW_FORM_strp instead of label and refcount. (output_addr_table): Check for removed entries, handle dw_val_class_loc. (resolve_addr_in_expr): Handle DW_OP_GNU_addr_index. (resolve_addr): Remove entry from addr_table if necessary. (hash_loc_operands): Add DW_OP_GNU_addr_index. (compare_loc_operands): Likewise. (dwarf2out_finish): Put DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_stmt_list, DW_AT_macptr in skeleton comp_unit DIE; write skeleton debug sections if regular debug section emitted. Index: dwarf2out.c === --- dwarf2out.c (revision 18) +++ dwarf2out.c (working copy) @@ -4779,6 +4779,8 @@ dwarf_stack_op_name (unsigned int op) return DW_OP_GNU_encoded_addr; case DW_OP_GNU_implicit_pointer: return DW_OP_GNU_implicit_pointer; +case DW_OP_GNU_addr_index: + return DW_OP_GNU_addr_index; default: return OP_unknown; @@ -4797,8 +4799,10 @@ new_loc_descr (enum dwarf_location_atom descr-dw_loc_opc = op; descr-dw_loc_oprnd1.val_class = dw_val_class_unsigned_const; + descr-dw_loc_oprnd1.val_index = -1U; descr-dw_loc_oprnd1.v.val_unsigned = oprnd1; descr-dw_loc_oprnd2.val_class = dw_val_class_unsigned_const; + descr-dw_loc_oprnd2.val_index = -1U; descr-dw_loc_oprnd2.v.val_unsigned = oprnd2; return descr; @@ -4897,6 +4901,9 @@ size_of_loc_descr (dw_loc_descr_ref loc) case DW_OP_addr: size += DWARF2_ADDR_SIZE; break; +case DW_OP_GNU_addr_index: + size += size_of_uleb128 (loc-dw_loc_oprnd1.v.val_unsigned);
[google/4.6] Fix problems with -gfission (issue5844043)
For google/gcc-4_6 branch. This patch fixes several problems with -gfission: - Bad index for range list in the compile unit DIE. - DW_AT_ranges attribute for compile unit in the wrong file. - Incorrect size for skeleton type unit DIEs. - Wrote location expression using DW_OP_addr to DWO file. - Emitted skeleton debug section even when there is no debug info. Tested: bootstrap, gcc regression tests, hand testing on -gfission test cases. include/ 2012-03-15 Sterling Augustine saugust...@google.com Cary Coutant ccout...@google.com * dwarf2.h (enum dwarf_location_atom): Add DW_OP_GNU_addr_index. gcc/ 2012-03-15 Sterling Augustine saugust...@google.com Cary Coutant ccout...@google.com * dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_addr_index. (size_of_loc_descr): Likewise. (output_loc_operands): Likewise. (output_loc_operands_raw): Likewise. (new_addr_loc_descr): New function. (add_AT_range_list): Store index in AT_index. (size_of_die): For range_list, use AT_index for index value. (add_top_level_skeleton_die_attrs): Don't add DW_AT_stmt_list here. (get_skeleton_type_unit): New function. (output_skeleton_debug_sections): Add comp_unit parameter; adjust caller. Don't allocate new comp unit DIE here. Move allocation of debug_skeleton_info_section_label and debug_skeleton_abbrev_section_label to dwarf2out_init. Call get_skeleton_type_unit. (output_comdat_type_unit): Remove assert; call get_skeleton_type_unit. (mem_loc_descriptor): Call new_addr_loc_desc. (loc_descriptor): Likewise. (loc_list_from_tree): Likewise. (add_const_value_attribute): Likewise. (dwarf2out_init): Allocate debug_skeleton_info_section_label and debug_skeleton_abbrev_section_label. (output_indirect_string): Check for DW_FORM_strp instead of label and refcount. (output_addr_table): Add case for dw_val_class_loc. (resolve_addr_in_expr): Handle DW_OP_addr_index. (hash_loc_operands): Likewise. (compare_loc_operands): Likewise. (dwarf2out_finish): Allocate skeleton compile unit DIE here; add range lists, DW_AT_stmt_list, and DW_AT_macro_info to it instead of dwo compile unit DIE. Output skeleton debug info section only if there is debug info. Index: include/dwarf2.h === --- include/dwarf2.h(revision 185451) +++ include/dwarf2.h(working copy) @@ -547,6 +547,8 @@ enum dwarf_location_atom DW_OP_GNU_uninit = 0xf0, DW_OP_GNU_encoded_addr = 0xf1, DW_OP_GNU_implicit_pointer = 0xf2, +/* Extension for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ +DW_OP_GNU_addr_index = 0xfb, /* HP extensions. */ DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */ DW_OP_HP_is_value= 0xe1, Index: gcc/dwarf2out.c === --- gcc/dwarf2out.c (revision 185451) +++ gcc/dwarf2out.c (working copy) @@ -4779,6 +4779,8 @@ dwarf_stack_op_name (unsigned int op) return DW_OP_GNU_encoded_addr; case DW_OP_GNU_implicit_pointer: return DW_OP_GNU_implicit_pointer; +case DW_OP_GNU_addr_index: + return DW_OP_GNU_addr_index; default: return OP_unknown; @@ -4897,6 +4899,9 @@ size_of_loc_descr (dw_loc_descr_ref loc) case DW_OP_addr: size += DWARF2_ADDR_SIZE; break; +case DW_OP_GNU_addr_index: + size += size_of_uleb128 (loc-dw_loc_oprnd1.v.val_unsigned); + break; case DW_OP_const1u: case DW_OP_const1s: size += 1; @@ -5275,6 +5280,11 @@ output_loc_operands (dw_loc_descr_ref lo } break; +case DW_OP_GNU_addr_index: + dw2_asm_output_data_uleb128 (loc-dw_loc_oprnd1.v.val_unsigned, + (address index)); + break; + case DW_OP_GNU_implicit_pointer: { char label[MAX_ARTIFICIAL_LABEL_BYTES @@ -5343,6 +5353,7 @@ output_loc_operands_raw (dw_loc_descr_re switch (loc-dw_loc_opc) { case DW_OP_addr: +case DW_OP_GNU_addr_index: case DW_OP_implicit_value: /* We cannot output addresses in .cfi_escape, only bytes. */ gcc_unreachable (); @@ -6314,6 +6325,7 @@ static inline dw_loc_descr_ref AT_loc (d static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute, dw_loc_list_ref); static inline dw_loc_list_ref AT_loc_list (dw_attr_ref); +static unsigned int add_addr_table_entry (dw_attr_node *); static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx); static inline rtx AT_addr (dw_attr_ref); static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *); @@ -6571,6 +6583,31 @@ static bool generic_type_p (tree); static void