OSDN Git Service

* intrinsic.texi (STAT): Fixed a format typo in sample code.
[pf3gnuchains/gcc-fork.git] / gcc / vmsdbgout.c
index 6e4e6c0..d8ed683 100644 (file)
@@ -1,9 +1,10 @@
-/* Output VMS debug format symbol table information from the GNU C compiler.
+/* Output VMS debug format symbol table information from GCC.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Douglas B. Rupp (rupp@gnat.com).
+   Updated by Bernard W. Giroud (bgiroud@users.sourceforge.net).
 
-This file is part of GNU CC.
+This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -17,20 +18,25 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 
 #ifdef VMS_DEBUGGING_INFO
-#include "system.h"
 #include "tree.h"
+#include "version.h"
 #include "flags.h"
 #include "rtl.h"
 #include "output.h"
 #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;
@@ -83,7 +89,7 @@ dst_file_info_entry;
 #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
@@ -98,11 +104,26 @@ static unsigned int file_info_table_in_use;
    table.  */
 #define FILE_TABLE_INCREMENT 64
 
-static char **func_table;
+/* A structure to hold basic information for the VMS end
+   routine.  */
+
+typedef struct vms_func_struct
+{
+  const char *vms_func_name;
+  unsigned funcdef_number;
+}
+vms_func_node;
+
+typedef struct vms_func_struct *vms_func_ref;
+
 static unsigned int func_table_allocated;
 static unsigned int func_table_in_use;
 #define FUNC_TABLE_INCREMENT 256
 
+/* A pointer to the base of a table that contains frame description
+   information for each routine.  */
+static vms_func_ref func_table;
+
 /* Local pointer to the name of the main input file.  Initialized in
    avmdbgout_init.  */
 static const char *primary_filename;
@@ -124,42 +145,43 @@ static unsigned int line_info_table_in_use;
 #define LINE_INFO_TABLE_INCREMENT 1024
 
 /* Forward declarations for functions defined in this file.  */
-static char *full_name                 PARAMS ((const char *));
-static unsigned int lookup_filename PARAMS ((const char *));
-static void addr_const_to_string PARAMS ((char *, rtx));
-static int write_debug_header  PARAMS ((DST_HEADER *, const char *, int));
-static int write_debug_addr    PARAMS ((char *, const char *, int));
-static int write_debug_data1   PARAMS ((unsigned int, const char *, int));
-static int write_debug_data2   PARAMS ((unsigned int, const char *, int));
-static int write_debug_data4   PARAMS ((unsigned long, const char *, int));
-static int write_debug_data8   PARAMS ((unsigned long long, const char *,
-                                        int));
-static int write_debug_delta4  PARAMS ((char *, char *, const char *, int));
-static int write_debug_string  PARAMS ((char *, const char *, int));
-static int write_modbeg                PARAMS ((int));
-static int write_modend                PARAMS ((int));
-static int write_rtnbeg                PARAMS ((int, int));
-static int write_rtnend                PARAMS ((int, int));
-static int write_pclines       PARAMS ((int));
-static int write_srccorr       PARAMS ((int, dst_file_info_entry, int));
-static int write_srccorrs      PARAMS ((int));
-
-static void vmsdbgout_init             PARAMS ((const char *));
-static void vmsdbgout_finish           PARAMS ((const char *));
-static void vmsdbgout_define           PARAMS ((unsigned int, const char *));
-static void vmsdbgout_undef            PARAMS ((unsigned int, const char *));
-static void vmsdbgout_start_source_file PARAMS ((unsigned int, const char *));
-static void vmsdbgout_end_source_file  PARAMS ((unsigned int));
-static void vmsdbgout_begin_block      PARAMS ((unsigned int, unsigned int));
-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_begin_function   PARAMS ((tree));
-static void vmsdbgout_decl             PARAMS ((tree));
-static void vmsdbgout_global_decl      PARAMS ((tree));
-static void vmsdbgout_abstract_function PARAMS ((tree));
+static char *full_name (const char *);
+static unsigned int lookup_filename (const char *);
+static void addr_const_to_string (char *, rtx);
+static int write_debug_header (DST_HEADER *, const char *, int);
+static int write_debug_addr (char *, const char *, int);
+static int write_debug_data1 (unsigned int, const char *, int);
+static int write_debug_data2 (unsigned int, const char *, int);
+static int write_debug_data4 (unsigned long, const char *, int);
+static int write_debug_data8 (unsigned long long, const char *, int);
+static int write_debug_delta4 (char *, char *, const char *, int);
+static int write_debug_string (char *, const char *, int);
+static int write_modbeg (int);
+static int write_modend (int);
+static int write_rtnbeg (int, int);
+static int write_rtnend (int, int);
+static int write_pclines (int);
+static int write_srccorr (int, dst_file_info_entry, int);
+static int write_srccorrs (int);
+
+static void vmsdbgout_init (const char *);
+static void vmsdbgout_finish (const char *);
+static void vmsdbgout_define (unsigned int, const char *);
+static void vmsdbgout_undef (unsigned int, const char *);
+static void vmsdbgout_start_source_file (unsigned int, const char *);
+static void vmsdbgout_end_source_file (unsigned int);
+static void vmsdbgout_begin_block (unsigned int, unsigned int);
+static void vmsdbgout_end_block (unsigned int, unsigned int);
+static bool vmsdbgout_ignore_block (tree);
+static void vmsdbgout_source_line (unsigned int, const char *);
+static void vmsdbgout_begin_prologue (unsigned int, const char *);
+static void vmsdbgout_end_prologue (unsigned int, const char *);
+static void vmsdbgout_end_function (unsigned int);
+static void vmsdbgout_end_epilogue (unsigned int, const char *);
+static void vmsdbgout_begin_function (tree);
+static void vmsdbgout_decl (tree);
+static void vmsdbgout_global_decl (tree);
+static void vmsdbgout_abstract_function (tree);
 
 /* The debug hooks structure.  */
 
@@ -175,15 +197,21 @@ const 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 */
+   debug_nothing_tree_int,       /* type_decl */
+   debug_nothing_tree_tree,       /* imported_module_or_decl */
+   debug_nothing_tree,           /* deferred_inline_function */
    vmsdbgout_abstract_function,
-   debug_nothing_rtx           /* label */
+   debug_nothing_rtx,            /* label */
+   debug_nothing_int,            /* handle_pch */
+   debug_nothing_rtx,            /* var_location */
+   debug_nothing_void,            /* switch_text_section */
+   0                              /* start_end_main_source_file */
 };
 
 /* Definitions of defaults for assembler-dependent names of various
@@ -346,7 +374,7 @@ 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)                \
@@ -375,7 +403,7 @@ 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)          \
+#define ASM_NAME_TO_STRING(STR, NAME)          \
   do                                           \
     {                                          \
       if ((NAME)[0] == '*')                    \
@@ -396,22 +424,18 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
    directly, because it writes to a file.  */
 
 static void
-addr_const_to_string (str, x)
-     char *str;
-     rtx x;
+addr_const_to_string (char *str, rtx x)
 {
   char buf1[256];
   char buf2[256];
 
-restart:
+ restart:
   str[0] = '\0';
   switch (GET_CODE (x))
     {
     case PC:
-      if (flag_pic)
-       strcat (str, ",");
-      else
-       abort ();
+      gcc_assert (flag_pic);
+      strcat (str, ",");
       break;
 
     case SYMBOL_REF:
@@ -523,13 +547,10 @@ 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)
-     DST_HEADER *header;
-     const char *comment;
-     int dosizeonly;
+write_debug_header (DST_HEADER *header, const char *comment, int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -555,13 +576,10 @@ 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)
-     char *symbol;
-     const char *comment;
-     int dosizeonly;
+write_debug_addr (char *symbol, const char *comment, int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -576,13 +594,10 @@ 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)
-     unsigned int data1;
-     const char *comment;
-     int dosizeonly;
+write_debug_data1 (unsigned int data1, const char *comment, int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -597,13 +612,10 @@ 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)
-     unsigned int data2;
-     const char *comment;
-     int dosizeonly;
+write_debug_data2 (unsigned int data2, const char *comment, int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -617,13 +629,10 @@ 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)
-     unsigned long data4;
-     const char *comment;
-     int dosizeonly;
+write_debug_data4 (unsigned long data4, const char *comment, int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -637,13 +646,11 @@ write_debug_data4 (data4, comment, dosizeonly)
 }
 
 /* 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)
-     unsigned long long data8;
-     const char *comment;
-     int dosizeonly;
+write_debug_data8 (unsigned long long data8, const char *comment,
+                  int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -658,14 +665,11 @@ 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)
-     char *label1;
-     char *label2;
-     const char *comment;
-     int dosizeonly;
+write_debug_delta4 (char *label1, char *label2, const char *comment,
+                   int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -680,13 +684,10 @@ 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)
-     char *string;
-     const char *comment;
-     int dosizeonly;
+write_debug_string (char *string, const char *comment, int dosizeonly)
 {
   if (!dosizeonly)
     {
@@ -700,11 +701,10 @@ write_debug_string (string, comment, dosizeonly)
 }
 
 /* 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)
-     int dosizeonly;
+write_modbeg (int dosizeonly)
 {
   DST_MODULE_BEGIN modbeg;
   DST_MB_TRLR mb_trlr;
@@ -764,11 +764,10 @@ 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)
-     int dosizeonly;
+write_modend (int dosizeonly)
 {
   DST_MODULE_END modend;
   int totsize = 0;
@@ -784,27 +783,23 @@ 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)
-     int rtnnum;
-     int dosizeonly;
+write_rtnbeg (int rtnnum, int dosizeonly)
 {
   char *rtnname;
-  int rtnnamelen, rtnentrynamelen;
+  int rtnnamelen;
   char *rtnentryname;
   int totsize = 0;
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
   DST_ROUTINE_BEGIN rtnbeg;
   DST_PROLOG prolog;
+  vms_func_ref fde = &func_table[rtnnum];
 
-  rtnname = func_table[rtnnum];
+  rtnname = (char *)fde->vms_func_name;
   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"))
     {
@@ -833,7 +828,7 @@ write_rtnbeg (rtnnum, dosizeonly)
       totsize += write_debug_string ((char *) go, "main name", dosizeonly);
     }
 
-  /* The header length never includes the length byte */
+  /* The header length never includes the length byte */
   rtnbeg.dst_a_rtnbeg_header.dst__header_length.dst_w_length
    = DST_K_RTNBEG_SIZE + rtnnamelen - 1;
   rtnbeg.dst_a_rtnbeg_header.dst__header_type.dst_w_type = DST_K_RTNBEG;
@@ -873,7 +868,7 @@ write_rtnbeg (rtnnum, dosizeonly)
       totsize += write_debug_header (&prolog.dst_a_prolog_header, "prolog",
                                     dosizeonly);
 
-      ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL, rtnnum);
+      ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL, fde->funcdef_number);
       totsize += write_debug_addr (label, "prolog breakpoint addr",
                                   dosizeonly);
     }
@@ -882,17 +877,17 @@ 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)
-     int rtnnum;
-     int dosizeonly;
+write_rtnend (int rtnnum, int dosizeonly)
 {
   DST_ROUTINE_END rtnend;
   char label1[MAX_ARTIFICIAL_LABEL_BYTES];
   char label2[MAX_ARTIFICIAL_LABEL_BYTES];
   int totsize;
+  vms_func_ref fde = &func_table[rtnnum];
+  int corrected_rtnnum = fde->funcdef_number;
 
   totsize = 0;
 
@@ -907,8 +902,8 @@ write_rtnend (rtnnum, dosizeonly)
   totsize += write_debug_data1 (rtnend.dst_b_rtnend_unused, "unused",
                                dosizeonly);
 
-  ASM_GENERATE_INTERNAL_LABEL (label1, FUNC_BEGIN_LABEL, rtnnum);
-  ASM_GENERATE_INTERNAL_LABEL (label2, FUNC_END_LABEL, rtnnum);
+  ASM_GENERATE_INTERNAL_LABEL (label1, FUNC_BEGIN_LABEL, corrected_rtnnum);
+  ASM_GENERATE_INTERNAL_LABEL (label2, FUNC_END_LABEL, corrected_rtnnum);
   totsize += write_debug_delta4 (label2, label1, "routine size", dosizeonly);
 
   return totsize;
@@ -926,11 +921,10 @@ 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)
-     int dosizeonly;
+write_pclines (int dosizeonly)
 {
   unsigned i;
   int fn;
@@ -955,7 +949,7 @@ write_pclines (dosizeonly)
       linestart = linestart + ((max_line / 10000) + 1) * 10000;
     }
 
-  /* Set starting address to beginning of text section */
+  /* Set starting address to beginning of text section */
   line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 8;
   line_num.dst_a_line_num_header.dst__header_type.dst_w_type = DST_K_LINE_NUM;
   pcline.dst_b_pcline_command = DST_K_SET_ABS_PC;
@@ -986,8 +980,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);
@@ -1057,13 +1051,11 @@ 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)
-     int fileid;
-     dst_file_info_entry file_info_entry;
-     int dosizeonly;
+write_srccorr (int fileid, dst_file_info_entry file_info_entry,
+              int dosizeonly)
 {
   int src_command_size;
   int linesleft = file_info_entry.max_line;
@@ -1186,73 +1178,76 @@ 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)
-     int dosizeonly;
+write_srccorrs (int dosizeonly)
 {
   unsigned int i;
   int totsize = 0;
@@ -1267,9 +1262,7 @@ write_srccorrs (dosizeonly)
    the prologue.  */
 
 static void
-vmsdbgout_begin_prologue (line, file)
-     unsigned int line;
-     const char *file;
+vmsdbgout_begin_prologue (unsigned int line, const char *file)
 {
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
@@ -1287,30 +1280,45 @@ 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 (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_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 (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 (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)
     {
@@ -1319,6 +1327,9 @@ vmsdbgout_end_epilogue ()
       ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
                                   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);
     }
 }
 
@@ -1326,37 +1337,32 @@ vmsdbgout_end_epilogue ()
    a lexical block.  */
 
 static void
-vmsdbgout_begin_block (line, blocknum)
-     register unsigned line;
-     register unsigned blocknum;
+vmsdbgout_begin_block (register unsigned line, register unsigned blocknum)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*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
    lexical block.  */
 
 static void
-vmsdbgout_end_block (line, blocknum)
-     register unsigned line;
-     register unsigned blocknum;
+vmsdbgout_end_block (register unsigned line, register unsigned blocknum)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*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.  */
 
 static bool
-vmsdbgout_ignore_block (block)
-     tree block;
+vmsdbgout_ignore_block (tree block)
 {
   bool retval = 0;
 
@@ -1369,10 +1375,10 @@ vmsdbgout_ignore_block (block)
 /* Add an entry for function DECL into the func_table.  */
 
 static void
-vmsdbgout_begin_function (decl)
-     tree decl;
+vmsdbgout_begin_function (tree decl)
 {
   const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+  vms_func_ref fde;
 
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.begin_function) (decl);
@@ -1380,12 +1386,16 @@ vmsdbgout_begin_function (decl)
   if (func_table_in_use == func_table_allocated)
     {
       func_table_allocated += FUNC_TABLE_INCREMENT;
-      func_table = (char **) xrealloc (func_table,
-                                      func_table_allocated * sizeof (char *));
+      func_table
+        = (vms_func_ref) xrealloc (func_table,
+                                  func_table_allocated * sizeof (vms_func_node));
     }
 
   /* Add the new entry to the end of the function name table.  */
-  func_table[func_table_in_use++] = xstrdup (name);
+  fde = &func_table[func_table_in_use++];
+  fde->vms_func_name = xstrdup (name);
+  fde->funcdef_number = current_function_funcdef_no;
+
 }
 
 static char fullname_buff [4096];
@@ -1394,8 +1404,7 @@ static char fullname_buff [4096];
    in VMS syntax in order to be processed by VMS Debug.  */
 
 static char *
-full_name (filename)
-     const char *filename;
+full_name (const char *filename)
 {
 #ifdef VMS
   FILE *fp = fopen (filename, "r");
@@ -1426,8 +1435,7 @@ full_name (filename)
    all searches.  */
 
 static unsigned int
-lookup_filename (file_name)
-     const char *file_name;
+lookup_filename (const char *file_name)
 {
   static unsigned int last_file_lookup_index = 0;
   register char *fn;
@@ -1446,17 +1454,17 @@ lookup_filename (file_name)
 #ifdef VMS
       struct tm *ts;
 
-      /* Adjust for GMT */
+      /* Adjust for GMT */
       ts = (struct tm *) localtime (&statbuf.st_ctime);
       gmtoff = ts->tm_gmtoff;
 
-      /* VMS has multiple file format types */
+      /* 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 */
+      /* Assume stream LF type file */
       rfo = 2;
 #endif
       cdt = 10000000 * (statbuf.st_ctime + gmtoff + vms_epoch_offset);
@@ -1501,10 +1509,9 @@ lookup_filename (file_name)
     {
 
       file_info_table_allocated += FILE_TABLE_INCREMENT;
-      file_info_table
-       = (dst_file_info_ref) xrealloc (file_info_table,
-                                       (file_info_table_allocated
-                                        * sizeof (dst_file_info_entry)));
+      file_info_table = xrealloc (file_info_table,
+                                 (file_info_table_allocated
+                                  * sizeof (dst_file_info_entry)));
     }
 
   /* Add the new entry to the end of the filename table.  */
@@ -1525,9 +1532,7 @@ lookup_filename (file_name)
    'line_info_table' for later output of the .debug_line section.  */
 
 static void
-vmsdbgout_source_line (line, filename)
-     register unsigned line;
-     register const char *filename;
+vmsdbgout_source_line (register unsigned line, register const char *filename)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.source_line) (line, filename);
@@ -1536,17 +1541,16 @@ vmsdbgout_source_line (line, filename)
     {
       dst_line_info_ref line_info;
 
-      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
-                                line_info_table_in_use);
+      targetm.asm_out.internal_label (asm_out_file, LINE_CODE_LABEL,
+                                     line_info_table_in_use);
 
       /* Expand the line info table if necessary.  */
       if (line_info_table_in_use == line_info_table_allocated)
        {
          line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
-         line_info_table
-           = (dst_line_info_ref) xrealloc (line_info_table,
-                                           (line_info_table_allocated
-                                            * sizeof (dst_line_info_entry)));
+         line_info_table = 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.  */
@@ -1562,9 +1566,7 @@ vmsdbgout_source_line (line, filename)
    At present, unimplemented.  */
 
 static void
-vmsdbgout_start_source_file (lineno, filename)
-     unsigned int lineno;
-     const char *filename;
+vmsdbgout_start_source_file (unsigned int lineno, const char *filename)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.start_source_file) (lineno, filename);
@@ -1574,8 +1576,7 @@ vmsdbgout_start_source_file (lineno, filename)
    At present, unimplemented.  */
 
 static void
-vmsdbgout_end_source_file (lineno)
-     unsigned int lineno ATTRIBUTE_UNUSED;
+vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.end_source_file) (lineno);
@@ -1584,8 +1585,7 @@ vmsdbgout_end_source_file (lineno)
 /* Set up for Debug output at the start of compilation.  */
 
 static void
-vmsdbgout_init (main_input_filename)
-     const char *main_input_filename;
+vmsdbgout_init (const char *main_input_filename)
 {
   const char *language_string = lang_hooks.name;
 
@@ -1600,21 +1600,19 @@ vmsdbgout_init (main_input_filename)
 
   /* Allocate the initial hunk of the file_info_table.  */
   file_info_table
-    = (dst_file_info_ref) xcalloc (FILE_TABLE_INCREMENT,
-                                  sizeof (dst_file_info_entry));
+    = xcalloc (FILE_TABLE_INCREMENT, sizeof (dst_file_info_entry));
   file_info_table_allocated = FILE_TABLE_INCREMENT;
 
   /* Skip the first entry - file numbers begin at 1 */
   file_info_table_in_use = 1;
 
-  func_table = (char **) xcalloc (FUNC_TABLE_INCREMENT, sizeof (char *));
+  func_table = (vms_func_ref) xcalloc (FUNC_TABLE_INCREMENT, sizeof (vms_func_node));
   func_table_allocated = FUNC_TABLE_INCREMENT;
   func_table_in_use = 1;
 
   /* Allocate the initial hunk of the line_info_table.  */
   line_info_table
-    = (dst_line_info_ref) xcalloc (LINE_INFO_TABLE_INCREMENT,
-                                  sizeof (dst_line_info_entry));
+    = xcalloc (LINE_INFO_TABLE_INCREMENT, sizeof (dst_line_info_entry));
   line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
   /* zero-th entry is allocated, but unused */
   line_info_table_in_use = 1;
@@ -1632,10 +1630,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);
 
@@ -1644,9 +1639,7 @@ vmsdbgout_init (main_input_filename)
 /* Not implemented in VMS Debug.  */
 
 static void
-vmsdbgout_define (lineno, buffer)
-     unsigned int lineno;
-     const char *buffer;
+vmsdbgout_define (unsigned int lineno, const char *buffer)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.define) (lineno, buffer);
@@ -1655,9 +1648,7 @@ vmsdbgout_define (lineno, buffer)
 /* Not implemented in VMS Debug.  */
 
 static void
-vmsdbgout_undef (lineno, buffer)
-     unsigned int lineno;
-     const char *buffer;
+vmsdbgout_undef (unsigned int lineno, const char *buffer)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.undef) (lineno, buffer);
@@ -1666,8 +1657,7 @@ vmsdbgout_undef (lineno, buffer)
 /* Not implemented in VMS Debug.  */
 
 static void
-vmsdbgout_decl (decl)
-     tree decl;
+vmsdbgout_decl (tree decl)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.function_decl) (decl);
@@ -1676,8 +1666,7 @@ vmsdbgout_decl (decl)
 /* Not implemented in VMS Debug.  */
 
 static void
-vmsdbgout_global_decl (decl)
-     tree decl;
+vmsdbgout_global_decl (tree decl)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.global_decl) (decl);
@@ -1686,8 +1675,7 @@ vmsdbgout_global_decl (decl)
 /* Not implemented in VMS Debug.  */
 
 static void
-vmsdbgout_abstract_function (decl)
-     tree decl;
+vmsdbgout_abstract_function (tree decl)
 {
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
     (*dwarf2_debug_hooks.outlining_inline_function) (decl);
@@ -1697,26 +1685,25 @@ vmsdbgout_abstract_function (decl)
    VMS Debug debugging info.  */
 
 static void
-vmsdbgout_finish (input_filename)
-     const char *input_filename ATTRIBUTE_UNUSED;
+vmsdbgout_finish (const char *main_input_filename ATTRIBUTE_UNUSED)
 {
   unsigned int i;
   int totsize;
 
   if (write_symbols == VMS_AND_DWARF2_DEBUG)
-    (*dwarf2_debug_hooks.finish) (input_filename);
+    (*dwarf2_debug_hooks.finish) (main_input_filename);
 
   if (debug_info_level == DINFO_LEVEL_NONE)
     return;
 
   /* Output a terminator label for the .text section.  */
-  text_section ();
-  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, TEXT_END_LABEL, 0);
+  switch_to_section (text_section);
+  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.  */
-  named_section (NULL_TREE, ".vmsdebug", 0);
+  switch_to_section (get_named_section (NULL, ".vmsdebug", 0));
   ASM_OUTPUT_ALIGN (asm_out_file, 0);
 
   totsize = write_modbeg (1);