gdb/
[deliverable/binutils-gdb.git] / gas / dwarf2dbg.c
index b7857f2caa4c600fa969a99616e359b2f81dace4..48a1ae7ba61f78b8b6924fd6c8b91ca888dcdd5f 100644 (file)
@@ -25,7 +25,8 @@
 
        .file FILENO "file.c"
        .loc  FILENO LINENO [COLUMN] [basic_block] [prologue_end] \
-             [epilogue_begin] [is_stmt VALUE] [isa VALUE]
+             [epilogue_begin] [is_stmt VALUE] [isa VALUE] \
+             [discriminator VALUE]
 */
 
 #include "as.h"
 # define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
 #endif
 
+#ifndef DWARF2_FILE_NAME
+#define DWARF2_FILE_NAME(FILENAME, DIRNAME) FILENAME
+#endif
+
+#ifndef DWARF2_FILE_TIME_NAME
+#define DWARF2_FILE_TIME_NAME(FILENAME,DIRNAME) 0
+#endif
+
+#ifndef DWARF2_FILE_SIZE_NAME
+#define DWARF2_FILE_SIZE_NAME(FILENAME,DIRNAME) 0
+#endif
+
 #include "subsegs.h"
 
 #include "elf/dwarf2.h"
@@ -182,7 +195,8 @@ bfd_boolean dwarf2_loc_mark_labels;
 /* Current location as indicated by the most recent .loc directive.  */
 static struct dwarf2_line_info current = {
   1, 1, 0, 0,
-  DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0
+  DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0,
+  0
 };
 
 /* The size of an address on the target.  */
@@ -319,6 +333,7 @@ dwarf2_where (struct dwarf2_line_info *line)
       line->column = 0;
       line->flags = DWARF2_FLAG_IS_STMT;
       line->isa = current.isa;
+      line->discriminator = current.discriminator;
     }
   else
     *line = current;
@@ -367,6 +382,7 @@ dwarf2_consume_line_info (void)
   current.flags &= ~(DWARF2_FLAG_BASIC_BLOCK
                     | DWARF2_FLAG_PROLOGUE_END
                     | DWARF2_FLAG_EPILOGUE_BEGIN);
+  current.discriminator = 0;
 }
 
 /* Called for each (preferably code) label.  If dwarf2_loc_mark_labels
@@ -434,7 +450,9 @@ get_filenum (const char *filename, unsigned int num)
   dir = 0;
   if (dir_len)
     {
+#ifndef DWARF2_DIR_SHOULD_END_WITH_SEPARATOR
       --dir_len;
+#endif
       for (dir = 1; dir < dirs_in_use; ++dir)
        if (strncmp (filename, dirs[dir], dir_len) == 0
            && dirs[dir][dir_len] == '\0')
@@ -567,6 +585,7 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
 
   current.filenum = filenum;
   current.line = line;
+  current.discriminator = 0;
 
 #ifndef NO_LISTING
   if (listing)
@@ -645,6 +664,18 @@ dwarf2_directive_loc (int dummy ATTRIBUTE_UNUSED)
              return;
            }
        }
+      else if (strcmp (p, "discriminator") == 0)
+       {
+         *input_line_pointer = c;
+         value = get_absolute_expression ();
+         if (value >= 0)
+           current.discriminator = value;
+         else
+           {
+             as_bad (_("discriminator less than zero"));
+             return;
+           }
+       }
       else
        {
          as_bad (_("unknown .loc sub-directive `%s'"), p);
@@ -734,6 +765,14 @@ out_uleb128 (addressT value)
   output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
 }
 
+/* Emit a signed "little-endian base 128" number.  */
+
+static void
+out_leb128 (addressT value)
+{
+  output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
+}
+
 /* Emit a tuple for .debug_abbrev.  */
 
 static inline void
@@ -1194,6 +1233,14 @@ process_entries (segT seg, struct line_entry *e)
          out_uleb128 (column);
        }
 
+      if (e->loc.discriminator != 0)
+       {
+         out_opcode (DW_LNS_extended_op);
+         out_leb128 (1 + sizeof_leb128 (e->loc.discriminator, 0));
+         out_opcode (DW_LNE_set_discriminator);
+         out_uleb128 (e->loc.discriminator);
+       }
+
       if (isa != e->loc.isa)
        {
          isa = e->loc.isa;
@@ -1281,6 +1328,8 @@ out_file_list (void)
 
   for (i = 1; i < files_in_use; ++i)
     {
+      const char *fullfilename;
+
       if (files[i].filename == NULL)
        {
          as_bad (_("unassigned file number %ld"), (long) i);
@@ -1289,13 +1338,19 @@ out_file_list (void)
          continue;
        }
 
-      size = strlen (files[i].filename) + 1;
+      fullfilename = DWARF2_FILE_NAME (files[i].filename,
+                                      files[i].dir ? dirs [files [i].dir] : "");
+      size = strlen (fullfilename) + 1;
       cp = frag_more (size);
-      memcpy (cp, files[i].filename, size);
+      memcpy (cp, fullfilename, size);
 
       out_uleb128 (files[i].dir);      /* directory number */
-      out_uleb128 (0);                 /* last modification timestamp */
-      out_uleb128 (0);                 /* filesize */
+      /* Output the last modification timestamp.  */
+      out_uleb128 (DWARF2_FILE_TIME_NAME (files[i].filename,
+                                         files[i].dir ? dirs [files [i].dir] : ""));
+      /* Output the filesize.  */
+      out_uleb128 (DWARF2_FILE_SIZE_NAME (files[i].filename,
+                                         files[i].dir ? dirs [files [i].dir] : ""));
     }
 
   /* Terminate filename list.  */
@@ -1614,9 +1669,15 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg)
     {
       dirname = remap_debug_filename (dirs[files[1].dir]);
       len = strlen (dirname);
+#ifdef TE_VMS
+      /* Already has trailing slash.  */
+      p = frag_more (len);
+      memcpy (p, dirname, len);
+#else
       p = frag_more (len + 1);
       memcpy (p, dirname, len);
       INSERT_DIR_SEPARATOR (p, len);
+#endif
     }
   len = strlen (files[1].filename) + 1;
   p = frag_more (len);
This page took 0.024601 seconds and 4 git commands to generate.