This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] [LVu] base subseg head view on prev subseg's tail


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=62e6b7b3b3c6f2fffe9f5863ddebf430533b79f0

commit 62e6b7b3b3c6f2fffe9f5863ddebf430533b79f0
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sun May 5 23:07:20 2019 -0300

    [LVu] base subseg head view on prev subseg's tail
    
    Location views at borders between subsegments/subsections in the same
    segment/section are computed as if each new subsegment/subsection
    started with a forced view reset to zero, but the line number program
    does not introduce resets that are not explicitly requested, so if a
    subsegment ends at the same address another starts, the line number
    program will have a continuity of views at the border address, whereas
    the initial view number label in the latter subsegment will be
    miscomputed as zero.
    
    This patch delays the assignment of view expressions at subsegment
    heads to the time of chaining the frags of subsegments into a single
    segment, so that they are set based on the view at the end of the
    previous subsegment in the same segment.
    
    The line number program created for the test program had an
    unnecessary DW_LNS_advance_pc at the end.  This patch also arranges
    for us not to emit it.
    
    
    for  gas/ChangeLog
    
    	* dwarf2dbg.c (set_or_check_view): Skip heads when assigning
    	views of prior locs.
    	(dwarf2_gen_line_info_1): Skip heads.
    	(size_inc_line_addr, emit_inc_line_addr): Drop
    	DW_LNS_advance_pc for zero addr delta.
    	(dwarf2_finish): Assign views for heads of segments.
    	* testsuite/gas/elf/dwarf2-19.d: New.
    	* testsuite/gas/elf/dwarf2-19.s: New.
    	* testsuite/gas/elf/elf.exp: Test it.

Diff:
---
 gas/ChangeLog                     | 12 ++++++++++++
 gas/dwarf2dbg.c                   | 37 ++++++++++++++++++++++++++++++-----
 gas/testsuite/gas/elf/dwarf2-19.d | 21 ++++++++++++++++++++
 gas/testsuite/gas/elf/dwarf2-19.s | 41 +++++++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/elf/elf.exp     |  1 +
 5 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8ba1cde..b5703cd 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@
+2019-05-05  Alexandre Oliva <aoliva@redhat.com>
+
+	* dwarf2dbg.c (set_or_check_view): Skip heads when assigning
+	views of prior locs.
+	(dwarf2_gen_line_info_1): Skip heads.
+	(size_inc_line_addr, emit_inc_line_addr): Drop
+	DW_LNS_advance_pc for zero addr delta.
+	(dwarf2_finish): Assign views for heads of segments.
+	* testsuite/gas/elf/dwarf2-19.d: New.
+	* testsuite/gas/elf/dwarf2-19.s: New.
+	* testsuite/gas/elf/elf.exp: Test it.
+
 2019-05-04  Alan Modra  <amodra@gmail.com>
 
 	* config/tc-m32c.c (insn_size): Delete static var.
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 2d316dd..b77751d 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -442,7 +442,16 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
       gas_assert (r == p);
       /* Set or check views until we find a defined or absent view.  */
       do
-	set_or_check_view (r, r->next, NULL);
+	{
+	  /* Do not define the head of a (sub?)segment view while
+	     handling others.  It would be defined too early, without
+	     regard to the last view of other subsegments.
+	     set_or_check_view will be called for every head segment
+	     that needs it.  */
+	  if (r == h)
+	    break;
+	  set_or_check_view (r, r->next, NULL);
+	}
       while (r->next && r->next->loc.view && !S_IS_DEFINED (r->next->loc.view)
 	     && (r = r->next));
 
@@ -454,6 +463,11 @@ set_or_check_view (struct line_entry *e, struct line_entry *p,
 	 simplify the view expressions, until we do so to P.  */
       do
 	{
+	  /* The head view of a subsegment may remain undefined while
+	     handling other elements, before it is linked to the last
+	     view of the previous subsegment.  */
+	  if (r == h)
+	    continue;
 	  gas_assert (S_IS_DEFINED (r->loc.view));
 	  resolve_expression (symbol_get_value_expression (r->loc.view));
 	}
@@ -480,9 +494,11 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
 
   lss = get_line_subseg (now_seg, now_subseg, TRUE);
 
-  if (loc->view)
+  /* Subseg heads are chained to previous subsegs in
+     dwarf2_finish.  */
+  if (loc->view && lss->head)
     set_or_check_view (e,
-		       !lss->head ? NULL : (struct line_entry *)lss->ptail,
+		       (struct line_entry *)lss->ptail,
 		       lss->head);
 
   *lss->ptail = e;
@@ -1176,7 +1192,7 @@ size_inc_line_addr (int line_delta, addressT addr_delta)
     {
       if (addr_delta == MAX_SPECIAL_ADDR_DELTA)
 	len = 1;
-      else
+      else if (addr_delta)
 	len = 1 + sizeof_leb128 (addr_delta, 0);
       return len + 3;
     }
@@ -1240,7 +1256,7 @@ emit_inc_line_addr (int line_delta, addressT addr_delta, char *p, int len)
     {
       if (addr_delta == MAX_SPECIAL_ADDR_DELTA)
 	*p++ = DW_LNS_const_add_pc;
-      else
+      else if (addr_delta)
 	{
 	  *p++ = DW_LNS_advance_pc;
 	  p += output_leb128 (p, addr_delta, 0);
@@ -2218,8 +2234,19 @@ dwarf2_finish (void)
       struct line_subseg *lss = s->head;
       struct line_entry **ptail = lss->ptail;
 
+      /* Reset the initial view of the first subsection of the
+	 section.  */
+      if (lss->head && lss->head->loc.view)
+	set_or_check_view (lss->head, NULL, NULL);
+
       while ((lss = lss->next) != NULL)
 	{
+	  /* Link the first view of subsequent subsections to the
+	     previous view.  */
+	  if (lss->head && lss->head->loc.view)
+	    set_or_check_view (lss->head,
+			       !s->head ? NULL : (struct line_entry *)ptail,
+			       s->head ? s->head->head : NULL);
 	  *ptail = lss->head;
 	  ptail = lss->ptail;
 	}
diff --git a/gas/testsuite/gas/elf/dwarf2-19.d b/gas/testsuite/gas/elf/dwarf2-19.d
new file mode 100644
index 0000000..ebb3bf9
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf2-19.d
@@ -0,0 +1,21 @@
+#as:
+#readelf: -x.rodata -wL
+#name: DWARF2 19
+# The am33 avr cr16 crx ft32 mn10 msp430 nds32 pru rl78 and xtensa targets do not evaluate the subtraction of symbols at assembly time.
+# The riscv targets do not support the subtraction of symbols.
+# The tile targets require 8-byte instructions, but the test only simulates 4-byte instructions.
+#notarget: am3*-* avr-* cr16-* crx-* ft32*-* mn10*-* msp430-* nds32*-* pru-* riscv*-* rl78-* tile*-* xtensa-*
+
+Hex dump of section '\.rodata':
+  0x00000000 01000102 *.*
+
+Contents of the \.debug_line section:
+
+CU: dwarf2-19\.c:
+File name  *Line number  *Starting address  *View +Stmt
+dwarf2-19\.c  *1  *0 +x
+dwarf2-19\.c  *2  *0  *1 +x
+dwarf2-19\.c  *4  *0x4 +x
+dwarf2-19\.c  *5  *0x4  *1 +x
+dwarf2-19\.c  *3  *0x4  *2 +x
+dwarf2-19\.c  *3  *0x4  *3 +x
diff --git a/gas/testsuite/gas/elf/dwarf2-19.s b/gas/testsuite/gas/elf/dwarf2-19.s
new file mode 100644
index 0000000..dd87be8
--- /dev/null
+++ b/gas/testsuite/gas/elf/dwarf2-19.s
@@ -0,0 +1,41 @@
+/* Test view numbering continuity at subsection borders.
+
+   Copyright (C) 2017-2019 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+	.file "dwarf2-19.c"
+	.text 0
+	.balign 4
+	.globl _start
+_start:
+	.file 1 "dwarf2-19.c"
+	.loc 1 1 view 0
+
+	.section .rodata
+	.uleb128 .L1
+	.uleb128 .L3
+	.uleb128 .L4
+	.uleb128 .L2
+
+	.text 1
+	.loc 1 2 view .L1 	/* same address as view 0 above -> view 1 */
+
+	.text 2
+	.loc 1 3 view .L2	/* same address as .L4 below -> view 2 */
+
+	.text 1
+	.dc.l 0
+	.loc 1 4 view .L3	/* bumped address from .L1's, view 0 */
+	.loc 1 5 view .L4	/* same address, view 1 */
diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp
index d616d5d..01d8b9d 100644
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -251,6 +251,7 @@ if { [is_elf_format] } then {
     run_dump_test "dwarf2-16"
     run_dump_test "dwarf2-17"
     run_dump_test "dwarf2-18"
+    run_dump_test "dwarf2-19"
     run_dump_test "bss"
     run_dump_test "bad-bss"
     run_dump_test "bad-section-flag"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]