public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Dwarf debug info generation improvements
@ 2022-03-28  9:06 Jan Beulich
  2022-03-28  9:07 ` [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros Jan Beulich
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:06 UTC (permalink / raw)
  To: Binutils

Or, as usual, so I hope. I think these are largely independent of one
another, but still fit a common theme. I'd like to note that patches
5 and 6 each individually address the original problem of addr2line
not reporting function names in certain cases, but I think both
changes are desirable to have irrespective of one sufficing for the
specific issue.

The last patch isn't particularly pretty for its ELF dependency, so
I'd welcome comments towards possible improvements.

1: gas/Dwarf: special-case .linefile only for macros
2: RISC-V: add testcase to check line number emission for .insn
3: Arm64: arrange for line number emission for .inst
4: Arm32: arrange for line number emission for .inst
5: bfd/Dwarf2: make find-nearest-line returned function name consistent
6: bfd/Dwarf2: gas doesn't mangle names
7: gas/Dwarf: record functions

Jan


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros
  2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
@ 2022-03-28  9:07 ` Jan Beulich
  2022-03-28  9:16   ` Andreas Schwab
  2022-03-28  9:08 ` [PATCH 2/7] RISC-V: add testcase to check line number emission for .insn Jan Beulich
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:07 UTC (permalink / raw)
  To: Binutils

Restrict the PR gas/16908 workaround to just macros, matching the
original intention as well as the comment there. For constructs like
.irp or .rept the reasoning doesn't apply, as there's no separate
"invocation" point which may be of interest to record (for, as said
there, short macros).

--- a/gas/macro.c
+++ b/gas/macro.c
@@ -233,7 +233,8 @@ buffer_and_nest (const char *from, const
 	     number when expanding the macro), and since for short
 	     macros we clearly prefer reporting the point of expansion
 	     anyway, there's not an obviously better fix here.  */
-	  if (strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
+	  if (from != NULL && strcasecmp (from, "MACRO") == 0
+	      && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
 	    {
 	      char saved_eol_char = ptr->ptr[ptr->len];
 
--- a/gas/testsuite/gas/elf/dwarf-5-irp.d
+++ b/gas/testsuite/gas/elf/dwarf-5-irp.d
@@ -52,6 +52,22 @@ Raw dump of debug contents .*
 .*Advance PC by .*
 .*Extended opcode 1: End of Sequence
 
+.*Set File Name to entry 4 .*
+.*Extended opcode 2: .*
+.*Advance Line by 35 to 36
+.*Copy
+.*Special opcode .* and Line by 1 to 37
+.*Advance PC by .*
+.*Extended opcode 1: End of Sequence
+
+.*Set File Name to entry 4 .*
+.*Extended opcode 2: .*
+.*Advance Line by 35 to 36
+.*Copy
+.*Special opcode .* and Line by 1 to 37
+.*Advance PC by .*
+.*Extended opcode 1: End of Sequence
+
 
 Contents of the \.debug_aranges section:
 
@@ -66,6 +82,8 @@ Contents of the \.debug_aranges section:
     0+ [0-9a-f]+ ?
     0+ [0-9a-f]+ ?
     0+ [0-9a-f]+ ?
+    0+ [0-9a-f]+ ?
+    0+ [0-9a-f]+ ?
     0+ 0+ ?
 
 Contents of the \.debug_rnglists section:
@@ -74,6 +92,8 @@ Contents of the \.debug_rnglists section
     [0-9a-f]+ 0+ [0-9a-f]+ ?
     [0-9a-f]+ 0+ [0-9a-f]+ ?
     [0-9a-f]+ 0+ [0-9a-f]+ ?
+    [0-9a-f]+ 0+ [0-9a-f]+ ?
+    [0-9a-f]+ 0+ [0-9a-f]+ ?
     [0-9a-f]+ 0+ [0-9a-f]+ ?
     [0-9a-f]+ <End of list>
 
--- a/gas/testsuite/gas/elf/dwarf-5-irp.s
+++ b/gas/testsuite/gas/elf/dwarf-5-irp.s
@@ -29,3 +29,10 @@ _start:
 	.nop
 	n = n - 1
 	.endr
+
+	.irp n, cd, nm
+# 35 "irp.s"
+	.section .text.\n, "ax"
+	.nop
+	.nop
+	.endr


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/7] RISC-V: add testcase to check line number emission for .insn
  2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
  2022-03-28  9:07 ` [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros Jan Beulich
@ 2022-03-28  9:08 ` Jan Beulich
  2022-04-06 17:51   ` Palmer Dabbelt
  2022-03-28  9:10 ` [PATCH 3/7] Arm64: arrange for line number emission for .inst Jan Beulich
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:08 UTC (permalink / raw)
  To: Binutils

Since no such test looks to exist, derive one from insn.s.

--- /dev/null
+++ b/gas/testsuite/gas/riscv/insn-dwarf.d
@@ -0,0 +1,71 @@
+#as: -march=rv64ifc -gdwarf-2
+#name: Dwarf line number info for .insn
+#objdump: -WL -w
+#source: insn.s
+
+.*:[ 	]+file format .*
+
+Contents of the .debug_line section:
+
+CU: .*/insn.s:
+File name +Line number +Starting address.*
+insn.s +2 +0.*
+insn.s +3 +0x4.*
+insn.s +4 +0x8.*
+insn.s +5 +0xc.*
+insn.s +6 +0x10.*
+insn.s +7 +0x14.*
+insn.s +8 +0x18.*
+insn.s +9 +0x1c.*
+insn.s +10 +0x20.*
+insn.s +11 +0x24.*
+insn.s +13 +0x28.*
+insn.s +14 +0x2a.*
+insn.s +15 +0x2c.*
+insn.s +16 +0x2e.*
+insn.s +17 +0x30.*
+insn.s +18 +0x32.*
+insn.s +19 +0x34.*
+insn.s +20 +0x36.*
+insn.s +22 +0x38.*
+insn.s +23 +0x3c.*
+insn.s +24 +0x40.*
+insn.s +25 +0x44.*
+insn.s +26 +0x48.*
+insn.s +27 +0x4c.*
+insn.s +28 +0x50.*
+insn.s +29 +0x54.*
+insn.s +30 +0x58.*
+insn.s +31 +0x5c.*
+insn.s +33 +0x60.*
+insn.s +34 +0x62.*
+insn.s +35 +0x64.*
+insn.s +36 +0x66.*
+insn.s +37 +0x68.*
+insn.s +38 +0x6a.*
+insn.s +39 +0x6c.*
+insn.s +40 +0x6e.*
+insn.s +41 +0x70.*
+insn.s +43 +0x72.*
+insn.s +44 +0x76.*
+insn.s +45 +0x7a.*
+insn.s +46 +0x7e.*
+insn.s +47 +0x82.*
+insn.s +48 +0x86.*
+insn.s +49 +0x8a.*
+insn.s +50 +0x8e.*
+insn.s +51 +0x92.*
+insn.s +52 +0x96.*
+insn.s +53 +0x9a.*
+insn.s +54 +0x9e.*
+insn.s +55 +0xa2.*
+insn.s +57 +0xa6.*
+insn.s +58 +0xa8.*
+insn.s +59 +0xac.*
+insn.s +60 +0xb2.*
+insn.s +61 +0xba.*
+insn.s +62 +0xbc.*
+insn.s +63 +0xc0.*
+insn.s +64 +0xc6.*
+insn.s +- +0xce
+#pass


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/7] Arm64: arrange for line number emission for .inst
  2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
  2022-03-28  9:07 ` [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros Jan Beulich
  2022-03-28  9:08 ` [PATCH 2/7] RISC-V: add testcase to check line number emission for .insn Jan Beulich
@ 2022-03-28  9:10 ` Jan Beulich
  2022-03-28  9:11 ` [PATCH 4/7] Arm32: " Jan Beulich
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:10 UTC (permalink / raw)
  To: Binutils; +Cc: richard.earnshaw, Marcus Shawcroft

Just like insns encoded the more conventional way these should have line
number info associated with them.

--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -1982,6 +1982,7 @@ static void
 s_aarch64_inst (int ignored ATTRIBUTE_UNUSED)
 {
   expressionS exp;
+  unsigned n = 0;
 
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
@@ -2020,10 +2021,13 @@ s_aarch64_inst (int ignored ATTRIBUTE_UN
 	  unsigned int val = exp.X_add_number;
 	  exp.X_add_number = SWAP_32 (val);
 	}
-      emit_expr (&exp, 4);
+      emit_expr (&exp, INSN_SIZE);
+      ++n;
     }
   while (*input_line_pointer++ == ',');
 
+  dwarf2_emit_insn (n * INSN_SIZE);
+
   /* Put terminator back into stream.  */
   input_line_pointer--;
   demand_empty_rest_of_line ();
--- a/gas/testsuite/gas/aarch64/inst-directive.d
+++ b/gas/testsuite/gas/aarch64/inst-directive.d
@@ -6,3 +6,6 @@ Disassembly of section \.text:
 
 0+ <.*>:
    0:	3619194c 	tbz	w12, #3, 2328 <\.text\+0x2328>
+ *[0-9a-f]*:	d503201f 	nop
+ *[0-9a-f]*:	d503201f 	nop
+ *[0-9a-f]*:	d503201f 	nop
--- a/gas/testsuite/gas/aarch64/inst-directive.s
+++ b/gas/testsuite/gas/aarch64/inst-directive.s
@@ -3,3 +3,4 @@
 
 .text
 	.inst	0x3619194c
+	.inst	0xd503201f, 0xd503201f, 0xd503201f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/inst-dwarf.d
@@ -0,0 +1,15 @@
+#as: -gdwarf-2
+#name: Dwarf line number info for .inst
+#objdump: -WL -w
+#source: inst-directive.s
+
+.*:[ 	]+file format .*
+
+Contents of the .debug_line section:
+
+CU: .*/inst-directive.s:
+File name +Line number +Starting address.*
+inst-directive.s +5 +0.*
+inst-directive.s +6 +0x4.*
+inst-directive.s +- +0x10
+#pass


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 4/7] Arm32: arrange for line number emission for .inst
  2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
                   ` (2 preceding siblings ...)
  2022-03-28  9:10 ` [PATCH 3/7] Arm64: arrange for line number emission for .inst Jan Beulich
@ 2022-03-28  9:11 ` Jan Beulich
  2022-03-28  9:11 ` [PATCH 5/7] bfd/Dwarf2: make find-nearest-line returned function name consistent Jan Beulich
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:11 UTC (permalink / raw)
  To: Binutils; +Cc: Nick Clifton, richard.earnshaw, ramana.radhakrishnan

Just like insns encoded the more conventional way these should have line
number info associated with them.

--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -4033,6 +4033,8 @@ s_arm_elf_inst (int nbytes)
       mapping_state (MAP_ARM);
     }
 
+  dwarf2_emit_insn (0);
+
   do
     {
       expressionS exp;
--- /dev/null
+++ b/gas/testsuite/gas/arm/inst-po-dwarf.d
@@ -0,0 +1,21 @@
+#as: -gdwarf-2
+#name: Dwarf line number info for .inst
+#objdump: -WL -w
+#source: inst-po.s
+#skip: *-*-pe *-*-wince
+
+.*:[ 	]+file format .*
+
+Contents of the .debug_line section:
+
+CU: .*/inst-po.s:
+File name +Line number +Starting address.*
+inst-po.s +5 +0.*
+inst-po.s +12 +0x4.*
+inst-po.s +13 +0x8.*
+inst-po.s +20 +0xe.*
+inst-po.s +22 +0x14.*
+inst-po.s +26 +0x16.*
+inst-po.s +27 +0x1a.*
+inst-po.s +- +0x1e
+#pass


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 5/7] bfd/Dwarf2: make find-nearest-line returned function name consistent
  2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
                   ` (3 preceding siblings ...)
  2022-03-28  9:11 ` [PATCH 4/7] Arm32: " Jan Beulich
@ 2022-03-28  9:11 ` Jan Beulich
  2022-03-28  9:11 ` [PATCH 6/7] bfd/Dwarf2: gas doesn't mangle names Jan Beulich
  2022-03-28  9:12 ` [PATCH 7/7] gas/Dwarf: record functions Jan Beulich
  6 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:11 UTC (permalink / raw)
  To: Binutils

Prior to entering the enclosing "else if()" the earlier associated if()
checks function->is_linkage and, if set, uses function->name. The
comment in patch context precedes (and explains) the setting
function->is_linkage. Yet with the flag set, we should then also return
the function name, just like said earlier if() would do when we came
here a 2nd time for the same "addr". And indeed passing the same address
twice on addr2line's command line would resolve the function for the 2nd
instance, but not for the 1st (if this code path is taken). (This,
obviously, is particularly relevant when there's no ELF symbol table in
the first place, like would be the case - naturally - in PE/COFF
binaries, for example.)

--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -5264,8 +5264,9 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd
 	  sec_vma = section->vma;
 	  if (section->output_section != NULL)
 	    sec_vma = section->output_section->vma + section->output_offset;
-	  if (fun != NULL
-	      && fun->value + sec_vma == function->arange.low)
+	  if (fun == NULL)
+	    *functionname_ptr = function->name;
+	  else if (fun->value + sec_vma == function->arange.low)
 	    function->name = *functionname_ptr;
 	  /* Even if we didn't find a linkage name, say that we have
 	     to stop a repeated search of symbols.  */


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 6/7] bfd/Dwarf2: gas doesn't mangle names
  2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
                   ` (4 preceding siblings ...)
  2022-03-28  9:11 ` [PATCH 5/7] bfd/Dwarf2: make find-nearest-line returned function name consistent Jan Beulich
@ 2022-03-28  9:11 ` Jan Beulich
  2022-03-28  9:12 ` [PATCH 7/7] gas/Dwarf: record functions Jan Beulich
  6 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:11 UTC (permalink / raw)
  To: Binutils

Include the language identifier emitted by gas in the set of ones where
no mangled names are expected. Even if there could be "hand-mangled"
names, gas doesn't emit DW_AT_linkage_name in the first place.
---
I wonder whether in the absence of a linkage-name attribute ->is_linkage
shouldn't be set independent of what non_mangled() returns.

--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -1441,6 +1441,7 @@ non_mangled (int lang)
     case DW_LANG_PLI:
     case DW_LANG_UPC:
     case DW_LANG_C11:
+    case DW_LANG_Mips_Assembler:
       return true;
     }
 }


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 7/7] gas/Dwarf: record functions
  2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
                   ` (5 preceding siblings ...)
  2022-03-28  9:11 ` [PATCH 6/7] bfd/Dwarf2: gas doesn't mangle names Jan Beulich
@ 2022-03-28  9:12 ` Jan Beulich
  6 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2022-03-28  9:12 UTC (permalink / raw)
  To: Binutils

To help tools like addr2line looking up function names, in particular
when dealing with e.g. PE/COFF binaries (linked from ELF objects), where
there's no ELF symbol table to fall back to, emit minimalistic
information for functions marked as such and having their size
specified.

Notes regarding the restriction to (pure) ELF:
- I realize this is a layering violation; I don't see how to deal with
  that in a better way.
- S_GET_SIZE(), when OBJ_MAYBE_ELF is defined, looks wrong: Unlike
  S_SET_SIZE() it does not check whether the hook is NULL.
- symbol_get_obj(), when OBJ_MAYBE_ELF is defined, looks unusable, as
  its return type can only ever be one object format's type (and this
  may then not be ELF's).

The new testcases are limited to x86 because I wanted to include the
case where function size can't be determined yet at the time Dwarf2 info
is generated. As .nops gains support by further targets, they could also
be added here then (with, as necessary, expecations suitably relaxed to
cover for insn size differences).

--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -2665,14 +2665,55 @@ out_debug_aranges (segT aranges_seg, seg
 static void
 out_debug_abbrev (segT abbrev_seg,
 		  segT info_seg ATTRIBUTE_UNUSED,
-		  segT line_seg ATTRIBUTE_UNUSED)
+		  segT line_seg ATTRIBUTE_UNUSED,
+		  unsigned char *func_formP)
 {
   int secoff_form;
+  bool have_efunc = false, have_lfunc = false;
+
+  /* Check the symbol table for function symbols which also have their size
+     specified.  */
+  if (symbol_rootP)
+    {
+      symbolS *symp;
+
+      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+	{
+	  /* A warning construct is a warning symbol followed by the
+	     symbol warned about.  Skip this and the following symbol.  */
+	  if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
+	    {
+	      symp = symbol_next (symp);
+	      if (!symp)
+	        break;
+	      continue;
+	    }
+
+	  if (!S_IS_DEFINED (symp) || !S_IS_FUNCTION (symp))
+	    continue;
+
+#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
+	  if (S_GET_SIZE (symp) == 0)
+	    {
+	      if (!IS_ELF || symbol_get_obj (symp)->size == NULL)
+		continue;
+	    }
+#else
+	  continue;
+#endif
+
+	  if (S_IS_EXTERNAL (symp))
+	    have_efunc = true;
+	  else
+	    have_lfunc = true;
+	}
+    }
+
   subseg_set (abbrev_seg, 0);
 
   out_uleb128 (1);
   out_uleb128 (DW_TAG_compile_unit);
-  out_byte (DW_CHILDREN_no);
+  out_byte (have_efunc || have_lfunc ? DW_CHILDREN_yes : DW_CHILDREN_no);
   if (DWARF2_VERSION < 4)
     {
       if (DWARF2_FORMAT (line_seg) == dwarf2_format_32bit)
@@ -2699,6 +2740,29 @@ out_debug_abbrev (segT abbrev_seg,
   out_abbrev (DW_AT_language, DW_FORM_data2);
   out_abbrev (0, 0);
 
+  if (have_efunc || have_lfunc)
+    {
+      out_uleb128 (2);
+      out_uleb128 (DW_TAG_subprogram);
+      out_byte (DW_CHILDREN_no);
+      out_abbrev (DW_AT_name, DW_FORM_strp);
+      if (have_efunc)
+	{
+	  if (have_lfunc || DWARF2_VERSION < 4)
+	    *func_formP = DW_FORM_flag;
+	  else
+	    *func_formP = DW_FORM_flag_present;
+	  out_abbrev (DW_AT_external, *func_formP);
+	}
+      else
+	/* Any non-zero value other than DW_FORM_flag will do.  */
+	*func_formP = DW_FORM_block;
+      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);
+    }
+
   /* Terminate the abbreviations for this compilation unit.  */
   out_byte (0);
 }
@@ -2706,9 +2770,10 @@ out_debug_abbrev (segT abbrev_seg,
 /* Emit a description of this compilation unit for .debug_info.  */
 
 static void
-out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg,
+out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT str_seg,
 		symbolS *ranges_sym, symbolS *name_sym,
-		symbolS *comp_dir_sym, symbolS *producer_sym)
+		symbolS *comp_dir_sym, symbolS *producer_sym,
+		unsigned char func_form)
 {
   expressionS exp;
   symbolS *info_end;
@@ -2790,6 +2855,81 @@ out_debug_info (segT info_seg, segT abbr
      dwarf2 draft has no standard code for assembler.  */
   out_two (DW_LANG_Mips_Assembler);
 
+  if (func_form)
+    {
+      symbolS *symp;
+
+      for (symp = symbol_rootP; symp; symp = symbol_next (symp))
+	{
+	  const char *name;
+	  size_t len;
+
+	  /* Skip warning constructs (see above).  */
+	  if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
+	    {
+	      symp = symbol_next (symp);
+	      if (!symp)
+	        break;
+	      continue;
+	    }
+
+	  if (!S_IS_DEFINED (symp) || !S_IS_FUNCTION (symp))
+	    continue;
+
+	  subseg_set (str_seg, 0);
+	  name_sym = symbol_temp_new_now_octets ();
+	  name = S_GET_NAME (symp);
+	  len = strlen (name) + 1;
+	  memcpy (frag_more (len), name, len);
+
+	  subseg_set (info_seg, 0);
+
+	  /* DW_TAG_subprogram DIE abbrev */
+	  out_uleb128 (2);
+
+	  /* DW_AT_name */
+	  TC_DWARF2_EMIT_OFFSET (name_sym, sizeof_offset);
+
+	  /* DW_AT_external.  */
+	  if (func_form == DW_FORM_flag)
+	    out_byte (S_IS_EXTERNAL (symp));
+
+	  /* DW_AT_low_pc */
+	  exp.X_op = O_symbol;
+	  exp.X_add_symbol = symp;
+	  exp.X_add_number = 0;
+	  emit_expr (&exp, sizeof_address);
+
+	  /* DW_AT_high_pc */
+	  exp.X_op = O_constant;
+#if defined (OBJ_ELF) /* || defined (OBJ_MAYBE_ELF) */
+	  exp.X_add_number = S_GET_SIZE (symp);
+	  if (exp.X_add_number == 0 && IS_ELF
+	      && symbol_get_obj (symp)->size != NULL)
+	    {
+	      exp.X_op = O_add;
+	      exp.X_op_symbol = make_expr_symbol (symbol_get_obj (symp)->size);
+	    }
+#else
+	  exp.X_add_number = 0;
+#endif
+	  if (DWARF2_VERSION < 4)
+	    {
+	      if (exp.X_op == O_constant)
+		exp.X_op = O_symbol;
+	      exp.X_add_symbol = symp;
+	      emit_expr (&exp, sizeof_address);
+	    }
+	  else if (exp.X_op == O_constant)
+	    out_uleb128 (exp.X_add_number);
+	  else
+	    emit_leb128_expr (symbol_get_value_expression (exp.X_op_symbol), 0);
+	}
+
+      /* End of children.  */
+      out_leb128 (0);
+    }
+
   symbol_set_value_now (info_end);
 }
 
@@ -2959,6 +3099,7 @@ dwarf2_finish (void)
       segT aranges_seg;
       segT str_seg;
       symbolS *name_sym, *comp_dir_sym, *producer_sym, *ranges_sym;
+      unsigned char func_form = 0;
 
       gas_assert (all_segs);
 
@@ -3004,10 +3145,11 @@ dwarf2_finish (void)
 	}
 
       out_debug_aranges (aranges_seg, info_seg);
-      out_debug_abbrev (abbrev_seg, info_seg, line_seg);
+      out_debug_abbrev (abbrev_seg, info_seg, line_seg, &func_form);
       out_debug_str (str_seg, &name_sym, &comp_dir_sym, &producer_sym);
-      out_debug_info (info_seg, abbrev_seg, line_seg, ranges_sym,
-		      name_sym, comp_dir_sym, producer_sym);
+      out_debug_info (info_seg, abbrev_seg, line_seg, str_seg,
+		      ranges_sym, name_sym, comp_dir_sym, producer_sym,
+		      func_form);
     }
 }
 
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf-3-func.d
@@ -0,0 +1,48 @@
+#as: --gdwarf-3
+#name: Dwarf3 function debug info
+#readelf: -W -wai
+#target: i?86-*-* x86_64-*-*
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +3
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <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_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_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_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_low_pc +: \(addr\) (0x)?35
+ +<[0-9a-f]+> +DW_AT_high_pc +: \(addr\) (0x)?38
+ <1><[0-9a-f]+>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+ +Number TAG \(0x0\)
+ +1 +DW_TAG_compile_unit +\[has children\]
+#...
+ +2 +DW_TAG_subprogram +\[no children\]
+ +DW_AT_name +DW_FORM_strp
+ +DW_AT_external +DW_FORM_flag
+ +DW_AT_low_pc +DW_FORM_addr
+ +DW_AT_high_pc +DW_FORM_addr
+ +DW_AT value: 0 +DW_FORM value: 0
+#pass
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf-3-func.s
@@ -0,0 +1,40 @@
+	.text
+
+	.ifndef LOCAL
+efunc1:
+	.nop
+	.nop
+	.global efunc1
+	.type efunc1, %function
+	.size efunc1, .-efunc1
+	.endif
+
+	.ifndef GLOBAL
+lfunc1:
+	.nops 16
+	.nop
+	.type lfunc1, %function
+	.size lfunc1, .-lfunc1
+	.endif
+
+	.ifndef LOCAL
+efunc2:
+	.nop
+	.nops 32
+	.nop
+	.global efunc2
+	.type efunc2, %function
+	.size efunc2, .-efunc2
+	.endif
+
+	.global efunc3
+	.type efunc3, %function
+
+	.ifndef GLOBAL
+lfunc2:
+	.nop
+	.nop
+	.nop
+	.type lfunc2, %function
+	.size lfunc2, .-lfunc2
+	.endif
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf-5-func-global.d
@@ -0,0 +1,40 @@
+#as: --gdwarf-5 --defsym GLOBAL=1
+#name: Dwarf5 global function debug info
+#readelf: -W -wai
+#source: dwarf-3-func.s
+#target: i?86-*-* x86_64-*-*
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +5
+ +Unit Type: +DW_UT_compile \(1\)
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <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_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_low_pc +: \(addr\) (0x)?2
+ +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 34
+ <1><[0-9a-f]+>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+ +Number TAG \(0x0\)
+ +1 +DW_TAG_compile_unit +\[has children\]
+#...
+ +2 +DW_TAG_subprogram +\[no children\]
+ +DW_AT_name +DW_FORM_strp
+ +DW_AT_external +DW_FORM_flag_present
+ +DW_AT_low_pc +DW_FORM_addr
+ +DW_AT_high_pc +DW_FORM_udata
+ +DW_AT value: 0 +DW_FORM value: 0
+#pass
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf-5-func-local.d
@@ -0,0 +1,37 @@
+#as: --gdwarf-5 --defsym LOCAL=1
+#name: Dwarf5 local function debug info
+#readelf: -W -wai
+#source: dwarf-3-func.s
+#target: i?86-*-* x86_64-*-*
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +5
+ +Unit Type: +DW_UT_compile \(1\)
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <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_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_low_pc +: \(addr\) (0x)?11
+ +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 3
+ <1><[0-9a-f]+>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+ +Number TAG \(0x0\)
+ +1 +DW_TAG_compile_unit +\[has children\]
+#...
+ +2 +DW_TAG_subprogram +\[no children\]
+ +DW_AT_name +DW_FORM_strp
+ +DW_AT_low_pc +DW_FORM_addr
+ +DW_AT_high_pc +DW_FORM_udata
+ +DW_AT value: 0 +DW_FORM value: 0
+#pass
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf-5-func.d
@@ -0,0 +1,50 @@
+#as: --gdwarf-5
+#name: Dwarf5 function debug info
+#readelf: -W -wai
+#source: dwarf-3-func.s
+#target: i?86-*-* x86_64-*-*
+
+Contents of the .debug_info section:
+
+ +Compilation Unit @ offset (0x)?0:
+ +Length: .*
+ +Version: +5
+ +Unit Type: +DW_UT_compile \(1\)
+ +Abbrev Offset: +(0x)?0
+ +Pointer Size: .*
+ <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_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_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_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_low_pc +: \(addr\) (0x)?35
+ +<[0-9a-f]+> +DW_AT_high_pc +: \(udata\) 3
+ <1><[0-9a-f]+>: Abbrev Number: 0
+
+Contents of the .debug_abbrev section:
+
+ +Number TAG \(0x0\)
+ +1 +DW_TAG_compile_unit +\[has children\]
+#...
+ +2 +DW_TAG_subprogram +\[no children\]
+ +DW_AT_name +DW_FORM_strp
+ +DW_AT_external +DW_FORM_flag
+ +DW_AT_low_pc +DW_FORM_addr
+ +DW_AT_high_pc +DW_FORM_udata
+ +DW_AT value: 0 +DW_FORM value: 0
+#pass
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -307,6 +307,10 @@ if { [is_elf_format] } then {
     run_dump_test "dwarf-5-cu" $dump_opts
     run_dump_test "dwarf-5-nop-for-line-table" $dump_opts
     run_dump_test "dwarf-5-irp" $dump_opts
+    run_dump_test "dwarf-3-func" $dump_opts
+    run_dump_test "dwarf-5-func" $dump_opts
+    run_dump_test "dwarf-5-func-global" $dump_opts
+    run_dump_test "dwarf-5-func-local" $dump_opts
     run_dump_test "pr25917"
     run_dump_test "bss"
     run_dump_test "bad-bss"


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros
  2022-03-28  9:07 ` [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros Jan Beulich
@ 2022-03-28  9:16   ` Andreas Schwab
  2022-03-28 10:24     ` Jan Beulich
  0 siblings, 1 reply; 11+ messages in thread
From: Andreas Schwab @ 2022-03-28  9:16 UTC (permalink / raw)
  To: Jan Beulich via Binutils

On Mär 28 2022, Jan Beulich via Binutils wrote:

> --- a/gas/macro.c
> +++ b/gas/macro.c
> @@ -233,7 +233,8 @@ buffer_and_nest (const char *from, const
>  	     number when expanding the macro), and since for short
>  	     macros we clearly prefer reporting the point of expansion
>  	     anyway, there's not an obviously better fix here.  */
> -	  if (strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
> +	  if (from != NULL && strcasecmp (from, "MACRO") == 0
> +	      && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)

That's relative to an old version of the file.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros
  2022-03-28  9:16   ` Andreas Schwab
@ 2022-03-28 10:24     ` Jan Beulich
  0 siblings, 0 replies; 11+ messages in thread
From: Jan Beulich @ 2022-03-28 10:24 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On 28.03.2022 11:16, Andreas Schwab wrote:
> On Mär 28 2022, Jan Beulich via Binutils wrote:
> 
>> --- a/gas/macro.c
>> +++ b/gas/macro.c
>> @@ -233,7 +233,8 @@ buffer_and_nest (const char *from, const
>>  	     number when expanding the macro), and since for short
>>  	     macros we clearly prefer reporting the point of expansion
>>  	     anyway, there's not an obviously better fix here.  */
>> -	  if (strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
>> +	  if (from != NULL && strcasecmp (from, "MACRO") == 0
>> +	      && strncasecmp (ptr->ptr + i, "linefile", 8) == 0)
> 
> That's relative to an old version of the file.

Hmm, yes, I will need to re-base this over 4c5f3d0c9eb3.

Jan


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/7] RISC-V: add testcase to check line number emission for .insn
  2022-03-28  9:08 ` [PATCH 2/7] RISC-V: add testcase to check line number emission for .insn Jan Beulich
@ 2022-04-06 17:51   ` Palmer Dabbelt
  0 siblings, 0 replies; 11+ messages in thread
From: Palmer Dabbelt @ 2022-04-06 17:51 UTC (permalink / raw)
  To: jbeulich; +Cc: binutils, Andrew Waterman, Jim Wilson, Nelson Chu

On Mon, 28 Mar 2022 02:08:55 PDT (-0700), jbeulich@suse.com wrote:
> Since no such test looks to exist, derive one from insn.s.
>
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/insn-dwarf.d
> @@ -0,0 +1,71 @@
> +#as: -march=rv64ifc -gdwarf-2
> +#name: Dwarf line number info for .insn
> +#objdump: -WL -w
> +#source: insn.s
> +
> +.*:[ 	]+file format .*
> +
> +Contents of the .debug_line section:
> +
> +CU: .*/insn.s:
> +File name +Line number +Starting address.*
> +insn.s +2 +0.*
> +insn.s +3 +0x4.*
> +insn.s +4 +0x8.*
> +insn.s +5 +0xc.*
> +insn.s +6 +0x10.*
> +insn.s +7 +0x14.*
> +insn.s +8 +0x18.*
> +insn.s +9 +0x1c.*
> +insn.s +10 +0x20.*
> +insn.s +11 +0x24.*
> +insn.s +13 +0x28.*
> +insn.s +14 +0x2a.*
> +insn.s +15 +0x2c.*
> +insn.s +16 +0x2e.*
> +insn.s +17 +0x30.*
> +insn.s +18 +0x32.*
> +insn.s +19 +0x34.*
> +insn.s +20 +0x36.*
> +insn.s +22 +0x38.*
> +insn.s +23 +0x3c.*
> +insn.s +24 +0x40.*
> +insn.s +25 +0x44.*
> +insn.s +26 +0x48.*
> +insn.s +27 +0x4c.*
> +insn.s +28 +0x50.*
> +insn.s +29 +0x54.*
> +insn.s +30 +0x58.*
> +insn.s +31 +0x5c.*
> +insn.s +33 +0x60.*
> +insn.s +34 +0x62.*
> +insn.s +35 +0x64.*
> +insn.s +36 +0x66.*
> +insn.s +37 +0x68.*
> +insn.s +38 +0x6a.*
> +insn.s +39 +0x6c.*
> +insn.s +40 +0x6e.*
> +insn.s +41 +0x70.*
> +insn.s +43 +0x72.*
> +insn.s +44 +0x76.*
> +insn.s +45 +0x7a.*
> +insn.s +46 +0x7e.*
> +insn.s +47 +0x82.*
> +insn.s +48 +0x86.*
> +insn.s +49 +0x8a.*
> +insn.s +50 +0x8e.*
> +insn.s +51 +0x92.*
> +insn.s +52 +0x96.*
> +insn.s +53 +0x9a.*
> +insn.s +54 +0x9e.*
> +insn.s +55 +0xa2.*
> +insn.s +57 +0xa6.*
> +insn.s +58 +0xa8.*
> +insn.s +59 +0xac.*
> +insn.s +60 +0xb2.*
> +insn.s +61 +0xba.*
> +insn.s +62 +0xbc.*
> +insn.s +63 +0xc0.*
> +insn.s +64 +0xc6.*
> +insn.s +- +0xce
> +#pass

Acked-by: Palmer Dabbelt <palmer@rivosinc.com>

The RISC-V port generally isn't as well tested as it should be, so it's 
always great to have stuff like this.  Thanks!

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2022-04-06 17:51 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-28  9:06 [PATCH 0/7] Dwarf debug info generation improvements Jan Beulich
2022-03-28  9:07 ` [PATCH 1/7] gas/Dwarf: special-case .linefile only for macros Jan Beulich
2022-03-28  9:16   ` Andreas Schwab
2022-03-28 10:24     ` Jan Beulich
2022-03-28  9:08 ` [PATCH 2/7] RISC-V: add testcase to check line number emission for .insn Jan Beulich
2022-04-06 17:51   ` Palmer Dabbelt
2022-03-28  9:10 ` [PATCH 3/7] Arm64: arrange for line number emission for .inst Jan Beulich
2022-03-28  9:11 ` [PATCH 4/7] Arm32: " Jan Beulich
2022-03-28  9:11 ` [PATCH 5/7] bfd/Dwarf2: make find-nearest-line returned function name consistent Jan Beulich
2022-03-28  9:11 ` [PATCH 6/7] bfd/Dwarf2: gas doesn't mangle names Jan Beulich
2022-03-28  9:12 ` [PATCH 7/7] gas/Dwarf: record functions Jan Beulich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).