/* True if the compilation unit places functions in more than one section. */
static GTY(()) bool have_multiple_function_sections = false;
-/* Whether the default text and cold text sections have been used at all. */
-static GTY(()) bool text_section_used = false;
-static GTY(()) bool cold_text_section_used = false;
-
/* The default cold text section. */
static GTY(()) section *cold_text_section;
+/* True if currently in text section. */
+static GTY(()) bool in_text_section_p = false;
+
+/* Last debug-on location in corresponding section. */
+static GTY(()) const char *last_text_label;
+static GTY(()) const char *last_cold_label;
+
+/* Mark debug-on/off locations per section.
+ NULL means the section is not used at all. */
+static GTY(()) vec<const char *, va_gc> *switch_text_ranges;
+static GTY(()) vec<const char *, va_gc> *switch_cold_ranges;
+
/* The DIE for C++14 'auto' in a function return type. */
static GTY(()) dw_die_ref auto_die;
/* Forward declarations for functions defined in this file. */
static void output_call_frame_info (int);
-static void dwarf2out_note_section_used (void);
/* Personality decl of current unit. Used only when assembler does not support
personality CFI. */
fde->dw_fde_current_label = dup_label;
fde->in_std_section = (fnsec == text_section
|| (cold_text_section && fnsec == cold_text_section));
+ fde->ignored_debug = DECL_IGNORED_P (current_function_decl);
+ in_text_section_p = fnsec == text_section;
/* We only want to output line number information for the genuine dwarf2
prologue case, not the eh frame case. */
fde->dw_fde_vms_begin_epilogue = xstrdup (label);
}
+/* Mark the ranges of non-debug subsections in the std text sections. */
+
+static void
+mark_ignored_debug_section (dw_fde_ref fde, bool second)
+{
+ bool std_section;
+ const char *begin_label, *end_label;
+ const char **last_end_label;
+ vec<const char *, va_gc> **switch_ranges;
+
+ if (second)
+ {
+ std_section = fde->second_in_std_section;
+ begin_label = fde->dw_fde_second_begin;
+ end_label = fde->dw_fde_second_end;
+ }
+ else
+ {
+ std_section = fde->in_std_section;
+ begin_label = fde->dw_fde_begin;
+ end_label = fde->dw_fde_end;
+ }
+
+ if (!std_section)
+ return;
+
+ if (in_text_section_p)
+ {
+ last_end_label = &last_text_label;
+ switch_ranges = &switch_text_ranges;
+ }
+ else
+ {
+ last_end_label = &last_cold_label;
+ switch_ranges = &switch_cold_ranges;
+ }
+
+ if (fde->ignored_debug)
+ {
+ if (*switch_ranges && !(vec_safe_length (*switch_ranges) & 1))
+ vec_safe_push (*switch_ranges, *last_end_label);
+ }
+ else
+ {
+ *last_end_label = end_label;
+
+ if (!*switch_ranges)
+ vec_alloc (*switch_ranges, 16);
+ else if (vec_safe_length (*switch_ranges) & 1)
+ vec_safe_push (*switch_ranges, begin_label);
+ }
+}
+
/* Output a marker (i.e. a label) for the absolute end of the generated code
for a function definition. This gets called *after* the epilogue code has
been generated. */
gcc_assert (fde != NULL);
if (fde->dw_fde_second_begin == NULL)
fde->dw_fde_end = xstrdup (label);
+
+ mark_ignored_debug_section (fde, fde->dw_fde_second_begin != NULL);
}
void
output_call_frame_info (1);
}
-/* Note that the current function section is being used for code. */
-
-static void
-dwarf2out_note_section_used (void)
-{
- section *sec = current_function_section ();
- if (sec == text_section)
- text_section_used = true;
- else if (sec == cold_text_section)
- cold_text_section_used = true;
-}
-
static void var_location_switch_text_section (void);
static void set_cur_line_info_table (section *);
}
have_multiple_function_sections = true;
- /* There is no need to mark used sections when not debugging. */
- if (cold_text_section != NULL)
- dwarf2out_note_section_used ();
-
if (dwarf2out_do_cfi_asm ())
fprintf (asm_out_file, "\t.cfi_endproc\n");
+ mark_ignored_debug_section (fde, false);
+
/* Now do the real section switch. */
sect = current_function_section ();
switch_to_section (sect);
fde->second_in_std_section
= (sect == text_section
|| (cold_text_section && sect == cold_text_section));
+ in_text_section_p = sect == text_section;
if (dwarf2out_do_cfi_asm ())
dwarf2out_do_cfi_startproc (true);
static void dwarf2out_begin_block (unsigned, unsigned);
static void dwarf2out_end_block (unsigned, unsigned);
static bool dwarf2out_ignore_block (const_tree);
+static void dwarf2out_set_ignored_loc (unsigned, unsigned, const char *);
static void dwarf2out_early_global_decl (tree);
static void dwarf2out_late_global_decl (tree);
static void dwarf2out_type_decl (tree, int);
dwarf2out_end_block,
dwarf2out_ignore_block,
dwarf2out_source_line,
+ dwarf2out_set_ignored_loc,
dwarf2out_begin_prologue,
#if VMS_DEBUGGING_INFO
dwarf2out_vms_end_prologue,
debug_nothing_int_int, /* end_block */
debug_true_const_tree, /* ignore_block */
dwarf2out_source_line, /* source_line */
+ debug_nothing_int_int_charstar, /* set_ignored_loc */
debug_nothing_int_int_charstar, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
debug_nothing_int_charstar, /* begin_epilogue */
size = DWARF_ARANGES_HEADER_SIZE;
/* Count the address/length pair for this compilation unit. */
- if (text_section_used)
- size += 2 * DWARF2_ADDR_SIZE;
- if (cold_text_section_used)
- size += 2 * DWARF2_ADDR_SIZE;
+ if (switch_text_ranges)
+ size += 2 * DWARF2_ADDR_SIZE
+ * (vec_safe_length (switch_text_ranges) / 2 + 1);
+ if (switch_cold_ranges)
+ size += 2 * DWARF2_ADDR_SIZE
+ * (vec_safe_length (switch_cold_ranges) / 2 + 1);
if (have_multiple_function_sections)
{
unsigned fde_idx;
FOR_EACH_VEC_ELT (*fde_vec, fde_idx, fde)
{
- if (DECL_IGNORED_P (fde->decl))
+ if (fde->ignored_debug)
continue;
if (!fde->in_std_section)
size += 2 * DWARF2_ADDR_SIZE;
the address may end up as 0 if the section is discarded by ld
--gc-sections, leaving an invalid (0, 0) entry that can be
confused with the terminator. */
- if (text_section_used)
+ if (switch_text_ranges)
{
- dw2_asm_output_addr (DWARF2_ADDR_SIZE, text_section_label, "Address");
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
- text_section_label, "Length");
+ const char *prev_loc = text_section_label;
+ const char *loc;
+ unsigned idx;
+
+ FOR_EACH_VEC_ELT (*switch_text_ranges, idx, loc)
+ if (prev_loc)
+ {
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, loc, prev_loc, "Length");
+ prev_loc = NULL;
+ }
+ else
+ prev_loc = loc;
+
+ if (prev_loc)
+ {
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
+ prev_loc, "Length");
+ }
}
- if (cold_text_section_used)
+
+ if (switch_cold_ranges)
{
- dw2_asm_output_addr (DWARF2_ADDR_SIZE, cold_text_section_label,
- "Address");
- dw2_asm_output_delta (DWARF2_ADDR_SIZE, cold_end_label,
- cold_text_section_label, "Length");
+ const char *prev_loc = cold_text_section_label;
+ const char *loc;
+ unsigned idx;
+
+ FOR_EACH_VEC_ELT (*switch_cold_ranges, idx, loc)
+ if (prev_loc)
+ {
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, loc, prev_loc, "Length");
+ prev_loc = NULL;
+ }
+ else
+ prev_loc = loc;
+
+ if (prev_loc)
+ {
+ dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
+ dw2_asm_output_delta (DWARF2_ADDR_SIZE, cold_end_label,
+ prev_loc, "Length");
+ }
}
if (have_multiple_function_sections)
FOR_EACH_VEC_ELT (*fde_vec, fde_idx, fde)
{
- if (DECL_IGNORED_P (fde->decl))
+ if (fde->ignored_debug)
continue;
if (!fde->in_std_section)
{
switch_to_section (sec);
}
- dwarf2out_note_section_used ();
call_site_count = 0;
tail_call_site_count = 0;
table->in_use = true;
}
+/* Record a source file location for a DECL_IGNORED_P function. */
+
+static void
+dwarf2out_set_ignored_loc (unsigned int line, unsigned int column,
+ const char *filename)
+{
+ dw_fde_ref fde = cfun->fde;
+
+ fde->ignored_debug = false;
+ set_cur_line_info_table (function_section (fde->decl));
+
+ dwarf2out_source_line (line, column, filename, 0, true);
+}
+
/* Record the beginning of a new source file. */
static void
/* We can only use the low/high_pc attributes if all of the code was
in .text. */
- if (!have_multiple_function_sections
+ if ((!have_multiple_function_sections
+ && vec_safe_length (switch_text_ranges) < 2)
|| (dwarf_version < 3 && dwarf_strict))
{
+ const char *end_label = text_end_label;
+ if (vec_safe_length (switch_text_ranges) == 1)
+ end_label = (*switch_text_ranges)[0];
/* Don't add if the CU has no associated code. */
- if (text_section_used)
- add_AT_low_high_pc (main_comp_unit_die, text_section_label,
- text_end_label, true);
+ if (switch_text_ranges)
+ add_AT_low_high_pc (main_comp_unit_die, text_section_label,
+ end_label, true);
}
else
{
unsigned fde_idx;
dw_fde_ref fde;
bool range_list_added = false;
+ if (switch_text_ranges)
+ {
+ const char *prev_loc = text_section_label;
+ const char *loc;
+ unsigned idx;
+
+ FOR_EACH_VEC_ELT (*switch_text_ranges, idx, loc)
+ if (prev_loc)
+ {
+ add_ranges_by_labels (main_comp_unit_die, prev_loc,
+ loc, &range_list_added, true);
+ prev_loc = NULL;
+ }
+ else
+ prev_loc = loc;
- if (text_section_used)
- add_ranges_by_labels (main_comp_unit_die, text_section_label,
- text_end_label, &range_list_added, true);
- if (cold_text_section_used)
- add_ranges_by_labels (main_comp_unit_die, cold_text_section_label,
- cold_end_label, &range_list_added, true);
+ if (prev_loc)
+ add_ranges_by_labels (main_comp_unit_die, prev_loc,
+ text_end_label, &range_list_added, true);
+ }
+
+ if (switch_cold_ranges)
+ {
+ const char *prev_loc = cold_text_section_label;
+ const char *loc;
+ unsigned idx;
+
+ FOR_EACH_VEC_ELT (*switch_cold_ranges, idx, loc)
+ if (prev_loc)
+ {
+ add_ranges_by_labels (main_comp_unit_die, prev_loc,
+ loc, &range_list_added, true);
+ prev_loc = NULL;
+ }
+ else
+ prev_loc = loc;
+
+ if (prev_loc)
+ add_ranges_by_labels (main_comp_unit_die, prev_loc,
+ cold_end_label, &range_list_added, true);
+ }
FOR_EACH_VEC_ELT (*fde_vec, fde_idx, fde)
{
- if (DECL_IGNORED_P (fde->decl))
+ if (fde->ignored_debug)
continue;
if (!fde->in_std_section)
add_ranges_by_labels (main_comp_unit_die, fde->dw_fde_begin,
skeleton_debug_str_hash = NULL;
dw2_string_counter = 0;
have_multiple_function_sections = false;
- text_section_used = false;
- cold_text_section_used = false;
+ in_text_section_p = false;
cold_text_section = NULL;
+ last_text_label = NULL;
+ last_cold_label = NULL;
+ switch_text_ranges = NULL;
+ switch_cold_ranges = NULL;
current_unit_personality = NULL;
early_dwarf = false;