OSDN Git Service

2003-01-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
[pf3gnuchains/gcc-fork.git] / gcc / vmsdbgout.c
index c558f44..a5cb8a2 100644 (file)
@@ -1,6 +1,6 @@
 /* Output VMS debug format symbol table information from the GNU C compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by Douglas B. Rupp (rupp@gnat.com).
 
 This file is part of GNU CC.
@@ -21,9 +21,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
 #include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 
 #ifdef VMS_DEBUGGING_INFO
-#include "system.h"
 #include "tree.h"
 #include "flags.h"
 #include "rtl.h"
@@ -31,6 +33,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "vmsdbg.h"
 #include "debug.h"
 #include "langhooks.h"
+#include "function.h"
+#include "target.h"
 
 /* Difference in seconds between the VMS Epoch and the Unix Epoch */
 static const long long vms_epoch_offset = 3506716800ll;
@@ -72,21 +76,18 @@ dst_file_info_entry;
 #define ASM_COMMENT_START ";#"
 #endif
 
-/* Maximum size (in bytes) of an artificially generated label.   */
+/* Maximum size (in bytes) of an artificially generated label.  */
 #define MAX_ARTIFICIAL_LABEL_BYTES     30
 
 /* Make sure we know the sizes of the various types debug can describe. These
    are only defaults.  If the sizes are different for your target, you should
    override these values by defining the appropriate symbols in your tm.h
    file.  */
-#ifndef CHAR_TYPE_SIZE
-#define CHAR_TYPE_SIZE BITS_PER_UNIT
-#endif
 #ifndef PTR_SIZE
 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
 #endif
 
-/* Pointer to an structure of filenames referenced by this compilation unit. */
+/* Pointer to a structure of filenames referenced by this compilation unit.  */
 static dst_file_info_ref file_info_table;
 
 /* Total number of entries in the table (i.e. array) pointed to by
@@ -126,13 +127,6 @@ static unsigned int line_info_table_in_use;
 /* Size (in elements) of increments by which we may expand line_info_table.  */
 #define LINE_INFO_TABLE_INCREMENT 1024
 
-/* The number of the current function definition for which debugging
-   information is being generated.  These numbers range from 1 up to the
-   maximum number of function definitions contained within the current
-   compilation unit.  These numbers are used to create unique label id's unique
-   to each function definition.  */
-static unsigned int current_funcdef_number = 0;
-
 /* Forward declarations for functions defined in this file.  */
 static char *full_name                 PARAMS ((const char *));
 static unsigned int lookup_filename PARAMS ((const char *));
@@ -165,7 +159,9 @@ static void vmsdbgout_end_block             PARAMS ((unsigned int, unsigned int));
 static bool vmsdbgout_ignore_block     PARAMS ((tree));
 static void vmsdbgout_source_line      PARAMS ((unsigned int, const char *));
 static void vmsdbgout_begin_prologue   PARAMS ((unsigned int, const char *));
-static void vmsdbgout_end_epilogue     PARAMS ((void));
+static void vmsdbgout_end_prologue     PARAMS ((unsigned int, const char *));
+static void vmsdbgout_end_function     PARAMS ((unsigned int));
+static void vmsdbgout_end_epilogue     PARAMS ((unsigned int, const char *));
 static void vmsdbgout_begin_function   PARAMS ((tree));
 static void vmsdbgout_decl             PARAMS ((tree));
 static void vmsdbgout_global_decl      PARAMS ((tree));
@@ -173,7 +169,7 @@ static void vmsdbgout_abstract_function PARAMS ((tree));
 
 /* The debug hooks structure.  */
 
-struct gcc_debug_hooks vmsdbg_debug_hooks
+const struct gcc_debug_hooks vmsdbg_debug_hooks
 = {vmsdbgout_init,
    vmsdbgout_finish,
    vmsdbgout_define,
@@ -185,10 +181,10 @@ struct gcc_debug_hooks vmsdbg_debug_hooks
    vmsdbgout_ignore_block,
    vmsdbgout_source_line,
    vmsdbgout_begin_prologue,
-   debug_nothing_int,          /* end_prologue */
-   vmsdbgout_end_epilogue,     /* end_epilogue */
-   vmsdbgout_begin_function,   /* begin_function */
-   debug_nothing_int,          /* end_function */
+   vmsdbgout_end_prologue,
+   vmsdbgout_end_epilogue,
+   vmsdbgout_begin_function,
+   vmsdbgout_end_function,
    vmsdbgout_decl,
    vmsdbgout_global_decl,
    debug_nothing_tree,         /* deferred_inline_function */
@@ -241,11 +237,6 @@ struct gcc_debug_hooks vmsdbg_debug_hooks
    : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
 #endif
 
-/* Pseudo-op for defining a new section.  */
-#ifndef SECTION_ASM_OP
-#define SECTION_ASM_OP ".section"
-#endif
-
 /* Definitions of defaults for formats and names of various special
    (artificial) labels which may be generated within this file (when the -g
    options is used and VMS_DEBUGGING_INFO is in effect.  If necessary, these
@@ -277,37 +268,49 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
 #endif
 
 #ifndef ASM_OUTPUT_DEBUG_DELTA2
-#define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2)                    \
- do {  fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP);             \
-       assemble_name (FILE, LABEL1);                                   \
-       fprintf (FILE, "-");                                            \
-       assemble_name (FILE, LABEL2);                                   \
-  } while (0)
+#define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2)                     \
+  do                                                                    \
+    {                                                                   \
+      fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP);               \
+      assemble_name (FILE, LABEL1);                                     \
+      fprintf (FILE, "-");                                              \
+      assemble_name (FILE, LABEL2);                                     \
+    }                                                                   \
+  while (0)
 #endif
 
 #ifndef ASM_OUTPUT_DEBUG_DELTA4
-#define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2)                    \
- do {  fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP);               \
-       assemble_name (FILE, LABEL1);                                   \
-       fprintf (FILE, "-");                                            \
-       assemble_name (FILE, LABEL2);                                   \
-  } while (0)
+#define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2)                     \
+  do                                                                    \
+    {                                                                   \
+      fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP);                         \
+      assemble_name (FILE, LABEL1);                                     \
+      fprintf (FILE, "-");                                              \
+      assemble_name (FILE, LABEL2);                                     \
+    }                                                                   \
+  while (0)
 #endif
 
 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
-#define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2)                        \
- do {  fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP);               \
-       assemble_name (FILE, LABEL1);                                   \
-       fprintf (FILE, "-");                                            \
-       assemble_name (FILE, LABEL2);                                   \
-  } while (0)
+#define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2)                         \
+  do                                                                    \
+    {                                                                   \
+      fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP);                         \
+      assemble_name (FILE, LABEL1);                                     \
+      fprintf (FILE, "-");                                              \
+      assemble_name (FILE, LABEL2);                                     \
+    }                                                                   \
+  while (0)
 #endif
 
 #ifndef ASM_OUTPUT_DEBUG_ADDR
-#define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL)                              \
- do {  fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP);               \
-       assemble_name (FILE, LABEL);                                    \
-  } while (0)
+#define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL)                               \
+  do                                                                    \
+    {                                                                   \
+      fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP);                         \
+      assemble_name (FILE, LABEL);                                      \
+    }                                                                   \
+  while (0)
 #endif
 
 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
@@ -349,27 +352,28 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
 #endif
 
 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
-   newline is produced.  When flag_verbose_asm is asserted, we add commnetary
+   newline is produced.  When flag_verbose_asm is asserted, we add commentary
    at the end of the line, so we must avoid output of a newline here.  */
 #ifndef ASM_OUTPUT_DEBUG_STRING
-#define ASM_OUTPUT_DEBUG_STRING(FILE,P)        \
-  do {                                 \
-    register int slen = strlen(P);      \
-    register char *p = (P);            \
-    register int i;                    \
-    fprintf (FILE, "\t.ascii \"");     \
-    for (i = 0; i < slen; i++)         \
-      {                                        \
-         register int c = p[i];        \
-         if (c == '\"' || c == '\\')   \
-           putc ('\\', FILE);          \
-         if (c >= ' ' && c < 0177)     \
-           putc (c, FILE);             \
-         else                          \
-           fprintf (FILE, "\\%o", c);  \
-      }                                        \
-    fprintf (FILE, "\"");              \
-  }                                    \
+#define ASM_OUTPUT_DEBUG_STRING(FILE,P)                \
+  do                                           \
+    {                                          \
+      register int slen = strlen(P);           \
+      register char *p = (P);                  \
+      register int i;                          \
+      fprintf (FILE, "\t.ascii \"");           \
+      for (i = 0; i < slen; i++)               \
+       {                                       \
+         register int c = p[i];                \
+         if (c == '\"' || c == '\\')           \
+           putc ('\\', FILE);                  \
+         if (c >= ' ' && c < 0177)             \
+           putc (c, FILE);                     \
+         else                                  \
+           fprintf (FILE, "\\%o", c);          \
+       }                                       \
+      fprintf (FILE, "\"");                    \
+    }                                          \
   while (0)
 #endif
 
@@ -377,13 +381,14 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
    macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
    a string rather than writing to a file.  */
 #ifndef ASM_NAME_TO_STRING
-#define ASM_NAME_TO_STRING(STR, NAME) \
-  do {                                                                       \
-      if ((NAME)[0] == '*')                                                  \
-       strcpy (STR, NAME+1);                                                 \
-      else                                                                   \
-       strcpy (STR, NAME);                                                   \
-  }                                                                           \
+#define ASM_NAME_TO_STRING(STR, NAME)          \
+  do                                           \
+    {                                          \
+      if ((NAME)[0] == '*')                    \
+       strcpy (STR, NAME+1);                   \
+      else                                     \
+       strcpy (STR, NAME);                     \
+    }                                          \
   while (0)
 #endif
 
@@ -438,7 +443,7 @@ restart:
       break;
 
     case CONST:
-      /* This used to output parentheses around the expression, but that does 
+      /* This used to output parentheses around the expression, but that does
          not work on the 386 (either ATT or BSD assembler).  */
       addr_const_to_string (buf1, XEXP (x, 0));
       strcat (str, buf1);
@@ -524,7 +529,7 @@ restart:
 
 /* Output the debug header HEADER.  Also output COMMENT if flag_verbose_asm is
    set.  Return the header size.  Just return the size if DOSIZEONLY is
-   non-zero. */
+   nonzero.  */
 
 static int
 write_debug_header (header, comment, dosizeonly)
@@ -556,7 +561,7 @@ write_debug_header (header, comment, dosizeonly)
 
 /* Output the address of SYMBOL.  Also output COMMENT if flag_verbose_asm is
    set.  Return the address size.  Just return the size if DOSIZEONLY is
-   non-zero. */
+   nonzero.  */
 
 static int
 write_debug_addr (symbol, comment, dosizeonly)
@@ -577,7 +582,7 @@ write_debug_addr (symbol, comment, dosizeonly)
 
 /* Output the single byte DATA1.  Also output COMMENT if flag_verbose_asm is
    set.  Return the data size.  Just return the size if DOSIZEONLY is
-   non-zero. */
+   nonzero.  */
 
 static int
 write_debug_data1 (data1, comment, dosizeonly)
@@ -598,7 +603,7 @@ write_debug_data1 (data1, comment, dosizeonly)
 
 /* Output the single word DATA2.  Also output COMMENT if flag_verbose_asm is
    set.  Return the data size.  Just return the size if DOSIZEONLY is
-   non-zero. */
+   nonzero.  */
 
 static int
 write_debug_data2 (data2, comment, dosizeonly)
@@ -618,7 +623,7 @@ write_debug_data2 (data2, comment, dosizeonly)
 }
 
 /* Output double word DATA4.  Also output COMMENT if flag_verbose_asm is set.
-   Return the data size.  Just return the size if DOSIZEONLY is non-zero. */
+   Return the data size.  Just return the size if DOSIZEONLY is nonzero.  */
 
 static int
 write_debug_data4 (data4, comment, dosizeonly)
@@ -633,12 +638,12 @@ write_debug_data4 (data4, comment, dosizeonly)
        fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
       fputc ('\n', asm_out_file);
     }
-  
+
   return 4;
 }
 
 /* Output quad word DATA8.  Also output COMMENT if flag_verbose_asm is set.
-   Return the data size.  Just return the size if DOSIZEONLY is non-zero.  */
+   Return the data size.  Just return the size if DOSIZEONLY is nonzero.  */
 
 static int
 write_debug_data8 (data8, comment, dosizeonly)
@@ -659,7 +664,7 @@ write_debug_data8 (data8, comment, dosizeonly)
 
 /* Output the difference between LABEL1 and LABEL2.  Also output COMMENT if
    flag_verbose_asm is set.  Return the data size.  Just return the size if
-   DOSIZEONLY is non-zero. */
+   DOSIZEONLY is nonzero.  */
 
 static int
 write_debug_delta4 (label1, label2, comment, dosizeonly)
@@ -681,7 +686,7 @@ write_debug_delta4 (label1, label2, comment, dosizeonly)
 
 /* Output a character string STRING.  Also write COMMENT if flag_verbose_asm is
    set.  Return the string length.  Just return the length if DOSIZEONLY is
-   non-zero. */
+   nonzero.  */
 
 static int
 write_debug_string (string, comment, dosizeonly)
@@ -696,12 +701,12 @@ write_debug_string (string, comment, dosizeonly)
        fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
       fputc ('\n', asm_out_file);
     }
-  
+
   return strlen (string);
 }
 
 /* Output a module begin header and return the header size.  Just return the
-   size if DOSIZEONLY is non-zero. */
+   size if DOSIZEONLY is nonzero.  */
 
 static int
 write_modbeg (dosizeonly)
@@ -715,7 +720,7 @@ write_modbeg (dosizeonly)
   int prodnamelen;
   int totsize = 0;
 
-  /* Assumes primary filename has Unix syntax file spec. */
+  /* Assumes primary filename has Unix syntax file spec.  */
   module_name = xstrdup (basename ((char *) primary_filename));
 
   m = strrchr (module_name, '.');
@@ -765,7 +770,7 @@ write_modbeg (dosizeonly)
 }
 
 /* Output a module end trailer and return the trailer size.   Just return
-   the size if DOSIZEONLY is non-zero. */
+   the size if DOSIZEONLY is nonzero.  */
 
 static int
 write_modend (dosizeonly)
@@ -785,7 +790,7 @@ write_modend (dosizeonly)
 }
 
 /* Output a routine begin header routine RTNNUM and return the header size.
-   Just return the size if DOSIZEONLY is non-zero. */
+   Just return the size if DOSIZEONLY is nonzero.  */
 
 static int
 write_rtnbeg (rtnnum, dosizeonly)
@@ -793,7 +798,7 @@ write_rtnbeg (rtnnum, dosizeonly)
      int dosizeonly;
 {
   char *rtnname;
-  int rtnnamelen, rtnentrynamelen;
+  int rtnnamelen;
   char *rtnentryname;
   int totsize = 0;
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -802,10 +807,7 @@ write_rtnbeg (rtnnum, dosizeonly)
 
   rtnname = func_table[rtnnum];
   rtnnamelen = strlen (rtnname);
-  rtnentrynamelen = rtnnamelen + 4; /* "..en" */
-  rtnentryname = (char *) xmalloc (rtnentrynamelen + 1);
-  strcpy (rtnentryname, rtnname);
-  strcat (rtnentryname, "..en");
+  rtnentryname = concat (rtnname, "..en", NULL);
 
   if (!strcmp (rtnname, "main"))
     {
@@ -818,7 +820,7 @@ write_rtnbeg (rtnnum, dosizeonly)
       /* header size - 1st byte + flag byte + STO_LW size
         + string count byte + string length */
       header.dst__header_length.dst_w_length
-        = DST_K_DST_HEADER_SIZE - 1 + 1 + 4 + 1 + strlen (go);
+       = DST_K_DST_HEADER_SIZE - 1 + 1 + 4 + 1 + strlen (go);
       header.dst__header_type.dst_w_type = 0x17;
 
       totsize += write_debug_header (&header, "transfer", dosizeonly);
@@ -883,7 +885,7 @@ write_rtnbeg (rtnnum, dosizeonly)
 }
 
 /* Output a routine end trailer for routine RTNNUM and return the header size.
-   Just return the size if DOSIZEONLY is non-zero. */
+   Just return the size if DOSIZEONLY is nonzero.  */
 
 static int
 write_rtnend (rtnnum, dosizeonly)
@@ -927,7 +929,7 @@ write_rtnend (rtnnum, dosizeonly)
   : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
 
 /* Output the PC to line number correlations and return the size.  Just return
-   the size if DOSIZEONLY is non-zero */
+   the size if DOSIZEONLY is nonzero */
 
 static int
 write_pclines (dosizeonly)
@@ -987,8 +989,8 @@ write_pclines (dosizeonly)
   totsize += write_debug_data1 (pcline.dst_b_pcline_command,
                                "line_num (SET LINUM LONG)", dosizeonly);
 
-  sprintf (buff, "line_num (%d)", ln - 1);
-  totsize += write_debug_data4 (ln - 1, buff, dosizeonly);
+  sprintf (buff, "line_num (%d)", ln ? ln - 1 : 0);
+  totsize += write_debug_data4 (ln ? ln - 1 : 0, buff, dosizeonly);
 
   lastln = ln;
   strcpy (lastlabel, TEXT_SECTION_ASM_OP);
@@ -1058,7 +1060,7 @@ write_pclines (dosizeonly)
 
 /* Output a source correlation for file FILEID using information saved in
    FILE_INFO_ENTRY and return the size.  Just return the size if DOSIZEONLY is
-   non-zero. */
+   nonzero.  */
 
 static int
 write_srccorr (fileid, file_info_entry, dosizeonly)
@@ -1122,7 +1124,7 @@ write_srccorr (fileid, file_info_entry, dosizeonly)
     = DST_K_SOURCE;
 
   src_cmdtrlr.dst_b_src_df_libmodname = 0;
-  
+
   totsize += write_debug_header (&src_header.dst_a_source_corr_header,
                                 "source corr", dosizeonly);
   totsize += write_debug_data1 (src_command.dst_b_src_command,
@@ -1142,7 +1144,7 @@ write_srccorr (fileid, file_info_entry, dosizeonly)
   totsize += write_debug_data8
     (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt,
      "source_corr (creation date)", dosizeonly);
-  
+
   totsize += write_debug_data4
     (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk,
      "source_corr (EOF block number)", dosizeonly);
@@ -1187,69 +1189,73 @@ write_srccorr (fileid, file_info_entry, dosizeonly)
   src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
     = DST_K_SOURCE;
 
-  totsize += write_debug_header (&src_header.dst_a_source_corr_header,
-                                "source corr", dosizeonly);
-
-  totsize += write_debug_data1 (src_command_sf.dst_b_src_command,
-                               "source_corr (src setfile)", dosizeonly);
-
-  totsize += write_debug_data2
-    (src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword,
-     "source_corr (fileid)", dosizeonly);
-
-  totsize += write_debug_data1 (src_command_sr.dst_b_src_command,
-                               "source_corr (setrec)", dosizeonly);
-
-  totsize += write_debug_data2
-    (src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword,
-     "source_corr (recnum)", dosizeonly);
-
-  totsize += write_debug_data1 (src_command_sl.dst_b_src_command,
-                               "source_corr (setlnum)", dosizeonly);
+  if (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword)
+    {
+      totsize += write_debug_header (&src_header.dst_a_source_corr_header,
+                                    "source corr", dosizeonly);
 
-  totsize += write_debug_data4
-    (src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong,
-     "source_corr (linenum)", dosizeonly);
+      totsize += write_debug_data1 (src_command_sf.dst_b_src_command,
+                                   "source_corr (src setfile)", dosizeonly);
 
-  totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
-                               "source_corr (deflines)", dosizeonly);
+      totsize += write_debug_data2
+       (src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword,
+        "source_corr (fileid)", dosizeonly);
 
-  sprintf (buff, "source_corr (%d)",
-          src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
-  totsize += write_debug_data2
-    (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword, buff, dosizeonly);
+      totsize += write_debug_data1 (src_command_sr.dst_b_src_command,
+                                   "source_corr (setrec)", dosizeonly);
 
-  while (linesleft > 0)
-    {
-      src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
-       = DST_K_SOURCE_CORR_HEADER_SIZE + 3 - 1;
-      src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
-       = DST_K_SOURCE;
-      src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
+      totsize += write_debug_data2
+       (src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword,
+        "source_corr (recnum)", dosizeonly);
 
-      if (linesleft > 65534)
-       linesleft = linesleft - 65534, linestodo = 65534;
-      else
-       linestodo = linesleft, linesleft = 0;
+      totsize += write_debug_data1 (src_command_sl.dst_b_src_command,
+                                   "source_corr (setlnum)", dosizeonly);
 
-      src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
+      totsize += write_debug_data4
+       (src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong,
+        "source_corr (linenum)", dosizeonly);
 
-      totsize += write_debug_header (&src_header.dst_a_source_corr_header,
-                                    "source corr", dosizeonly);
       totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
                                    "source_corr (deflines)", dosizeonly);
+
       sprintf (buff, "source_corr (%d)",
               src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
       totsize += write_debug_data2
        (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
         buff, dosizeonly);
+
+      while (linesleft > 0)
+       {
+         src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
+           = DST_K_SOURCE_CORR_HEADER_SIZE + 3 - 1;
+         src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
+           = DST_K_SOURCE;
+         src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
+
+         if (linesleft > 65534)
+           linesleft = linesleft - 65534, linestodo = 65534;
+         else
+           linestodo = linesleft, linesleft = 0;
+
+         src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
+
+         totsize += write_debug_header (&src_header.dst_a_source_corr_header,
+                                        "source corr", dosizeonly);
+         totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
+                                       "source_corr (deflines)", dosizeonly);
+         sprintf (buff, "source_corr (%d)",
+                  src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
+         totsize += write_debug_data2
+           (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
+            buff, dosizeonly);
+       }
     }
 
   return totsize;
 }
 
 /* Output all the source correlation entries and return the size.  Just return
-   the size if DOSIZEONLY is non-zero. */
+   the size if DOSIZEONLY is nonzero.  */
 
 static int
 write_srccorrs (dosizeonly)
@@ -1262,7 +1268,7 @@ write_srccorrs (dosizeonly)
     totsize += write_srccorr (i, file_info_table[i], dosizeonly);
 
   return totsize;
-}     
+}
 \f
 /* Output a marker (i.e. a label) for the beginning of a function, before
    the prologue.  */
@@ -1279,9 +1285,8 @@ vmsdbgout_begin_prologue (line, file)
 
   if (debug_info_level > DINFO_LEVEL_NONE)
     {
-      current_funcdef_number++;
       ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
-                                  current_funcdef_number);
+                                  current_function_funcdef_no);
       ASM_OUTPUT_LABEL (asm_out_file, label);
     }
 }
@@ -1289,38 +1294,61 @@ vmsdbgout_begin_prologue (line, file)
 /* Output a marker (i.e. a label) for the beginning of a function, after
    the prologue.  */
 
-void
-vmsdbgout_after_prologue ()
+static void
+vmsdbgout_end_prologue (line, file)
+     unsigned int line;
+     const char *file;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
+  if (write_symbols == VMS_AND_DWARF2_DEBUG)
+    (*dwarf2_debug_hooks.end_prologue) (line, file);
+
   if (debug_info_level > DINFO_LEVEL_TERSE)
     {
       ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL,
-                                  current_funcdef_number);
+                                  current_function_funcdef_no);
       ASM_OUTPUT_LABEL (asm_out_file, label);
+
+      /* VMS PCA expects every PC range to correlate to some line and file */
+      vmsdbgout_source_line (line, file);
     }
 }
 
+/* No output for VMS debug, but make obligatory call to Dwarf2 debug */
+
+static void
+vmsdbgout_end_function (line)
+     unsigned int line;
+{
+  if (write_symbols == VMS_AND_DWARF2_DEBUG)
+    (*dwarf2_debug_hooks.end_function) (line);
+}
+
 /* Output a marker (i.e. a label) for the absolute end of the generated code
    for a function definition.  This gets called *after* the epilogue code has
    been generated.  */
 
 static void
-vmsdbgout_end_epilogue ()
+vmsdbgout_end_epilogue (line, file)
+     unsigned int line;
+     const char *file;
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
-    (*dwarf2_debug_hooks.end_epilogue) ();
+    (*dwarf2_debug_hooks.end_epilogue) (line, file);
 
   if (debug_info_level > DINFO_LEVEL_NONE)
     {
       /* Output a label to mark the endpoint of the code generated for this
-         function.        */
+         function.  */
       ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
-                                  current_funcdef_number);
+                                  current_function_funcdef_no);
       ASM_OUTPUT_LABEL (asm_out_file, label);
+
+      /* VMS PCA expects every PC range to correlate to some line and file */
+      vmsdbgout_source_line (line, file);
     }
 }
 
@@ -1336,7 +1364,7 @@ vmsdbgout_begin_block (line, blocknum)
     (*dwarf2_debug_hooks.begin_block) (line, blocknum);
 
   if (debug_info_level > DINFO_LEVEL_TERSE)
-    ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
+    (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
 }
 
 /* Output a marker (i.e. a label) for the end of the generated code for a
@@ -1351,7 +1379,7 @@ vmsdbgout_end_block (line, blocknum)
     (*dwarf2_debug_hooks.end_block) (line, blocknum);
 
   if (debug_info_level > DINFO_LEVEL_TERSE)
-    ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
+    (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_END_LABEL, blocknum);
 }
 
 /* Not implemented in VMS Debug.  */
@@ -1393,7 +1421,7 @@ vmsdbgout_begin_function (decl)
 static char fullname_buff [4096];
 
 /* Return the full file specification for FILENAME.  The specification must be
-   in VMS syntax in order to be processed by VMS Debug. */
+   in VMS syntax in order to be processed by VMS Debug.  */
 
 static char *
 full_name (filename)
@@ -1444,15 +1472,26 @@ lookup_filename (file_name)
 
   if (stat (file_name, &statbuf) == 0)
     {
-      cdt = 10000000 * (statbuf.st_ctime + vms_epoch_offset);
-      ebk = statbuf.st_size / 512 + 1;
-      ffb = statbuf.st_size - ((statbuf.st_size / 512) * 512);
+      long gmtoff;
 #ifdef VMS
+      struct tm *ts;
+
+      /* Adjust for GMT */
+      ts = (struct tm *) localtime (&statbuf.st_ctime);
+      gmtoff = ts->tm_gmtoff;
+
+      /* VMS has multiple file format types */
       rfo = statbuf.st_fab_rfm;
 #else
+      /* Is GMT adjustment an issue with a cross-compiler? */
+      gmtoff = 0;
+
       /* Assume stream LF type file */
       rfo = 2;
 #endif
+      cdt = 10000000 * (statbuf.st_ctime + gmtoff + vms_epoch_offset);
+      ebk = statbuf.st_size / 512 + 1;
+      ffb = statbuf.st_size - ((statbuf.st_size / 512) * 512);
       fnam = full_name (file_name);
       flen = strlen (fnam);
     }
@@ -1462,7 +1501,7 @@ lookup_filename (file_name)
       ebk = 0;
       ffb = 0;
       rfo = 0;
-      fnam = (char *) 0;
+      fnam = (char *) "";
       flen = 0;
     }
 
@@ -1486,7 +1525,7 @@ lookup_filename (file_name)
        }
     }
 
-  /* Prepare to add a new table entry by making sure there is enough space in 
+  /* Prepare to add a new table entry by making sure there is enough space in
      the table to do so.  If not, expand the current table.  */
   if (file_info_table_in_use == file_info_table_allocated)
     {
@@ -1527,7 +1566,7 @@ vmsdbgout_source_line (line, filename)
     {
       dst_line_info_ref line_info;
 
-      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
+      (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
                                 line_info_table_in_use);
 
       /* Expand the line info table if necessary.  */
@@ -1538,7 +1577,7 @@ vmsdbgout_source_line (line, filename)
            = (dst_line_info_ref) xrealloc (line_info_table,
                                            (line_info_table_allocated
                                             * sizeof (dst_line_info_entry)));
-         }
+       }
 
       /* Add the new entry at the end of the line_info_table.  */
       line_info = &line_info_table[line_info_table_in_use++];
@@ -1623,10 +1662,7 @@ vmsdbgout_init (main_input_filename)
   else
     module_language = DST_K_UNKNOWN;
 
-  module_producer
-    = (char *) xmalloc (strlen (language_string) + 1
-                       + strlen (version_string + 1));
-  sprintf (module_producer, "%s %s", language_string, version_string);
+  module_producer = concat (language_string, " ", version_string, NULL);
 
   ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
 
@@ -1702,11 +1738,11 @@ vmsdbgout_finish (input_filename)
 
   /* Output a terminator label for the .text section.  */
   text_section ();
-  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, TEXT_END_LABEL, 0);
+  (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
 
   /* Output debugging information.
      Warning! Do not change the name of the .vmsdebug section without
-     changing it in the assembler also. */
+     changing it in the assembler also.  */
   named_section (NULL_TREE, ".vmsdebug", 0);
   ASM_OUTPUT_ALIGN (asm_out_file, 0);