1 /* Output VMS debug format symbol table information from GCC.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Douglas B. Rupp (rupp@gnat.com).
6 Updated by Bernard W. Giroud (bgiroud@users.sourceforge.net).
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
29 #ifdef VMS_DEBUGGING_INFO
37 #include "langhooks.h"
41 /* Difference in seconds between the VMS Epoch and the Unix Epoch */
42 static const long long vms_epoch_offset = 3506716800ll;
44 int vms_file_stats_name (const char *, long long *, long *, char *, int *);
46 /* NOTE: In the comments in this file, many references are made to "Debug
47 Symbol Table". This term is abbreviated as `DST' throughout the remainder
50 typedef struct dst_line_info_struct *dst_line_info_ref;
52 /* Each entry in the line_info_table maintains the file and
53 line number associated with the label generated for that
54 entry. The label gives the PC value associated with
55 the line number entry. */
56 typedef struct dst_line_info_struct
58 unsigned long dst_file_num;
59 unsigned long dst_line_num;
63 typedef struct dst_file_info_struct *dst_file_info_ref;
65 typedef struct dst_file_info_struct
68 unsigned int max_line;
69 unsigned int listing_line_start;
78 /* How to start an assembler comment. */
79 #ifndef ASM_COMMENT_START
80 #define ASM_COMMENT_START ";#"
83 /* Maximum size (in bytes) of an artificially generated label. */
84 #define MAX_ARTIFICIAL_LABEL_BYTES 30
86 /* Make sure we know the sizes of the various types debug can describe. These
87 are only defaults. If the sizes are different for your target, you should
88 override these values by defining the appropriate symbols in your tm.h
91 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
94 /* Pointer to a structure of filenames referenced by this compilation unit. */
95 static dst_file_info_ref file_info_table;
97 /* Total number of entries in the table (i.e. array) pointed to by
98 `file_info_table'. This is the *total* and includes both used and unused
100 static unsigned int file_info_table_allocated;
102 /* Number of entries in the file_info_table which are actually in use. */
103 static unsigned int file_info_table_in_use;
105 /* Size (in elements) of increments by which we may expand the filename
107 #define FILE_TABLE_INCREMENT 64
109 /* A structure to hold basic information for the VMS end
112 typedef struct vms_func_struct
114 const char *vms_func_name;
115 unsigned funcdef_number;
119 typedef struct vms_func_struct *vms_func_ref;
121 static unsigned int func_table_allocated;
122 static unsigned int func_table_in_use;
123 #define FUNC_TABLE_INCREMENT 256
125 /* A pointer to the base of a table that contains frame description
126 information for each routine. */
127 static vms_func_ref func_table;
129 /* Local pointer to the name of the main input file. Initialized in
131 static const char *primary_filename;
133 static char *module_producer;
134 static unsigned int module_language;
136 /* A pointer to the base of a table that contains line information
137 for each source code line in .text in the compilation unit. */
138 static dst_line_info_ref line_info_table;
140 /* Number of elements currently allocated for line_info_table. */
141 static unsigned int line_info_table_allocated;
143 /* Number of elements in line_info_table currently in use. */
144 static unsigned int line_info_table_in_use;
146 /* Size (in elements) of increments by which we may expand line_info_table. */
147 #define LINE_INFO_TABLE_INCREMENT 1024
149 /* Forward declarations for functions defined in this file. */
150 static char *full_name (const char *);
151 static unsigned int lookup_filename (const char *);
152 static void addr_const_to_string (char *, rtx);
153 static int write_debug_header (DST_HEADER *, const char *, int);
154 static int write_debug_addr (const char *, const char *, int);
155 static int write_debug_data1 (unsigned int, const char *, int);
156 static int write_debug_data2 (unsigned int, const char *, int);
157 static int write_debug_data4 (unsigned long, const char *, int);
158 static int write_debug_data8 (unsigned long long, const char *, int);
159 static int write_debug_delta4 (const char *, const char *, const char *, int);
160 static int write_debug_string (const char *, const char *, int);
161 static int write_modbeg (int);
162 static int write_modend (int);
163 static int write_rtnbeg (int, int);
164 static int write_rtnend (int, int);
165 static int write_pclines (int);
166 static int write_srccorr (int, dst_file_info_entry, int);
167 static int write_srccorrs (int);
169 static void vmsdbgout_init (const char *);
170 static void vmsdbgout_finish (const char *);
171 static void vmsdbgout_define (unsigned int, const char *);
172 static void vmsdbgout_undef (unsigned int, const char *);
173 static void vmsdbgout_start_source_file (unsigned int, const char *);
174 static void vmsdbgout_end_source_file (unsigned int);
175 static void vmsdbgout_begin_block (unsigned int, unsigned int);
176 static void vmsdbgout_end_block (unsigned int, unsigned int);
177 static bool vmsdbgout_ignore_block (const_tree);
178 static void vmsdbgout_source_line (unsigned int, const char *, int, bool);
179 static void vmsdbgout_begin_prologue (unsigned int, const char *);
180 static void vmsdbgout_end_prologue (unsigned int, const char *);
181 static void vmsdbgout_end_function (unsigned int);
182 static void vmsdbgout_end_epilogue (unsigned int, const char *);
183 static void vmsdbgout_begin_function (tree);
184 static void vmsdbgout_decl (tree);
185 static void vmsdbgout_global_decl (tree);
186 static void vmsdbgout_abstract_function (tree);
188 /* The debug hooks structure. */
190 const struct gcc_debug_hooks vmsdbg_debug_hooks
195 vmsdbgout_start_source_file,
196 vmsdbgout_end_source_file,
197 vmsdbgout_begin_block,
199 vmsdbgout_ignore_block,
200 vmsdbgout_source_line,
201 vmsdbgout_begin_prologue,
202 vmsdbgout_end_prologue,
203 vmsdbgout_end_epilogue,
204 vmsdbgout_begin_function,
205 vmsdbgout_end_function,
207 vmsdbgout_global_decl,
208 debug_nothing_tree_int, /* type_decl */
209 debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
210 debug_nothing_tree, /* deferred_inline_function */
211 vmsdbgout_abstract_function,
212 debug_nothing_rtx, /* label */
213 debug_nothing_int, /* handle_pch */
214 debug_nothing_rtx, /* var_location */
215 debug_nothing_void, /* switch_text_section */
216 debug_nothing_tree, /* direct_call */
217 debug_nothing_tree_int, /* virtual_call_token */
218 debug_nothing_uid, /* virtual_call */
219 debug_nothing_tree_tree, /* set_name */
220 0 /* start_end_main_source_file */
223 /* Definitions of defaults for assembler-dependent names of various
224 pseudo-ops and section names.
225 Theses may be overridden in the tm.h file (if necessary) for a particular
227 #ifdef UNALIGNED_SHORT_ASM_OP
228 #undef UNALIGNED_SHORT_ASM_OP
230 #define UNALIGNED_SHORT_ASM_OP ".word"
232 #ifdef UNALIGNED_INT_ASM_OP
233 #undef UNALIGNED_INT_ASM_OP
235 #define UNALIGNED_INT_ASM_OP ".long"
237 #ifdef UNALIGNED_LONG_ASM_OP
238 #undef UNALIGNED_LONG_ASM_OP
240 #define UNALIGNED_LONG_ASM_OP ".long"
242 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
243 #undef UNALIGNED_DOUBLE_INT_ASM_OP
245 #define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
250 #define ASM_BYTE_OP ".byte"
252 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
254 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
256 #ifndef UNALIGNED_PTR_ASM_OP
257 #define UNALIGNED_PTR_ASM_OP \
258 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
261 #ifndef UNALIGNED_OFFSET_ASM_OP
262 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
263 (NUMBYTES(OFFSET) == 4 \
264 ? UNALIGNED_LONG_ASM_OP \
265 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
268 /* Definitions of defaults for formats and names of various special
269 (artificial) labels which may be generated within this file (when the -g
270 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
271 may be overridden from within the tm.h file, but typically, overriding these
272 defaults is unnecessary. */
274 static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
276 #ifndef TEXT_END_LABEL
277 #define TEXT_END_LABEL "Lvetext"
279 #ifndef FUNC_BEGIN_LABEL
280 #define FUNC_BEGIN_LABEL "LVFB"
282 #ifndef FUNC_PROLOG_LABEL
283 #define FUNC_PROLOG_LABEL "LVFP"
285 #ifndef FUNC_END_LABEL
286 #define FUNC_END_LABEL "LVFE"
288 #ifndef BLOCK_BEGIN_LABEL
289 #define BLOCK_BEGIN_LABEL "LVBB"
291 #ifndef BLOCK_END_LABEL
292 #define BLOCK_END_LABEL "LVBE"
294 #ifndef LINE_CODE_LABEL
295 #define LINE_CODE_LABEL "LVM"
298 #ifndef ASM_OUTPUT_DEBUG_DELTA2
299 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
302 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
303 assemble_name (FILE, LABEL1); \
304 fprintf (FILE, "-"); \
305 assemble_name (FILE, LABEL2); \
310 #ifndef ASM_OUTPUT_DEBUG_DELTA4
311 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
314 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
315 assemble_name (FILE, LABEL1); \
316 fprintf (FILE, "-"); \
317 assemble_name (FILE, LABEL2); \
322 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
323 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
326 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
327 assemble_name (FILE, LABEL1); \
328 fprintf (FILE, "-"); \
329 assemble_name (FILE, LABEL2); \
334 #ifndef ASM_OUTPUT_DEBUG_ADDR
335 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
338 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
339 assemble_name (FILE, LABEL); \
344 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
345 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
346 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
349 #ifndef ASM_OUTPUT_DEBUG_DATA1
350 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
351 fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned char) VALUE)
354 #ifndef ASM_OUTPUT_DEBUG_DATA2
355 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
356 fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, \
357 (unsigned short) VALUE)
360 #ifndef ASM_OUTPUT_DEBUG_DATA4
361 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
362 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
365 #ifndef ASM_OUTPUT_DEBUG_DATA
366 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
367 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
370 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
371 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
372 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_PTR_ASM_OP, \
373 (unsigned long) VALUE)
376 #ifndef ASM_OUTPUT_DEBUG_DATA8
377 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
378 fprintf ((FILE), "\t%s\t0x%llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
379 (unsigned long long) VALUE)
382 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
383 newline is produced. When flag_verbose_asm is asserted, we add commentary
384 at the end of the line, so we must avoid output of a newline here. */
385 #ifndef ASM_OUTPUT_DEBUG_STRING
386 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
389 register int slen = strlen(P); \
390 register const char *p = (P); \
392 fprintf (FILE, "\t.ascii \""); \
393 for (i = 0; i < slen; i++) \
395 register int c = p[i]; \
396 if (c == '\"' || c == '\\') \
398 if (c >= ' ' && c < 0177) \
401 fprintf (FILE, "\\%o", c); \
403 fprintf (FILE, "\""); \
408 /* Convert a reference to the assembler name of a C-level name. This
409 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
410 a string rather than writing to a file. */
411 #ifndef ASM_NAME_TO_STRING
412 #define ASM_NAME_TO_STRING(STR, NAME) \
415 if ((NAME)[0] == '*') \
416 strcpy (STR, NAME+1); \
418 strcpy (STR, NAME); \
424 /* General utility functions. */
426 /* Convert an integer constant expression into assembler syntax. Addition and
427 subtraction are the only arithmetic that may appear in these expressions.
428 This is an adaptation of output_addr_const in final.c. Here, the target
429 of the conversion is a string buffer. We can't use output_addr_const
430 directly, because it writes to a file. */
433 addr_const_to_string (char *str, rtx x)
440 switch (GET_CODE (x))
443 gcc_assert (flag_pic);
448 ASM_NAME_TO_STRING (buf1, XSTR (x, 0));
453 ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
454 ASM_NAME_TO_STRING (buf2, buf1);
459 ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (x));
460 ASM_NAME_TO_STRING (buf2, buf1);
465 sprintf (buf1, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
470 /* This used to output parentheses around the expression, but that does
471 not work on the 386 (either ATT or BSD assembler). */
472 addr_const_to_string (buf1, XEXP (x, 0));
477 if (GET_MODE (x) == VOIDmode)
479 /* We can use %d if the number is one word and positive. */
480 if (CONST_DOUBLE_HIGH (x))
481 sprintf (buf1, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
482 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
483 else if (CONST_DOUBLE_LOW (x) < 0)
484 sprintf (buf1, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
486 sprintf (buf1, HOST_WIDE_INT_PRINT_DEC,
487 CONST_DOUBLE_LOW (x));
491 /* We can't handle floating point constants; PRINT_OPERAND must
493 output_operand_lossage ("floating constant misused");
497 /* Some assemblers need integer constants to appear last (eg masm). */
498 if (CONST_INT_P (XEXP (x, 0)))
500 addr_const_to_string (buf1, XEXP (x, 1));
502 if (INTVAL (XEXP (x, 0)) >= 0)
504 addr_const_to_string (buf1, XEXP (x, 0));
509 addr_const_to_string (buf1, XEXP (x, 0));
511 if (INTVAL (XEXP (x, 1)) >= 0)
513 addr_const_to_string (buf1, XEXP (x, 1));
519 /* Avoid outputting things like x-x or x+5-x, since some assemblers
520 can't handle that. */
521 x = simplify_subtraction (x);
522 if (GET_CODE (x) != MINUS)
525 addr_const_to_string (buf1, XEXP (x, 0));
528 if (CONST_INT_P (XEXP (x, 1))
529 && INTVAL (XEXP (x, 1)) < 0)
532 addr_const_to_string (buf1, XEXP (x, 1));
538 addr_const_to_string (buf1, XEXP (x, 1));
545 addr_const_to_string (buf1, XEXP (x, 0));
550 output_operand_lossage ("invalid expression as operand");
554 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
555 set. Return the header size. Just return the size if DOSIZEONLY is
559 write_debug_header (DST_HEADER *header, const char *comment, int dosizeonly)
563 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
564 header->dst__header_length.dst_w_length);
566 if (flag_verbose_asm)
567 fprintf (asm_out_file, "\t%s record length", ASM_COMMENT_START);
568 fputc ('\n', asm_out_file);
570 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
571 header->dst__header_type.dst_w_type);
573 if (flag_verbose_asm)
574 fprintf (asm_out_file, "\t%s record type (%s)", ASM_COMMENT_START,
577 fputc ('\n', asm_out_file);
583 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
584 set. Return the address size. Just return the size if DOSIZEONLY is
588 write_debug_addr (const char *symbol, const char *comment, int dosizeonly)
592 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, symbol);
593 if (flag_verbose_asm)
594 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
595 fputc ('\n', asm_out_file);
601 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
602 set. Return the data size. Just return the size if DOSIZEONLY is
606 write_debug_data1 (unsigned int data1, const char *comment, int dosizeonly)
610 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file, data1);
611 if (flag_verbose_asm)
612 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
613 fputc ('\n', asm_out_file);
619 /* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
620 set. Return the data size. Just return the size if DOSIZEONLY is
624 write_debug_data2 (unsigned int data2, const char *comment, int dosizeonly)
628 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file, data2);
629 if (flag_verbose_asm)
630 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
631 fputc ('\n', asm_out_file);
637 /* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
638 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
641 write_debug_data4 (unsigned long data4, const char *comment, int dosizeonly)
645 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file, data4);
646 if (flag_verbose_asm)
647 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
648 fputc ('\n', asm_out_file);
654 /* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
655 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
658 write_debug_data8 (unsigned long long data8, const char *comment,
663 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file, data8);
664 if (flag_verbose_asm)
665 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
666 fputc ('\n', asm_out_file);
672 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
673 flag_verbose_asm is set. Return the data size. Just return the size if
674 DOSIZEONLY is nonzero. */
677 write_debug_delta4 (const char *label1, const char *label2,
678 const char *comment, int dosizeonly)
682 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file, label1, label2);
683 if (flag_verbose_asm)
684 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
685 fputc ('\n', asm_out_file);
691 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
692 set. Return the string length. Just return the length if DOSIZEONLY is
696 write_debug_string (const char *string, const char *comment, int dosizeonly)
700 ASM_OUTPUT_DEBUG_STRING (asm_out_file, string);
701 if (flag_verbose_asm)
702 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
703 fputc ('\n', asm_out_file);
706 return strlen (string);
709 /* Output a module begin header and return the header size. Just return the
710 size if DOSIZEONLY is nonzero. */
713 write_modbeg (int dosizeonly)
715 DST_MODULE_BEGIN modbeg;
718 char *module_name, *m;
723 /* Assumes primary filename has Unix syntax file spec. */
724 module_name = xstrdup (lbasename (primary_filename));
726 m = strrchr (module_name, '.');
730 modnamelen = strlen (module_name);
731 for (i = 0; i < modnamelen; i++)
732 module_name[i] = TOUPPER (module_name[i]);
734 prodnamelen = strlen (module_producer);
736 modbeg.dst_a_modbeg_header.dst__header_length.dst_w_length
737 = DST_K_MODBEG_SIZE + modnamelen + DST_K_MB_TRLR_SIZE + prodnamelen - 1;
738 modbeg.dst_a_modbeg_header.dst__header_type.dst_w_type = DST_K_MODBEG;
739 modbeg.dst_b_modbeg_flags.dst_v_modbeg_hide = 0;
740 modbeg.dst_b_modbeg_flags.dst_v_modbeg_version = 1;
741 modbeg.dst_b_modbeg_flags.dst_v_modbeg_unused = 0;
742 modbeg.dst_b_modbeg_unused = 0;
743 modbeg.dst_l_modbeg_language = module_language;
744 modbeg.dst_w_version_major = DST_K_VERSION_MAJOR;
745 modbeg.dst_w_version_minor = DST_K_VERSION_MINOR;
746 modbeg.dst_b_modbeg_name = strlen (module_name);
748 mb_trlr.dst_b_compiler = strlen (module_producer);
750 totsize += write_debug_header (&modbeg.dst_a_modbeg_header,
751 "modbeg", dosizeonly);
752 totsize += write_debug_data1 (*((char *) &modbeg.dst_b_modbeg_flags),
753 "flags", dosizeonly);
754 totsize += write_debug_data1 (modbeg.dst_b_modbeg_unused,
755 "unused", dosizeonly);
756 totsize += write_debug_data4 (modbeg.dst_l_modbeg_language,
757 "language", dosizeonly);
758 totsize += write_debug_data2 (modbeg.dst_w_version_major,
759 "DST major version", dosizeonly);
760 totsize += write_debug_data2 (modbeg.dst_w_version_minor,
761 "DST minor version", dosizeonly);
762 totsize += write_debug_data1 (modbeg.dst_b_modbeg_name,
763 "length of module name", dosizeonly);
764 totsize += write_debug_string (module_name, "module name", dosizeonly);
765 totsize += write_debug_data1 (mb_trlr.dst_b_compiler,
766 "length of compiler name", dosizeonly);
767 totsize += write_debug_string (module_producer, "compiler name", dosizeonly);
772 /* Output a module end trailer and return the trailer size. Just return
773 the size if DOSIZEONLY is nonzero. */
776 write_modend (int dosizeonly)
778 DST_MODULE_END modend;
781 modend.dst_a_modend_header.dst__header_length.dst_w_length
782 = DST_K_MODEND_SIZE - 1;
783 modend.dst_a_modend_header.dst__header_type.dst_w_type = DST_K_MODEND;
785 totsize += write_debug_header (&modend.dst_a_modend_header, "modend",
791 /* Output a routine begin header routine RTNNUM and return the header size.
792 Just return the size if DOSIZEONLY is nonzero. */
795 write_rtnbeg (int rtnnum, int dosizeonly)
801 char label[MAX_ARTIFICIAL_LABEL_BYTES];
802 DST_ROUTINE_BEGIN rtnbeg;
804 vms_func_ref fde = &func_table[rtnnum];
806 rtnname = fde->vms_func_name;
807 rtnnamelen = strlen (rtnname);
808 rtnentryname = concat (rtnname, "..en", NULL);
810 if (!strcmp (rtnname, "main"))
813 const char *go = "TRANSFER$BREAK$GO";
815 /* This command isn't documented in DSTRECORDS, so it's made to
816 look like what DEC C does */
818 /* header size - 1st byte + flag byte + STO_LW size
819 + string count byte + string length */
820 header.dst__header_length.dst_w_length
821 = DST_K_DST_HEADER_SIZE - 1 + 1 + 4 + 1 + strlen (go);
822 header.dst__header_type.dst_w_type = 0x17;
824 totsize += write_debug_header (&header, "transfer", dosizeonly);
826 /* I think this is a flag byte, but I don't know what this flag means */
827 totsize += write_debug_data1 (0x1, "flags ???", dosizeonly);
829 /* Routine Begin PD Address */
830 totsize += write_debug_addr (rtnname, "main procedure descriptor",
832 totsize += write_debug_data1 (strlen (go), "length of main_name",
834 totsize += write_debug_string (go, "main name", dosizeonly);
837 /* The header length never includes the length byte. */
838 rtnbeg.dst_a_rtnbeg_header.dst__header_length.dst_w_length
839 = DST_K_RTNBEG_SIZE + rtnnamelen - 1;
840 rtnbeg.dst_a_rtnbeg_header.dst__header_type.dst_w_type = DST_K_RTNBEG;
841 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unused = 0;
842 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unalloc = 0;
843 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_prototype = 0;
844 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_inlined = 0;
845 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_no_call = 1;
846 rtnbeg.dst_b_rtnbeg_name = rtnnamelen;
848 totsize += write_debug_header (&rtnbeg.dst_a_rtnbeg_header, "rtnbeg",
850 totsize += write_debug_data1 (*((char *) &rtnbeg.dst_b_rtnbeg_flags),
851 "flags", dosizeonly);
853 /* Routine Begin Address */
854 totsize += write_debug_addr (rtnentryname, "routine entry name", dosizeonly);
856 /* Routine Begin PD Address */
857 totsize += write_debug_addr (rtnname, "routine procedure descriptor",
860 /* Routine Begin Name */
861 totsize += write_debug_data1 (rtnbeg.dst_b_rtnbeg_name,
862 "length of routine name", dosizeonly);
864 totsize += write_debug_string (rtnname, "routine name", dosizeonly);
868 if (debug_info_level > DINFO_LEVEL_TERSE)
870 prolog.dst_a_prolog_header.dst__header_length.dst_w_length
871 = DST_K_PROLOG_SIZE - 1;
872 prolog.dst_a_prolog_header.dst__header_type.dst_w_type = DST_K_PROLOG;
874 totsize += write_debug_header (&prolog.dst_a_prolog_header, "prolog",
877 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL, fde->funcdef_number);
878 totsize += write_debug_addr (label, "prolog breakpoint addr",
885 /* Output a routine end trailer for routine RTNNUM and return the header size.
886 Just return the size if DOSIZEONLY is nonzero. */
889 write_rtnend (int rtnnum, int dosizeonly)
891 DST_ROUTINE_END rtnend;
892 char label1[MAX_ARTIFICIAL_LABEL_BYTES];
893 char label2[MAX_ARTIFICIAL_LABEL_BYTES];
895 vms_func_ref fde = &func_table[rtnnum];
896 int corrected_rtnnum = fde->funcdef_number;
900 rtnend.dst_a_rtnend_header.dst__header_length.dst_w_length
901 = DST_K_RTNEND_SIZE - 1;
902 rtnend.dst_a_rtnend_header.dst__header_type.dst_w_type = DST_K_RTNEND;
903 rtnend.dst_b_rtnend_unused = 0;
904 rtnend.dst_l_rtnend_size = 0; /* Calculated below. */
906 totsize += write_debug_header (&rtnend.dst_a_rtnend_header, "rtnend",
908 totsize += write_debug_data1 (rtnend.dst_b_rtnend_unused, "unused",
911 ASM_GENERATE_INTERNAL_LABEL (label1, FUNC_BEGIN_LABEL, corrected_rtnnum);
912 ASM_GENERATE_INTERNAL_LABEL (label2, FUNC_END_LABEL, corrected_rtnnum);
913 totsize += write_debug_delta4 (label2, label1, "routine size", dosizeonly);
918 #define K_DELTA_PC(I) \
919 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
921 #define K_SET_LINUM(I) \
922 ((I) < 256 ? DST_K_SET_LINUM_B \
923 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
925 #define K_INCR_LINUM(I) \
926 ((I) < 256 ? DST_K_INCR_LINUM \
927 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
929 /* Output the PC to line number correlations and return the size. Just return
930 the size if DOSIZEONLY is nonzero */
933 write_pclines (int dosizeonly)
940 DST_LINE_NUM_HEADER line_num;
941 DST_PCLINE_COMMANDS pcline;
942 char label[MAX_ARTIFICIAL_LABEL_BYTES];
943 char lastlabel[MAX_ARTIFICIAL_LABEL_BYTES];
947 max_line = file_info_table[1].max_line;
948 file_info_table[1].listing_line_start = linestart;
949 linestart = linestart + ((max_line / 100000) + 1) * 100000;
951 for (i = 2; i < file_info_table_in_use; i++)
953 max_line = file_info_table[i].max_line;
954 file_info_table[i].listing_line_start = linestart;
955 linestart = linestart + ((max_line / 10000) + 1) * 10000;
958 /* Set starting address to beginning of text section. */
959 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 8;
960 line_num.dst_a_line_num_header.dst__header_type.dst_w_type = DST_K_LINE_NUM;
961 pcline.dst_b_pcline_command = DST_K_SET_ABS_PC;
963 totsize += write_debug_header (&line_num.dst_a_line_num_header,
964 "line_num", dosizeonly);
965 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
966 "line_num (SET ABS PC)", dosizeonly);
972 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, TEXT_SECTION_ASM_OP);
973 if (flag_verbose_asm)
974 fprintf (asm_out_file, "\t%s line_num", ASM_COMMENT_START);
975 fputc ('\n', asm_out_file);
978 fn = line_info_table[1].dst_file_num;
979 ln = (file_info_table[fn].listing_line_start
980 + line_info_table[1].dst_line_num);
981 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 4 + 4;
982 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
984 totsize += write_debug_header (&line_num.dst_a_line_num_header,
985 "line_num", dosizeonly);
986 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
987 "line_num (SET LINUM LONG)", dosizeonly);
989 sprintf (buff, "line_num (%d)", ln ? ln - 1 : 0);
990 totsize += write_debug_data4 (ln ? ln - 1 : 0, buff, dosizeonly);
993 strcpy (lastlabel, TEXT_SECTION_ASM_OP);
994 for (i = 1; i < line_info_table_in_use; i++)
998 fn = line_info_table[i].dst_file_num;
999 ln = (file_info_table[fn].listing_line_start
1000 + line_info_table[i].dst_line_num);
1002 if (ln - lastln > 1)
1003 extrabytes = 5; /* NUMBYTES (ln - lastln - 1) + 1; */
1004 else if (ln <= lastln)
1005 extrabytes = 5; /* NUMBYTES (ln - 1) + 1; */
1009 line_num.dst_a_line_num_header.dst__header_length.dst_w_length
1012 totsize += write_debug_header
1013 (&line_num.dst_a_line_num_header, "line_num", dosizeonly);
1015 if (ln - lastln > 1)
1017 int lndif = ln - lastln - 1;
1019 /* K_INCR_LINUM (lndif); */
1020 pcline.dst_b_pcline_command = DST_K_INCR_LINUM_L;
1022 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
1023 "line_num (INCR LINUM LONG)",
1026 sprintf (buff, "line_num (%d)", lndif);
1027 totsize += write_debug_data4 (lndif, buff, dosizeonly);
1029 else if (ln <= lastln)
1031 /* K_SET_LINUM (ln-1); */
1032 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
1034 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
1035 "line_num (SET LINUM LONG)",
1038 sprintf (buff, "line_num (%d)", ln - 1);
1039 totsize += write_debug_data4 (ln - 1, buff, dosizeonly);
1042 pcline.dst_b_pcline_command = DST_K_DELTA_PC_L;
1044 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
1045 "line_num (DELTA PC LONG)", dosizeonly);
1047 ASM_GENERATE_INTERNAL_LABEL (label, LINE_CODE_LABEL, i);
1048 totsize += write_debug_delta4 (label, lastlabel, "increment line_num",
1052 strcpy (lastlabel, label);
1058 /* Output a source correlation for file FILEID using information saved in
1059 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
1063 write_srccorr (int fileid, dst_file_info_entry file_info_entry,
1066 int src_command_size;
1067 int linesleft = file_info_entry.max_line;
1068 int linestart = file_info_entry.listing_line_start;
1069 int flen = file_info_entry.flen;
1071 DST_SOURCE_CORR src_header;
1072 DST_SRC_COMMAND src_command;
1073 DST_SRC_COMMAND src_command_sf;
1074 DST_SRC_COMMAND src_command_sl;
1075 DST_SRC_COMMAND src_command_sr;
1076 DST_SRC_COMMAND src_command_dl;
1077 DST_SRC_CMDTRLR src_cmdtrlr;
1083 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1084 = DST_K_SOURCE_CORR_HEADER_SIZE + 1 - 1;
1085 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1087 src_command.dst_b_src_command = DST_K_SRC_FORMFEED;
1089 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1090 "source corr", dosizeonly);
1092 totsize += write_debug_data1 (src_command.dst_b_src_command,
1093 "source_corr (SRC FORMFEED)",
1098 = DST_K_SRC_COMMAND_SIZE + flen + DST_K_SRC_CMDTRLR_SIZE;
1099 src_command.dst_b_src_command = DST_K_SRC_DECLFILE;
1100 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length
1101 = src_command_size - 2;
1102 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags = 0;
1103 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid
1105 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt
1106 = file_info_entry.cdt;
1107 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk
1108 = file_info_entry.ebk;
1109 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb
1110 = file_info_entry.ffb;
1111 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo
1112 = file_info_entry.rfo;
1113 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename
1114 = file_info_entry.flen;
1116 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1117 = DST_K_SOURCE_CORR_HEADER_SIZE + src_command_size - 1;
1118 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1121 src_cmdtrlr.dst_b_src_df_libmodname = 0;
1123 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1124 "source corr", dosizeonly);
1125 totsize += write_debug_data1 (src_command.dst_b_src_command,
1126 "source_corr (DECL SRC FILE)", dosizeonly);
1127 totsize += write_debug_data1
1128 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length,
1129 "source_corr (length)", dosizeonly);
1131 totsize += write_debug_data1
1132 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags,
1133 "source_corr (flags)", dosizeonly);
1135 totsize += write_debug_data2
1136 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid,
1137 "source_corr (fileid)", dosizeonly);
1139 totsize += write_debug_data8
1140 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt,
1141 "source_corr (creation date)", dosizeonly);
1143 totsize += write_debug_data4
1144 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk,
1145 "source_corr (EOF block number)", dosizeonly);
1147 totsize += write_debug_data2
1148 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb,
1149 "source_corr (first free byte)", dosizeonly);
1151 totsize += write_debug_data1
1152 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo,
1153 "source_corr (record and file organization)", dosizeonly);
1155 totsize += write_debug_data1
1156 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename,
1157 "source_corr (filename length)", dosizeonly);
1159 totsize += write_debug_string (remap_debug_filename (
1160 file_info_entry.file_name),
1161 "source file name", dosizeonly);
1162 totsize += write_debug_data1 (src_cmdtrlr.dst_b_src_df_libmodname,
1163 "source_corr (libmodname)", dosizeonly);
1165 src_command_sf.dst_b_src_command = DST_K_SRC_SETFILE;
1166 src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword = fileid;
1168 src_command_sr.dst_b_src_command = DST_K_SRC_SETREC_W;
1169 src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword = 1;
1171 src_command_sl.dst_b_src_command = DST_K_SRC_SETLNUM_L;
1172 src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong = linestart + 1;
1174 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1176 if (linesleft > 65534)
1177 linesleft = linesleft - 65534, linestodo = 65534;
1179 linestodo = linesleft, linesleft = 0;
1181 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1183 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1184 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 + 3 + 5 + 3 - 1;
1185 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1188 if (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword)
1190 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1191 "source corr", dosizeonly);
1193 totsize += write_debug_data1 (src_command_sf.dst_b_src_command,
1194 "source_corr (src setfile)", dosizeonly);
1196 totsize += write_debug_data2
1197 (src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword,
1198 "source_corr (fileid)", dosizeonly);
1200 totsize += write_debug_data1 (src_command_sr.dst_b_src_command,
1201 "source_corr (setrec)", dosizeonly);
1203 totsize += write_debug_data2
1204 (src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword,
1205 "source_corr (recnum)", dosizeonly);
1207 totsize += write_debug_data1 (src_command_sl.dst_b_src_command,
1208 "source_corr (setlnum)", dosizeonly);
1210 totsize += write_debug_data4
1211 (src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong,
1212 "source_corr (linenum)", dosizeonly);
1214 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1215 "source_corr (deflines)", dosizeonly);
1217 sprintf (buff, "source_corr (%d)",
1218 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1219 totsize += write_debug_data2
1220 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1223 while (linesleft > 0)
1225 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1226 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 - 1;
1227 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1229 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1231 if (linesleft > 65534)
1232 linesleft = linesleft - 65534, linestodo = 65534;
1234 linestodo = linesleft, linesleft = 0;
1236 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1238 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1239 "source corr", dosizeonly);
1240 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1241 "source_corr (deflines)", dosizeonly);
1242 sprintf (buff, "source_corr (%d)",
1243 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1244 totsize += write_debug_data2
1245 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1253 /* Output all the source correlation entries and return the size. Just return
1254 the size if DOSIZEONLY is nonzero. */
1257 write_srccorrs (int dosizeonly)
1262 for (i = 1; i < file_info_table_in_use; i++)
1263 totsize += write_srccorr (i, file_info_table[i], dosizeonly);
1268 /* Output a marker (i.e. a label) for the beginning of a function, before
1272 vmsdbgout_begin_prologue (unsigned int line, const char *file)
1274 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1276 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1277 (*dwarf2_debug_hooks.begin_prologue) (line, file);
1279 if (debug_info_level > DINFO_LEVEL_NONE)
1281 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
1282 current_function_funcdef_no);
1283 ASM_OUTPUT_LABEL (asm_out_file, label);
1287 /* Output a marker (i.e. a label) for the beginning of a function, after
1291 vmsdbgout_end_prologue (unsigned int line, const char *file)
1293 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1295 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1296 (*dwarf2_debug_hooks.end_prologue) (line, file);
1298 if (debug_info_level > DINFO_LEVEL_TERSE)
1300 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL,
1301 current_function_funcdef_no);
1302 ASM_OUTPUT_LABEL (asm_out_file, label);
1304 /* VMS PCA expects every PC range to correlate to some line and file. */
1305 vmsdbgout_source_line (line, file, 0, true);
1309 /* No output for VMS debug, but make obligatory call to Dwarf2 debug */
1312 vmsdbgout_end_function (unsigned int line)
1314 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1315 (*dwarf2_debug_hooks.end_function) (line);
1318 /* Output a marker (i.e. a label) for the absolute end of the generated code
1319 for a function definition. This gets called *after* the epilogue code has
1323 vmsdbgout_end_epilogue (unsigned int line, const char *file)
1325 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1327 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1328 (*dwarf2_debug_hooks.end_epilogue) (line, file);
1330 if (debug_info_level > DINFO_LEVEL_NONE)
1332 /* Output a label to mark the endpoint of the code generated for this
1334 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
1335 current_function_funcdef_no);
1336 ASM_OUTPUT_LABEL (asm_out_file, label);
1338 /* VMS PCA expects every PC range to correlate to some line and file. */
1339 vmsdbgout_source_line (line, file, 0, true);
1343 /* Output a marker (i.e. a label) for the beginning of the generated code for
1347 vmsdbgout_begin_block (register unsigned line, register unsigned blocknum)
1349 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1350 (*dwarf2_debug_hooks.begin_block) (line, blocknum);
1352 if (debug_info_level > DINFO_LEVEL_TERSE)
1353 targetm.asm_out.internal_label (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
1356 /* Output a marker (i.e. a label) for the end of the generated code for a
1360 vmsdbgout_end_block (register unsigned line, register unsigned blocknum)
1362 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1363 (*dwarf2_debug_hooks.end_block) (line, blocknum);
1365 if (debug_info_level > DINFO_LEVEL_TERSE)
1366 targetm.asm_out.internal_label (asm_out_file, BLOCK_END_LABEL, blocknum);
1369 /* Not implemented in VMS Debug. */
1372 vmsdbgout_ignore_block (const_tree block)
1376 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1377 retval = (*dwarf2_debug_hooks.ignore_block) (block);
1382 /* Add an entry for function DECL into the func_table. */
1385 vmsdbgout_begin_function (tree decl)
1387 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
1390 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1391 (*dwarf2_debug_hooks.begin_function) (decl);
1393 if (func_table_in_use == func_table_allocated)
1395 func_table_allocated += FUNC_TABLE_INCREMENT;
1397 = (vms_func_ref) xrealloc (func_table,
1398 func_table_allocated * sizeof (vms_func_node));
1401 /* Add the new entry to the end of the function name table. */
1402 fde = &func_table[func_table_in_use++];
1403 fde->vms_func_name = xstrdup (name);
1404 fde->funcdef_number = current_function_funcdef_no;
1408 static char fullname_buff [4096];
1410 /* Return the full file specification for FILENAME. The specification must be
1411 in VMS syntax in order to be processed by VMS Debug. */
1414 full_name (const char *filename)
1417 FILE *fp = fopen (filename, "r");
1419 fgetname (fp, fullname_buff, 1);
1422 getcwd (fullname_buff, sizeof (fullname_buff));
1424 strcat (fullname_buff, "/");
1425 strcat (fullname_buff, filename);
1427 /* ??? Insert hairy code here to translate Unix style file specification
1431 return fullname_buff;
1434 /* Lookup a filename (in the list of filenames that we know about here in
1435 vmsdbgout.c) and return its "index". The index of each (known) filename is
1436 just a unique number which is associated with only that one filename. We
1437 need such numbers for the sake of generating labels and references
1438 to those files numbers. If the filename given as an argument is not
1439 found in our current list, add it to the list and assign it the next
1440 available unique index number. In order to speed up searches, we remember
1441 the index of the filename was looked up last. This handles the majority of
1445 lookup_filename (const char *file_name)
1447 static unsigned int last_file_lookup_index = 0;
1449 register unsigned i;
1459 fnam = full_name (file_name);
1460 flen = strlen (fnam);
1462 /* Check to see if the file name that was searched on the previous call
1463 matches this file name. If so, return the index. */
1464 if (last_file_lookup_index != 0)
1466 fn = file_info_table[last_file_lookup_index].file_name;
1467 if (strcmp (fnam, fn) == 0)
1468 return last_file_lookup_index;
1471 /* Didn't match the previous lookup, search the table */
1472 for (i = 1; i < file_info_table_in_use; ++i)
1474 fn = file_info_table[i].file_name;
1475 if (strcmp (fnam, fn) == 0)
1477 last_file_lookup_index = i;
1482 /* Prepare to add a new table entry by making sure there is enough space in
1483 the table to do so. If not, expand the current table. */
1484 if (file_info_table_in_use == file_info_table_allocated)
1487 file_info_table_allocated += FILE_TABLE_INCREMENT;
1488 file_info_table = XRESIZEVEC (dst_file_info_entry, file_info_table,
1489 file_info_table_allocated);
1492 if (vms_file_stats_name (file_name, &cdt, &siz, &rfo, &ver) == 0)
1494 ebk = siz / 512 + 1;
1495 ffb = siz - ((siz / 512) * 512);
1498 /* Add the new entry to the end of the filename table. */
1499 file_info_table[file_info_table_in_use].file_name = xstrdup (fnam);
1500 file_info_table[file_info_table_in_use].max_line = 0;
1501 file_info_table[file_info_table_in_use].cdt = cdt;
1502 file_info_table[file_info_table_in_use].ebk = ebk;
1503 file_info_table[file_info_table_in_use].ffb = ffb;
1504 file_info_table[file_info_table_in_use].rfo = rfo;
1505 file_info_table[file_info_table_in_use].flen = flen;
1507 last_file_lookup_index = file_info_table_in_use++;
1508 return last_file_lookup_index;
1511 /* Output a label to mark the beginning of a source code line entry
1512 and record information relating to this source line, in
1513 'line_info_table' for later output of the .debug_line section. */
1516 vmsdbgout_source_line (register unsigned line, register const char *filename,
1517 int discriminator, bool is_stmt)
1519 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1520 (*dwarf2_debug_hooks.source_line) (line, filename, discriminator, is_stmt);
1522 if (debug_info_level >= DINFO_LEVEL_TERSE)
1524 dst_line_info_ref line_info;
1526 targetm.asm_out.internal_label (asm_out_file, LINE_CODE_LABEL,
1527 line_info_table_in_use);
1529 /* Expand the line info table if necessary. */
1530 if (line_info_table_in_use == line_info_table_allocated)
1532 line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
1533 line_info_table = XRESIZEVEC (dst_line_info_entry, line_info_table,
1534 line_info_table_allocated);
1537 /* Add the new entry at the end of the line_info_table. */
1538 line_info = &line_info_table[line_info_table_in_use++];
1539 line_info->dst_file_num = lookup_filename (filename);
1540 line_info->dst_line_num = line;
1541 if (line > file_info_table[line_info->dst_file_num].max_line)
1542 file_info_table[line_info->dst_file_num].max_line = line;
1546 /* Record the beginning of a new source file, for later output.
1547 At present, unimplemented. */
1550 vmsdbgout_start_source_file (unsigned int lineno, const char *filename)
1552 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1553 (*dwarf2_debug_hooks.start_source_file) (lineno, filename);
1556 /* Record the end of a source file, for later output.
1557 At present, unimplemented. */
1560 vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
1562 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1563 (*dwarf2_debug_hooks.end_source_file) (lineno);
1566 /* Set up for Debug output at the start of compilation. */
1569 vmsdbgout_init (const char *main_input_filename)
1571 const char *language_string = lang_hooks.name;
1573 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1574 (*dwarf2_debug_hooks.init) (main_input_filename);
1576 if (debug_info_level == DINFO_LEVEL_NONE)
1579 /* Remember the name of the primary input file. */
1580 primary_filename = main_input_filename;
1582 /* Allocate the initial hunk of the file_info_table. */
1583 file_info_table = XCNEWVEC (dst_file_info_entry, FILE_TABLE_INCREMENT);
1584 file_info_table_allocated = FILE_TABLE_INCREMENT;
1586 /* Skip the first entry - file numbers begin at 1 */
1587 file_info_table_in_use = 1;
1589 func_table = (vms_func_ref) xcalloc (FUNC_TABLE_INCREMENT, sizeof (vms_func_node));
1590 func_table_allocated = FUNC_TABLE_INCREMENT;
1591 func_table_in_use = 1;
1593 /* Allocate the initial hunk of the line_info_table. */
1594 line_info_table = XCNEWVEC (dst_line_info_entry, LINE_INFO_TABLE_INCREMENT);
1595 line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
1596 /* zero-th entry is allocated, but unused */
1597 line_info_table_in_use = 1;
1599 lookup_filename (primary_filename);
1601 if (!strcmp (language_string, "GNU C"))
1602 module_language = DST_K_C;
1603 else if (!strcmp (language_string, "GNU C++"))
1604 module_language = DST_K_CXX;
1605 else if (!strcmp (language_string, "GNU Ada"))
1606 module_language = DST_K_ADA;
1607 else if (!strcmp (language_string, "GNU F77"))
1608 module_language = DST_K_FORTRAN;
1610 module_language = DST_K_UNKNOWN;
1612 module_producer = concat (language_string, " ", version_string, NULL);
1614 ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
1618 /* Not implemented in VMS Debug. */
1621 vmsdbgout_define (unsigned int lineno, const char *buffer)
1623 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1624 (*dwarf2_debug_hooks.define) (lineno, buffer);
1627 /* Not implemented in VMS Debug. */
1630 vmsdbgout_undef (unsigned int lineno, const char *buffer)
1632 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1633 (*dwarf2_debug_hooks.undef) (lineno, buffer);
1636 /* Not implemented in VMS Debug. */
1639 vmsdbgout_decl (tree decl)
1641 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1642 (*dwarf2_debug_hooks.function_decl) (decl);
1645 /* Not implemented in VMS Debug. */
1648 vmsdbgout_global_decl (tree decl)
1650 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1651 (*dwarf2_debug_hooks.global_decl) (decl);
1654 /* Not implemented in VMS Debug. */
1657 vmsdbgout_abstract_function (tree decl)
1659 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1660 (*dwarf2_debug_hooks.outlining_inline_function) (decl);
1663 /* Output stuff that Debug requires at the end of every file and generate the
1664 VMS Debug debugging info. */
1667 vmsdbgout_finish (const char *main_input_filename ATTRIBUTE_UNUSED)
1672 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1673 (*dwarf2_debug_hooks.finish) (main_input_filename);
1675 if (debug_info_level == DINFO_LEVEL_NONE)
1678 /* Output a terminator label for the .text section. */
1679 switch_to_section (text_section);
1680 targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
1682 /* Output debugging information.
1683 Warning! Do not change the name of the .vmsdebug section without
1684 changing it in the assembler also. */
1685 switch_to_section (get_named_section (NULL, ".vmsdebug", 0));
1686 ASM_OUTPUT_ALIGN (asm_out_file, 0);
1688 totsize = write_modbeg (1);
1689 for (i = 1; i < func_table_in_use; i++)
1691 totsize += write_rtnbeg (i, 1);
1692 totsize += write_rtnend (i, 1);
1694 totsize += write_pclines (1);
1697 for (i = 1; i < func_table_in_use; i++)
1699 write_rtnbeg (i, 0);
1700 write_rtnend (i, 0);
1704 if (debug_info_level > DINFO_LEVEL_TERSE)
1706 totsize = write_srccorrs (1);
1710 totsize = write_modend (1);
1714 /* Need for both Dwarf2 on IVMS and VMS Debug on AVMS */
1717 #define __NEW_STARLET 1
1718 #include <vms/rms.h>
1719 #include <vms/atrdef.h>
1720 #include <vms/fibdef.h>
1721 #include <vms/stsdef.h>
1722 #include <vms/iodef.h>
1723 #include <vms/fatdef.h>
1725 #include <vms/descrip.h>
1727 #include <unixlib.h>
1731 /* descrip.h doesn't have everything ... */
1732 typedef struct fibdef* __fibdef_ptr32 __attribute__ (( mode (SI) ));
1733 struct dsc$descriptor_fib
1735 unsigned int fib$l_len;
1736 __fibdef_ptr32 fib$l_addr;
1739 /* I/O Status Block. */
1742 unsigned short status, count;
1743 unsigned int devdep;
1746 static char *tryfile;
1748 /* Variable length string. */
1752 char string[NAM$C_MAXRSS+1];
1755 static char filename_buff [MAXPATH];
1756 static char vms_filespec [MAXPATH];
1758 /* Callback function for filespec style conversion. */
1761 translate_unix (char *name, int type ATTRIBUTE_UNUSED)
1763 strncpy (filename_buff, name, MAXPATH);
1764 filename_buff [MAXPATH - 1] = (char) 0;
1768 /* Wrapper for DECC function that converts a Unix filespec
1769 to VMS style filespec. */
1772 to_vms_file_spec (char *filespec)
1774 strncpy (vms_filespec, "", MAXPATH);
1775 decc$to_vms (filespec, translate_unix, 1, 1);
1776 strncpy (vms_filespec, filename_buff, MAXPATH);
1778 vms_filespec [MAXPATH - 1] = (char) 0;
1780 return vms_filespec;
1784 #define VMS_EPOCH_OFFSET 35067168000000000
1785 #define VMS_GRANULARITY_FACTOR 10000000
1788 /* Return VMS file date, size, format, version given a name. */
1791 vms_file_stats_name (const char *filename, long long *cdt, long *siz, char *rfo,
1798 unsigned long long create;
1800 char ascnamebuff [256];
1804 { ATR$S_CREDATE, ATR$C_CREDATE, &create },
1805 { ATR$S_RECATTR, ATR$C_RECATTR, &recattr },
1806 { ATR$S_ASCNAME, ATR$C_ASCNAME, &ascnamebuff },
1811 struct dsc$descriptor_fib fibdsc = {sizeof (fib), (void *) &fib};
1816 unsigned short chan;
1818 struct vstring file;
1819 struct dsc$descriptor_s filedsc
1820 = {NAM$C_MAXRSS, DSC$K_DTYPE_T, DSC$K_CLASS_S, (void *) file.string};
1821 struct vstring device;
1822 struct dsc$descriptor_s devicedsc
1823 = {NAM$C_MAXRSS, DSC$K_DTYPE_T, DSC$K_CLASS_S, (void *) device.string};
1824 struct vstring result;
1825 struct dsc$descriptor_s resultdsc
1826 = {NAM$C_MAXRSS, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, (void *) result.string};
1828 if (strcmp (filename, "<internal>") == 0
1829 || strcmp (filename, "<built-in>") == 0)
1846 tryfile = to_vms_file_spec (filename);
1848 /* Allocate and initialize a FAB and NAM structures. */
1852 nam.nam$l_esa = file.string;
1853 nam.nam$b_ess = NAM$C_MAXRSS;
1854 nam.nam$l_rsa = result.string;
1855 nam.nam$b_rss = NAM$C_MAXRSS;
1856 fab.fab$l_fna = tryfile;
1857 fab.fab$b_fns = strlen (tryfile);
1858 fab.fab$l_nam = &nam;
1860 /* Validate filespec syntax and device existence. */
1861 status = SYS$PARSE (&fab, 0, 0);
1862 if ((status & 1) != 1)
1865 file.string[nam.nam$b_esl] = 0;
1867 /* Find matching filespec. */
1868 status = SYS$SEARCH (&fab, 0, 0);
1869 if ((status & 1) != 1)
1872 file.string[nam.nam$b_esl] = 0;
1873 result.string[result.length=nam.nam$b_rsl] = 0;
1875 /* Get the device name and assign an IO channel. */
1876 strncpy (device.string, nam.nam$l_dev, nam.nam$b_dev);
1877 devicedsc.dsc$w_length = nam.nam$b_dev;
1879 status = SYS$ASSIGN (&devicedsc, &chan, 0, 0, 0);
1880 if ((status & 1) != 1)
1883 /* Initialize the FIB and fill in the directory id field. */
1884 memset (&fib, 0, sizeof (fib));
1885 fib.fib$w_did[0] = nam.nam$w_did[0];
1886 fib.fib$w_did[1] = nam.nam$w_did[1];
1887 fib.fib$w_did[2] = nam.nam$w_did[2];
1888 fib.fib$l_acctl = 0;
1890 strcpy (file.string, (strrchr (result.string, ']') + 1));
1891 filedsc.dsc$w_length = strlen (file.string);
1892 result.string[result.length = 0] = 0;
1894 /* Open and close the file to fill in the attributes. */
1896 = SYS$QIOW (0, chan, IO$_ACCESS|IO$M_ACCESS, &iosb, 0, 0,
1897 &fibdsc, &filedsc, &result.length, &resultdsc, &atrlst, 0);
1898 if ((status & 1) != 1)
1900 if ((iosb.status & 1) != 1)
1903 result.string[result.length] = 0;
1904 status = SYS$QIOW (0, chan, IO$_DEACCESS, &iosb, 0, 0, &fibdsc, 0, 0, 0,
1906 if ((status & 1) != 1)
1908 if ((iosb.status & 1) != 1)
1911 /* Deassign the channel and exit. */
1912 status = SYS$DASSGN (chan);
1913 if ((status & 1) != 1)
1916 if (cdt) *cdt = create;
1917 if (siz) *siz = (512 * 65536 * recattr.fat$w_efblkh) +
1918 (512 * (recattr.fat$w_efblkl - 1)) +
1919 recattr.fat$w_ffbyte;
1920 if (rfo) *rfo = recattr.fat$v_rtype;
1921 if (ver) *ver = strtol (strrchr (ascnamebuff, ';')+1, 0, 10);
1927 if ((stat (filename, &buff)) != 0)
1931 *cdt = (long long) (buff.st_mtime * VMS_GRANULARITY_FACTOR)
1935 *siz = buff.st_size;
1938 *rfo = 2; /* Stream LF format */