Commit 3362b6b6 by Sterling Augustine Committed by Sterling Augustine

2013-04-24 Sterling Augustine <saugustine@google.com>

	* dwarf2out.c (skeleton_debug_str_hash, add_skeleton_AT_string)
	(comp_dir_string, debug_str_dwo_section): New.
	(DEBUG_STR_DWO_SECTION): Rename to ...
	(DEBUG_DWO_STR_SECTION): ... this.
	(DEBUG_NORM_STR_SECTION): Delete.
	(DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS): Edit definitions.
	(DEBUG_STR_DWO_SECTION_FLAGS): New.
	(find_AT_string): Move most logic to ...
	(find_AT_string_in_table): ... here.  New.
	(add_top_level_skeleton_die_attrs): Call comp_dir_string and
	add_skeleton_AT_string.  Delete logic.
	(output_skeleton_debug_sections): Remove call to
	add_top_level_skeleton_die_attrs.
	(add_comp_dir_attribute): Move logic to comp_dir_string.
	(dwarf2out_init): Initialize debug_str_dwo_section.
	(output_indirect_string): Call find_string_form.
	(output_indirect_strings): Rewrite.
	(prune_unused_types): Empty skeleton_debug_str_hash.
	Call get_skeleton_type_unit and add_top_level_skeleton_die_attrs.
	(dwarf2out_finish):  Call output_indirect_strings.

From-SVN: r198259
parent e93e18e9
2013-04-24 Sterling Augustine <saugustine@google.com>
* dwarf2out.c (skeleton_debug_str_hash, add_skeleton_AT_string)
(comp_dir_string, debug_str_dwo_section): New.
(DEBUG_STR_DWO_SECTION): Rename to ...
(DEBUG_DWO_STR_SECTION): ... this.
(DEBUG_NORM_STR_SECTION): Delete.
(DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS): Edit definitions.
(DEBUG_STR_DWO_SECTION_FLAGS): New.
(find_AT_string): Move most logic to ...
(find_AT_string_in_table): ... here. New.
(add_top_level_skeleton_die_attrs): Call comp_dir_string and
add_skeleton_AT_string. Delete logic.
(output_skeleton_debug_sections): Remove call to
add_top_level_skeleton_die_attrs.
(add_comp_dir_attribute): Move logic to comp_dir_string.
(dwarf2out_init): Initialize debug_str_dwo_section.
(output_indirect_string): Call find_string_form.
(output_indirect_strings): Rewrite.
(prune_unused_types): Empty skeleton_debug_str_hash.
Call get_skeleton_type_unit and add_top_level_skeleton_die_attrs.
(dwarf2out_finish): Call output_indirect_strings.
2013-04-24 Paolo Carlini <paolo.carlini@oracle.com> 2013-04-24 Paolo Carlini <paolo.carlini@oracle.com>
* doc/cpp.texi: Remove __GXX_EXPERIMENTAL_CXX1Y__. * doc/cpp.texi: Remove __GXX_EXPERIMENTAL_CXX1Y__.
......
...@@ -157,6 +157,7 @@ static GTY(()) section *debug_loc_section; ...@@ -157,6 +157,7 @@ static GTY(()) section *debug_loc_section;
static GTY(()) section *debug_pubnames_section; static GTY(()) section *debug_pubnames_section;
static GTY(()) section *debug_pubtypes_section; static GTY(()) section *debug_pubtypes_section;
static GTY(()) section *debug_str_section; static GTY(()) section *debug_str_section;
static GTY(()) section *debug_str_dwo_section;
static GTY(()) section *debug_str_offsets_section; static GTY(()) section *debug_str_offsets_section;
static GTY(()) section *debug_ranges_section; static GTY(()) section *debug_ranges_section;
static GTY(()) section *debug_frame_section; static GTY(()) section *debug_frame_section;
...@@ -206,6 +207,28 @@ struct GTY(()) indirect_string_node { ...@@ -206,6 +207,28 @@ struct GTY(()) indirect_string_node {
static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash; static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash;
/* With split_debug_info, both the comp_dir and dwo_name go in the
main object file, rather than the dwo, similar to the force_direct
parameter elsewhere but with additional complications:
1) The string is needed in both the main object file and the dwo.
That is, the comp_dir and dwo_name will appear in both places.
2) Strings can use three forms: DW_FORM_string, DW_FORM_strp or
DW_FORM_GNU_str_index.
3) GCC chooses the form to use late, depending on the size and
reference count.
Rather than forcing the all debug string handling functions and
callers to deal with these complications, simply use a separate,
special-cased string table for any attribute that should go in the
main object file. This limits the complexity to just the places
that need it. */
static GTY ((param_is (struct indirect_string_node)))
htab_t skeleton_debug_str_hash;
static GTY(()) int dw2_string_counter; static GTY(()) int dw2_string_counter;
/* True if the compilation unit places functions in more than one section. */ /* True if the compilation unit places functions in more than one section. */
...@@ -3197,6 +3220,8 @@ static bool generic_type_p (tree); ...@@ -3197,6 +3220,8 @@ static bool generic_type_p (tree);
static void schedule_generic_params_dies_gen (tree t); static void schedule_generic_params_dies_gen (tree t);
static void gen_scheduled_generic_parms_dies (void); static void gen_scheduled_generic_parms_dies (void);
static const char *comp_dir_string (void);
/* enum for tracking thread-local variables whose address is really an offset /* enum for tracking thread-local variables whose address is really an offset
relative to the TLS pointer, which will need link-time relocation, but will relative to the TLS pointer, which will need link-time relocation, but will
not need relocation by the DWARF consumer. */ not need relocation by the DWARF consumer. */
...@@ -3310,11 +3335,11 @@ new_addr_loc_descr (rtx addr, enum dtprel_bool dtprel) ...@@ -3310,11 +3335,11 @@ new_addr_loc_descr (rtx addr, enum dtprel_bool dtprel)
(!dwarf_split_debug_info \ (!dwarf_split_debug_info \
? (DEBUG_NORM_STR_OFFSETS_SECTION) : (DEBUG_DWO_STR_OFFSETS_SECTION)) ? (DEBUG_NORM_STR_OFFSETS_SECTION) : (DEBUG_DWO_STR_OFFSETS_SECTION))
#endif #endif
#define DEBUG_DWO_STR_SECTION ".debug_str.dwo" #ifndef DEBUG_STR_DWO_SECTION
#define DEBUG_NORM_STR_SECTION ".debug_str" #define DEBUG_STR_DWO_SECTION ".debug_str.dwo"
#endif
#ifndef DEBUG_STR_SECTION #ifndef DEBUG_STR_SECTION
#define DEBUG_STR_SECTION \ #define DEBUG_STR_SECTION ".debug_str"
(!dwarf_split_debug_info ? (DEBUG_NORM_STR_SECTION) : (DEBUG_DWO_STR_SECTION))
#endif #endif
#ifndef DEBUG_RANGES_SECTION #ifndef DEBUG_RANGES_SECTION
#define DEBUG_RANGES_SECTION ".debug_ranges" #define DEBUG_RANGES_SECTION ".debug_ranges"
...@@ -3331,11 +3356,12 @@ new_addr_loc_descr (rtx addr, enum dtprel_bool dtprel) ...@@ -3331,11 +3356,12 @@ new_addr_loc_descr (rtx addr, enum dtprel_bool dtprel)
/* Section flags for .debug_str section. */ /* Section flags for .debug_str section. */
#define DEBUG_STR_SECTION_FLAGS \ #define DEBUG_STR_SECTION_FLAGS \
(dwarf_split_debug_info \ (HAVE_GAS_SHF_MERGE && flag_merge_debug_strings \
? SECTION_DEBUG | SECTION_EXCLUDE \
: (HAVE_GAS_SHF_MERGE && flag_merge_debug_strings \
? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1 \ ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1 \
: SECTION_DEBUG)) : SECTION_DEBUG)
/* Section flags for .debug_str.dwo section. */
#define DEBUG_STR_DWO_SECTION_FLAGS (SECTION_DEBUG | SECTION_EXCLUDE)
/* Labels we insert at beginning sections we can reference instead of /* Labels we insert at beginning sections we can reference instead of
the section names themselves. */ the section names themselves. */
...@@ -3819,19 +3845,15 @@ debug_str_eq (const void *x1, const void *x2) ...@@ -3819,19 +3845,15 @@ debug_str_eq (const void *x1, const void *x2)
(const char *)x2) == 0; (const char *)x2) == 0;
} }
/* Add STR to the indirect string hash table. */ /* Add STR to the given string hash table. */
static struct indirect_string_node * static struct indirect_string_node *
find_AT_string (const char *str) find_AT_string_in_table (const char *str, htab_t table)
{ {
struct indirect_string_node *node; struct indirect_string_node *node;
void **slot; void **slot;
if (! debug_str_hash) slot = htab_find_slot_with_hash (table, str,
debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
debug_str_eq, NULL);
slot = htab_find_slot_with_hash (debug_str_hash, str,
htab_hash_string (str), INSERT); htab_hash_string (str), INSERT);
if (*slot == NULL) if (*slot == NULL)
{ {
...@@ -3846,6 +3868,18 @@ find_AT_string (const char *str) ...@@ -3846,6 +3868,18 @@ find_AT_string (const char *str)
return node; return node;
} }
/* Add STR to the indirect string hash table. */
static struct indirect_string_node *
find_AT_string (const char *str)
{
if (! debug_str_hash)
debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
debug_str_eq, NULL);
return find_AT_string_in_table (str, debug_str_hash);
}
/* Add a string attribute value to a DIE. */ /* Add a string attribute value to a DIE. */
static inline void static inline void
...@@ -8680,6 +8714,31 @@ add_AT_pubnames (dw_die_ref die) ...@@ -8680,6 +8714,31 @@ add_AT_pubnames (dw_die_ref die)
add_AT_flag (die, DW_AT_GNU_pubnames, 1); add_AT_flag (die, DW_AT_GNU_pubnames, 1);
} }
/* Add a string attribute value to a skeleton DIE. */
static inline void
add_skeleton_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind,
const char *str)
{
dw_attr_node attr;
struct indirect_string_node *node;
if (! skeleton_debug_str_hash)
skeleton_debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
debug_str_eq, NULL);
node = find_AT_string_in_table (str, skeleton_debug_str_hash);
find_string_form (node);
if (node->form == DW_FORM_GNU_str_index)
node->form = DW_FORM_strp;
attr.dw_attr = attr_kind;
attr.dw_attr_val.val_class = dw_val_class_str;
attr.dw_attr_val.val_entry = NULL;
attr.dw_attr_val.v.val_str = node;
add_dwarf_attr (die, &attr);
}
/* Helper function to generate top-level dies for skeleton debug_info and /* Helper function to generate top-level dies for skeleton debug_info and
debug_types. */ debug_types. */
...@@ -8687,18 +8746,11 @@ static void ...@@ -8687,18 +8746,11 @@ static void
add_top_level_skeleton_die_attrs (dw_die_ref die) add_top_level_skeleton_die_attrs (dw_die_ref die)
{ {
const char *dwo_file_name = concat (aux_base_name, ".dwo", NULL); const char *dwo_file_name = concat (aux_base_name, ".dwo", NULL);
dw_attr_ref attr; const char *comp_dir = comp_dir_string ();
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
having a .debug_str section. We know that they exist in the die because
we just added them. */
attr = get_AT (die, DW_AT_GNU_dwo_name);
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;
add_skeleton_AT_string (die, DW_AT_GNU_dwo_name, dwo_file_name);
if (comp_dir != NULL)
add_skeleton_AT_string (die, DW_AT_comp_dir, comp_dir);
add_AT_pubnames (die); add_AT_pubnames (die);
add_AT_lineptr (die, DW_AT_GNU_addr_base, debug_addr_section_label); add_AT_lineptr (die, DW_AT_GNU_addr_base, debug_addr_section_label);
} }
...@@ -8732,9 +8784,6 @@ output_skeleton_debug_sections (dw_die_ref comp_unit) ...@@ -8732,9 +8784,6 @@ output_skeleton_debug_sections (dw_die_ref comp_unit)
remove_AT (comp_unit, DW_AT_producer); remove_AT (comp_unit, DW_AT_producer);
remove_AT (comp_unit, DW_AT_language); 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);
switch_to_section (debug_skeleton_info_section); switch_to_section (debug_skeleton_info_section);
ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_info_section_label); ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_info_section_label);
...@@ -15787,16 +15836,21 @@ add_gnat_descriptive_type_attribute (dw_die_ref die, tree type, ...@@ -15787,16 +15836,21 @@ add_gnat_descriptive_type_attribute (dw_die_ref die, tree type,
add_AT_die_ref (die, DW_AT_GNAT_descriptive_type, dtype_die); add_AT_die_ref (die, DW_AT_GNAT_descriptive_type, dtype_die);
} }
/* Generate a DW_AT_comp_dir attribute for DIE. */ /* Retrieve the comp_dir string suitable for use with DW_AT_comp_dir. */
static void static const char *
add_comp_dir_attribute (dw_die_ref die) comp_dir_string (void)
{ {
const char *wd = get_src_pwd (); const char *wd;
char *wd1; char *wd1;
static const char *cached_wd = NULL;
if (cached_wd != NULL)
return cached_wd;
wd = get_src_pwd ();
if (wd == NULL) if (wd == NULL)
return; return NULL;
if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR) if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR)
{ {
...@@ -15810,7 +15864,18 @@ add_comp_dir_attribute (dw_die_ref die) ...@@ -15810,7 +15864,18 @@ add_comp_dir_attribute (dw_die_ref die)
wd = wd1; wd = wd1;
} }
add_AT_string (die, DW_AT_comp_dir, remap_debug_filename (wd)); cached_wd = remap_debug_filename (wd);
return cached_wd;
}
/* Generate a DW_AT_comp_dir attribute for DIE. */
static void
add_comp_dir_attribute (dw_die_ref die)
{
const char * wd = comp_dir_string ();
if (wd != NULL)
add_AT_string (die, DW_AT_comp_dir, wd);
} }
/* Return the default for DW_AT_lower_bound, or -1 if there is not any /* Return the default for DW_AT_lower_bound, or -1 if there is not any
...@@ -21730,6 +21795,8 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) ...@@ -21730,6 +21795,8 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
DEBUG_SKELETON_INFO_SECTION_LABEL, 0); DEBUG_SKELETON_INFO_SECTION_LABEL, 0);
debug_loc_section = get_section (DEBUG_DWO_LOC_SECTION, debug_loc_section = get_section (DEBUG_DWO_LOC_SECTION,
SECTION_DEBUG | SECTION_EXCLUDE, NULL); SECTION_DEBUG | SECTION_EXCLUDE, NULL);
debug_str_dwo_section = get_section (DEBUG_STR_DWO_SECTION,
DEBUG_STR_DWO_SECTION_FLAGS, NULL);
} }
debug_aranges_section = get_section (DEBUG_ARANGES_SECTION, debug_aranges_section = get_section (DEBUG_ARANGES_SECTION,
SECTION_DEBUG, NULL); SECTION_DEBUG, NULL);
...@@ -21854,7 +21921,6 @@ output_index_string (void **h, void *v) ...@@ -21854,7 +21921,6 @@ output_index_string (void **h, void *v)
/* Assert that the strings are output in the same order as their /* Assert that the strings are output in the same order as their
indexes were assigned. */ indexes were assigned. */
gcc_assert (*cur_idx == node->index); gcc_assert (*cur_idx == node->index);
ASM_OUTPUT_LABEL (asm_out_file, node->label);
assemble_string (node->str, strlen (node->str) + 1); assemble_string (node->str, strlen (node->str) + 1);
*cur_idx += 1; *cur_idx += 1;
} }
...@@ -21869,6 +21935,7 @@ output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED) ...@@ -21869,6 +21935,7 @@ output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED)
{ {
struct indirect_string_node *node = (struct indirect_string_node *) *h; struct indirect_string_node *node = (struct indirect_string_node *) *h;
node->form = find_string_form (node);
if (node->form == DW_FORM_strp && node->refcount > 0) if (node->form == DW_FORM_strp && node->refcount > 0)
{ {
ASM_OUTPUT_LABEL (asm_out_file, node->label); ASM_OUTPUT_LABEL (asm_out_file, node->label);
...@@ -21883,21 +21950,21 @@ output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED) ...@@ -21883,21 +21950,21 @@ output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED)
static void static void
output_indirect_strings (void) output_indirect_strings (void)
{ {
if (!dwarf_split_debug_info)
{
switch_to_section (debug_str_section); switch_to_section (debug_str_section);
if (!dwarf_split_debug_info)
htab_traverse (debug_str_hash, output_indirect_string, NULL); htab_traverse (debug_str_hash, output_indirect_string, NULL);
}
else else
{ {
unsigned int offset = 0; unsigned int offset = 0;
unsigned int cur_idx = 0; unsigned int cur_idx = 0;
htab_traverse (skeleton_debug_str_hash, output_indirect_string, NULL);
switch_to_section (debug_str_offsets_section); switch_to_section (debug_str_offsets_section);
htab_traverse_noresize (debug_str_hash, htab_traverse_noresize (debug_str_hash,
output_index_string_offset, output_index_string_offset,
&offset); &offset);
switch_to_section (debug_str_section); switch_to_section (debug_str_dwo_section);
htab_traverse_noresize (debug_str_hash, htab_traverse_noresize (debug_str_hash,
output_index_string, output_index_string,
&cur_idx); &cur_idx);
...@@ -22312,6 +22379,8 @@ prune_unused_types (void) ...@@ -22312,6 +22379,8 @@ prune_unused_types (void)
if (debug_str_hash) if (debug_str_hash)
htab_empty (debug_str_hash); htab_empty (debug_str_hash);
if (skeleton_debug_str_hash)
htab_empty (skeleton_debug_str_hash);
prune_unused_types_prune (comp_unit_die ()); prune_unused_types_prune (comp_unit_die ());
for (node = limbo_die_list; node; node = node->next) for (node = limbo_die_list; node; node = node->next)
prune_unused_types_prune (node->die); prune_unused_types_prune (node->die);
...@@ -23781,9 +23850,18 @@ dwarf2out_finish (const char *filename) ...@@ -23781,9 +23850,18 @@ dwarf2out_finish (const char *filename)
optimize_location_lists (comp_unit_die ()); optimize_location_lists (comp_unit_die ());
save_macinfo_strings (); save_macinfo_strings ();
if (dwarf_split_debug_info) if (dwarf_split_debug_info)
{ {
unsigned int index = 0; unsigned int index = 0;
/* Add attributes common to skeleton compile_units and
type_units. Because these attributes include strings, it
must be done before freezing the string table. Top-level
skeleton die attrs are added when the skeleton type unit is
created, so ensure it is created by this point. */
add_top_level_skeleton_die_attrs (main_comp_unit_die);
(void) get_skeleton_type_unit ();
htab_traverse_noresize (debug_str_hash, index_string, &index); htab_traverse_noresize (debug_str_hash, index_string, &index);
} }
...@@ -23931,7 +24009,7 @@ dwarf2out_finish (const char *filename) ...@@ -23931,7 +24009,7 @@ dwarf2out_finish (const char *filename)
} }
/* If we emitted any indirect strings, output the string table too. */ /* If we emitted any indirect strings, output the string table too. */
if (debug_str_hash) if (debug_str_hash || skeleton_debug_str_hash)
output_indirect_strings (); output_indirect_strings ();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment