aboutsummaryrefslogtreecommitdiff
path: root/gas/dwarf2dbg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/dwarf2dbg.c')
-rw-r--r--gas/dwarf2dbg.c37
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;
}