1 /* Output VMS debug format symbol table information from the GNU C compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Douglas B. Rupp (rupp@gnat.com).
6 This file is part of GNU CC.
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 #ifdef VMS_DEBUGGING_INFO
33 #include "langhooks.h"
35 /* Difference in seconds between the VMS Epoch and the Unix Epoch */
36 static const long long vms_epoch_offset
= 3506716800ll;
38 /* NOTE: In the comments in this file, many references are made to "Debug
39 Symbol Table". This term is abbreviated as `DST' throughout the remainder
42 typedef struct dst_line_info_struct
*dst_line_info_ref
;
44 /* Each entry in the line_info_table maintains the file and
45 line number associated with the label generated for that
46 entry. The label gives the PC value associated with
47 the line number entry. */
48 typedef struct dst_line_info_struct
50 unsigned long dst_file_num
;
51 unsigned long dst_line_num
;
55 typedef struct dst_file_info_struct
*dst_file_info_ref
;
57 typedef struct dst_file_info_struct
60 unsigned int max_line
;
61 unsigned int listing_line_start
;
70 /* How to start an assembler comment. */
71 #ifndef ASM_COMMENT_START
72 #define ASM_COMMENT_START ";#"
75 /* Maximum size (in bytes) of an artificially generated label. */
76 #define MAX_ARTIFICIAL_LABEL_BYTES 30
78 /* Make sure we know the sizes of the various types debug can describe. These
79 are only defaults. If the sizes are different for your target, you should
80 override these values by defining the appropriate symbols in your tm.h
82 #ifndef CHAR_TYPE_SIZE
83 #define CHAR_TYPE_SIZE BITS_PER_UNIT
86 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
89 /* Pointer to an structure of filenames referenced by this compilation unit. */
90 static dst_file_info_ref file_info_table
;
92 /* Total number of entries in the table (i.e. array) pointed to by
93 `file_info_table'. This is the *total* and includes both used and unused
95 static unsigned int file_info_table_allocated
;
97 /* Number of entries in the file_info_table which are actually in use. */
98 static unsigned int file_info_table_in_use
;
100 /* Size (in elements) of increments by which we may expand the filename
102 #define FILE_TABLE_INCREMENT 64
104 static char **func_table
;
105 static unsigned int func_table_allocated
;
106 static unsigned int func_table_in_use
;
107 #define FUNC_TABLE_INCREMENT 256
109 /* Local pointer to the name of the main input file. Initialized in
111 static const char *primary_filename
;
113 static char *module_producer
;
114 static unsigned int module_language
;
116 /* A pointer to the base of a table that contains line information
117 for each source code line in .text in the compilation unit. */
118 static dst_line_info_ref line_info_table
;
120 /* Number of elements currently allocated for line_info_table. */
121 static unsigned int line_info_table_allocated
;
123 /* Number of elements in line_info_table currently in use. */
124 static unsigned int line_info_table_in_use
;
126 /* Size (in elements) of increments by which we may expand line_info_table. */
127 #define LINE_INFO_TABLE_INCREMENT 1024
129 /* The number of the current function definition for which debugging
130 information is being generated. These numbers range from 1 up to the
131 maximum number of function definitions contained within the current
132 compilation unit. These numbers are used to create unique label id's unique
133 to each function definition. */
134 static unsigned int current_funcdef_number
= 0;
136 /* Forward declarations for functions defined in this file. */
137 static char *full_name
PARAMS ((const char *));
138 static unsigned int lookup_filename
PARAMS ((const char *));
139 static void addr_const_to_string
PARAMS ((char *, rtx
));
140 static int write_debug_header
PARAMS ((DST_HEADER
*, const char *, int));
141 static int write_debug_addr
PARAMS ((char *, const char *, int));
142 static int write_debug_data1
PARAMS ((unsigned int, const char *, int));
143 static int write_debug_data2
PARAMS ((unsigned int, const char *, int));
144 static int write_debug_data4
PARAMS ((unsigned long, const char *, int));
145 static int write_debug_data8
PARAMS ((unsigned long long, const char *,
147 static int write_debug_delta4
PARAMS ((char *, char *, const char *, int));
148 static int write_debug_string
PARAMS ((char *, const char *, int));
149 static int write_modbeg
PARAMS ((int));
150 static int write_modend
PARAMS ((int));
151 static int write_rtnbeg
PARAMS ((int, int));
152 static int write_rtnend
PARAMS ((int, int));
153 static int write_pclines
PARAMS ((int));
154 static int write_srccorr
PARAMS ((int, dst_file_info_entry
, int));
155 static int write_srccorrs
PARAMS ((int));
157 static void vmsdbgout_init
PARAMS ((const char *));
158 static void vmsdbgout_finish
PARAMS ((const char *));
159 static void vmsdbgout_define
PARAMS ((unsigned int, const char *));
160 static void vmsdbgout_undef
PARAMS ((unsigned int, const char *));
161 static void vmsdbgout_start_source_file
PARAMS ((unsigned int, const char *));
162 static void vmsdbgout_end_source_file
PARAMS ((unsigned int));
163 static void vmsdbgout_begin_block
PARAMS ((unsigned int, unsigned int));
164 static void vmsdbgout_end_block
PARAMS ((unsigned int, unsigned int));
165 static bool vmsdbgout_ignore_block
PARAMS ((tree
));
166 static void vmsdbgout_source_line
PARAMS ((unsigned int, const char *));
167 static void vmsdbgout_begin_prologue
PARAMS ((unsigned int, const char *));
168 static void vmsdbgout_end_epilogue
PARAMS ((void));
169 static void vmsdbgout_begin_function
PARAMS ((tree
));
170 static void vmsdbgout_decl
PARAMS ((tree
));
171 static void vmsdbgout_global_decl
PARAMS ((tree
));
172 static void vmsdbgout_abstract_function
PARAMS ((tree
));
174 /* The debug hooks structure. */
176 struct gcc_debug_hooks vmsdbg_debug_hooks
181 vmsdbgout_start_source_file
,
182 vmsdbgout_end_source_file
,
183 vmsdbgout_begin_block
,
185 vmsdbgout_ignore_block
,
186 vmsdbgout_source_line
,
187 vmsdbgout_begin_prologue
,
188 debug_nothing_int
, /* end_prologue */
189 vmsdbgout_end_epilogue
, /* end_epilogue */
190 vmsdbgout_begin_function
, /* begin_function */
191 debug_nothing_int
, /* end_function */
193 vmsdbgout_global_decl
,
194 debug_nothing_tree
, /* deferred_inline_function */
195 vmsdbgout_abstract_function
,
196 debug_nothing_rtx
/* label */
199 /* Definitions of defaults for assembler-dependent names of various
200 pseudo-ops and section names.
201 Theses may be overridden in the tm.h file (if necessary) for a particular
203 #ifdef UNALIGNED_SHORT_ASM_OP
204 #undef UNALIGNED_SHORT_ASM_OP
206 #define UNALIGNED_SHORT_ASM_OP ".word"
208 #ifdef UNALIGNED_INT_ASM_OP
209 #undef UNALIGNED_INT_ASM_OP
211 #define UNALIGNED_INT_ASM_OP ".long"
213 #ifdef UNALIGNED_LONG_ASM_OP
214 #undef UNALIGNED_LONG_ASM_OP
216 #define UNALIGNED_LONG_ASM_OP ".long"
218 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
219 #undef UNALIGNED_DOUBLE_INT_ASM_OP
221 #define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
226 #define ASM_BYTE_OP ".byte"
228 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
230 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
232 #ifndef UNALIGNED_PTR_ASM_OP
233 #define UNALIGNED_PTR_ASM_OP \
234 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
237 #ifndef UNALIGNED_OFFSET_ASM_OP
238 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
239 (NUMBYTES(OFFSET) == 4 \
240 ? UNALIGNED_LONG_ASM_OP \
241 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
244 /* Pseudo-op for defining a new section. */
245 #ifndef SECTION_ASM_OP
246 #define SECTION_ASM_OP ".section"
249 /* Definitions of defaults for formats and names of various special
250 (artificial) labels which may be generated within this file (when the -g
251 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
252 may be overridden from within the tm.h file, but typically, overriding these
253 defaults is unnecessary. */
255 static char text_end_label
[MAX_ARTIFICIAL_LABEL_BYTES
];
257 #ifndef TEXT_END_LABEL
258 #define TEXT_END_LABEL "Lvetext"
260 #ifndef FUNC_BEGIN_LABEL
261 #define FUNC_BEGIN_LABEL "LVFB"
263 #ifndef FUNC_PROLOG_LABEL
264 #define FUNC_PROLOG_LABEL "LVFP"
266 #ifndef FUNC_END_LABEL
267 #define FUNC_END_LABEL "LVFE"
269 #ifndef BLOCK_BEGIN_LABEL
270 #define BLOCK_BEGIN_LABEL "LVBB"
272 #ifndef BLOCK_END_LABEL
273 #define BLOCK_END_LABEL "LVBE"
275 #ifndef LINE_CODE_LABEL
276 #define LINE_CODE_LABEL "LVM"
279 #ifndef ASM_OUTPUT_DEBUG_DELTA2
280 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
283 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
284 assemble_name (FILE, LABEL1); \
285 fprintf (FILE, "-"); \
286 assemble_name (FILE, LABEL2); \
291 #ifndef ASM_OUTPUT_DEBUG_DELTA4
292 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
295 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
296 assemble_name (FILE, LABEL1); \
297 fprintf (FILE, "-"); \
298 assemble_name (FILE, LABEL2); \
303 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
304 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
307 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
308 assemble_name (FILE, LABEL1); \
309 fprintf (FILE, "-"); \
310 assemble_name (FILE, LABEL2); \
315 #ifndef ASM_OUTPUT_DEBUG_ADDR
316 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
319 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
320 assemble_name (FILE, LABEL); \
325 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
326 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
327 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
330 #ifndef ASM_OUTPUT_DEBUG_DATA1
331 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
332 fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned char) VALUE)
335 #ifndef ASM_OUTPUT_DEBUG_DATA2
336 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
337 fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, \
338 (unsigned short) VALUE)
341 #ifndef ASM_OUTPUT_DEBUG_DATA4
342 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
343 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
346 #ifndef ASM_OUTPUT_DEBUG_DATA
347 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
348 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
351 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
352 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
353 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_PTR_ASM_OP, \
354 (unsigned long) VALUE)
357 #ifndef ASM_OUTPUT_DEBUG_DATA8
358 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
359 fprintf ((FILE), "\t%s\t0x%llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
360 (unsigned long long) VALUE)
363 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
364 newline is produced. When flag_verbose_asm is asserted, we add commnetary
365 at the end of the line, so we must avoid output of a newline here. */
366 #ifndef ASM_OUTPUT_DEBUG_STRING
367 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
370 register int slen = strlen(P); \
371 register char *p = (P); \
373 fprintf (FILE, "\t.ascii \""); \
374 for (i = 0; i < slen; i++) \
376 register int c = p[i]; \
377 if (c == '\"' || c == '\\') \
379 if (c >= ' ' && c < 0177) \
382 fprintf (FILE, "\\%o", c); \
384 fprintf (FILE, "\""); \
389 /* Convert a reference to the assembler name of a C-level name. This
390 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
391 a string rather than writing to a file. */
392 #ifndef ASM_NAME_TO_STRING
393 #define ASM_NAME_TO_STRING(STR, NAME) \
396 if ((NAME)[0] == '*') \
397 strcpy (STR, NAME+1); \
399 strcpy (STR, NAME); \
405 /* General utility functions. */
407 /* Convert an integer constant expression into assembler syntax. Addition and
408 subtraction are the only arithmetic that may appear in these expressions.
409 This is an adaptation of output_addr_const in final.c. Here, the target
410 of the conversion is a string buffer. We can't use output_addr_const
411 directly, because it writes to a file. */
414 addr_const_to_string (str
, x
)
423 switch (GET_CODE (x
))
433 ASM_NAME_TO_STRING (buf1
, XSTR (x
, 0));
438 ASM_GENERATE_INTERNAL_LABEL (buf1
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
439 ASM_NAME_TO_STRING (buf2
, buf1
);
444 ASM_GENERATE_INTERNAL_LABEL (buf1
, "L", CODE_LABEL_NUMBER (x
));
445 ASM_NAME_TO_STRING (buf2
, buf1
);
450 sprintf (buf1
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
455 /* This used to output parentheses around the expression, but that does
456 not work on the 386 (either ATT or BSD assembler). */
457 addr_const_to_string (buf1
, XEXP (x
, 0));
462 if (GET_MODE (x
) == VOIDmode
)
464 /* We can use %d if the number is one word and positive. */
465 if (CONST_DOUBLE_HIGH (x
))
466 sprintf (buf1
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
467 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
468 else if (CONST_DOUBLE_LOW (x
) < 0)
469 sprintf (buf1
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
471 sprintf (buf1
, HOST_WIDE_INT_PRINT_DEC
,
472 CONST_DOUBLE_LOW (x
));
476 /* We can't handle floating point constants; PRINT_OPERAND must
478 output_operand_lossage ("floating constant misused");
482 /* Some assemblers need integer constants to appear last (eg masm). */
483 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
485 addr_const_to_string (buf1
, XEXP (x
, 1));
487 if (INTVAL (XEXP (x
, 0)) >= 0)
489 addr_const_to_string (buf1
, XEXP (x
, 0));
494 addr_const_to_string (buf1
, XEXP (x
, 0));
496 if (INTVAL (XEXP (x
, 1)) >= 0)
498 addr_const_to_string (buf1
, XEXP (x
, 1));
504 /* Avoid outputting things like x-x or x+5-x, since some assemblers
505 can't handle that. */
506 x
= simplify_subtraction (x
);
507 if (GET_CODE (x
) != MINUS
)
510 addr_const_to_string (buf1
, XEXP (x
, 0));
513 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
514 && INTVAL (XEXP (x
, 1)) < 0)
517 addr_const_to_string (buf1
, XEXP (x
, 1));
523 addr_const_to_string (buf1
, XEXP (x
, 1));
530 addr_const_to_string (buf1
, XEXP (x
, 0));
535 output_operand_lossage ("invalid expression as operand");
539 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
540 set. Return the header size. Just return the size if DOSIZEONLY is
544 write_debug_header (header
, comment
, dosizeonly
)
551 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
552 header
->dst__header_length
.dst_w_length
);
554 if (flag_verbose_asm
)
555 fprintf (asm_out_file
, "\t%s record length", ASM_COMMENT_START
);
556 fputc ('\n', asm_out_file
);
558 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
559 header
->dst__header_type
.dst_w_type
);
561 if (flag_verbose_asm
)
562 fprintf (asm_out_file
, "\t%s record type (%s)", ASM_COMMENT_START
,
565 fputc ('\n', asm_out_file
);
571 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
572 set. Return the address size. Just return the size if DOSIZEONLY is
576 write_debug_addr (symbol
, comment
, dosizeonly
)
583 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, symbol
);
584 if (flag_verbose_asm
)
585 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
586 fputc ('\n', asm_out_file
);
592 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
593 set. Return the data size. Just return the size if DOSIZEONLY is
597 write_debug_data1 (data1
, comment
, dosizeonly
)
604 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file
, data1
);
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 the single word DATA2. Also output COMMENT if flag_verbose_asm is
614 set. Return the data size. Just return the size if DOSIZEONLY is
618 write_debug_data2 (data2
, comment
, dosizeonly
)
625 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
, data2
);
626 if (flag_verbose_asm
)
627 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
628 fputc ('\n', asm_out_file
);
634 /* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
635 Return the data size. Just return the size if DOSIZEONLY is non-zero. */
638 write_debug_data4 (data4
, comment
, 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 non-zero. */
658 write_debug_data8 (data8
, comment
, dosizeonly
)
659 unsigned long long data8
;
665 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file
, data8
);
666 if (flag_verbose_asm
)
667 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
668 fputc ('\n', asm_out_file
);
674 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
675 flag_verbose_asm is set. Return the data size. Just return the size if
676 DOSIZEONLY is non-zero. */
679 write_debug_delta4 (label1
, label2
, comment
, dosizeonly
)
687 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file
, label1
, label2
);
688 if (flag_verbose_asm
)
689 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
690 fputc ('\n', asm_out_file
);
696 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
697 set. Return the string length. Just return the length if DOSIZEONLY is
701 write_debug_string (string
, comment
, dosizeonly
)
708 ASM_OUTPUT_DEBUG_STRING (asm_out_file
, string
);
709 if (flag_verbose_asm
)
710 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
711 fputc ('\n', asm_out_file
);
714 return strlen (string
);
717 /* Output a module begin header and return the header size. Just return the
718 size if DOSIZEONLY is non-zero. */
721 write_modbeg (dosizeonly
)
724 DST_MODULE_BEGIN modbeg
;
727 char *module_name
, *m
;
732 /* Assumes primary filename has Unix syntax file spec. */
733 module_name
= xstrdup (basename ((char *) primary_filename
));
735 m
= strrchr (module_name
, '.');
739 modnamelen
= strlen (module_name
);
740 for (i
= 0; i
< modnamelen
; i
++)
741 module_name
[i
] = TOUPPER (module_name
[i
]);
743 prodnamelen
= strlen (module_producer
);
745 modbeg
.dst_a_modbeg_header
.dst__header_length
.dst_w_length
746 = DST_K_MODBEG_SIZE
+ modnamelen
+ DST_K_MB_TRLR_SIZE
+ prodnamelen
- 1;
747 modbeg
.dst_a_modbeg_header
.dst__header_type
.dst_w_type
= DST_K_MODBEG
;
748 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_hide
= 0;
749 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_version
= 1;
750 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_unused
= 0;
751 modbeg
.dst_b_modbeg_unused
= 0;
752 modbeg
.dst_l_modbeg_language
= module_language
;
753 modbeg
.dst_w_version_major
= DST_K_VERSION_MAJOR
;
754 modbeg
.dst_w_version_minor
= DST_K_VERSION_MINOR
;
755 modbeg
.dst_b_modbeg_name
= strlen (module_name
);
757 mb_trlr
.dst_b_compiler
= strlen (module_producer
);
759 totsize
+= write_debug_header (&modbeg
.dst_a_modbeg_header
,
760 "modbeg", dosizeonly
);
761 totsize
+= write_debug_data1 (*((char *) &modbeg
.dst_b_modbeg_flags
),
762 "flags", dosizeonly
);
763 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_unused
,
764 "unused", dosizeonly
);
765 totsize
+= write_debug_data4 (modbeg
.dst_l_modbeg_language
,
766 "language", dosizeonly
);
767 totsize
+= write_debug_data2 (modbeg
.dst_w_version_major
,
768 "DST major version", dosizeonly
);
769 totsize
+= write_debug_data2 (modbeg
.dst_w_version_minor
,
770 "DST minor version", dosizeonly
);
771 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_name
,
772 "length of module name", dosizeonly
);
773 totsize
+= write_debug_string (module_name
, "module name", dosizeonly
);
774 totsize
+= write_debug_data1 (mb_trlr
.dst_b_compiler
,
775 "length of compiler name", dosizeonly
);
776 totsize
+= write_debug_string (module_producer
, "compiler name", dosizeonly
);
781 /* Output a module end trailer and return the trailer size. Just return
782 the size if DOSIZEONLY is non-zero. */
785 write_modend (dosizeonly
)
788 DST_MODULE_END modend
;
791 modend
.dst_a_modend_header
.dst__header_length
.dst_w_length
792 = DST_K_MODEND_SIZE
- 1;
793 modend
.dst_a_modend_header
.dst__header_type
.dst_w_type
= DST_K_MODEND
;
795 totsize
+= write_debug_header (&modend
.dst_a_modend_header
, "modend",
801 /* Output a routine begin header routine RTNNUM and return the header size.
802 Just return the size if DOSIZEONLY is non-zero. */
805 write_rtnbeg (rtnnum
, dosizeonly
)
810 int rtnnamelen
, rtnentrynamelen
;
813 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
814 DST_ROUTINE_BEGIN rtnbeg
;
817 rtnname
= func_table
[rtnnum
];
818 rtnnamelen
= strlen (rtnname
);
819 rtnentrynamelen
= rtnnamelen
+ 4; /* "..en" */
820 rtnentryname
= (char *) xmalloc (rtnentrynamelen
+ 1);
821 strcpy (rtnentryname
, rtnname
);
822 strcat (rtnentryname
, "..en");
824 if (!strcmp (rtnname
, "main"))
827 const char *go
= "TRANSFER$BREAK$GO";
829 /* This command isn't documented in DSTRECORDS, so it's made to
830 look like what DEC C does */
832 /* header size - 1st byte + flag byte + STO_LW size
833 + string count byte + string length */
834 header
.dst__header_length
.dst_w_length
835 = DST_K_DST_HEADER_SIZE
- 1 + 1 + 4 + 1 + strlen (go
);
836 header
.dst__header_type
.dst_w_type
= 0x17;
838 totsize
+= write_debug_header (&header
, "transfer", dosizeonly
);
840 /* I think this is a flag byte, but I don't know what this flag means */
841 totsize
+= write_debug_data1 (0x1, "flags ???", dosizeonly
);
843 /* Routine Begin PD Address */
844 totsize
+= write_debug_addr (rtnname
, "main procedure descriptor",
846 totsize
+= write_debug_data1 (strlen (go
), "length of main_name",
848 totsize
+= write_debug_string ((char *) go
, "main name", dosizeonly
);
851 /* The header length never includes the length byte */
852 rtnbeg
.dst_a_rtnbeg_header
.dst__header_length
.dst_w_length
853 = DST_K_RTNBEG_SIZE
+ rtnnamelen
- 1;
854 rtnbeg
.dst_a_rtnbeg_header
.dst__header_type
.dst_w_type
= DST_K_RTNBEG
;
855 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unused
= 0;
856 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unalloc
= 0;
857 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_prototype
= 0;
858 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_inlined
= 0;
859 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_no_call
= 1;
860 rtnbeg
.dst_b_rtnbeg_name
= rtnnamelen
;
862 totsize
+= write_debug_header (&rtnbeg
.dst_a_rtnbeg_header
, "rtnbeg",
864 totsize
+= write_debug_data1 (*((char *) &rtnbeg
.dst_b_rtnbeg_flags
),
865 "flags", dosizeonly
);
867 /* Routine Begin Address */
868 totsize
+= write_debug_addr (rtnentryname
, "routine entry name", dosizeonly
);
870 /* Routine Begin PD Address */
871 totsize
+= write_debug_addr (rtnname
, "routine procedure descriptor",
874 /* Routine Begin Name */
875 totsize
+= write_debug_data1 (rtnbeg
.dst_b_rtnbeg_name
,
876 "length of routine name", dosizeonly
);
878 totsize
+= write_debug_string (rtnname
, "routine name", dosizeonly
);
882 if (debug_info_level
> DINFO_LEVEL_TERSE
)
884 prolog
.dst_a_prolog_header
.dst__header_length
.dst_w_length
885 = DST_K_PROLOG_SIZE
- 1;
886 prolog
.dst_a_prolog_header
.dst__header_type
.dst_w_type
= DST_K_PROLOG
;
888 totsize
+= write_debug_header (&prolog
.dst_a_prolog_header
, "prolog",
891 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
, rtnnum
);
892 totsize
+= write_debug_addr (label
, "prolog breakpoint addr",
899 /* Output a routine end trailer for routine RTNNUM and return the header size.
900 Just return the size if DOSIZEONLY is non-zero. */
903 write_rtnend (rtnnum
, dosizeonly
)
907 DST_ROUTINE_END rtnend
;
908 char label1
[MAX_ARTIFICIAL_LABEL_BYTES
];
909 char label2
[MAX_ARTIFICIAL_LABEL_BYTES
];
914 rtnend
.dst_a_rtnend_header
.dst__header_length
.dst_w_length
915 = DST_K_RTNEND_SIZE
- 1;
916 rtnend
.dst_a_rtnend_header
.dst__header_type
.dst_w_type
= DST_K_RTNEND
;
917 rtnend
.dst_b_rtnend_unused
= 0;
918 rtnend
.dst_l_rtnend_size
= 0; /* Calculated below. */
920 totsize
+= write_debug_header (&rtnend
.dst_a_rtnend_header
, "rtnend",
922 totsize
+= write_debug_data1 (rtnend
.dst_b_rtnend_unused
, "unused",
925 ASM_GENERATE_INTERNAL_LABEL (label1
, FUNC_BEGIN_LABEL
, rtnnum
);
926 ASM_GENERATE_INTERNAL_LABEL (label2
, FUNC_END_LABEL
, rtnnum
);
927 totsize
+= write_debug_delta4 (label2
, label1
, "routine size", dosizeonly
);
932 #define K_DELTA_PC(I) \
933 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
935 #define K_SET_LINUM(I) \
936 ((I) < 256 ? DST_K_SET_LINUM_B \
937 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
939 #define K_INCR_LINUM(I) \
940 ((I) < 256 ? DST_K_INCR_LINUM \
941 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
943 /* Output the PC to line number correlations and return the size. Just return
944 the size if DOSIZEONLY is non-zero */
947 write_pclines (dosizeonly
)
955 DST_LINE_NUM_HEADER line_num
;
956 DST_PCLINE_COMMANDS pcline
;
957 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
958 char lastlabel
[MAX_ARTIFICIAL_LABEL_BYTES
];
962 max_line
= file_info_table
[1].max_line
;
963 file_info_table
[1].listing_line_start
= linestart
;
964 linestart
= linestart
+ ((max_line
/ 100000) + 1) * 100000;
966 for (i
= 2; i
< file_info_table_in_use
; i
++)
968 max_line
= file_info_table
[i
].max_line
;
969 file_info_table
[i
].listing_line_start
= linestart
;
970 linestart
= linestart
+ ((max_line
/ 10000) + 1) * 10000;
973 /* Set starting address to beginning of text section */
974 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 8;
975 line_num
.dst_a_line_num_header
.dst__header_type
.dst_w_type
= DST_K_LINE_NUM
;
976 pcline
.dst_b_pcline_command
= DST_K_SET_ABS_PC
;
978 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
979 "line_num", dosizeonly
);
980 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
981 "line_num (SET ABS PC)", dosizeonly
);
987 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, TEXT_SECTION_ASM_OP
);
988 if (flag_verbose_asm
)
989 fprintf (asm_out_file
, "\t%s line_num", ASM_COMMENT_START
);
990 fputc ('\n', asm_out_file
);
993 fn
= line_info_table
[1].dst_file_num
;
994 ln
= (file_info_table
[fn
].listing_line_start
995 + line_info_table
[1].dst_line_num
);
996 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 4 + 4;
997 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
999 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
1000 "line_num", dosizeonly
);
1001 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1002 "line_num (SET LINUM LONG)", dosizeonly
);
1004 sprintf (buff
, "line_num (%d)", ln
- 1);
1005 totsize
+= write_debug_data4 (ln
- 1, buff
, dosizeonly
);
1008 strcpy (lastlabel
, TEXT_SECTION_ASM_OP
);
1009 for (i
= 1; i
< line_info_table_in_use
; i
++)
1013 fn
= line_info_table
[i
].dst_file_num
;
1014 ln
= (file_info_table
[fn
].listing_line_start
1015 + line_info_table
[i
].dst_line_num
);
1017 if (ln
- lastln
> 1)
1018 extrabytes
= 5; /* NUMBYTES (ln - lastln - 1) + 1; */
1019 else if (ln
<= lastln
)
1020 extrabytes
= 5; /* NUMBYTES (ln - 1) + 1; */
1024 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
1027 totsize
+= write_debug_header
1028 (&line_num
.dst_a_line_num_header
, "line_num", dosizeonly
);
1030 if (ln
- lastln
> 1)
1032 int lndif
= ln
- lastln
- 1;
1034 /* K_INCR_LINUM (lndif); */
1035 pcline
.dst_b_pcline_command
= DST_K_INCR_LINUM_L
;
1037 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1038 "line_num (INCR LINUM LONG)",
1041 sprintf (buff
, "line_num (%d)", lndif
);
1042 totsize
+= write_debug_data4 (lndif
, buff
, dosizeonly
);
1044 else if (ln
<= lastln
)
1046 /* K_SET_LINUM (ln-1); */
1047 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
1049 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1050 "line_num (SET LINUM LONG)",
1053 sprintf (buff
, "line_num (%d)", ln
- 1);
1054 totsize
+= write_debug_data4 (ln
- 1, buff
, dosizeonly
);
1057 pcline
.dst_b_pcline_command
= DST_K_DELTA_PC_L
;
1059 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1060 "line_num (DELTA PC LONG)", dosizeonly
);
1062 ASM_GENERATE_INTERNAL_LABEL (label
, LINE_CODE_LABEL
, i
);
1063 totsize
+= write_debug_delta4 (label
, lastlabel
, "increment line_num",
1067 strcpy (lastlabel
, label
);
1073 /* Output a source correlation for file FILEID using information saved in
1074 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
1078 write_srccorr (fileid
, file_info_entry
, dosizeonly
)
1080 dst_file_info_entry file_info_entry
;
1083 int src_command_size
;
1084 int linesleft
= file_info_entry
.max_line
;
1085 int linestart
= file_info_entry
.listing_line_start
;
1086 int flen
= file_info_entry
.flen
;
1088 DST_SOURCE_CORR src_header
;
1089 DST_SRC_COMMAND src_command
;
1090 DST_SRC_COMMAND src_command_sf
;
1091 DST_SRC_COMMAND src_command_sl
;
1092 DST_SRC_COMMAND src_command_sr
;
1093 DST_SRC_COMMAND src_command_dl
;
1094 DST_SRC_CMDTRLR src_cmdtrlr
;
1100 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1101 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 1 - 1;
1102 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1104 src_command
.dst_b_src_command
= DST_K_SRC_FORMFEED
;
1106 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1107 "source corr", dosizeonly
);
1109 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
1110 "source_corr (SRC FORMFEED)",
1115 = DST_K_SRC_COMMAND_SIZE
+ flen
+ DST_K_SRC_CMDTRLR_SIZE
;
1116 src_command
.dst_b_src_command
= DST_K_SRC_DECLFILE
;
1117 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
1118 = src_command_size
- 2;
1119 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
= 0;
1120 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
1122 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
1123 = file_info_entry
.cdt
;
1124 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
1125 = file_info_entry
.ebk
;
1126 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
1127 = file_info_entry
.ffb
;
1128 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
1129 = file_info_entry
.rfo
;
1130 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
1131 = file_info_entry
.flen
;
1133 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1134 = DST_K_SOURCE_CORR_HEADER_SIZE
+ src_command_size
- 1;
1135 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1138 src_cmdtrlr
.dst_b_src_df_libmodname
= 0;
1140 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1141 "source corr", dosizeonly
);
1142 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
1143 "source_corr (DECL SRC FILE)", dosizeonly
);
1144 totsize
+= write_debug_data1
1145 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
,
1146 "source_corr (length)", dosizeonly
);
1148 totsize
+= write_debug_data1
1149 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
,
1150 "source_corr (flags)", dosizeonly
);
1152 totsize
+= write_debug_data2
1153 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
,
1154 "source_corr (fileid)", dosizeonly
);
1156 totsize
+= write_debug_data8
1157 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
,
1158 "source_corr (creation date)", dosizeonly
);
1160 totsize
+= write_debug_data4
1161 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
,
1162 "source_corr (EOF block number)", dosizeonly
);
1164 totsize
+= write_debug_data2
1165 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
,
1166 "source_corr (first free byte)", dosizeonly
);
1168 totsize
+= write_debug_data1
1169 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
,
1170 "source_corr (record and file organization)", dosizeonly
);
1172 totsize
+= write_debug_data1
1173 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
,
1174 "source_corr (filename length)", dosizeonly
);
1176 totsize
+= write_debug_string (file_info_entry
.file_name
,
1177 "source file name", dosizeonly
);
1178 totsize
+= write_debug_data1 (src_cmdtrlr
.dst_b_src_df_libmodname
,
1179 "source_corr (libmodname)", dosizeonly
);
1181 src_command_sf
.dst_b_src_command
= DST_K_SRC_SETFILE
;
1182 src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
= fileid
;
1184 src_command_sr
.dst_b_src_command
= DST_K_SRC_SETREC_W
;
1185 src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
= 1;
1187 src_command_sl
.dst_b_src_command
= DST_K_SRC_SETLNUM_L
;
1188 src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
= linestart
+ 1;
1190 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1192 if (linesleft
> 65534)
1193 linesleft
= linesleft
- 65534, linestodo
= 65534;
1195 linestodo
= linesleft
, linesleft
= 0;
1197 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1199 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1200 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 + 3 + 5 + 3 - 1;
1201 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1204 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1205 "source corr", dosizeonly
);
1207 totsize
+= write_debug_data1 (src_command_sf
.dst_b_src_command
,
1208 "source_corr (src setfile)", dosizeonly
);
1210 totsize
+= write_debug_data2
1211 (src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1212 "source_corr (fileid)", dosizeonly
);
1214 totsize
+= write_debug_data1 (src_command_sr
.dst_b_src_command
,
1215 "source_corr (setrec)", dosizeonly
);
1217 totsize
+= write_debug_data2
1218 (src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1219 "source_corr (recnum)", dosizeonly
);
1221 totsize
+= write_debug_data1 (src_command_sl
.dst_b_src_command
,
1222 "source_corr (setlnum)", dosizeonly
);
1224 totsize
+= write_debug_data4
1225 (src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
,
1226 "source_corr (linenum)", dosizeonly
);
1228 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1229 "source_corr (deflines)", dosizeonly
);
1231 sprintf (buff
, "source_corr (%d)",
1232 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1233 totsize
+= write_debug_data2
1234 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
, buff
, dosizeonly
);
1236 while (linesleft
> 0)
1238 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1239 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 - 1;
1240 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1242 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1244 if (linesleft
> 65534)
1245 linesleft
= linesleft
- 65534, linestodo
= 65534;
1247 linestodo
= linesleft
, linesleft
= 0;
1249 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1251 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1252 "source corr", dosizeonly
);
1253 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1254 "source_corr (deflines)", dosizeonly
);
1255 sprintf (buff
, "source_corr (%d)",
1256 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1257 totsize
+= write_debug_data2
1258 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1265 /* Output all the source correlation entries and return the size. Just return
1266 the size if DOSIZEONLY is non-zero. */
1269 write_srccorrs (dosizeonly
)
1275 for (i
= 1; i
< file_info_table_in_use
; i
++)
1276 totsize
+= write_srccorr (i
, file_info_table
[i
], dosizeonly
);
1281 /* Output a marker (i.e. a label) for the beginning of a function, before
1285 vmsdbgout_begin_prologue (line
, file
)
1289 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1291 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1292 (*dwarf2_debug_hooks
.begin_prologue
) (line
, file
);
1294 if (debug_info_level
> DINFO_LEVEL_NONE
)
1296 current_funcdef_number
++;
1297 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_BEGIN_LABEL
,
1298 current_funcdef_number
);
1299 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1303 /* Output a marker (i.e. a label) for the beginning of a function, after
1307 vmsdbgout_after_prologue ()
1309 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1311 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1313 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
,
1314 current_funcdef_number
);
1315 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1319 /* Output a marker (i.e. a label) for the absolute end of the generated code
1320 for a function definition. This gets called *after* the epilogue code has
1324 vmsdbgout_end_epilogue ()
1326 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1328 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1329 (*dwarf2_debug_hooks
.end_epilogue
) ();
1331 if (debug_info_level
> DINFO_LEVEL_NONE
)
1333 /* Output a label to mark the endpoint of the code generated for this
1335 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_END_LABEL
,
1336 current_funcdef_number
);
1337 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1341 /* Output a marker (i.e. a label) for the beginning of the generated code for
1345 vmsdbgout_begin_block (line
, blocknum
)
1346 register unsigned line
;
1347 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 ASM_OUTPUT_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 (line
, blocknum
)
1361 register unsigned line
;
1362 register unsigned blocknum
;
1364 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1365 (*dwarf2_debug_hooks
.end_block
) (line
, blocknum
);
1367 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1368 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, BLOCK_END_LABEL
, blocknum
);
1371 /* Not implemented in VMS Debug. */
1374 vmsdbgout_ignore_block (block
)
1379 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1380 retval
= (*dwarf2_debug_hooks
.ignore_block
) (block
);
1385 /* Add an entry for function DECL into the func_table. */
1388 vmsdbgout_begin_function (decl
)
1391 const char *name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
1393 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1394 (*dwarf2_debug_hooks
.begin_function
) (decl
);
1396 if (func_table_in_use
== func_table_allocated
)
1398 func_table_allocated
+= FUNC_TABLE_INCREMENT
;
1399 func_table
= (char **) xrealloc (func_table
,
1400 func_table_allocated
* sizeof (char *));
1403 /* Add the new entry to the end of the function name table. */
1404 func_table
[func_table_in_use
++] = xstrdup (name
);
1407 static char fullname_buff
[4096];
1409 /* Return the full file specification for FILENAME. The specification must be
1410 in VMS syntax in order to be processed by VMS Debug. */
1413 full_name (filename
)
1414 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 (file_name
)
1446 const char *file_name
;
1448 static unsigned int last_file_lookup_index
= 0;
1450 register unsigned i
;
1457 struct stat statbuf
;
1459 if (stat (file_name
, &statbuf
) == 0)
1461 cdt
= 10000000 * (statbuf
.st_ctime
+ vms_epoch_offset
);
1462 ebk
= statbuf
.st_size
/ 512 + 1;
1463 ffb
= statbuf
.st_size
- ((statbuf
.st_size
/ 512) * 512);
1465 rfo
= statbuf
.st_fab_rfm
;
1467 /* Assume stream LF type file */
1470 fnam
= full_name (file_name
);
1471 flen
= strlen (fnam
);
1483 /* Check to see if the file name that was searched on the previous call
1484 matches this file name. If so, return the index. */
1485 if (last_file_lookup_index
!= 0)
1487 fn
= file_info_table
[last_file_lookup_index
].file_name
;
1488 if (strcmp (fnam
, fn
) == 0)
1489 return last_file_lookup_index
;
1492 /* Didn't match the previous lookup, search the table */
1493 for (i
= 1; i
< file_info_table_in_use
; ++i
)
1495 fn
= file_info_table
[i
].file_name
;
1496 if (strcmp (fnam
, fn
) == 0)
1498 last_file_lookup_index
= i
;
1503 /* Prepare to add a new table entry by making sure there is enough space in
1504 the table to do so. If not, expand the current table. */
1505 if (file_info_table_in_use
== file_info_table_allocated
)
1508 file_info_table_allocated
+= FILE_TABLE_INCREMENT
;
1510 = (dst_file_info_ref
) xrealloc (file_info_table
,
1511 (file_info_table_allocated
1512 * sizeof (dst_file_info_entry
)));
1515 /* Add the new entry to the end of the filename table. */
1516 file_info_table
[file_info_table_in_use
].file_name
= xstrdup (fnam
);
1517 file_info_table
[file_info_table_in_use
].max_line
= 0;
1518 file_info_table
[file_info_table_in_use
].cdt
= cdt
;
1519 file_info_table
[file_info_table_in_use
].ebk
= ebk
;
1520 file_info_table
[file_info_table_in_use
].ffb
= ffb
;
1521 file_info_table
[file_info_table_in_use
].rfo
= rfo
;
1522 file_info_table
[file_info_table_in_use
].flen
= flen
;
1524 last_file_lookup_index
= file_info_table_in_use
++;
1525 return last_file_lookup_index
;
1528 /* Output a label to mark the beginning of a source code line entry
1529 and record information relating to this source line, in
1530 'line_info_table' for later output of the .debug_line section. */
1533 vmsdbgout_source_line (line
, filename
)
1534 register unsigned line
;
1535 register const char *filename
;
1537 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1538 (*dwarf2_debug_hooks
.source_line
) (line
, filename
);
1540 if (debug_info_level
>= DINFO_LEVEL_TERSE
)
1542 dst_line_info_ref line_info
;
1544 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, LINE_CODE_LABEL
,
1545 line_info_table_in_use
);
1547 /* Expand the line info table if necessary. */
1548 if (line_info_table_in_use
== line_info_table_allocated
)
1550 line_info_table_allocated
+= LINE_INFO_TABLE_INCREMENT
;
1552 = (dst_line_info_ref
) xrealloc (line_info_table
,
1553 (line_info_table_allocated
1554 * sizeof (dst_line_info_entry
)));
1557 /* Add the new entry at the end of the line_info_table. */
1558 line_info
= &line_info_table
[line_info_table_in_use
++];
1559 line_info
->dst_file_num
= lookup_filename (filename
);
1560 line_info
->dst_line_num
= line
;
1561 if (line
> file_info_table
[line_info
->dst_file_num
].max_line
)
1562 file_info_table
[line_info
->dst_file_num
].max_line
= line
;
1566 /* Record the beginning of a new source file, for later output.
1567 At present, unimplemented. */
1570 vmsdbgout_start_source_file (lineno
, filename
)
1571 unsigned int lineno
;
1572 const char *filename
;
1574 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1575 (*dwarf2_debug_hooks
.start_source_file
) (lineno
, filename
);
1578 /* Record the end of a source file, for later output.
1579 At present, unimplemented. */
1582 vmsdbgout_end_source_file (lineno
)
1583 unsigned int lineno ATTRIBUTE_UNUSED
;
1585 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1586 (*dwarf2_debug_hooks
.end_source_file
) (lineno
);
1589 /* Set up for Debug output at the start of compilation. */
1592 vmsdbgout_init (main_input_filename
)
1593 const char *main_input_filename
;
1595 const char *language_string
= lang_hooks
.name
;
1597 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1598 (*dwarf2_debug_hooks
.init
) (main_input_filename
);
1600 if (debug_info_level
== DINFO_LEVEL_NONE
)
1603 /* Remember the name of the primary input file. */
1604 primary_filename
= main_input_filename
;
1606 /* Allocate the initial hunk of the file_info_table. */
1608 = (dst_file_info_ref
) xcalloc (FILE_TABLE_INCREMENT
,
1609 sizeof (dst_file_info_entry
));
1610 file_info_table_allocated
= FILE_TABLE_INCREMENT
;
1612 /* Skip the first entry - file numbers begin at 1 */
1613 file_info_table_in_use
= 1;
1615 func_table
= (char **) xcalloc (FUNC_TABLE_INCREMENT
, sizeof (char *));
1616 func_table_allocated
= FUNC_TABLE_INCREMENT
;
1617 func_table_in_use
= 1;
1619 /* Allocate the initial hunk of the line_info_table. */
1621 = (dst_line_info_ref
) xcalloc (LINE_INFO_TABLE_INCREMENT
,
1622 sizeof (dst_line_info_entry
));
1623 line_info_table_allocated
= LINE_INFO_TABLE_INCREMENT
;
1624 /* zero-th entry is allocated, but unused */
1625 line_info_table_in_use
= 1;
1627 lookup_filename (primary_filename
);
1629 if (!strcmp (language_string
, "GNU C"))
1630 module_language
= DST_K_C
;
1631 else if (!strcmp (language_string
, "GNU C++"))
1632 module_language
= DST_K_CXX
;
1633 else if (!strcmp (language_string
, "GNU Ada"))
1634 module_language
= DST_K_ADA
;
1635 else if (!strcmp (language_string
, "GNU F77"))
1636 module_language
= DST_K_FORTRAN
;
1638 module_language
= DST_K_UNKNOWN
;
1641 = (char *) xmalloc (strlen (language_string
) + 1
1642 + strlen (version_string
+ 1));
1643 sprintf (module_producer
, "%s %s", language_string
, version_string
);
1645 ASM_GENERATE_INTERNAL_LABEL (text_end_label
, TEXT_END_LABEL
, 0);
1649 /* Not implemented in VMS Debug. */
1652 vmsdbgout_define (lineno
, buffer
)
1653 unsigned int lineno
;
1656 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1657 (*dwarf2_debug_hooks
.define
) (lineno
, buffer
);
1660 /* Not implemented in VMS Debug. */
1663 vmsdbgout_undef (lineno
, buffer
)
1664 unsigned int lineno
;
1667 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1668 (*dwarf2_debug_hooks
.undef
) (lineno
, buffer
);
1671 /* Not implemented in VMS Debug. */
1674 vmsdbgout_decl (decl
)
1677 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1678 (*dwarf2_debug_hooks
.function_decl
) (decl
);
1681 /* Not implemented in VMS Debug. */
1684 vmsdbgout_global_decl (decl
)
1687 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1688 (*dwarf2_debug_hooks
.global_decl
) (decl
);
1691 /* Not implemented in VMS Debug. */
1694 vmsdbgout_abstract_function (decl
)
1697 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1698 (*dwarf2_debug_hooks
.outlining_inline_function
) (decl
);
1701 /* Output stuff that Debug requires at the end of every file and generate the
1702 VMS Debug debugging info. */
1705 vmsdbgout_finish (input_filename
)
1706 const char *input_filename ATTRIBUTE_UNUSED
;
1711 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1712 (*dwarf2_debug_hooks
.finish
) (input_filename
);
1714 if (debug_info_level
== DINFO_LEVEL_NONE
)
1717 /* Output a terminator label for the .text section. */
1719 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, TEXT_END_LABEL
, 0);
1721 /* Output debugging information.
1722 Warning! Do not change the name of the .vmsdebug section without
1723 changing it in the assembler also. */
1724 named_section (NULL_TREE
, ".vmsdebug", 0);
1725 ASM_OUTPUT_ALIGN (asm_out_file
, 0);
1727 totsize
= write_modbeg (1);
1728 for (i
= 1; i
< func_table_in_use
; i
++)
1730 totsize
+= write_rtnbeg (i
, 1);
1731 totsize
+= write_rtnend (i
, 1);
1733 totsize
+= write_pclines (1);
1736 for (i
= 1; i
< func_table_in_use
; i
++)
1738 write_rtnbeg (i
, 0);
1739 write_rtnend (i
, 0);
1743 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1745 totsize
= write_srccorrs (1);
1749 totsize
= write_modend (1);
1752 #endif /* VMS_DEBUGGING_INFO */