From 5578fbf672ee497ea19826edeb509f4cc3e825a8 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 25 Aug 2022 11:48:00 +0100 Subject: [PATCH] GAS: Add a return type tag to DWARF DIEs generated for function symbols. PR 29517 * dwarf2dbg.c (GAS_ABBREV_COMP_UNIT): New defined constant. (GAS_ABBREV_SUBPROG): New defined constant. (GAS_ABBREV_NO_TYPE): New defined constant. (out_debug_abbrev): Use the new defined constants when emitting abbreviation numbers. Generate an abbreviation for an unspecified type. (out_debug_info): Use the new defined constants when referring to abbreviations. Generate a use of the no_type abbreviation. Reference the use when generating DIEs for functions. * testsuite/gas/elf/dwarf-3-func.d: Update to allow for newly extended output from the assembler. * testsuite/gas/elf/dwarf-5-func-global.d: Likewise. * testsuite/gas/elf/dwarf-5-func-local.d: Likewise. * testsuite/gas/elf/dwarf-5-func.d: Likewise. --- gas/ChangeLog | 18 +++++++++ gas/dwarf2dbg.c | 44 +++++++++++++++++++-- gas/testsuite/gas/elf/dwarf-3-func.d | 7 ++++ gas/testsuite/gas/elf/dwarf-5-func-global.d | 5 +++ gas/testsuite/gas/elf/dwarf-5-func-local.d | 5 +++ gas/testsuite/gas/elf/dwarf-5-func.d | 7 ++++ 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index d3f52bf84d1..e79b986f880 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,21 @@ +2022-08-25 Nick Clifton + + PR 29517 + * dwarf2dbg.c (GAS_ABBREV_COMP_UNIT): New defined constant. + (GAS_ABBREV_SUBPROG): New defined constant. + (GAS_ABBREV_NO_TYPE): New defined constant. + (out_debug_abbrev): Use the new defined constants when emitting + abbreviation numbers. Generate an abbreviation for an unspecified + type. + (out_debug_info): Use the new defined constants when referring to + abbreviations. Generate a use of the no_type abbreviation. + Reference the use when generating DIEs for functions. + * testsuite/gas/elf/dwarf-3-func.d: Update to allow for newly + extended output from the assembler. + * testsuite/gas/elf/dwarf-5-func-global.d: Likewise. + * testsuite/gas/elf/dwarf-5-func-local.d: Likewise. + * testsuite/gas/elf/dwarf-5-func.d: Likewise. + 2022-08-25 Nick Clifton PR 29519 diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index f346bd6a412..8f3d528ed2e 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -160,6 +160,10 @@ #define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE #endif +#define GAS_ABBREV_COMP_UNIT 1 +#define GAS_ABBREV_SUBPROG 2 +#define GAS_ABBREV_NO_TYPE 3 + struct line_entry { struct line_entry *next; @@ -2730,7 +2734,7 @@ out_debug_abbrev (segT abbrev_seg, subseg_set (abbrev_seg, 0); - out_uleb128 (1); + out_uleb128 (GAS_ABBREV_COMP_UNIT); out_uleb128 (DW_TAG_compile_unit); out_byte (have_efunc || have_lfunc ? DW_CHILDREN_yes : DW_CHILDREN_no); if (DWARF2_VERSION < 4) @@ -2761,7 +2765,7 @@ out_debug_abbrev (segT abbrev_seg, if (have_efunc || have_lfunc) { - out_uleb128 (2); + out_uleb128 (GAS_ABBREV_SUBPROG); out_uleb128 (DW_TAG_subprogram); out_byte (DW_CHILDREN_no); out_abbrev (DW_AT_name, DW_FORM_strp); @@ -2776,10 +2780,26 @@ out_debug_abbrev (segT abbrev_seg, else /* Any non-zero value other than DW_FORM_flag will do. */ *func_formP = DW_FORM_block; + + /* PR 29517: Provide a return type for the function. */ + if (DWARF2_VERSION > 2) + out_abbrev (DW_AT_type, DW_FORM_ref_udata); + out_abbrev (DW_AT_low_pc, DW_FORM_addr); out_abbrev (DW_AT_high_pc, DWARF2_VERSION < 4 ? DW_FORM_addr : DW_FORM_udata); out_abbrev (0, 0); + + if (DWARF2_VERSION > 2) + { + /* PR 29517: We do not actually know the return type of these + functions, so provide an abbrev that uses DWARF's unspecified + type. */ + out_uleb128 (GAS_ABBREV_NO_TYPE); + out_uleb128 (DW_TAG_unspecified_type); + out_byte (DW_CHILDREN_no); + out_abbrev (0, 0); + } } /* Terminate the abbreviations for this compilation unit. */ @@ -2797,6 +2817,7 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg, expressionS exp; symbolS *info_end; int sizeof_offset; + valueT no_type_die = 0; memset (&exp, 0, sizeof exp); sizeof_offset = out_header (info_seg, &exp); @@ -2825,8 +2846,18 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg, TC_DWARF2_EMIT_OFFSET (section_symbol (abbrev_seg), sizeof_offset); } + if (func_form && DWARF2_VERSION > 2) + { + /* PR 29517: Generate a DIE for the unspecified type abbrev. + We do it here so that the offset from the start of the + section is fixed. */ + subseg_set (info_seg, 0); + no_type_die = frag_now_fix_octets (); + out_uleb128 (GAS_ABBREV_NO_TYPE); + } + /* DW_TAG_compile_unit DIE abbrev */ - out_uleb128 (1); + out_uleb128 (GAS_ABBREV_COMP_UNIT); /* DW_AT_stmt_list */ TC_DWARF2_EMIT_OFFSET (section_symbol (line_seg), @@ -2917,7 +2948,7 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg, subseg_set (info_seg, 0); /* DW_TAG_subprogram DIE abbrev */ - out_uleb128 (2); + out_uleb128 (GAS_ABBREV_SUBPROG); /* DW_AT_name */ TC_DWARF2_EMIT_OFFSET (name_sym, sizeof_offset); @@ -2926,6 +2957,11 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg, if (func_form == DW_FORM_flag) out_byte (S_IS_EXTERNAL (symp)); + /* PR 29517: Let consumers know that we do not + have return type information for this function. */ + if (DWARF2_VERSION > 2) + out_uleb128 (no_type_die); + /* DW_AT_low_pc */ exp.X_op = O_symbol; exp.X_add_symbol = symp; diff --git a/gas/testsuite/gas/elf/dwarf-3-func.d b/gas/testsuite/gas/elf/dwarf-3-func.d index e17dff27dd0..d084518aba1 100644 --- a/gas/testsuite/gas/elf/dwarf-3-func.d +++ b/gas/testsuite/gas/elf/dwarf-3-func.d @@ -10,26 +10,32 @@ Contents of the .debug_info section: +Version: +3 +Abbrev Offset: +(0x)?0 +Pointer Size: .* + <0><[0-9a-f]+>: Abbrev Number: 3 \(DW_TAG_unspecified_type\) +#... <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\) #... <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): efunc1 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 1 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?0 +<[0-9a-f]+> +DW_AT_high_pc +: \(addr\) (0x)?2 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): lfunc1 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 0 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?2 +<[0-9a-f]+> +DW_AT_high_pc +: \(addr\) (0x)?13 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): efunc2 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 1 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?13 +<[0-9a-f]+> +DW_AT_high_pc +: \(addr\) (0x)?35 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): lfunc2 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 0 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?35 +<[0-9a-f]+> +DW_AT_high_pc +: \(addr\) (0x)?38 <1><[0-9a-f]+>: Abbrev Number: 0 @@ -42,6 +48,7 @@ Contents of the .debug_abbrev section: +2 +DW_TAG_subprogram +\[no children\] +DW_AT_name +DW_FORM_strp +DW_AT_external +DW_FORM_flag + +DW_AT_type +DW_FORM_ref_udata +DW_AT_low_pc +DW_FORM_addr +DW_AT_high_pc +DW_FORM_addr +DW_AT value: 0 +DW_FORM value: 0 diff --git a/gas/testsuite/gas/elf/dwarf-5-func-global.d b/gas/testsuite/gas/elf/dwarf-5-func-global.d index 03c425dcc8b..65c2ab0f512 100644 --- a/gas/testsuite/gas/elf/dwarf-5-func-global.d +++ b/gas/testsuite/gas/elf/dwarf-5-func-global.d @@ -12,16 +12,20 @@ Contents of the .debug_info section: +Unit Type: +DW_UT_compile \(1\) +Abbrev Offset: +(0x)?0 +Pointer Size: .* + <0><[0-9a-f]+>: Abbrev Number: 3 \(DW_TAG_unspecified_type\) +#... <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\) #... <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): efunc1 +<[0-9a-f]+> +DW_AT_external +: \(flag_present\) 1 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?0 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 2 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): efunc2 +<[0-9a-f]+> +DW_AT_external +: \(flag_present\) 1 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?2 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 34 <1><[0-9a-f]+>: Abbrev Number: 0 @@ -34,6 +38,7 @@ Contents of the .debug_abbrev section: +2 +DW_TAG_subprogram +\[no children\] +DW_AT_name +DW_FORM_strp +DW_AT_external +DW_FORM_flag_present + +DW_AT_type +DW_FORM_ref_udata +DW_AT_low_pc +DW_FORM_addr +DW_AT_high_pc +DW_FORM_udata +DW_AT value: 0 +DW_FORM value: 0 diff --git a/gas/testsuite/gas/elf/dwarf-5-func-local.d b/gas/testsuite/gas/elf/dwarf-5-func-local.d index ae635159acb..ac666ea93e1 100644 --- a/gas/testsuite/gas/elf/dwarf-5-func-local.d +++ b/gas/testsuite/gas/elf/dwarf-5-func-local.d @@ -12,14 +12,18 @@ Contents of the .debug_info section: +Unit Type: +DW_UT_compile \(1\) +Abbrev Offset: +(0x)?0 +Pointer Size: .* + <0><[0-9a-f]+>: Abbrev Number: 3 \(DW_TAG_unspecified_type\) +#... <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\) #... <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): lfunc1 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?0 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 17 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): lfunc2 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?11 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 3 <1><[0-9a-f]+>: Abbrev Number: 0 @@ -31,6 +35,7 @@ Contents of the .debug_abbrev section: #... +2 +DW_TAG_subprogram +\[no children\] +DW_AT_name +DW_FORM_strp + +DW_AT_type +DW_FORM_ref_udata +DW_AT_low_pc +DW_FORM_addr +DW_AT_high_pc +DW_FORM_udata +DW_AT value: 0 +DW_FORM value: 0 diff --git a/gas/testsuite/gas/elf/dwarf-5-func.d b/gas/testsuite/gas/elf/dwarf-5-func.d index 0d331c6aaa4..612c9f23b16 100644 --- a/gas/testsuite/gas/elf/dwarf-5-func.d +++ b/gas/testsuite/gas/elf/dwarf-5-func.d @@ -12,26 +12,32 @@ Contents of the .debug_info section: +Unit Type: +DW_UT_compile \(1\) +Abbrev Offset: +(0x)?0 +Pointer Size: .* + <0><[0-9a-f]+>: Abbrev Number: 3 \(DW_TAG_unspecified_type\) +#... <0><[0-9a-f]+>: Abbrev Number: 1 \(DW_TAG_compile_unit\) #... <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): efunc1 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 1 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?0 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 2 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): lfunc1 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 0 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?2 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 17 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): efunc2 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 1 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?13 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 34 <1><[0-9a-f]+>: Abbrev Number: 2 \(DW_TAG_subprogram\) +<[0-9a-f]+> +DW_AT_name +: \(strp\) \(offset: (0x)?[0-9a-f]+\): lfunc2 +<[0-9a-f]+> +DW_AT_external +: \(flag\) 0 + +<[0-9a-f]+> +DW_AT_type +: \(ref_udata\) <0x.> +<[0-9a-f]+> +DW_AT_low_pc +: \(addr\) (0x)?35 +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 3 <1><[0-9a-f]+>: Abbrev Number: 0 @@ -44,6 +50,7 @@ Contents of the .debug_abbrev section: +2 +DW_TAG_subprogram +\[no children\] +DW_AT_name +DW_FORM_strp +DW_AT_external +DW_FORM_flag + +DW_AT_type +DW_FORM_ref_udata +DW_AT_low_pc +DW_FORM_addr +DW_AT_high_pc +DW_FORM_udata +DW_AT value: 0 +DW_FORM value: 0 -- 2.30.2