[LVu] base subseg head view on prev subseg's tail
[deliverable/binutils-gdb.git] / gas / dwarf2dbg.c
index 2d316ddcb9ca18da799302d28ca2c42f36dce80d..b77751d8af3d922a7648d4525a775e26727644f5 100644 (file)
@@ -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;
        }
This page took 0.025589 seconds and 4 git commands to generate.