https://gcc.gnu.org/g:e908efbf2061c0ad46caed47a54222e894ac2d29
commit r15-5824-ge908efbf2061c0ad46caed47a54222e894ac2d29 Author: Mark Harmstone <m...@harmstone.com> Date: Tue Nov 19 00:52:55 2024 +0000 Don't output CodeView line numbers for inlined functions If we encounter an inlined function, treat it as another codeview_function, and skip over these when outputting line numbers. This information will instead be output as part of the S_INLINESITE symbols. gcc/ * dwarf2codeview.cc (struct codeview_function): Add parent and inline_block fields. (cur_func): New global variable. (new_codeview_function): New function. (codeview_source_line): Call new_codeview_function, and use cur_func instead of last_func. (codeview_begin_block): New function. (codeview_end_block): New function. (write_line_numbers): No longer free data as we go along. (codeview_switch_text_section): Call new_codeview_function, and use cur_func instead of last_func. (codeview_end_epilogue): Use cur_func instead of last_func. (codeview_debug_finish): Free funcs list and its contents. * dwarf2codeview.h (codeview_begin_block): Add declaration. (codeview_end_block): Add declaration. * dwarf2out.cc (dwarf2out_begin_block): Call codeview_begin_block if outputting CodeView debug info. (dwarf2out_end_block): Call codeview_end_block if outputting CodeView debug info. Diff: --- gcc/dwarf2codeview.cc | 199 +++++++++++++++++++++++++++++++++----------------- gcc/dwarf2codeview.h | 2 + gcc/dwarf2out.cc | 10 +++ 3 files changed, 145 insertions(+), 66 deletions(-) diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc index 650e83f5ac37..63ac5356427a 100644 --- a/gcc/dwarf2codeview.cc +++ b/gcc/dwarf2codeview.cc @@ -1147,6 +1147,8 @@ struct codeview_function function *func; unsigned int end_label; codeview_line_block *blocks, *last_block; + codeview_function *parent; + unsigned int inline_block; }; struct codeview_symbol @@ -1423,7 +1425,7 @@ static unsigned int num_files; static uint32_t string_offset = 1; static hash_table<string_hasher> *strings_htab; static codeview_string *strings, *last_string; -static codeview_function *funcs, *last_func; +static codeview_function *funcs, *last_func, *cur_func; static const char* last_filename; static uint32_t last_file_id; static codeview_symbol *sym, *last_sym; @@ -1440,6 +1442,30 @@ static uint32_t get_type_num_subroutine_type (dw_die_ref type, bool in_struct, static void write_cv_padding (size_t padding); static void flush_deferred_types (void); +/* Allocate and initialize a codeview_function struct. */ + +static codeview_function * +new_codeview_function (void) +{ + codeview_function *f = (codeview_function *) + xmalloc (sizeof (codeview_function)); + + f->next = NULL; + f->func = cfun; + f->end_label = 0; + f->blocks = f->last_block = NULL; + f->inline_block = 0; + + if (!funcs) + funcs = f; + else + last_func->next = f; + + last_func = f; + + return f; +} + /* Record new line number against the current function. */ void @@ -1451,22 +1477,13 @@ codeview_source_line (unsigned int line_no, const char *filename) targetm.asm_out.internal_label (asm_out_file, LINE_LABEL, label_num); - if (!last_func || last_func->func != cfun) + if (!cur_func || cur_func->func != cfun) { - codeview_function *f = (codeview_function *) - xmalloc (sizeof (codeview_function)); + codeview_function *f = new_codeview_function (); - f->next = NULL; - f->func = cfun; - f->end_label = 0; - f->blocks = f->last_block = NULL; - - if (!funcs) - funcs = f; - else - last_func->next = f; + f->parent = NULL; - last_func = f; + cur_func = f; } if (filename != last_filename) @@ -1491,7 +1508,7 @@ codeview_source_line (unsigned int line_no, const char *filename) } } - if (!last_func->last_block || last_func->last_block->file_id != file_id) + if (!cur_func->last_block || cur_func->last_block->file_id != file_id) { codeview_line_block *b; @@ -1502,16 +1519,16 @@ codeview_source_line (unsigned int line_no, const char *filename) b->num_lines = 0; b->lines = b->last_line = NULL; - if (!last_func->blocks) - last_func->blocks = b; + if (!cur_func->blocks) + cur_func->blocks = b; else - last_func->last_block->next = b; + cur_func->last_block->next = b; - last_func->last_block = b; + cur_func->last_block = b; } - if (last_func->last_block->last_line - && last_func->last_block->last_line->line_no == line_no) + if (cur_func->last_block->last_line + && cur_func->last_block->last_line->line_no == line_no) return; l = (codeview_line *) xmalloc (sizeof (codeview_line)); @@ -1520,13 +1537,45 @@ codeview_source_line (unsigned int line_no, const char *filename) l->line_no = line_no; l->label_num = label_num; - if (!last_func->last_block->lines) - last_func->last_block->lines = l; + if (!cur_func->last_block->lines) + cur_func->last_block->lines = l; else - last_func->last_block->last_line->next = l; + cur_func->last_block->last_line->next = l; - last_func->last_block->last_line = l; - last_func->last_block->num_lines++; + cur_func->last_block->last_line = l; + cur_func->last_block->num_lines++; +} + +/* We have encountered the beginning of a lexical block. If this is actually + an inlined function, allocate a new codeview_function for this. */ + +void +codeview_begin_block (unsigned int line ATTRIBUTE_UNUSED, + unsigned int blocknum, tree block) +{ + if (inlined_function_outer_scope_p (block)) + { + location_t locus = BLOCK_SOURCE_LOCATION (block); + expanded_location s = expand_location (locus); + codeview_function *f = new_codeview_function (); + + codeview_source_line (s.line, s.file); + + f->parent = cur_func; + f->inline_block = blocknum; + + cur_func = f; + } +} + +/* We have encountered the end of a lexical block. If this is the end of an + inlined function, change cur_func back to its parent. */ + +void +codeview_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum) +{ + if (cur_func && cur_func->inline_block == blocknum) + cur_func = cur_func->parent; } /* Adds string to the string table, returning its offset. If already present, @@ -1729,11 +1778,19 @@ static void write_line_numbers (void) { unsigned int func_num = 0; + codeview_function *f = funcs; - while (funcs) + while (f) { - codeview_function *next = funcs->next; + codeview_function *next_func = f->next; unsigned int first_label_num; + codeview_line_block *b = f->blocks; + + if (f->inline_block != 0) + { + f = next_func; + continue; + } fputs (integer_asm_op (4, false), asm_out_file); fprint_whex (asm_out_file, DEBUG_S_LINES); @@ -1758,26 +1815,27 @@ write_line_numbers (void) */ asm_fprintf (asm_out_file, "\t.secrel32\t%L" LINE_LABEL "%u\n", - funcs->blocks->lines->label_num); + b->lines->label_num); asm_fprintf (asm_out_file, "\t.secidx\t%L" LINE_LABEL "%u\n", - funcs->blocks->lines->label_num); + b->lines->label_num); /* flags */ fputs (integer_asm_op (2, false), asm_out_file); fprint_whex (asm_out_file, 0); putc ('\n', asm_out_file); - first_label_num = funcs->blocks->lines->label_num; + first_label_num = b->lines->label_num; /* length */ fputs (integer_asm_op (4, false), asm_out_file); asm_fprintf (asm_out_file, "%L" END_FUNC_LABEL "%u - %L" LINE_LABEL "%u\n", - funcs->end_label, first_label_num); + f->end_label, first_label_num); - while (funcs->blocks) + while (b) { - codeview_line_block *next = funcs->blocks->next; + codeview_line_block *next_block = b->next; + codeview_line *l = b->lines; /* Next comes the blocks, each block being a part of a function within the same source file (struct cv_lines_block in binutils or @@ -1793,23 +1851,23 @@ write_line_numbers (void) /* file ID */ fputs (integer_asm_op (4, false), asm_out_file); - fprint_whex (asm_out_file, funcs->blocks->file_id); + fprint_whex (asm_out_file, b->file_id); putc ('\n', asm_out_file); /* number of lines */ fputs (integer_asm_op (4, false), asm_out_file); - fprint_whex (asm_out_file, funcs->blocks->num_lines); + fprint_whex (asm_out_file, b->num_lines); putc ('\n', asm_out_file); /* length of code block: (num_lines * sizeof (struct cv_line)) + sizeof (struct cv_lines_block) */ fputs (integer_asm_op (4, false), asm_out_file); - fprint_whex (asm_out_file, (funcs->blocks->num_lines * 0x8) + 0xc); + fprint_whex (asm_out_file, (b->num_lines * 0x8) + 0xc); putc ('\n', asm_out_file); - while (funcs->blocks->lines) + while (l) { - codeview_line *next = funcs->blocks->lines->next; + codeview_line *next_line = l->next; /* Finally comes the line number information (struct cv_line in binutils or CV_Line_t in Microsoft's cvinfo.h): @@ -1827,30 +1885,24 @@ write_line_numbers (void) fputs (integer_asm_op (4, false), asm_out_file); asm_fprintf (asm_out_file, "%L" LINE_LABEL "%u - %L" LINE_LABEL "%u\n", - funcs->blocks->lines->label_num, first_label_num); + l->label_num, first_label_num); fputs (integer_asm_op (4, false), asm_out_file); fprint_whex (asm_out_file, 0x80000000 - | (funcs->blocks->lines->line_no & 0xffffff)); + | (l->line_no & 0xffffff)); putc ('\n', asm_out_file); - free (funcs->blocks->lines); - - funcs->blocks->lines = next; + l = next_line; } - free (funcs->blocks); - - funcs->blocks = next; + b = next_block; } - free (funcs); - asm_fprintf (asm_out_file, "%LLcv_lines%u_end:\n", func_num); func_num++; - funcs = next; + f = next_func; } } @@ -1862,29 +1914,20 @@ codeview_switch_text_section (void) { codeview_function *f; - if (last_func && last_func->end_label == 0) + if (cur_func && cur_func->end_label == 0) { unsigned int label_num = ++func_label_num; targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL, label_num); - last_func->end_label = label_num; + cur_func->end_label = label_num; } - f = (codeview_function *) xmalloc (sizeof (codeview_function)); + f = new_codeview_function (); + f->parent = cur_func ? cur_func->parent : NULL; - f->next = NULL; - f->func = cfun; - f->end_label = 0; - f->blocks = f->last_block = NULL; - - if (!funcs) - funcs = f; - else - last_func->next = f; - - last_func = f; + cur_func = f; } /* Mark the end of the current function. */ @@ -1892,14 +1935,14 @@ codeview_switch_text_section (void) void codeview_end_epilogue (void) { - if (last_func && last_func->end_label == 0) + if (cur_func && cur_func->end_label == 0) { unsigned int label_num = ++func_label_num; targetm.asm_out.internal_label (asm_out_file, END_FUNC_LABEL, label_num); - last_func->end_label = label_num; + cur_func->end_label = label_num; } } @@ -4723,6 +4766,30 @@ codeview_debug_finish (void) if (custom_types) write_custom_types (); + while (funcs) + { + codeview_function *next_func = funcs->next; + + while (funcs->blocks) + { + codeview_line_block *next_block = funcs->blocks->next; + + while (funcs->blocks->lines) + { + codeview_line *next_line = funcs->blocks->lines->next; + + free (funcs->blocks->lines); + funcs->blocks->lines = next_line; + } + + free (funcs->blocks); + funcs->blocks = next_block; + } + + free (funcs); + funcs = next_func; + } + if (types_htab) delete types_htab; diff --git a/gcc/dwarf2codeview.h b/gcc/dwarf2codeview.h index 52ffc6cfb99b..367334d68cbf 100644 --- a/gcc/dwarf2codeview.h +++ b/gcc/dwarf2codeview.h @@ -95,5 +95,7 @@ extern void codeview_start_source_file (const char *); extern void codeview_switch_text_section (); extern void codeview_end_epilogue (void); extern void codeview_debug_early_finish (dw_die_ref die); +extern void codeview_begin_block (unsigned int, unsigned int, tree); +extern void codeview_end_block (unsigned int, unsigned int); #endif /* GCC_DWARF2CODEVIEW_H */ diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index a4957cf68ac9..e913c52fd626 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -27808,6 +27808,11 @@ dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum, tree block ATTRIBUTE_UNUSED) { +#ifdef CODEVIEW_DEBUGGING_INFO + if (codeview_debuginfo_p ()) + codeview_begin_block (line, blocknum, block); +#endif + switch_to_section (current_function_section ()); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum); } @@ -27818,6 +27823,11 @@ dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED, static void dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum) { +#ifdef CODEVIEW_DEBUGGING_INFO + if (codeview_debuginfo_p ()) + codeview_end_block (line, blocknum); +#endif + switch_to_section (current_function_section ()); ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum); }