1999-09-11 Donn Terry <donn@interix.com>
[deliverable/binutils-gdb.git] / gas / dwarf2dbg.c
index d1909c87348950dae17179d95ee356dca3d82bcc..e735592e73787ceec801198c462d8a704bef94b8 100644 (file)
@@ -33,7 +33,7 @@
 #include "dwarf2dbg.h"
 #include "subsegs.h"
 
-#include <elf/dwarf2.h>
+#include "elf/dwarf2.h"
 
 /* Since we can't generate the prolog until the body is complete, we
    use three different subsegments for .debug_line: one holding the
@@ -78,7 +78,7 @@
    is not made available by the GCC front-end.  */
 #define        DWARF2_LINE_DEFAULT_IS_STMT     1
 
-/* Given a special op, return the line skip amount: */
+/* Given a special op, return the line skip amount */
 #define SPECIAL_LINE(op) \
        (((op) - DWARF2_LINE_OPCODE_BASE)%DWARF2_LINE_RANGE + DWARF2_LINE_BASE)
 
    DWARF2_LINE_MIN_INSN_LENGTH.  */
 #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
 
-/* The maximum address skip amont that can be encoded with a special op: */
+/* The maximum address skip amount that can be encoded with a special op.  */
 #define MAX_SPECIAL_ADDR_DELTA         SPECIAL_ADDR(255)
 
 #define INITIAL_STATE                                          \
-  /* initialize as per DWARF2.0 standard: */                   \
+  /* Initialize as per DWARF2.0 standard.  */                  \
   0,                                   /* address */           \
   1,                                   /* file */              \
   1,                                   /* line */              \
@@ -118,6 +118,7 @@ static struct
     unsigned int
       any_dwarf2_directives : 1;       /* did we emit any DWARF2 line debug directives? */
 
+    fragS * frag;      /* frag that "addr" is relative to */
     segT text_seg;     /* text segment "addr" is relative to */
     subsegT text_subseg;
     segT line_seg;     /* ".debug_line" segment */
@@ -142,6 +143,35 @@ ls =
     {
       INITIAL_STATE
     },
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    NULL,
+    { NULL, 0, 0, 0, 0 },
+    0,
+    {
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    }
   };
 
 
@@ -296,6 +326,7 @@ static void
 out_end_sequence ()
 {
   addressT addr, delta;
+  fragS *text_frag;
 
   if (ls.text_seg)
     {
@@ -305,17 +336,25 @@ out_end_sequence ()
 #else
       addr = frag_now_fix ();
 #endif
+      text_frag = frag_now;
       subseg_set (ls.line_seg, DL_BODY);
-      if (addr < ls.sm.addr)
+      if (text_frag != ls.frag)
        {
          out_set_addr (addr);
          ls.sm.addr = addr;
+         ls.frag = text_frag;
        }
       else
        {
-         delta = addr - ls.sm.addr;
+         delta = (addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH;
          if (delta > 0)
-           gen_addr_line (0, delta / DWARF2_LINE_MIN_INSN_LENGTH);
+           {
+             /* Advance address without updating the line-debug
+                matrix---the end_sequence entry is used only to tell
+                the debugger the end of the sequence.*/
+             out_opcode (DW_LNS_advance_pc);
+             out_uleb128 (delta);
+           }
        }
     }
   else
@@ -331,7 +370,7 @@ out_end_sequence ()
 /* Look up a filenumber either by filename or by filenumber.  If both
    a filenumber and a filename are specified, lookup by filename takes
    precedence.  If the filename cannot be found, it is added to the
-   filetable the filenumber for the new entry is returned.  */
+   filetable and the filenumber for the new entry is returned.  */
 static int
 get_filenum (filenum, file)
      int filenum;
@@ -340,10 +379,12 @@ get_filenum (filenum, file)
   int i, last = filenum - 1;
   char char0 = file[0];
 
-  if ((unsigned) last >= ls.num_filenames)
+  /* If filenum is out of range of the filename table, then try using the
+     table entry returned from the previous call.  */
+  if (last >= ls.num_filenames || last < 0)
     last = ls.last_filename;
 
-  /* do a quick check against the previously used filename: */
+  /* Do a quick check against the specified or previously used filenum.  */
   if (ls.num_filenames > 0 && ls.file[last].name[0] == char0
       && strcmp (ls.file[last].name + 1, file + 1) == 0)
     return last + 1;
@@ -367,9 +408,13 @@ get_filenum (filenum, file)
     }
   ls.file[ls.num_filenames].dir = 0;
   ls.file[ls.num_filenames].name = file;
+  ls.last_filename = ls.num_filenames;
   return ++ls.num_filenames;
 }
 
+/* Emit an entry in the line number table if the address or line has changed.
+   ADDR is relative to the current frag in the text section.  */
+
 void
 dwarf2_gen_line_info (addr, l)
      addressT addr;
@@ -379,14 +424,15 @@ dwarf2_gen_line_info (addr, l)
   unsigned int any_output = 0;
   subsegT saved_subseg;
   segT saved_seg;
+  fragS *saved_frag;
 
   if (flag_debug)
-    fprintf (stderr, "line: addr %llx file `%s' line %u col %u flags %x\n",
-            (long long) addr, l->filename, l->line, l->column, l->flags);
+    fprintf (stderr, "line: addr %lx file `%s' line %u col %u flags %x\n",
+            (unsigned long) addr, l->filename, l->line, l->column, l->flags);
 
   if (filenum > 0 && !l->filename)
     {
-      if (filenum >= ls.num_filenames)
+      if (filenum >= (unsigned int) ls.num_filenames)
        {
          as_warn ("Encountered bad file number in line number debug info!");
          return;
@@ -397,6 +443,12 @@ dwarf2_gen_line_info (addr, l)
   else
     return;    /* no filename, no filnum => no play */
 
+  /* Must save these before the subseg_new call, as that call will change
+     them.  */
+  saved_seg = now_seg;
+  saved_subseg = now_subseg;
+  saved_frag = frag_now;
+
   if (!ls.line_seg)
     {
 #ifdef BFD_ASSEMBLER
@@ -417,8 +469,6 @@ dwarf2_gen_line_info (addr, l)
 #endif
     }
 
-  saved_seg = now_seg;
-  saved_subseg = now_subseg;
   subseg_set (ls.line_seg, DL_BODY);
 
   if (ls.text_seg != saved_seg || ls.text_subseg != saved_subseg)
@@ -433,6 +483,7 @@ dwarf2_gen_line_info (addr, l)
       ls.text_subseg = saved_subseg;
       out_set_addr (addr);
       ls.sm.addr = addr;
+      ls.frag = saved_frag;
     }
 
   if (ls.sm.filenum != filenum)
@@ -466,15 +517,15 @@ dwarf2_gen_line_info (addr, l)
   if (ls.sm.line != l->line)
     {
       any_output = 1;
-      if (addr < ls.sm.addr)
+      if (saved_frag != ls.frag)
        {
-         if (!ls.sm.empty_sequence)
-           {
-             out_end_sequence ();
-             ls.sm.empty_sequence = 1;
-           }
+         /* If a new frag got allocated (for whatever reason), then
+            deal with it by generating a reference symbol.  Note: no
+            end_sequence needs to be generated because the address did
+            not really decrease (only the reference point changed).  */
          out_set_addr (addr);
          ls.sm.addr = addr;
+         ls.frag = saved_frag;
        }
       gen_addr_line (l->line - ls.sm.line,
                     (addr - ls.sm.addr) / DWARF2_LINE_MIN_INSN_LENGTH);
@@ -510,7 +561,7 @@ gen_dir_list ()
            {
              if (strcmp (str, dp) == 0)
                {
-                 ls.file[i].dir = j;
+                 ls.file[i].dir = j + 1;
                  break;
                }
              dp += strlen (dp);
@@ -560,7 +611,8 @@ print_stats (total_size)
       "set_column", "negate_stmt", "set_basic_block", "const_add_pc",
       "fixed_advance_pc"
     };
-  int i, j;
+  size_t i;
+  int j;
 
   fprintf (stderr, "Average size: %g bytes/line\n",
           total_size / (double) ls.num_line_entries);
@@ -655,7 +707,7 @@ dwarf2_finish ()
 
 void
 dwarf2_directive_file (dummy)
-     int dummy;
+     int dummy ATTRIBUTE_UNUSED;
 {
   int len;
 
@@ -682,7 +734,7 @@ dwarf2_directive_file (dummy)
 
 void
 dwarf2_directive_loc (dummy)
-     int dummy;
+     int dummy ATTRIBUTE_UNUSED;
 {
   ls.any_dwarf2_directives = 1;
 
This page took 0.026189 seconds and 4 git commands to generate.