diff options
-rw-r--r-- | gcc/dbxout.c | 2 | ||||
-rw-r--r-- | gcc/debug.c | 1 | ||||
-rw-r--r-- | gcc/debug.h | 4 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 244 | ||||
-rw-r--r-- | gcc/dwarf2out.h | 2 | ||||
-rw-r--r-- | gcc/final.c | 8 | ||||
-rw-r--r-- | gcc/ggc-page.c | 6 | ||||
-rw-r--r-- | gcc/stringpool.c | 6 | ||||
-rw-r--r-- | gcc/vmsdbgout.c | 1 |
9 files changed, 224 insertions, 50 deletions
diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 70b635c..d20527b 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -362,6 +362,7 @@ const struct gcc_debug_hooks dbx_debug_hooks = dbxout_end_block, debug_true_const_tree, /* ignore_block */ dbxout_source_line, /* source_line */ + debug_nothing_int_int_charstar, /* set_ignored_loc */ dbxout_begin_prologue, /* begin_prologue */ debug_nothing_int_charstar, /* end_prologue */ debug_nothing_int_charstar, /* begin_epilogue */ @@ -409,6 +410,7 @@ const struct gcc_debug_hooks xcoff_debug_hooks = xcoffout_end_block, debug_true_const_tree, /* ignore_block */ xcoffout_source_line, + debug_nothing_int_int_charstar, /* set_ignored_loc */ xcoffout_begin_prologue, /* begin_prologue */ debug_nothing_int_charstar, /* end_prologue */ debug_nothing_int_charstar, /* begin_epilogue */ diff --git a/gcc/debug.c b/gcc/debug.c index 0a7fcfa..39add0d 100644 --- a/gcc/debug.c +++ b/gcc/debug.c @@ -36,6 +36,7 @@ const struct gcc_debug_hooks do_nothing_debug_hooks = debug_nothing_int_int, /* end_block */ debug_true_const_tree, /* ignore_block */ debug_nothing_int_int_charstar_int_bool, /* 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 */ diff --git a/gcc/debug.h b/gcc/debug.h index cd265ff..ad45ea53 100644 --- a/gcc/debug.h +++ b/gcc/debug.h @@ -73,6 +73,10 @@ struct gcc_debug_hooks void (* source_line) (unsigned int line, unsigned int column, const char *file, int discriminator, bool is_stmt); + /* Record a source file location for a DECL_IGNORED_P function. */ + void (* set_ignored_loc) (unsigned int line, unsigned int column, + const char *file); + /* Called at start of prologue code. LINE is the first line in the function. */ void (* begin_prologue) (unsigned int line, unsigned int column, diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 5b819ab..871362b 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -259,13 +259,21 @@ static GTY(()) int dw2_string_counter; /* 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; @@ -275,7 +283,6 @@ static GTY(()) dw_die_ref decltype_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. */ @@ -1107,6 +1114,8 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, 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. */ @@ -1174,6 +1183,59 @@ dwarf2out_vms_begin_epilogue (unsigned int line ATTRIBUTE_UNUSED, 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. */ @@ -1200,6 +1262,8 @@ dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, 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 @@ -1214,18 +1278,6 @@ dwarf2out_frame_finish (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 *); @@ -1254,13 +1306,11 @@ dwarf2out_switch_text_section (void) } 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); @@ -1268,6 +1318,7 @@ dwarf2out_switch_text_section (void) 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); @@ -2801,6 +2852,7 @@ static void dwarf2out_function_decl (tree); 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); @@ -2836,6 +2888,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks = dwarf2out_end_block, dwarf2out_ignore_block, dwarf2out_source_line, + dwarf2out_set_ignored_loc, dwarf2out_begin_prologue, #if VMS_DEBUGGING_INFO dwarf2out_vms_end_prologue, @@ -2885,6 +2938,7 @@ const struct gcc_debug_hooks dwarf2_lineno_debug_hooks = 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 */ @@ -9756,10 +9810,12 @@ size_of_aranges (void) 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; @@ -9767,7 +9823,7 @@ size_of_aranges (void) 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; @@ -11713,18 +11769,52 @@ output_aranges (void) 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) @@ -11734,7 +11824,7 @@ output_aranges (void) 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) { @@ -28020,7 +28110,6 @@ dwarf2out_begin_function (tree fun) switch_to_section (sec); } - dwarf2out_note_section_used (); call_site_count = 0; tail_call_site_count = 0; @@ -28323,6 +28412,20 @@ dwarf2out_source_line (unsigned int line, unsigned int column, 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 @@ -31760,30 +31863,68 @@ dwarf2out_finish (const char *filename) /* 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, @@ -32657,9 +32798,12 @@ dwarf2out_c_finalize (void) 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; diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index 76a9c0a..54b6343 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -114,6 +114,8 @@ struct GTY(()) dw_fde_node { hard frame pointer register should be emitted only on the latter instruction. */ unsigned rule18 : 1; + /* True if this function is to be ignored by debugger. */ + unsigned ignored_debug : 1; }; diff --git a/gcc/final.c b/gcc/final.c index ba4285d..e0a70fc 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1724,6 +1724,9 @@ final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen, if (!dwarf2_debug_info_emitted_p (current_function_decl)) dwarf2out_begin_prologue (0, 0, NULL); + if (DECL_IGNORED_P (current_function_decl) && last_linenum && last_filename) + debug_hooks->set_ignored_loc (last_linenum, last_columnnum, last_filename); + #ifdef LEAF_REG_REMAP if (crtl->uses_only_leaf_regs) leaf_renumber_regs (first); @@ -2187,6 +2190,7 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, in_cold_section_p = !in_cold_section_p; + gcc_checking_assert (in_cold_section_p); if (in_cold_section_p) cold_function_name = clone_function_name (current_function_decl, "cold"); @@ -2200,6 +2204,10 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, } else if (!DECL_IGNORED_P (current_function_decl)) debug_hooks->switch_text_section (); + if (DECL_IGNORED_P (current_function_decl) && last_linenum + && last_filename) + debug_hooks->set_ignored_loc (last_linenum, last_columnnum, + last_filename); switch_to_section (current_function_section ()); targetm.asm_out.function_switched_text_sections (asm_out_file, diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c index 4d11692..1b09f0d 100644 --- a/gcc/ggc-page.c +++ b/gcc/ggc-page.c @@ -1518,6 +1518,12 @@ gt_ggc_mx (const char *& x) } void +gt_ggc_mx (char *& x) +{ + gt_ggc_m_S (x); +} + +void gt_ggc_mx (unsigned char *& x) { gt_ggc_m_S (x); diff --git a/gcc/stringpool.c b/gcc/stringpool.c index e4d79b0..2f21466 100644 --- a/gcc/stringpool.c +++ b/gcc/stringpool.c @@ -206,6 +206,12 @@ gt_pch_nx (const char *& x) } void +gt_pch_nx (char *& x) +{ + gt_pch_n_S (x); +} + +void gt_pch_nx (unsigned char *& x) { gt_pch_n_S (x); diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c index c226bc6..05fadce 100644 --- a/gcc/vmsdbgout.c +++ b/gcc/vmsdbgout.c @@ -188,6 +188,7 @@ const struct gcc_debug_hooks vmsdbg_debug_hooks vmsdbgout_end_block, vmsdbgout_ignore_block, vmsdbgout_source_line, + debug_nothing_int_int_charstar, /* set_ignored_loc */ vmsdbgout_begin_prologue, vmsdbgout_end_prologue, vmsdbgout_begin_epilogue, |