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 Free Software Foundation, Inc.
4 Contributed by Douglas B. Rupp (rupp@gnat.com).
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 #include "coretypes.h"
28 #ifdef VMS_DEBUGGING_INFO
35 #include "langhooks.h"
39 /* Difference in seconds between the VMS Epoch and the Unix Epoch */
40 static const long long vms_epoch_offset = 3506716800ll;
42 /* NOTE: In the comments in this file, many references are made to "Debug
43 Symbol Table". This term is abbreviated as `DST' throughout the remainder
46 typedef struct dst_line_info_struct *dst_line_info_ref;
48 /* Each entry in the line_info_table maintains the file and
49 line number associated with the label generated for that
50 entry. The label gives the PC value associated with
51 the line number entry. */
52 typedef struct dst_line_info_struct
54 unsigned long dst_file_num;
55 unsigned long dst_line_num;
59 typedef struct dst_file_info_struct *dst_file_info_ref;
61 typedef struct dst_file_info_struct
64 unsigned int max_line;
65 unsigned int listing_line_start;
74 /* How to start an assembler comment. */
75 #ifndef ASM_COMMENT_START
76 #define ASM_COMMENT_START ";#"
79 /* Maximum size (in bytes) of an artificially generated label. */
80 #define MAX_ARTIFICIAL_LABEL_BYTES 30
82 /* Make sure we know the sizes of the various types debug can describe. These
83 are only defaults. If the sizes are different for your target, you should
84 override these values by defining the appropriate symbols in your tm.h
87 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
90 /* Pointer to a structure of filenames referenced by this compilation unit. */
91 static dst_file_info_ref file_info_table;
93 /* Total number of entries in the table (i.e. array) pointed to by
94 `file_info_table'. This is the *total* and includes both used and unused
96 static unsigned int file_info_table_allocated;
98 /* Number of entries in the file_info_table which are actually in use. */
99 static unsigned int file_info_table_in_use;
101 /* Size (in elements) of increments by which we may expand the filename
103 #define FILE_TABLE_INCREMENT 64
105 static char **func_table;
106 static unsigned int func_table_allocated;
107 static unsigned int func_table_in_use;
108 #define FUNC_TABLE_INCREMENT 256
110 /* Local pointer to the name of the main input file. Initialized in
112 static const char *primary_filename;
114 static char *module_producer;
115 static unsigned int module_language;
117 /* A pointer to the base of a table that contains line information
118 for each source code line in .text in the compilation unit. */
119 static dst_line_info_ref line_info_table;
121 /* Number of elements currently allocated for line_info_table. */
122 static unsigned int line_info_table_allocated;
124 /* Number of elements in line_info_table currently in use. */
125 static unsigned int line_info_table_in_use;
127 /* Size (in elements) of increments by which we may expand line_info_table. */
128 #define LINE_INFO_TABLE_INCREMENT 1024
130 /* Forward declarations for functions defined in this file. */
131 static char *full_name (const char *);
132 static unsigned int lookup_filename (const char *);
133 static void addr_const_to_string (char *, rtx);
134 static int write_debug_header (DST_HEADER *, const char *, int);
135 static int write_debug_addr (char *, const char *, int);
136 static int write_debug_data1 (unsigned int, const char *, int);
137 static int write_debug_data2 (unsigned int, const char *, int);
138 static int write_debug_data4 (unsigned long, const char *, int);
139 static int write_debug_data8 (unsigned long long, const char *, int);
140 static int write_debug_delta4 (char *, char *, const char *, int);
141 static int write_debug_string (char *, const char *, int);
142 static int write_modbeg (int);
143 static int write_modend (int);
144 static int write_rtnbeg (int, int);
145 static int write_rtnend (int, int);
146 static int write_pclines (int);
147 static int write_srccorr (int, dst_file_info_entry, int);
148 static int write_srccorrs (int);
150 static void vmsdbgout_init (const char *);
151 static void vmsdbgout_finish (const char *);
152 static void vmsdbgout_define (unsigned int, const char *);
153 static void vmsdbgout_undef (unsigned int, const char *);
154 static void vmsdbgout_start_source_file (unsigned int, const char *);
155 static void vmsdbgout_end_source_file (unsigned int);
156 static void vmsdbgout_begin_block (unsigned int, unsigned int);
157 static void vmsdbgout_end_block (unsigned int, unsigned int);
158 static bool vmsdbgout_ignore_block (tree);
159 static void vmsdbgout_source_line (unsigned int, const char *);
160 static void vmsdbgout_begin_prologue (unsigned int, const char *);
161 static void vmsdbgout_end_prologue (unsigned int, const char *);
162 static void vmsdbgout_end_function (unsigned int);
163 static void vmsdbgout_end_epilogue (unsigned int, const char *);
164 static void vmsdbgout_begin_function (tree);
165 static void vmsdbgout_decl (tree);
166 static void vmsdbgout_global_decl (tree);
167 static void vmsdbgout_abstract_function (tree);
169 /* The debug hooks structure. */
171 const struct gcc_debug_hooks vmsdbg_debug_hooks
176 vmsdbgout_start_source_file,
177 vmsdbgout_end_source_file,
178 vmsdbgout_begin_block,
180 vmsdbgout_ignore_block,
181 vmsdbgout_source_line,
182 vmsdbgout_begin_prologue,
183 vmsdbgout_end_prologue,
184 vmsdbgout_end_epilogue,
185 vmsdbgout_begin_function,
186 vmsdbgout_end_function,
188 vmsdbgout_global_decl,
189 debug_nothing_tree_tree, /* imported_module_or_decl */
190 debug_nothing_tree, /* deferred_inline_function */
191 vmsdbgout_abstract_function,
192 debug_nothing_rtx, /* label */
193 debug_nothing_int, /* handle_pch */
194 debug_nothing_rtx /* var_location */
197 /* Definitions of defaults for assembler-dependent names of various
198 pseudo-ops and section names.
199 Theses may be overridden in the tm.h file (if necessary) for a particular
201 #ifdef UNALIGNED_SHORT_ASM_OP
202 #undef UNALIGNED_SHORT_ASM_OP
204 #define UNALIGNED_SHORT_ASM_OP ".word"
206 #ifdef UNALIGNED_INT_ASM_OP
207 #undef UNALIGNED_INT_ASM_OP
209 #define UNALIGNED_INT_ASM_OP ".long"
211 #ifdef UNALIGNED_LONG_ASM_OP
212 #undef UNALIGNED_LONG_ASM_OP
214 #define UNALIGNED_LONG_ASM_OP ".long"
216 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
217 #undef UNALIGNED_DOUBLE_INT_ASM_OP
219 #define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
224 #define ASM_BYTE_OP ".byte"
226 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
228 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
230 #ifndef UNALIGNED_PTR_ASM_OP
231 #define UNALIGNED_PTR_ASM_OP \
232 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
235 #ifndef UNALIGNED_OFFSET_ASM_OP
236 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
237 (NUMBYTES(OFFSET) == 4 \
238 ? UNALIGNED_LONG_ASM_OP \
239 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
242 /* Definitions of defaults for formats and names of various special
243 (artificial) labels which may be generated within this file (when the -g
244 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
245 may be overridden from within the tm.h file, but typically, overriding these
246 defaults is unnecessary. */
248 static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
250 #ifndef TEXT_END_LABEL
251 #define TEXT_END_LABEL "Lvetext"
253 #ifndef FUNC_BEGIN_LABEL
254 #define FUNC_BEGIN_LABEL "LVFB"
256 #ifndef FUNC_PROLOG_LABEL
257 #define FUNC_PROLOG_LABEL "LVFP"
259 #ifndef FUNC_END_LABEL
260 #define FUNC_END_LABEL "LVFE"
262 #ifndef BLOCK_BEGIN_LABEL
263 #define BLOCK_BEGIN_LABEL "LVBB"
265 #ifndef BLOCK_END_LABEL
266 #define BLOCK_END_LABEL "LVBE"
268 #ifndef LINE_CODE_LABEL
269 #define LINE_CODE_LABEL "LVM"
272 #ifndef ASM_OUTPUT_DEBUG_DELTA2
273 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
276 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
277 assemble_name (FILE, LABEL1); \
278 fprintf (FILE, "-"); \
279 assemble_name (FILE, LABEL2); \
284 #ifndef ASM_OUTPUT_DEBUG_DELTA4
285 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
288 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
289 assemble_name (FILE, LABEL1); \
290 fprintf (FILE, "-"); \
291 assemble_name (FILE, LABEL2); \
296 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
297 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
300 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
301 assemble_name (FILE, LABEL1); \
302 fprintf (FILE, "-"); \
303 assemble_name (FILE, LABEL2); \
308 #ifndef ASM_OUTPUT_DEBUG_ADDR
309 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
312 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
313 assemble_name (FILE, LABEL); \
318 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
319 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
320 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
323 #ifndef ASM_OUTPUT_DEBUG_DATA1
324 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
325 fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned char) VALUE)
328 #ifndef ASM_OUTPUT_DEBUG_DATA2
329 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
330 fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, \
331 (unsigned short) VALUE)
334 #ifndef ASM_OUTPUT_DEBUG_DATA4
335 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
336 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
339 #ifndef ASM_OUTPUT_DEBUG_DATA
340 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
341 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
344 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
345 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
346 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_PTR_ASM_OP, \
347 (unsigned long) VALUE)
350 #ifndef ASM_OUTPUT_DEBUG_DATA8
351 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
352 fprintf ((FILE), "\t%s\t0x%llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
353 (unsigned long long) VALUE)
356 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
357 newline is produced. When flag_verbose_asm is asserted, we add commentary
358 at the end of the line, so we must avoid output of a newline here. */
359 #ifndef ASM_OUTPUT_DEBUG_STRING
360 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
363 register int slen = strlen(P); \
364 register char *p = (P); \
366 fprintf (FILE, "\t.ascii \""); \
367 for (i = 0; i < slen; i++) \
369 register int c = p[i]; \
370 if (c == '\"' || c == '\\') \
372 if (c >= ' ' && c < 0177) \
375 fprintf (FILE, "\\%o", c); \
377 fprintf (FILE, "\""); \
382 /* Convert a reference to the assembler name of a C-level name. This
383 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
384 a string rather than writing to a file. */
385 #ifndef ASM_NAME_TO_STRING
386 #define ASM_NAME_TO_STRING(STR, NAME) \
389 if ((NAME)[0] == '*') \
390 strcpy (STR, NAME+1); \
392 strcpy (STR, NAME); \
398 /* General utility functions. */
400 /* Convert an integer constant expression into assembler syntax. Addition and
401 subtraction are the only arithmetic that may appear in these expressions.
402 This is an adaptation of output_addr_const in final.c. Here, the target
403 of the conversion is a string buffer. We can't use output_addr_const
404 directly, because it writes to a file. */
407 addr_const_to_string (char *str, rtx x)
414 switch (GET_CODE (x))
424 ASM_NAME_TO_STRING (buf1, XSTR (x, 0));
429 ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
430 ASM_NAME_TO_STRING (buf2, buf1);
435 ASM_GENERATE_INTERNAL_LABEL (buf1, "L", CODE_LABEL_NUMBER (x));
436 ASM_NAME_TO_STRING (buf2, buf1);
441 sprintf (buf1, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
446 /* This used to output parentheses around the expression, but that does
447 not work on the 386 (either ATT or BSD assembler). */
448 addr_const_to_string (buf1, XEXP (x, 0));
453 if (GET_MODE (x) == VOIDmode)
455 /* We can use %d if the number is one word and positive. */
456 if (CONST_DOUBLE_HIGH (x))
457 sprintf (buf1, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
458 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
459 else if (CONST_DOUBLE_LOW (x) < 0)
460 sprintf (buf1, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
462 sprintf (buf1, HOST_WIDE_INT_PRINT_DEC,
463 CONST_DOUBLE_LOW (x));
467 /* We can't handle floating point constants; PRINT_OPERAND must
469 output_operand_lossage ("floating constant misused");
473 /* Some assemblers need integer constants to appear last (eg masm). */
474 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
476 addr_const_to_string (buf1, XEXP (x, 1));
478 if (INTVAL (XEXP (x, 0)) >= 0)
480 addr_const_to_string (buf1, XEXP (x, 0));
485 addr_const_to_string (buf1, XEXP (x, 0));
487 if (INTVAL (XEXP (x, 1)) >= 0)
489 addr_const_to_string (buf1, XEXP (x, 1));
495 /* Avoid outputting things like x-x or x+5-x, since some assemblers
496 can't handle that. */
497 x = simplify_subtraction (x);
498 if (GET_CODE (x) != MINUS)
501 addr_const_to_string (buf1, XEXP (x, 0));
504 if (GET_CODE (XEXP (x, 1)) == CONST_INT
505 && INTVAL (XEXP (x, 1)) < 0)
508 addr_const_to_string (buf1, XEXP (x, 1));
514 addr_const_to_string (buf1, XEXP (x, 1));
521 addr_const_to_string (buf1, XEXP (x, 0));
526 output_operand_lossage ("invalid expression as operand");
530 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
531 set. Return the header size. Just return the size if DOSIZEONLY is
535 write_debug_header (DST_HEADER *header, const char *comment, int dosizeonly)
539 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
540 header->dst__header_length.dst_w_length);
542 if (flag_verbose_asm)
543 fprintf (asm_out_file, "\t%s record length", ASM_COMMENT_START);
544 fputc ('\n', asm_out_file);
546 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
547 header->dst__header_type.dst_w_type);
549 if (flag_verbose_asm)
550 fprintf (asm_out_file, "\t%s record type (%s)", ASM_COMMENT_START,
553 fputc ('\n', asm_out_file);
559 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
560 set. Return the address size. Just return the size if DOSIZEONLY is
564 write_debug_addr (char *symbol, const char *comment, int dosizeonly)
568 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, symbol);
569 if (flag_verbose_asm)
570 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
571 fputc ('\n', asm_out_file);
577 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
578 set. Return the data size. Just return the size if DOSIZEONLY is
582 write_debug_data1 (unsigned int data1, const char *comment, int dosizeonly)
586 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file, data1);
587 if (flag_verbose_asm)
588 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
589 fputc ('\n', asm_out_file);
595 /* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
596 set. Return the data size. Just return the size if DOSIZEONLY is
600 write_debug_data2 (unsigned int data2, const char *comment, int dosizeonly)
604 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file, data2);
605 if (flag_verbose_asm)
606 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
607 fputc ('\n', asm_out_file);
613 /* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
614 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
617 write_debug_data4 (unsigned long data4, const char *comment, int dosizeonly)
621 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file, data4);
622 if (flag_verbose_asm)
623 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
624 fputc ('\n', asm_out_file);
630 /* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
631 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
634 write_debug_data8 (unsigned long long data8, const char *comment,
639 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file, data8);
640 if (flag_verbose_asm)
641 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
642 fputc ('\n', asm_out_file);
648 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
649 flag_verbose_asm is set. Return the data size. Just return the size if
650 DOSIZEONLY is nonzero. */
653 write_debug_delta4 (char *label1, char *label2, const char *comment,
658 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file, label1, label2);
659 if (flag_verbose_asm)
660 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
661 fputc ('\n', asm_out_file);
667 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
668 set. Return the string length. Just return the length if DOSIZEONLY is
672 write_debug_string (char *string, const char *comment, int dosizeonly)
676 ASM_OUTPUT_DEBUG_STRING (asm_out_file, string);
677 if (flag_verbose_asm)
678 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
679 fputc ('\n', asm_out_file);
682 return strlen (string);
685 /* Output a module begin header and return the header size. Just return the
686 size if DOSIZEONLY is nonzero. */
689 write_modbeg (int dosizeonly)
691 DST_MODULE_BEGIN modbeg;
694 char *module_name, *m;
699 /* Assumes primary filename has Unix syntax file spec. */
700 module_name = xstrdup (basename ((char *) primary_filename));
702 m = strrchr (module_name, '.');
706 modnamelen = strlen (module_name);
707 for (i = 0; i < modnamelen; i++)
708 module_name[i] = TOUPPER (module_name[i]);
710 prodnamelen = strlen (module_producer);
712 modbeg.dst_a_modbeg_header.dst__header_length.dst_w_length
713 = DST_K_MODBEG_SIZE + modnamelen + DST_K_MB_TRLR_SIZE + prodnamelen - 1;
714 modbeg.dst_a_modbeg_header.dst__header_type.dst_w_type = DST_K_MODBEG;
715 modbeg.dst_b_modbeg_flags.dst_v_modbeg_hide = 0;
716 modbeg.dst_b_modbeg_flags.dst_v_modbeg_version = 1;
717 modbeg.dst_b_modbeg_flags.dst_v_modbeg_unused = 0;
718 modbeg.dst_b_modbeg_unused = 0;
719 modbeg.dst_l_modbeg_language = module_language;
720 modbeg.dst_w_version_major = DST_K_VERSION_MAJOR;
721 modbeg.dst_w_version_minor = DST_K_VERSION_MINOR;
722 modbeg.dst_b_modbeg_name = strlen (module_name);
724 mb_trlr.dst_b_compiler = strlen (module_producer);
726 totsize += write_debug_header (&modbeg.dst_a_modbeg_header,
727 "modbeg", dosizeonly);
728 totsize += write_debug_data1 (*((char *) &modbeg.dst_b_modbeg_flags),
729 "flags", dosizeonly);
730 totsize += write_debug_data1 (modbeg.dst_b_modbeg_unused,
731 "unused", dosizeonly);
732 totsize += write_debug_data4 (modbeg.dst_l_modbeg_language,
733 "language", dosizeonly);
734 totsize += write_debug_data2 (modbeg.dst_w_version_major,
735 "DST major version", dosizeonly);
736 totsize += write_debug_data2 (modbeg.dst_w_version_minor,
737 "DST minor version", dosizeonly);
738 totsize += write_debug_data1 (modbeg.dst_b_modbeg_name,
739 "length of module name", dosizeonly);
740 totsize += write_debug_string (module_name, "module name", dosizeonly);
741 totsize += write_debug_data1 (mb_trlr.dst_b_compiler,
742 "length of compiler name", dosizeonly);
743 totsize += write_debug_string (module_producer, "compiler name", dosizeonly);
748 /* Output a module end trailer and return the trailer size. Just return
749 the size if DOSIZEONLY is nonzero. */
752 write_modend (int dosizeonly)
754 DST_MODULE_END modend;
757 modend.dst_a_modend_header.dst__header_length.dst_w_length
758 = DST_K_MODEND_SIZE - 1;
759 modend.dst_a_modend_header.dst__header_type.dst_w_type = DST_K_MODEND;
761 totsize += write_debug_header (&modend.dst_a_modend_header, "modend",
767 /* Output a routine begin header routine RTNNUM and return the header size.
768 Just return the size if DOSIZEONLY is nonzero. */
771 write_rtnbeg (int rtnnum, int dosizeonly)
777 char label[MAX_ARTIFICIAL_LABEL_BYTES];
778 DST_ROUTINE_BEGIN rtnbeg;
781 rtnname = func_table[rtnnum];
782 rtnnamelen = strlen (rtnname);
783 rtnentryname = concat (rtnname, "..en", NULL);
785 if (!strcmp (rtnname, "main"))
788 const char *go = "TRANSFER$BREAK$GO";
790 /* This command isn't documented in DSTRECORDS, so it's made to
791 look like what DEC C does */
793 /* header size - 1st byte + flag byte + STO_LW size
794 + string count byte + string length */
795 header.dst__header_length.dst_w_length
796 = DST_K_DST_HEADER_SIZE - 1 + 1 + 4 + 1 + strlen (go);
797 header.dst__header_type.dst_w_type = 0x17;
799 totsize += write_debug_header (&header, "transfer", dosizeonly);
801 /* I think this is a flag byte, but I don't know what this flag means */
802 totsize += write_debug_data1 (0x1, "flags ???", dosizeonly);
804 /* Routine Begin PD Address */
805 totsize += write_debug_addr (rtnname, "main procedure descriptor",
807 totsize += write_debug_data1 (strlen (go), "length of main_name",
809 totsize += write_debug_string ((char *) go, "main name", dosizeonly);
812 /* The header length never includes the length byte. */
813 rtnbeg.dst_a_rtnbeg_header.dst__header_length.dst_w_length
814 = DST_K_RTNBEG_SIZE + rtnnamelen - 1;
815 rtnbeg.dst_a_rtnbeg_header.dst__header_type.dst_w_type = DST_K_RTNBEG;
816 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unused = 0;
817 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unalloc = 0;
818 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_prototype = 0;
819 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_inlined = 0;
820 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_no_call = 1;
821 rtnbeg.dst_b_rtnbeg_name = rtnnamelen;
823 totsize += write_debug_header (&rtnbeg.dst_a_rtnbeg_header, "rtnbeg",
825 totsize += write_debug_data1 (*((char *) &rtnbeg.dst_b_rtnbeg_flags),
826 "flags", dosizeonly);
828 /* Routine Begin Address */
829 totsize += write_debug_addr (rtnentryname, "routine entry name", dosizeonly);
831 /* Routine Begin PD Address */
832 totsize += write_debug_addr (rtnname, "routine procedure descriptor",
835 /* Routine Begin Name */
836 totsize += write_debug_data1 (rtnbeg.dst_b_rtnbeg_name,
837 "length of routine name", dosizeonly);
839 totsize += write_debug_string (rtnname, "routine name", dosizeonly);
843 if (debug_info_level > DINFO_LEVEL_TERSE)
845 prolog.dst_a_prolog_header.dst__header_length.dst_w_length
846 = DST_K_PROLOG_SIZE - 1;
847 prolog.dst_a_prolog_header.dst__header_type.dst_w_type = DST_K_PROLOG;
849 totsize += write_debug_header (&prolog.dst_a_prolog_header, "prolog",
852 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL, rtnnum);
853 totsize += write_debug_addr (label, "prolog breakpoint addr",
860 /* Output a routine end trailer for routine RTNNUM and return the header size.
861 Just return the size if DOSIZEONLY is nonzero. */
864 write_rtnend (int rtnnum, int dosizeonly)
866 DST_ROUTINE_END rtnend;
867 char label1[MAX_ARTIFICIAL_LABEL_BYTES];
868 char label2[MAX_ARTIFICIAL_LABEL_BYTES];
873 rtnend.dst_a_rtnend_header.dst__header_length.dst_w_length
874 = DST_K_RTNEND_SIZE - 1;
875 rtnend.dst_a_rtnend_header.dst__header_type.dst_w_type = DST_K_RTNEND;
876 rtnend.dst_b_rtnend_unused = 0;
877 rtnend.dst_l_rtnend_size = 0; /* Calculated below. */
879 totsize += write_debug_header (&rtnend.dst_a_rtnend_header, "rtnend",
881 totsize += write_debug_data1 (rtnend.dst_b_rtnend_unused, "unused",
884 ASM_GENERATE_INTERNAL_LABEL (label1, FUNC_BEGIN_LABEL, rtnnum);
885 ASM_GENERATE_INTERNAL_LABEL (label2, FUNC_END_LABEL, rtnnum);
886 totsize += write_debug_delta4 (label2, label1, "routine size", dosizeonly);
891 #define K_DELTA_PC(I) \
892 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
894 #define K_SET_LINUM(I) \
895 ((I) < 256 ? DST_K_SET_LINUM_B \
896 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
898 #define K_INCR_LINUM(I) \
899 ((I) < 256 ? DST_K_INCR_LINUM \
900 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
902 /* Output the PC to line number correlations and return the size. Just return
903 the size if DOSIZEONLY is nonzero */
906 write_pclines (int dosizeonly)
913 DST_LINE_NUM_HEADER line_num;
914 DST_PCLINE_COMMANDS pcline;
915 char label[MAX_ARTIFICIAL_LABEL_BYTES];
916 char lastlabel[MAX_ARTIFICIAL_LABEL_BYTES];
920 max_line = file_info_table[1].max_line;
921 file_info_table[1].listing_line_start = linestart;
922 linestart = linestart + ((max_line / 100000) + 1) * 100000;
924 for (i = 2; i < file_info_table_in_use; i++)
926 max_line = file_info_table[i].max_line;
927 file_info_table[i].listing_line_start = linestart;
928 linestart = linestart + ((max_line / 10000) + 1) * 10000;
931 /* Set starting address to beginning of text section. */
932 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 8;
933 line_num.dst_a_line_num_header.dst__header_type.dst_w_type = DST_K_LINE_NUM;
934 pcline.dst_b_pcline_command = DST_K_SET_ABS_PC;
936 totsize += write_debug_header (&line_num.dst_a_line_num_header,
937 "line_num", dosizeonly);
938 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
939 "line_num (SET ABS PC)", dosizeonly);
945 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, TEXT_SECTION_ASM_OP);
946 if (flag_verbose_asm)
947 fprintf (asm_out_file, "\t%s line_num", ASM_COMMENT_START);
948 fputc ('\n', asm_out_file);
951 fn = line_info_table[1].dst_file_num;
952 ln = (file_info_table[fn].listing_line_start
953 + line_info_table[1].dst_line_num);
954 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 4 + 4;
955 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
957 totsize += write_debug_header (&line_num.dst_a_line_num_header,
958 "line_num", dosizeonly);
959 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
960 "line_num (SET LINUM LONG)", dosizeonly);
962 sprintf (buff, "line_num (%d)", ln ? ln - 1 : 0);
963 totsize += write_debug_data4 (ln ? ln - 1 : 0, buff, dosizeonly);
966 strcpy (lastlabel, TEXT_SECTION_ASM_OP);
967 for (i = 1; i < line_info_table_in_use; i++)
971 fn = line_info_table[i].dst_file_num;
972 ln = (file_info_table[fn].listing_line_start
973 + line_info_table[i].dst_line_num);
976 extrabytes = 5; /* NUMBYTES (ln - lastln - 1) + 1; */
977 else if (ln <= lastln)
978 extrabytes = 5; /* NUMBYTES (ln - 1) + 1; */
982 line_num.dst_a_line_num_header.dst__header_length.dst_w_length
985 totsize += write_debug_header
986 (&line_num.dst_a_line_num_header, "line_num", dosizeonly);
990 int lndif = ln - lastln - 1;
992 /* K_INCR_LINUM (lndif); */
993 pcline.dst_b_pcline_command = DST_K_INCR_LINUM_L;
995 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
996 "line_num (INCR LINUM LONG)",
999 sprintf (buff, "line_num (%d)", lndif);
1000 totsize += write_debug_data4 (lndif, buff, dosizeonly);
1002 else if (ln <= lastln)
1004 /* K_SET_LINUM (ln-1); */
1005 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
1007 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
1008 "line_num (SET LINUM LONG)",
1011 sprintf (buff, "line_num (%d)", ln - 1);
1012 totsize += write_debug_data4 (ln - 1, buff, dosizeonly);
1015 pcline.dst_b_pcline_command = DST_K_DELTA_PC_L;
1017 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
1018 "line_num (DELTA PC LONG)", dosizeonly);
1020 ASM_GENERATE_INTERNAL_LABEL (label, LINE_CODE_LABEL, i);
1021 totsize += write_debug_delta4 (label, lastlabel, "increment line_num",
1025 strcpy (lastlabel, label);
1031 /* Output a source correlation for file FILEID using information saved in
1032 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
1036 write_srccorr (int fileid, dst_file_info_entry file_info_entry,
1039 int src_command_size;
1040 int linesleft = file_info_entry.max_line;
1041 int linestart = file_info_entry.listing_line_start;
1042 int flen = file_info_entry.flen;
1044 DST_SOURCE_CORR src_header;
1045 DST_SRC_COMMAND src_command;
1046 DST_SRC_COMMAND src_command_sf;
1047 DST_SRC_COMMAND src_command_sl;
1048 DST_SRC_COMMAND src_command_sr;
1049 DST_SRC_COMMAND src_command_dl;
1050 DST_SRC_CMDTRLR src_cmdtrlr;
1056 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1057 = DST_K_SOURCE_CORR_HEADER_SIZE + 1 - 1;
1058 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1060 src_command.dst_b_src_command = DST_K_SRC_FORMFEED;
1062 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1063 "source corr", dosizeonly);
1065 totsize += write_debug_data1 (src_command.dst_b_src_command,
1066 "source_corr (SRC FORMFEED)",
1071 = DST_K_SRC_COMMAND_SIZE + flen + DST_K_SRC_CMDTRLR_SIZE;
1072 src_command.dst_b_src_command = DST_K_SRC_DECLFILE;
1073 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length
1074 = src_command_size - 2;
1075 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags = 0;
1076 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid
1078 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt
1079 = file_info_entry.cdt;
1080 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk
1081 = file_info_entry.ebk;
1082 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb
1083 = file_info_entry.ffb;
1084 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo
1085 = file_info_entry.rfo;
1086 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename
1087 = file_info_entry.flen;
1089 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1090 = DST_K_SOURCE_CORR_HEADER_SIZE + src_command_size - 1;
1091 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1094 src_cmdtrlr.dst_b_src_df_libmodname = 0;
1096 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1097 "source corr", dosizeonly);
1098 totsize += write_debug_data1 (src_command.dst_b_src_command,
1099 "source_corr (DECL SRC FILE)", dosizeonly);
1100 totsize += write_debug_data1
1101 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length,
1102 "source_corr (length)", dosizeonly);
1104 totsize += write_debug_data1
1105 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags,
1106 "source_corr (flags)", dosizeonly);
1108 totsize += write_debug_data2
1109 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid,
1110 "source_corr (fileid)", dosizeonly);
1112 totsize += write_debug_data8
1113 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt,
1114 "source_corr (creation date)", dosizeonly);
1116 totsize += write_debug_data4
1117 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk,
1118 "source_corr (EOF block number)", dosizeonly);
1120 totsize += write_debug_data2
1121 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb,
1122 "source_corr (first free byte)", dosizeonly);
1124 totsize += write_debug_data1
1125 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo,
1126 "source_corr (record and file organization)", dosizeonly);
1128 totsize += write_debug_data1
1129 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename,
1130 "source_corr (filename length)", dosizeonly);
1132 totsize += write_debug_string (file_info_entry.file_name,
1133 "source file name", dosizeonly);
1134 totsize += write_debug_data1 (src_cmdtrlr.dst_b_src_df_libmodname,
1135 "source_corr (libmodname)", dosizeonly);
1137 src_command_sf.dst_b_src_command = DST_K_SRC_SETFILE;
1138 src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword = fileid;
1140 src_command_sr.dst_b_src_command = DST_K_SRC_SETREC_W;
1141 src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword = 1;
1143 src_command_sl.dst_b_src_command = DST_K_SRC_SETLNUM_L;
1144 src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong = linestart + 1;
1146 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1148 if (linesleft > 65534)
1149 linesleft = linesleft - 65534, linestodo = 65534;
1151 linestodo = linesleft, linesleft = 0;
1153 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1155 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1156 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 + 3 + 5 + 3 - 1;
1157 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1160 if (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword)
1162 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1163 "source corr", dosizeonly);
1165 totsize += write_debug_data1 (src_command_sf.dst_b_src_command,
1166 "source_corr (src setfile)", dosizeonly);
1168 totsize += write_debug_data2
1169 (src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword,
1170 "source_corr (fileid)", dosizeonly);
1172 totsize += write_debug_data1 (src_command_sr.dst_b_src_command,
1173 "source_corr (setrec)", dosizeonly);
1175 totsize += write_debug_data2
1176 (src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword,
1177 "source_corr (recnum)", dosizeonly);
1179 totsize += write_debug_data1 (src_command_sl.dst_b_src_command,
1180 "source_corr (setlnum)", dosizeonly);
1182 totsize += write_debug_data4
1183 (src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong,
1184 "source_corr (linenum)", dosizeonly);
1186 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1187 "source_corr (deflines)", dosizeonly);
1189 sprintf (buff, "source_corr (%d)",
1190 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1191 totsize += write_debug_data2
1192 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1195 while (linesleft > 0)
1197 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1198 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 - 1;
1199 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1201 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1203 if (linesleft > 65534)
1204 linesleft = linesleft - 65534, linestodo = 65534;
1206 linestodo = linesleft, linesleft = 0;
1208 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1210 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1211 "source corr", dosizeonly);
1212 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1213 "source_corr (deflines)", dosizeonly);
1214 sprintf (buff, "source_corr (%d)",
1215 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1216 totsize += write_debug_data2
1217 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1225 /* Output all the source correlation entries and return the size. Just return
1226 the size if DOSIZEONLY is nonzero. */
1229 write_srccorrs (int dosizeonly)
1234 for (i = 1; i < file_info_table_in_use; i++)
1235 totsize += write_srccorr (i, file_info_table[i], dosizeonly);
1240 /* Output a marker (i.e. a label) for the beginning of a function, before
1244 vmsdbgout_begin_prologue (unsigned int line, const char *file)
1246 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1248 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1249 (*dwarf2_debug_hooks.begin_prologue) (line, file);
1251 if (debug_info_level > DINFO_LEVEL_NONE)
1253 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
1254 current_function_funcdef_no);
1255 ASM_OUTPUT_LABEL (asm_out_file, label);
1259 /* Output a marker (i.e. a label) for the beginning of a function, after
1263 vmsdbgout_end_prologue (unsigned int line, const char *file)
1265 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1267 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1268 (*dwarf2_debug_hooks.end_prologue) (line, file);
1270 if (debug_info_level > DINFO_LEVEL_TERSE)
1272 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL,
1273 current_function_funcdef_no);
1274 ASM_OUTPUT_LABEL (asm_out_file, label);
1276 /* VMS PCA expects every PC range to correlate to some line and file. */
1277 vmsdbgout_source_line (line, file);
1281 /* No output for VMS debug, but make obligatory call to Dwarf2 debug */
1284 vmsdbgout_end_function (unsigned int line)
1286 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1287 (*dwarf2_debug_hooks.end_function) (line);
1290 /* Output a marker (i.e. a label) for the absolute end of the generated code
1291 for a function definition. This gets called *after* the epilogue code has
1295 vmsdbgout_end_epilogue (unsigned int line, const char *file)
1297 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1299 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1300 (*dwarf2_debug_hooks.end_epilogue) (line, file);
1302 if (debug_info_level > DINFO_LEVEL_NONE)
1304 /* Output a label to mark the endpoint of the code generated for this
1306 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
1307 current_function_funcdef_no);
1308 ASM_OUTPUT_LABEL (asm_out_file, label);
1310 /* VMS PCA expects every PC range to correlate to some line and file. */
1311 vmsdbgout_source_line (line, file);
1315 /* Output a marker (i.e. a label) for the beginning of the generated code for
1319 vmsdbgout_begin_block (register unsigned line, register unsigned blocknum)
1321 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1322 (*dwarf2_debug_hooks.begin_block) (line, blocknum);
1324 if (debug_info_level > DINFO_LEVEL_TERSE)
1325 (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
1328 /* Output a marker (i.e. a label) for the end of the generated code for a
1332 vmsdbgout_end_block (register unsigned line, register unsigned blocknum)
1334 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1335 (*dwarf2_debug_hooks.end_block) (line, blocknum);
1337 if (debug_info_level > DINFO_LEVEL_TERSE)
1338 (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_END_LABEL, blocknum);
1341 /* Not implemented in VMS Debug. */
1344 vmsdbgout_ignore_block (tree block)
1348 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1349 retval = (*dwarf2_debug_hooks.ignore_block) (block);
1354 /* Add an entry for function DECL into the func_table. */
1357 vmsdbgout_begin_function (tree decl)
1359 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
1361 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1362 (*dwarf2_debug_hooks.begin_function) (decl);
1364 if (func_table_in_use == func_table_allocated)
1366 func_table_allocated += FUNC_TABLE_INCREMENT;
1367 func_table = xrealloc (func_table,
1368 func_table_allocated * sizeof (char *));
1371 /* Add the new entry to the end of the function name table. */
1372 func_table[func_table_in_use++] = xstrdup (name);
1375 static char fullname_buff [4096];
1377 /* Return the full file specification for FILENAME. The specification must be
1378 in VMS syntax in order to be processed by VMS Debug. */
1381 full_name (const char *filename)
1384 FILE *fp = fopen (filename, "r");
1386 fgetname (fp, fullname_buff, 1);
1389 getcwd (fullname_buff, sizeof (fullname_buff));
1391 strcat (fullname_buff, "/");
1392 strcat (fullname_buff, filename);
1394 /* ??? Insert hairy code here to translate Unix style file specification
1398 return fullname_buff;
1401 /* Lookup a filename (in the list of filenames that we know about here in
1402 vmsdbgout.c) and return its "index". The index of each (known) filename is
1403 just a unique number which is associated with only that one filename. We
1404 need such numbers for the sake of generating labels and references
1405 to those files numbers. If the filename given as an argument is not
1406 found in our current list, add it to the list and assign it the next
1407 available unique index number. In order to speed up searches, we remember
1408 the index of the filename was looked up last. This handles the majority of
1412 lookup_filename (const char *file_name)
1414 static unsigned int last_file_lookup_index = 0;
1416 register unsigned i;
1423 struct stat statbuf;
1425 if (stat (file_name, &statbuf) == 0)
1431 /* Adjust for GMT. */
1432 ts = (struct tm *) localtime (&statbuf.st_ctime);
1433 gmtoff = ts->tm_gmtoff;
1435 /* VMS has multiple file format types. */
1436 rfo = statbuf.st_fab_rfm;
1438 /* Is GMT adjustment an issue with a cross-compiler? */
1441 /* Assume stream LF type file. */
1444 cdt = 10000000 * (statbuf.st_ctime + gmtoff + vms_epoch_offset);
1445 ebk = statbuf.st_size / 512 + 1;
1446 ffb = statbuf.st_size - ((statbuf.st_size / 512) * 512);
1447 fnam = full_name (file_name);
1448 flen = strlen (fnam);
1460 /* Check to see if the file name that was searched on the previous call
1461 matches this file name. If so, return the index. */
1462 if (last_file_lookup_index != 0)
1464 fn = file_info_table[last_file_lookup_index].file_name;
1465 if (strcmp (fnam, fn) == 0)
1466 return last_file_lookup_index;
1469 /* Didn't match the previous lookup, search the table */
1470 for (i = 1; i < file_info_table_in_use; ++i)
1472 fn = file_info_table[i].file_name;
1473 if (strcmp (fnam, fn) == 0)
1475 last_file_lookup_index = i;
1480 /* Prepare to add a new table entry by making sure there is enough space in
1481 the table to do so. If not, expand the current table. */
1482 if (file_info_table_in_use == file_info_table_allocated)
1485 file_info_table_allocated += FILE_TABLE_INCREMENT;
1486 file_info_table = xrealloc (file_info_table,
1487 (file_info_table_allocated
1488 * sizeof (dst_file_info_entry)));
1491 /* Add the new entry to the end of the filename table. */
1492 file_info_table[file_info_table_in_use].file_name = xstrdup (fnam);
1493 file_info_table[file_info_table_in_use].max_line = 0;
1494 file_info_table[file_info_table_in_use].cdt = cdt;
1495 file_info_table[file_info_table_in_use].ebk = ebk;
1496 file_info_table[file_info_table_in_use].ffb = ffb;
1497 file_info_table[file_info_table_in_use].rfo = rfo;
1498 file_info_table[file_info_table_in_use].flen = flen;
1500 last_file_lookup_index = file_info_table_in_use++;
1501 return last_file_lookup_index;
1504 /* Output a label to mark the beginning of a source code line entry
1505 and record information relating to this source line, in
1506 'line_info_table' for later output of the .debug_line section. */
1509 vmsdbgout_source_line (register unsigned line, register const char *filename)
1511 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1512 (*dwarf2_debug_hooks.source_line) (line, filename);
1514 if (debug_info_level >= DINFO_LEVEL_TERSE)
1516 dst_line_info_ref line_info;
1518 (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
1519 line_info_table_in_use);
1521 /* Expand the line info table if necessary. */
1522 if (line_info_table_in_use == line_info_table_allocated)
1524 line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
1525 line_info_table = xrealloc (line_info_table,
1526 (line_info_table_allocated
1527 * sizeof (dst_line_info_entry)));
1530 /* Add the new entry at the end of the line_info_table. */
1531 line_info = &line_info_table[line_info_table_in_use++];
1532 line_info->dst_file_num = lookup_filename (filename);
1533 line_info->dst_line_num = line;
1534 if (line > file_info_table[line_info->dst_file_num].max_line)
1535 file_info_table[line_info->dst_file_num].max_line = line;
1539 /* Record the beginning of a new source file, for later output.
1540 At present, unimplemented. */
1543 vmsdbgout_start_source_file (unsigned int lineno, const char *filename)
1545 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1546 (*dwarf2_debug_hooks.start_source_file) (lineno, filename);
1549 /* Record the end of a source file, for later output.
1550 At present, unimplemented. */
1553 vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
1555 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1556 (*dwarf2_debug_hooks.end_source_file) (lineno);
1559 /* Set up for Debug output at the start of compilation. */
1562 vmsdbgout_init (const char *main_input_filename)
1564 const char *language_string = lang_hooks.name;
1566 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1567 (*dwarf2_debug_hooks.init) (main_input_filename);
1569 if (debug_info_level == DINFO_LEVEL_NONE)
1572 /* Remember the name of the primary input file. */
1573 primary_filename = main_input_filename;
1575 /* Allocate the initial hunk of the file_info_table. */
1577 = xcalloc (FILE_TABLE_INCREMENT, sizeof (dst_file_info_entry));
1578 file_info_table_allocated = FILE_TABLE_INCREMENT;
1580 /* Skip the first entry - file numbers begin at 1 */
1581 file_info_table_in_use = 1;
1583 func_table = xcalloc (FUNC_TABLE_INCREMENT, sizeof (char *));
1584 func_table_allocated = FUNC_TABLE_INCREMENT;
1585 func_table_in_use = 1;
1587 /* Allocate the initial hunk of the line_info_table. */
1589 = xcalloc (LINE_INFO_TABLE_INCREMENT, sizeof (dst_line_info_entry));
1590 line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
1591 /* zero-th entry is allocated, but unused */
1592 line_info_table_in_use = 1;
1594 lookup_filename (primary_filename);
1596 if (!strcmp (language_string, "GNU C"))
1597 module_language = DST_K_C;
1598 else if (!strcmp (language_string, "GNU C++"))
1599 module_language = DST_K_CXX;
1600 else if (!strcmp (language_string, "GNU Ada"))
1601 module_language = DST_K_ADA;
1602 else if (!strcmp (language_string, "GNU F77"))
1603 module_language = DST_K_FORTRAN;
1605 module_language = DST_K_UNKNOWN;
1607 module_producer = concat (language_string, " ", version_string, NULL);
1609 ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
1613 /* Not implemented in VMS Debug. */
1616 vmsdbgout_define (unsigned int lineno, const char *buffer)
1618 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1619 (*dwarf2_debug_hooks.define) (lineno, buffer);
1622 /* Not implemented in VMS Debug. */
1625 vmsdbgout_undef (unsigned int lineno, const char *buffer)
1627 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1628 (*dwarf2_debug_hooks.undef) (lineno, buffer);
1631 /* Not implemented in VMS Debug. */
1634 vmsdbgout_decl (tree decl)
1636 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1637 (*dwarf2_debug_hooks.function_decl) (decl);
1640 /* Not implemented in VMS Debug. */
1643 vmsdbgout_global_decl (tree decl)
1645 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1646 (*dwarf2_debug_hooks.global_decl) (decl);
1649 /* Not implemented in VMS Debug. */
1652 vmsdbgout_abstract_function (tree decl)
1654 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1655 (*dwarf2_debug_hooks.outlining_inline_function) (decl);
1658 /* Output stuff that Debug requires at the end of every file and generate the
1659 VMS Debug debugging info. */
1662 vmsdbgout_finish (const char *main_input_filename ATTRIBUTE_UNUSED)
1667 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1668 (*dwarf2_debug_hooks.finish) (main_input_filename);
1670 if (debug_info_level == DINFO_LEVEL_NONE)
1673 /* Output a terminator label for the .text section. */
1675 (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
1677 /* Output debugging information.
1678 Warning! Do not change the name of the .vmsdebug section without
1679 changing it in the assembler also. */
1680 named_section (NULL_TREE, ".vmsdebug", 0);
1681 ASM_OUTPUT_ALIGN (asm_out_file, 0);
1683 totsize = write_modbeg (1);
1684 for (i = 1; i < func_table_in_use; i++)
1686 totsize += write_rtnbeg (i, 1);
1687 totsize += write_rtnend (i, 1);
1689 totsize += write_pclines (1);
1692 for (i = 1; i < func_table_in_use; i++)
1694 write_rtnbeg (i, 0);
1695 write_rtnend (i, 0);
1699 if (debug_info_level > DINFO_LEVEL_TERSE)
1701 totsize = write_srccorrs (1);
1705 totsize = write_modend (1);
1708 #endif /* VMS_DEBUGGING_INFO */