diff options
Diffstat (limited to 'gas/dwarf2dbg.c')
-rw-r--r-- | gas/dwarf2dbg.c | 37 |
1 files changed, 32 insertions, 5 deletions
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; } |