Subversion Repositories Kolibri OS

Rev

Rev 5222 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5222 Rev 6324
Line 1... Line 1...
1
/* dwarf2dbg.c - DWARF2 debug support
1
/* dwarf2dbg.c - DWARF2 debug support
2
   Copyright 1999-2013 Free Software Foundation, Inc.
2
   Copyright (C) 1999-2015 Free Software Foundation, Inc.
3
   Contributed by David Mosberger-Tang 
3
   Contributed by David Mosberger-Tang 
Line 4... Line 4...
4
 
4
 
Line 5... Line 5...
5
   This file is part of GAS, the GNU Assembler.
5
   This file is part of GAS, the GNU Assembler.
Line 156... Line 156...
156
#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
156
#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
Line 157... Line 157...
157
 
157
 
158
/* The maximum address skip amount that can be encoded with a special op.  */
158
/* The maximum address skip amount that can be encoded with a special op.  */
Line -... Line 159...
-
 
159
#define MAX_SPECIAL_ADDR_DELTA		SPECIAL_ADDR(255)
-
 
160
 
-
 
161
#ifndef TC_PARSE_CONS_RETURN_NONE
-
 
162
#define TC_PARSE_CONS_RETURN_NONE BFD_RELOC_NONE
159
#define MAX_SPECIAL_ADDR_DELTA		SPECIAL_ADDR(255)
163
#endif
160
 
164
 
161
struct line_entry {
165
struct line_entry {
162
  struct line_entry *next;
166
  struct line_entry *next;
163
  symbolS *label;
167
  symbolS *label;
Line 180... Line 184...
180
  symbolS *text_end;
184
  symbolS *text_end;
181
};
185
};
Line 182... Line 186...
182
 
186
 
183
/* Collects data for all line table entries during assembly.  */
187
/* Collects data for all line table entries during assembly.  */
184
static struct line_seg *all_segs;
-
 
185
/* Hash used to quickly lookup a segment by name, avoiding the need to search
-
 
186
   through the all_segs list.  */
-
 
187
static struct hash_control *all_segs_hash;
188
static struct line_seg *all_segs;
Line 188... Line 189...
188
static struct line_seg **last_seg_ptr;
189
static struct line_seg **last_seg_ptr;
189
 
190
 
190
struct file_entry {
191
struct file_entry {
Line 242... Line 243...
242
/* Find or create (if CREATE_P) an entry for SEG+SUBSEG in ALL_SEGS.  */
243
/* Find or create (if CREATE_P) an entry for SEG+SUBSEG in ALL_SEGS.  */
Line 243... Line 244...
243
 
244
 
244
static struct line_subseg *
245
static struct line_subseg *
245
get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p)
246
get_line_subseg (segT seg, subsegT subseg, bfd_boolean create_p)
246
{
-
 
247
  static segT last_seg;
-
 
248
  static subsegT last_subseg;
247
{
249
  static struct line_subseg *last_line_subseg;
-
 
250
 
-
 
251
  struct line_seg *s;
248
  struct line_seg *s = seg_info (seg)->dwarf2_line_seg;
Line 252... Line -...
252
  struct line_subseg **pss, *lss;
-
 
253
 
-
 
254
  if (seg == last_seg && subseg == last_subseg)
-
 
255
    return last_line_subseg;
-
 
256
 
249
  struct line_subseg **pss, *lss;
257
  s = (struct line_seg *) hash_find (all_segs_hash, seg->name);
250
 
258
  if (s == NULL)
251
  if (s == NULL)
259
    {
252
    {
Line 264... Line 257...
264
      s->next = NULL;
257
      s->next = NULL;
265
      s->seg = seg;
258
      s->seg = seg;
266
      s->head = NULL;
259
      s->head = NULL;
267
      *last_seg_ptr = s;
260
      *last_seg_ptr = s;
268
      last_seg_ptr = &s->next;
261
      last_seg_ptr = &s->next;
269
      hash_insert (all_segs_hash, seg->name, s);
262
      seg_info (seg)->dwarf2_line_seg = s;
270
    }
263
    }
271
  gas_assert (seg == s->seg);
264
  gas_assert (seg == s->seg);
Line 272... Line 265...
272
 
265
 
273
  for (pss = &s->head; (lss = *pss) != NULL ; pss = &lss->next)
266
  for (pss = &s->head; (lss = *pss) != NULL ; pss = &lss->next)
Line 285... Line 278...
285
  lss->ptail = &lss->head;
278
  lss->ptail = &lss->head;
286
  lss->pmove_tail = &lss->head;
279
  lss->pmove_tail = &lss->head;
287
  *pss = lss;
280
  *pss = lss;
Line 288... Line 281...
288
 
281
 
289
 found_subseg:
-
 
290
  last_seg = seg;
-
 
291
  last_subseg = subseg;
-
 
292
  last_line_subseg = lss;
-
 
293
 
282
 found_subseg:
294
  return lss;
283
  return lss;
Line 295... Line 284...
295
}
284
}
Line 679... Line 668...
679
  while (ISALPHA (*input_line_pointer))
668
  while (ISALPHA (*input_line_pointer))
680
    {
669
    {
681
      char *p, c;
670
      char *p, c;
682
      offsetT value;
671
      offsetT value;
Line 683... Line -...
683
 
-
 
684
      p = input_line_pointer;
672
 
Line 685... Line 673...
685
      c = get_symbol_end ();
673
      c = get_symbol_name (& p);
686
 
674
 
687
      if (strcmp (p, "basic_block") == 0)
675
      if (strcmp (p, "basic_block") == 0)
688
	{
676
	{
Line 699... Line 687...
699
	  current.flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
687
	  current.flags |= DWARF2_FLAG_EPILOGUE_BEGIN;
700
	  *input_line_pointer = c;
688
	  *input_line_pointer = c;
701
	}
689
	}
702
      else if (strcmp (p, "is_stmt") == 0)
690
      else if (strcmp (p, "is_stmt") == 0)
703
	{
691
	{
704
	  *input_line_pointer = c;
692
	  (void) restore_line_pointer (c);
705
	  value = get_absolute_expression ();
693
	  value = get_absolute_expression ();
706
	  if (value == 0)
694
	  if (value == 0)
707
	    current.flags &= ~DWARF2_FLAG_IS_STMT;
695
	    current.flags &= ~DWARF2_FLAG_IS_STMT;
708
	  else if (value == 1)
696
	  else if (value == 1)
709
	    current.flags |= DWARF2_FLAG_IS_STMT;
697
	    current.flags |= DWARF2_FLAG_IS_STMT;
Line 713... Line 701...
713
	      return;
701
	      return;
714
	    }
702
	    }
715
	}
703
	}
716
      else if (strcmp (p, "isa") == 0)
704
      else if (strcmp (p, "isa") == 0)
717
	{
705
	{
718
	  *input_line_pointer = c;
706
	  (void) restore_line_pointer (c);
719
	  value = get_absolute_expression ();
707
	  value = get_absolute_expression ();
720
	  if (value >= 0)
708
	  if (value >= 0)
721
	    current.isa = value;
709
	    current.isa = value;
722
	  else
710
	  else
723
	    {
711
	    {
Line 725... Line 713...
725
	      return;
713
	      return;
726
	    }
714
	    }
727
	}
715
	}
728
      else if (strcmp (p, "discriminator") == 0)
716
      else if (strcmp (p, "discriminator") == 0)
729
	{
717
	{
730
	  *input_line_pointer = c;
718
	  (void) restore_line_pointer (c);
731
	  value = get_absolute_expression ();
719
	  value = get_absolute_expression ();
732
	  if (value >= 0)
720
	  if (value >= 0)
733
	    current.discriminator = value;
721
	    current.discriminator = value;
734
	  else
722
	  else
735
	    {
723
	    {
Line 738... Line 726...
738
	    }
726
	    }
739
	}
727
	}
740
      else
728
      else
741
	{
729
	{
742
	  as_bad (_("unknown .loc sub-directive `%s'"), p);
730
	  as_bad (_("unknown .loc sub-directive `%s'"), p);
743
	  *input_line_pointer = c;
731
	  (void) restore_line_pointer (c);
744
	  return;
732
	  return;
745
	}
733
	}
Line 746... Line 734...
746
 
734
 
747
      SKIP_WHITESPACE ();
735
      SKIP_WHITESPACE_AFTER_NAME ();
Line 748... Line 736...
748
    }
736
    }
749
 
737
 
750
  demand_empty_rest_of_line ();
738
  demand_empty_rest_of_line ();
Line 1142... Line 1130...
1142
      p += output_leb128 (p, sizeof_address + 1, 0);
1130
      p += output_leb128 (p, sizeof_address + 1, 0);
1143
      *p++ = DW_LNE_set_address;
1131
      *p++ = DW_LNE_set_address;
1144
      exp.X_op = O_symbol;
1132
      exp.X_op = O_symbol;
1145
      exp.X_add_symbol = to_sym;
1133
      exp.X_add_symbol = to_sym;
1146
      exp.X_add_number = 0;
1134
      exp.X_add_number = 0;
1147
      emit_expr_fix (&exp, sizeof_address, frag, p);
1135
      emit_expr_fix (&exp, sizeof_address, frag, p, TC_PARSE_CONS_RETURN_NONE);
1148
      p += sizeof_address;
1136
      p += sizeof_address;
1149
    }
1137
    }
1150
  else
1138
  else
1151
    {
1139
    {
1152
      *p++ = DW_LNS_fixed_advance_pc;
1140
      *p++ = DW_LNS_fixed_advance_pc;
1153
      emit_expr_fix (pexp, 2, frag, p);
1141
      emit_expr_fix (pexp, 2, frag, p, TC_PARSE_CONS_RETURN_NONE);
1154
      p += 2;
1142
      p += 2;
1155
    }
1143
    }
Line 1156... Line 1144...
1156
 
1144
 
1157
  if (line_delta == INT_MAX)
1145
  if (line_delta == INT_MAX)
Line 1467... Line 1455...
1467
  out_byte (0);
1455
  out_byte (0);
1468
}
1456
}
Line 1469... Line 1457...
1469
 
1457
 
1470
/* Switch to SEC and output a header length field.  Return the size of
1458
/* Switch to SEC and output a header length field.  Return the size of
-
 
1459
   offsets used in SEC.  The caller must set EXPR->X_add_symbol value
1471
   offsets used in SEC.  The caller must set EXPR->X_add_symbol value
1460
   to the end of the section.  EXPR->X_add_number will be set to the
Line 1472... Line 1461...
1472
   to the end of the section.  */
1461
   negative size of the header.  */
1473
 
1462
 
1474
static int
1463
static int
1475
out_header (asection *sec, expressionS *exp)
1464
out_header (asection *sec, expressionS *exp)
1476
{
1465
{
Line 1477... Line 1466...
1477
  symbolS *start_sym;
1466
  symbolS *start_sym;
-
 
1467
  symbolS *end_sym;
-
 
1468
 
-
 
1469
  subseg_set (sec, 0);
-
 
1470
 
-
 
1471
  if (flag_dwarf_sections)
-
 
1472
    {
-
 
1473
      /* If we are going to put the start and end symbols in different
-
 
1474
	 sections, then we need real symbols, not just fake, local ones.  */
-
 
1475
      frag_now_fix ();
-
 
1476
      start_sym = symbol_make (".Ldebug_line_start");
-
 
1477
      end_sym = symbol_make (".Ldebug_line_end");
-
 
1478
      symbol_set_value_now (start_sym);
1478
  symbolS *end_sym;
1479
    }
1479
 
1480
  else
-
 
1481
    {
Line 1480... Line 1482...
1480
  subseg_set (sec, 0);
1482
      start_sym = symbol_temp_new_now ();
1481
  start_sym = symbol_temp_new_now ();
1483
      end_sym = symbol_temp_make ();
1482
  end_sym = symbol_temp_make ();
1484
    }
1483
 
1485
 
Line 1513... Line 1515...
1513
 
1515
 
1514
static void
1516
static void
1515
out_debug_line (segT line_seg)
1517
out_debug_line (segT line_seg)
1516
{
1518
{
1517
  expressionS exp;
1519
  expressionS exp;
1518
  symbolS *prologue_end;
1520
  symbolS *prologue_start, *prologue_end;
1519
  symbolS *line_end;
1521
  symbolS *line_end;
1520
  struct line_seg *s;
1522
  struct line_seg *s;
Line 1521... Line 1523...
1521
  int sizeof_offset;
1523
  int sizeof_offset;
Line 1525... Line 1527...
1525
 
1527
 
1526
  /* Version.  */
1528
  /* Version.  */
Line 1527... Line 1529...
1527
  out_two (DWARF2_LINE_VERSION);
1529
  out_two (DWARF2_LINE_VERSION);
-
 
1530
 
1528
 
1531
  /* Length of the prologue following this length.  */
-
 
1532
  prologue_start = symbol_temp_make ();
1529
  /* Length of the prologue following this length.  */
1533
  prologue_end = symbol_temp_make ();
-
 
1534
  exp.X_op = O_subtract;
1530
  prologue_end = symbol_temp_make ();
1535
  exp.X_add_symbol = prologue_end;
1531
  exp.X_add_symbol = prologue_end;
1536
  exp.X_op_symbol = prologue_start;
-
 
1537
  exp.X_add_number = 0;
Line 1532... Line 1538...
1532
  exp.X_add_number = - (4 + 2 + 4);
1538
  emit_expr (&exp, sizeof_offset);
1533
  emit_expr (&exp, sizeof_offset);
1539
  symbol_set_value_now (prologue_start);
1534
 
1540
 
1535
  /* Parameters of the state machine.  */
1541
  /* Parameters of the state machine.  */
Line 1630... Line 1636...
1630
 
1636
 
1631
static void
1637
static void
1632
out_debug_aranges (segT aranges_seg, segT info_seg)
1638
out_debug_aranges (segT aranges_seg, segT info_seg)
1633
{
1639
{
-
 
1640
  unsigned int addr_size = sizeof_address;
1634
  unsigned int addr_size = sizeof_address;
1641
  offsetT size;
1635
  struct line_seg *s;
1642
  struct line_seg *s;
1636
  expressionS exp;
1643
  expressionS exp;
1637
  symbolS *aranges_end;
1644
  symbolS *aranges_end;
1638
  char *p;
1645
  char *p;
Line 1639... Line 1646...
1639
  int sizeof_offset;
1646
  int sizeof_offset;
1640
 
1647
 
-
 
1648
  sizeof_offset = out_header (aranges_seg, &exp);
Line 1641... Line 1649...
1641
  sizeof_offset = out_header (aranges_seg, &exp);
1649
  aranges_end = exp.X_add_symbol;
1642
  aranges_end = exp.X_add_symbol;
1650
  size = -exp.X_add_number;
-
 
1651
 
Line 1643... Line 1652...
1643
 
1652
  /* Version.  */
1644
  /* Version.  */
1653
  out_two (DWARF2_ARANGES_VERSION);
-
 
1654
  size += 2;
Line 1645... Line 1655...
1645
  out_two (DWARF2_ARANGES_VERSION);
1655
 
1646
 
1656
  /* Offset to .debug_info.  */
-
 
1657
  TC_DWARF2_EMIT_OFFSET (section_symbol (info_seg), sizeof_offset);
Line 1647... Line 1658...
1647
  /* Offset to .debug_info.  */
1658
  size += sizeof_offset;
1648
  TC_DWARF2_EMIT_OFFSET (section_symbol (info_seg), sizeof_offset);
1659
 
-
 
1660
  /* Size of an address (offset portion).  */
Line 1649... Line 1661...
1649
 
1661
  out_byte (addr_size);
1650
  /* Size of an address (offset portion).  */
1662
  size++;
-
 
1663
 
Line 1651... Line 1664...
1651
  out_byte (addr_size);
1664
  /* Size of a segment descriptor.  */
1652
 
1665
  out_byte (0);
1653
  /* Size of a segment descriptor.  */
1666
  size++;
1654
  out_byte (0);
1667
 
Line 1837... Line 1850...
1837
}
1850
}
Line 1838... Line 1851...
1838
 
1851
 
1839
void
1852
void
1840
dwarf2_init (void)
1853
dwarf2_init (void)
1841
{
-
 
1842
  all_segs_hash = hash_new ();
1854
{
1843
  last_seg_ptr = &all_segs;
1855
  last_seg_ptr = &all_segs;
Line 1844... Line 1856...
1844
}
1856
}