[google/4.6] Fix problems with -gfission (issue5844043)
Cary Coutant
ccoutant@google.com
Fri Mar 16 02:07:00 GMT 2012
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 <saugustine@google.com>
Cary Coutant <ccoutant@google.com>
* dwarf2.h (enum dwarf_location_atom): Add
DW_OP_GNU_addr_index.
gcc/
2012-03-15 Sterling Augustine <saugustine@google.com>
Cary Coutant <ccoutant@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 schedule_generic_params_dies_gen (tree t);
static void gen_scheduled_generic_parms_dies (void);
+/* Return a pointer to a newly allocated address location description. If
+ dwarf_split_debug_info is true, then record the address with the appropriate
+ relocation. */
+static inline dw_loc_descr_ref
+new_addr_loc_descr (rtx addr, int dtprel)
+{
+ dw_loc_descr_ref ref = new_loc_descr (DW_OP_addr, 0, 0);
+
+ ref->dw_loc_oprnd1.val_class = dw_val_class_addr;
+ ref->dw_loc_oprnd1.v.val_addr = addr;
+ if (dwarf_split_debug_info)
+ {
+ dw_attr_node attr;
+
+ attr.dw_attr = DW_AT_location;
+ attr.dw_attr_val.val_class = (dtprel
+ ? dw_val_class_loc : dw_val_class_addr);
+ attr.dw_attr_val.v.val_addr = addr;
+
+ ref->dw_loc_opc = DW_OP_GNU_addr_index;
+ ref->dw_loc_oprnd1.v.val_unsigned = add_addr_table_entry (&attr);
+ }
+ return ref;
+}
+
/* Section names used to hold DWARF debugging information. */
#ifndef DEBUG_INFO_SECTION
@@ -7358,7 +7395,7 @@ AT_class (dw_attr_ref a)
}
/* Return the index for any attribute that will be referenced with a
- DW_FORM_GNU_ref_index of DW_FORM_GNU_addr_index. Strings have their
+ DW_FORM_GNU_ref_index or DW_FORM_GNU_addr_index. Strings have their
indices handled differently to account for reference counting
pruning. */
@@ -7372,7 +7409,7 @@ AT_index (dw_attr_ref a)
}
/* Set the index for any attribute that will be referenced with a
- DW_FORM_GNU_ref_index of DW_FORM_GNU_addr_index. */
+ DW_FORM_GNU_ref_index or DW_FORM_GNU_addr_index. */
static inline void
set_AT_index (dw_attr_ref a, unsigned int index)
@@ -7905,7 +7942,7 @@ add_ref_table_entry (dw_attr_node *attr)
return 0;
}
-/* Add an range_list attribute value to a DIE. */
+/* Add a range_list attribute value to a DIE. */
static void
add_AT_range_list (dw_die_ref die, enum dwarf_attribute attr_kind,
@@ -7919,11 +7956,12 @@ add_AT_range_list (dw_die_ref die, enum
add_dwarf_attr (die, &attr);
if (dwarf_split_debug_info)
{
+ dw_attr_ref a = get_AT (die, DW_AT_ranges);
+
/* There will be two copies of the attr, one in the die, and one in the
- ref table. Substitute the index for the actual offset in the die, and
- save the actual offset in the ref table. */
- get_AT (die, DW_AT_ranges)->dw_attr_val.v.val_offset
- = add_ref_table_entry (&attr);
+ ref table. Store the index in the die, and save the actual offset
+ in the ref table. */
+ set_AT_index (a, add_ref_table_entry (&attr));
}
}
@@ -10901,14 +10939,9 @@ size_of_die (dw_die_ref die)
}
break;
case dw_val_class_loc_list:
- if (dwarf_split_debug_info)
- size += size_of_uleb128 (AT_index (a));
- else
- size += DWARF_OFFSET_SIZE;
- break;
case dw_val_class_range_list:
if (dwarf_split_debug_info)
- size += size_of_uleb128 (a->dw_attr_val.v.val_offset);
+ size += size_of_uleb128 (AT_index (a));
else
size += DWARF_OFFSET_SIZE;
break;
@@ -11867,12 +11900,9 @@ add_AT_pubnames (dw_die_ref die)
static void
add_top_level_skeleton_die_attrs (dw_die_ref die)
{
- /* The splitter will fill in the file name. It would be good to allocate
- a fairly large string here to make it easy for the splitter though. */
const char *dwo_file_name = concat (aux_base_name, ".dwo", NULL);
dw_attr_ref attr;
- add_AT_lineptr (die, DW_AT_stmt_list, debug_line_section_label);
add_comp_dir_attribute (die);
add_AT_string (die, DW_AT_GNU_dwo_name, dwo_file_name);
/* The specification suggests that these attributes be inline to avoid
@@ -11882,17 +11912,31 @@ add_top_level_skeleton_die_attrs (dw_die
attr->dw_attr_val.v.val_str->form = DW_FORM_string;
attr = get_AT (die, DW_AT_comp_dir);
attr->dw_attr_val.v.val_str->form = DW_FORM_string;
- /* The post compile splitter will fill in this value. */
+
add_AT_pubnames (die);
add_AT_lineptr (die, DW_AT_GNU_ref_base, debug_ref_section_label);
add_AT_lineptr (die, DW_AT_GNU_addr_base, debug_addr_section_label);
}
-/* For split_debug_sections with use_type info, all type units int the skeleton
- sections have identical dies (but different headers). This single die will
- be output many times. */
+/* Return the single type-unit die for skeleton type units. */
-static dw_die_ref skeleton_type_unit = NULL;
+static dw_die_ref
+get_skeleton_type_unit (void)
+{
+ /* For split_debug_sections with use_type info, all type units int the
+ skeleton sections have identical dies (but different headers). This single
+ die will be output many times. */
+
+ static dw_die_ref skeleton_type_unit = NULL;
+
+ if (skeleton_type_unit == NULL)
+ {
+ skeleton_type_unit = new_die (DW_TAG_type_unit, NULL, NULL);
+ add_top_level_skeleton_die_attrs (skeleton_type_unit);
+ skeleton_type_unit->die_abbrev = SKELETON_TYPE_DIE_ABBREV;
+ }
+ return skeleton_type_unit;
+}
/* The splitter will fill in this value. */
@@ -11901,21 +11945,19 @@ unsigned char dwo_id_placeholder[8] = {
/* Output skeleton debug sections that point to the dwo file. */
static void
-output_skeleton_debug_sections (void)
+output_skeleton_debug_sections (dw_die_ref comp_unit)
{
- dw_die_ref comp_unit = gen_compile_unit_die (NULL);
-
/* These attributes will be found in the full debug_info section. */
remove_AT (comp_unit, DW_AT_producer);
remove_AT (comp_unit, DW_AT_language);
+ /* Add attributes common to skeleton compile_units and type_units. */
add_top_level_skeleton_die_attrs (comp_unit);
- /* Only the compilation unit gets the dwo_id. */
+
+ /* The dwo_id is only for compile_units. */
add_AT_data8 (comp_unit, DW_AT_GNU_dwo_id, dwo_id_placeholder);
switch_to_section (debug_skeleton_info_section);
- ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
- DEBUG_SKELETON_INFO_SECTION_LABEL, 0);
ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_info_section_label);
/* Produce the skeleton compilation-unit header. This one differs enough from
@@ -11932,8 +11974,6 @@ output_skeleton_debug_sections (void)
+ size_of_die (comp_unit) + 1,
"Length of Compilation Unit Info");
dw2_asm_output_data (2, dwarf_version, "DWARF version number");
- ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label,
- DEBUG_SKELETON_ABBREV_SECTION_LABEL, 0);
dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_skeleton_abbrev_section_label,
debug_abbrev_section,
"Offset Into Abbrev. Section");
@@ -11950,14 +11990,7 @@ output_skeleton_debug_sections (void)
output_die_abbrevs (SKELETON_COMP_DIE_ABBREV, comp_unit);
if (dwarf_version >= 4)
- {
- /* Because all skeleton type_units have identical dies, just generate
- one, and output it repeatedly. */
- skeleton_type_unit = new_die (DW_TAG_type_unit, NULL, NULL);
- add_top_level_skeleton_die_attrs (skeleton_type_unit);
- skeleton_type_unit->die_abbrev = SKELETON_TYPE_DIE_ABBREV;
- output_die_abbrevs (SKELETON_TYPE_DIE_ABBREV, skeleton_type_unit);
- }
+ output_die_abbrevs (SKELETON_TYPE_DIE_ABBREV, get_skeleton_type_unit ());
dw2_asm_output_data (1, 0, "end of skeleton .debug_abbrev");
}
@@ -12020,7 +12053,6 @@ output_comdat_type_unit (comdat_type_nod
{
/* Produce the skeleton type-unit header. */
const char *secname = ".debug_types";
- gcc_assert (skeleton_type_unit);
targetm.asm_out.named_section (secname,
SECTION_DEBUG | SECTION_LINKONCE,
@@ -12033,7 +12065,7 @@ output_comdat_type_unit (comdat_type_nod
dw2_asm_output_data (DWARF_OFFSET_SIZE,
DWARF_COMPILE_UNIT_HEADER_SIZE
- DWARF_INITIAL_LENGTH_SIZE
- + size_of_die (skeleton_type_unit)
+ + size_of_die (get_skeleton_type_unit ())
+ DWARF_TYPE_SIGNATURE_SIZE + DWARF_OFFSET_SIZE,
"Length of Type Unit Info");
dw2_asm_output_data (2, dwarf_version, "DWARF version number");
@@ -12045,7 +12077,7 @@ output_comdat_type_unit (comdat_type_nod
output_signature (node->signature, "Type Signature");
dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, "Offset to Type DIE");
- output_die (skeleton_type_unit);
+ output_die (get_skeleton_type_unit ());
/* dw2_asm_output_data (1, 0, "end of skeleton .debug_types"); */
}
}
@@ -14477,9 +14509,7 @@ mem_loc_descriptor (rtx rtl, enum machin
break;
symref:
- mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
- mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
- mem_loc_result->dw_loc_oprnd1.v.val_addr = rtl;
+ mem_loc_result = new_addr_loc_descr (rtl, 0);
VEC_safe_push (rtx, gc, used_rtx_array, rtl);
break;
@@ -15341,9 +15371,7 @@ loc_descriptor (rtx rtl, enum machine_mo
if (mode != VOIDmode && GET_MODE_SIZE (mode) == DWARF2_ADDR_SIZE
&& (dwarf_version >= 4 || !dwarf_strict))
{
- loc_result = new_loc_descr (DW_OP_addr, 0, 0);
- loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
- loc_result->dw_loc_oprnd1.v.val_addr = rtl;
+ loc_result = new_addr_loc_descr (rtl, 0);
add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
VEC_safe_push (rtx, gc, used_rtx_array, rtl);
}
@@ -16084,9 +16112,15 @@ loc_list_from_tree (tree loc, int want_a
if (! CONSTANT_P (rtl))
return 0;
- ret = new_loc_descr (first_op, 0, 0);
- ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
- ret->dw_loc_oprnd1.v.val_addr = rtl;
+ if (dwarf_split_debug_info && first_op == DW_OP_addr)
+ ret = new_addr_loc_descr (rtl, dtprel);
+ else
+ {
+ ret = new_loc_descr (first_op, 0, 0);
+ ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
+ ret->dw_loc_oprnd1.v.val_addr = rtl;
+ }
+
ret->dtprel = dtprel;
ret1 = new_loc_descr (second_op, 0, 0);
@@ -16134,11 +16168,7 @@ loc_list_from_tree (tree loc, int want_a
return 0;
}
else if (CONSTANT_P (rtl) && const_ok_for_output (rtl))
- {
- ret = new_loc_descr (DW_OP_addr, 0, 0);
- ret->dw_loc_oprnd1.val_class = dw_val_class_addr;
- ret->dw_loc_oprnd1.v.val_addr = rtl;
- }
+ ret = new_addr_loc_descr (rtl, 0);
else
{
enum machine_mode mode;
@@ -17072,9 +17102,7 @@ add_const_value_attribute (dw_die_ref di
dw_loc_descr_ref loc_result;
resolve_one_addr (&rtl, NULL);
rtl_addr:
- loc_result = new_loc_descr (DW_OP_addr, 0, 0);
- loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
- loc_result->dw_loc_oprnd1.v.val_addr = rtl;
+ loc_result = new_addr_loc_descr (rtl, 0);
add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
add_AT_loc (die, DW_AT_location, loc_result);
VEC_safe_push (rtx, gc, used_rtx_array, rtl);
@@ -20211,7 +20239,7 @@ gen_variable_die (tree decl, tree origin
{
/* Optimize the common case. */
if (single_element_loc_list_p (loc)
- && loc->expr->dw_loc_opc == DW_OP_addr
+ && loc->expr->dw_loc_opc == DW_OP_addr
&& loc->expr->dw_loc_next == NULL
&& GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF)
loc->expr->dw_loc_oprnd1.v.val_addr
@@ -22956,6 +22984,8 @@ dwarf2out_init (const char *filename ATT
SECTION_DEBUG, NULL);
debug_skeleton_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
SECTION_DEBUG, NULL);
+ ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label,
+ DEBUG_SKELETON_ABBREV_SECTION_LABEL, 0);
/* Somewhat confusing detail: The skeleton_[abbrev|info] sections stay in
the main .o, but the skeleton_line goes into the split off dwo. */
@@ -22965,6 +22995,8 @@ dwarf2out_init (const char *filename ATT
DEBUG_SKELETON_LINE_SECTION_LABEL, 0);
debug_str_offsets_section = get_section (DEBUG_STR_OFFSETS_SECTION,
SECTION_DEBUG, NULL);
+ ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
+ DEBUG_SKELETON_INFO_SECTION_LABEL, 0);
}
debug_aranges_section = get_section (DEBUG_ARANGES_SECTION,
SECTION_DEBUG, NULL);
@@ -23042,7 +23074,7 @@ output_indirect_string (void **h, void *
{
struct indirect_string_node *node = (struct indirect_string_node *) *h;
- if (node->label && node->refcount)
+ if (node->form == DW_FORM_strp)
{
switch_to_section (debug_str_section);
ASM_OUTPUT_LABEL (asm_out_file, node->label);
@@ -23124,6 +23156,12 @@ output_addr_table (void)
dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, AT_addr (node),
"%s", name);
break;
+ case dw_val_class_loc:
+ gcc_assert (targetm.asm_out.output_dwarf_dtprel);
+ targetm.asm_out.output_dwarf_dtprel (asm_out_file,
+ DWARF2_ADDR_SIZE,
+ AT_addr (node));
+ break;
case dw_val_class_lbl_id:
dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (node), "%s", name);
break;
@@ -23629,23 +23667,32 @@ static bool
resolve_addr_in_expr (dw_loc_descr_ref loc)
{
for (; loc; loc = loc->dw_loc_next)
- if (((loc->dw_loc_opc == DW_OP_addr || loc->dtprel)
- && resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr, NULL))
- || (loc->dw_loc_opc == DW_OP_implicit_value
- && loc->dw_loc_oprnd2.val_class == dw_val_class_addr
- && resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr, NULL)))
- return false;
- else if (loc->dw_loc_opc == DW_OP_GNU_implicit_pointer
- && loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
- {
- dw_die_ref ref
- = lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref);
- if (ref == NULL)
- return false;
- loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
- loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
- loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
- }
+ {
+ if (loc->dw_loc_opc == DW_OP_GNU_addr_index)
+ {
+ unsigned int idx = loc->dw_loc_oprnd1.v.val_unsigned;
+ dw_attr_node *node = VEC_index (dw_attr_node, addr_index_table, idx);
+ if (resolve_one_addr (&node->dw_attr_val.v.val_addr, NULL))
+ return false;
+ }
+ else if (((loc->dw_loc_opc == DW_OP_addr || loc->dtprel)
+ && resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr, NULL))
+ || (loc->dw_loc_opc == DW_OP_implicit_value
+ && loc->dw_loc_oprnd2.val_class == dw_val_class_addr
+ && resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr, NULL)))
+ return false;
+ else if (loc->dw_loc_opc == DW_OP_GNU_implicit_pointer
+ && loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
+ {
+ dw_die_ref ref
+ = lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref);
+ if (ref == NULL)
+ return false;
+ loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+ loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
+ loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
+ }
+ }
return true;
}
@@ -23856,6 +23903,18 @@ hash_loc_operands (dw_loc_descr_ref loc,
}
hash = iterative_hash_rtx (val1->v.val_addr, hash);
break;
+ case DW_OP_GNU_addr_index:
+ {
+ dw_attr_ref attr = VEC_index (dw_attr_node, addr_index_table,
+ val1->v.val_unsigned);
+ if (loc->dtprel)
+ {
+ unsigned char dtprel = 0xd1;
+ hash = iterative_hash_object (dtprel, hash);
+ }
+ hash = iterative_hash_rtx (attr->dw_attr_val.v.val_addr, hash);
+ }
+ break;
case DW_OP_GNU_implicit_pointer:
hash = iterative_hash_object (val2->v.val_int, hash);
break;
@@ -24011,6 +24070,17 @@ compare_loc_operands (dw_loc_descr_ref x
case DW_OP_addr:
hash_addr:
return rtx_equal_p (valx1->v.val_addr, valy1->v.val_addr);
+ case DW_OP_GNU_addr_index:
+ {
+ dw_attr_node *attrx1 = VEC_index (dw_attr_node,
+ addr_index_table,
+ valx1->v.val_unsigned);
+ dw_attr_node *attry1 = VEC_index (dw_attr_node,
+ addr_index_table,
+ valy1->v.val_unsigned);
+ return rtx_equal_p (attrx1->dw_attr_val.v.val_addr,
+ attry1->dw_attr_val.v.val_addr);
+ }
case DW_OP_GNU_implicit_pointer:
return valx1->val_class == dw_val_class_die_ref
&& valx1->val_class == valy1->val_class
@@ -24133,6 +24203,15 @@ dwarf2out_finish (const char *filename)
comdat_type_node *ctnode;
htab_t comdat_type_table;
unsigned int i;
+ dw_die_ref main_comp_unit_die;
+
+ /* When splitting DWARF info, we put some attributes in the
+ skeleton compile_unit DIE that remains in the .o, while
+ most attributes go in the DWO compile_unit_die. */
+ if (dwarf_split_debug_info)
+ main_comp_unit_die = gen_compile_unit_die (NULL);
+ else
+ main_comp_unit_die = comp_unit_die ();
gen_scheduled_generic_parms_dies ();
gen_remaining_tmpl_value_param_die_attribute ();
@@ -24305,10 +24384,10 @@ dwarf2out_finish (const char *filename)
add_AT_addr (comp_unit_die (), DW_AT_entry_pc, const0_rtx);
if (text_section_used)
- add_ranges_by_labels (comp_unit_die (), text_section_label,
+ add_ranges_by_labels (main_comp_unit_die, text_section_label,
text_end_label, &range_list_added);
if (cold_text_section_used)
- add_ranges_by_labels (comp_unit_die (), cold_text_section_label,
+ add_ranges_by_labels (main_comp_unit_die, cold_text_section_label,
cold_end_label, &range_list_added);
for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++)
@@ -24316,10 +24395,10 @@ dwarf2out_finish (const char *filename)
dw_fde_ref fde = &fde_table[fde_idx];
if (!fde->in_std_section)
- add_ranges_by_labels (comp_unit_die (), fde->dw_fde_begin,
+ add_ranges_by_labels (main_comp_unit_die, fde->dw_fde_begin,
fde->dw_fde_end, &range_list_added);
if (fde->dw_fde_second_begin && !fde->second_in_std_section)
- add_ranges_by_labels (comp_unit_die (), fde->dw_fde_second_begin,
+ add_ranges_by_labels (main_comp_unit_die, fde->dw_fde_second_begin,
fde->dw_fde_second_end, &range_list_added);
}
@@ -24328,11 +24407,11 @@ dwarf2out_finish (const char *filename)
}
if (generate_debug_line_table)
- add_AT_lineptr (comp_unit_die (), DW_AT_stmt_list,
+ add_AT_lineptr (main_comp_unit_die, DW_AT_stmt_list,
debug_line_section_label);
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
- add_AT_macptr (comp_unit_die (), DW_AT_macro_info, macinfo_section_label);
+ add_AT_macptr (main_comp_unit_die, DW_AT_macro_info, macinfo_section_label);
if (have_location_lists)
{
@@ -24340,15 +24419,6 @@ dwarf2out_finish (const char *filename)
index_location_lists (comp_unit_die ());
}
- if (dwarf_split_debug_info)
- {
- /* Add a place-holder for the dwo_id to the comp-unit die. Similarly, the
- skeleton die gets a placeholder inside
- output_skeleton_debug_sections. */
- add_AT_data8 (comp_unit_die (), DW_AT_GNU_dwo_id, dwo_id_placeholder);
- output_skeleton_debug_sections ();
- }
-
/* Output all of the compilation units. We put the main one last so that
the offsets are available to output_pubnames. */
for (node = limbo_die_list; node; node = node->next)
@@ -24380,10 +24450,17 @@ dwarf2out_finish (const char *filename)
if (!dwarf_split_debug_info)
add_AT_pubnames (comp_unit_die ());
+ if (dwarf_split_debug_info)
+ /* Add a place-holder for the dwo_id to the comp-unit die. */
+ add_AT_data8 (comp_unit_die (), DW_AT_GNU_dwo_id, dwo_id_placeholder);
+
/* Output the main compilation unit if non-empty or if .debug_macinfo
will be emitted. */
output_comp_unit (comp_unit_die (), debug_info_level >= DINFO_LEVEL_VERBOSE);
+ if (dwarf_split_debug_info && info_section_emitted)
+ output_skeleton_debug_sections (main_comp_unit_die);
+
/* Output the abbreviation table. */
switch_to_section (debug_abbrev_section);
ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
@@ -24465,7 +24542,7 @@ dwarf2out_finish (const char *filename)
dw2_asm_output_data (1, 0, "End compilation unit");
}
- if (dwarf_split_debug_info)
+ if (dwarf_split_debug_info && info_section_emitted)
{
switch_to_section (debug_skeleton_line_section);
ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_line_section_label);
--
This patch is available for review at http://codereview.appspot.com/5844043
More information about the Gcc-patches
mailing list