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
83 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
86 /* Pointer to an structure of filenames referenced by this compilation unit. */
87 static dst_file_info_ref file_info_table
;
89 /* Total number of entries in the table (i.e. array) pointed to by
90 `file_info_table'. This is the *total* and includes both used and unused
92 static unsigned int file_info_table_allocated
;
94 /* Number of entries in the file_info_table which are actually in use. */
95 static unsigned int file_info_table_in_use
;
97 /* Size (in elements) of increments by which we may expand the filename
99 #define FILE_TABLE_INCREMENT 64
101 static char **func_table
;
102 static unsigned int func_table_allocated
;
103 static unsigned int func_table_in_use
;
104 #define FUNC_TABLE_INCREMENT 256
106 /* Local pointer to the name of the main input file. Initialized in
108 static const char *primary_filename
;
110 static char *module_producer
;
111 static unsigned int module_language
;
113 /* A pointer to the base of a table that contains line information
114 for each source code line in .text in the compilation unit. */
115 static dst_line_info_ref line_info_table
;
117 /* Number of elements currently allocated for line_info_table. */
118 static unsigned int line_info_table_allocated
;
120 /* Number of elements in line_info_table currently in use. */
121 static unsigned int line_info_table_in_use
;
123 /* Size (in elements) of increments by which we may expand line_info_table. */
124 #define LINE_INFO_TABLE_INCREMENT 1024
126 /* The number of the current function definition for which debugging
127 information is being generated. These numbers range from 1 up to the
128 maximum number of function definitions contained within the current
129 compilation unit. These numbers are used to create unique label id's unique
130 to each function definition. */
131 static unsigned int current_funcdef_number
= 0;
133 /* Forward declarations for functions defined in this file. */
134 static char *full_name
PARAMS ((const char *));
135 static unsigned int lookup_filename
PARAMS ((const char *));
136 static void addr_const_to_string
PARAMS ((char *, rtx
));
137 static int write_debug_header
PARAMS ((DST_HEADER
*, const char *, int));
138 static int write_debug_addr
PARAMS ((char *, const char *, int));
139 static int write_debug_data1
PARAMS ((unsigned int, const char *, int));
140 static int write_debug_data2
PARAMS ((unsigned int, const char *, int));
141 static int write_debug_data4
PARAMS ((unsigned long, const char *, int));
142 static int write_debug_data8
PARAMS ((unsigned long long, const char *,
144 static int write_debug_delta4
PARAMS ((char *, char *, const char *, int));
145 static int write_debug_string
PARAMS ((char *, const char *, int));
146 static int write_modbeg
PARAMS ((int));
147 static int write_modend
PARAMS ((int));
148 static int write_rtnbeg
PARAMS ((int, int));
149 static int write_rtnend
PARAMS ((int, int));
150 static int write_pclines
PARAMS ((int));
151 static int write_srccorr
PARAMS ((int, dst_file_info_entry
, int));
152 static int write_srccorrs
PARAMS ((int));
154 static void vmsdbgout_init
PARAMS ((const char *));
155 static void vmsdbgout_finish
PARAMS ((const char *));
156 static void vmsdbgout_define
PARAMS ((unsigned int, const char *));
157 static void vmsdbgout_undef
PARAMS ((unsigned int, const char *));
158 static void vmsdbgout_start_source_file
PARAMS ((unsigned int, const char *));
159 static void vmsdbgout_end_source_file
PARAMS ((unsigned int));
160 static void vmsdbgout_begin_block
PARAMS ((unsigned int, unsigned int));
161 static void vmsdbgout_end_block
PARAMS ((unsigned int, unsigned int));
162 static bool vmsdbgout_ignore_block
PARAMS ((tree
));
163 static void vmsdbgout_source_line
PARAMS ((unsigned int, const char *));
164 static void vmsdbgout_begin_prologue
PARAMS ((unsigned int, const char *));
165 static void vmsdbgout_end_epilogue
PARAMS ((void));
166 static void vmsdbgout_begin_function
PARAMS ((tree
));
167 static void vmsdbgout_decl
PARAMS ((tree
));
168 static void vmsdbgout_global_decl
PARAMS ((tree
));
169 static void vmsdbgout_abstract_function
PARAMS ((tree
));
171 /* The debug hooks structure. */
173 const struct gcc_debug_hooks vmsdbg_debug_hooks
178 vmsdbgout_start_source_file
,
179 vmsdbgout_end_source_file
,
180 vmsdbgout_begin_block
,
182 vmsdbgout_ignore_block
,
183 vmsdbgout_source_line
,
184 vmsdbgout_begin_prologue
,
185 debug_nothing_int
, /* end_prologue */
186 vmsdbgout_end_epilogue
, /* end_epilogue */
187 vmsdbgout_begin_function
, /* begin_function */
188 debug_nothing_int
, /* end_function */
190 vmsdbgout_global_decl
,
191 debug_nothing_tree
, /* deferred_inline_function */
192 vmsdbgout_abstract_function
,
193 debug_nothing_rtx
/* label */
196 /* Definitions of defaults for assembler-dependent names of various
197 pseudo-ops and section names.
198 Theses may be overridden in the tm.h file (if necessary) for a particular
200 #ifdef UNALIGNED_SHORT_ASM_OP
201 #undef UNALIGNED_SHORT_ASM_OP
203 #define UNALIGNED_SHORT_ASM_OP ".word"
205 #ifdef UNALIGNED_INT_ASM_OP
206 #undef UNALIGNED_INT_ASM_OP
208 #define UNALIGNED_INT_ASM_OP ".long"
210 #ifdef UNALIGNED_LONG_ASM_OP
211 #undef UNALIGNED_LONG_ASM_OP
213 #define UNALIGNED_LONG_ASM_OP ".long"
215 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
216 #undef UNALIGNED_DOUBLE_INT_ASM_OP
218 #define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
223 #define ASM_BYTE_OP ".byte"
225 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
227 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
229 #ifndef UNALIGNED_PTR_ASM_OP
230 #define UNALIGNED_PTR_ASM_OP \
231 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
234 #ifndef UNALIGNED_OFFSET_ASM_OP
235 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
236 (NUMBYTES(OFFSET) == 4 \
237 ? UNALIGNED_LONG_ASM_OP \
238 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
241 /* Pseudo-op for defining a new section. */
242 #ifndef SECTION_ASM_OP
243 #define SECTION_ASM_OP ".section"
246 /* Definitions of defaults for formats and names of various special
247 (artificial) labels which may be generated within this file (when the -g
248 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
249 may be overridden from within the tm.h file, but typically, overriding these
250 defaults is unnecessary. */
252 static char text_end_label
[MAX_ARTIFICIAL_LABEL_BYTES
];
254 #ifndef TEXT_END_LABEL
255 #define TEXT_END_LABEL "Lvetext"
257 #ifndef FUNC_BEGIN_LABEL
258 #define FUNC_BEGIN_LABEL "LVFB"
260 #ifndef FUNC_PROLOG_LABEL
261 #define FUNC_PROLOG_LABEL "LVFP"
263 #ifndef FUNC_END_LABEL
264 #define FUNC_END_LABEL "LVFE"
266 #ifndef BLOCK_BEGIN_LABEL
267 #define BLOCK_BEGIN_LABEL "LVBB"
269 #ifndef BLOCK_END_LABEL
270 #define BLOCK_END_LABEL "LVBE"
272 #ifndef LINE_CODE_LABEL
273 #define LINE_CODE_LABEL "LVM"
276 #ifndef ASM_OUTPUT_DEBUG_DELTA2
277 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
280 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
281 assemble_name (FILE, LABEL1); \
282 fprintf (FILE, "-"); \
283 assemble_name (FILE, LABEL2); \
288 #ifndef ASM_OUTPUT_DEBUG_DELTA4
289 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
292 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
293 assemble_name (FILE, LABEL1); \
294 fprintf (FILE, "-"); \
295 assemble_name (FILE, LABEL2); \
300 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
301 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
304 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
305 assemble_name (FILE, LABEL1); \
306 fprintf (FILE, "-"); \
307 assemble_name (FILE, LABEL2); \
312 #ifndef ASM_OUTPUT_DEBUG_ADDR
313 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
316 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
317 assemble_name (FILE, LABEL); \
322 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
323 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
324 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
327 #ifndef ASM_OUTPUT_DEBUG_DATA1
328 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
329 fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned char) VALUE)
332 #ifndef ASM_OUTPUT_DEBUG_DATA2
333 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
334 fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, \
335 (unsigned short) VALUE)
338 #ifndef ASM_OUTPUT_DEBUG_DATA4
339 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
340 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
343 #ifndef ASM_OUTPUT_DEBUG_DATA
344 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
345 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
348 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
349 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
350 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_PTR_ASM_OP, \
351 (unsigned long) VALUE)
354 #ifndef ASM_OUTPUT_DEBUG_DATA8
355 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
356 fprintf ((FILE), "\t%s\t0x%llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
357 (unsigned long long) VALUE)
360 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
361 newline is produced. When flag_verbose_asm is asserted, we add commnetary
362 at the end of the line, so we must avoid output of a newline here. */
363 #ifndef ASM_OUTPUT_DEBUG_STRING
364 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
367 register int slen = strlen(P); \
368 register char *p = (P); \
370 fprintf (FILE, "\t.ascii \""); \
371 for (i = 0; i < slen; i++) \
373 register int c = p[i]; \
374 if (c == '\"' || c == '\\') \
376 if (c >= ' ' && c < 0177) \
379 fprintf (FILE, "\\%o", c); \
381 fprintf (FILE, "\""); \
386 /* Convert a reference to the assembler name of a C-level name. This
387 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
388 a string rather than writing to a file. */
389 #ifndef ASM_NAME_TO_STRING
390 #define ASM_NAME_TO_STRING(STR, NAME) \
393 if ((NAME)[0] == '*') \
394 strcpy (STR, NAME+1); \
396 strcpy (STR, NAME); \
402 /* General utility functions. */
404 /* Convert an integer constant expression into assembler syntax. Addition and
405 subtraction are the only arithmetic that may appear in these expressions.
406 This is an adaptation of output_addr_const in final.c. Here, the target
407 of the conversion is a string buffer. We can't use output_addr_const
408 directly, because it writes to a file. */
411 addr_const_to_string (str
, x
)
420 switch (GET_CODE (x
))
430 ASM_NAME_TO_STRING (buf1
, XSTR (x
, 0));
435 ASM_GENERATE_INTERNAL_LABEL (buf1
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
436 ASM_NAME_TO_STRING (buf2
, buf1
);
441 ASM_GENERATE_INTERNAL_LABEL (buf1
, "L", CODE_LABEL_NUMBER (x
));
442 ASM_NAME_TO_STRING (buf2
, buf1
);
447 sprintf (buf1
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
452 /* This used to output parentheses around the expression, but that does
453 not work on the 386 (either ATT or BSD assembler). */
454 addr_const_to_string (buf1
, XEXP (x
, 0));
459 if (GET_MODE (x
) == VOIDmode
)
461 /* We can use %d if the number is one word and positive. */
462 if (CONST_DOUBLE_HIGH (x
))
463 sprintf (buf1
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
464 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
465 else if (CONST_DOUBLE_LOW (x
) < 0)
466 sprintf (buf1
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
468 sprintf (buf1
, HOST_WIDE_INT_PRINT_DEC
,
469 CONST_DOUBLE_LOW (x
));
473 /* We can't handle floating point constants; PRINT_OPERAND must
475 output_operand_lossage ("floating constant misused");
479 /* Some assemblers need integer constants to appear last (eg masm). */
480 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
482 addr_const_to_string (buf1
, XEXP (x
, 1));
484 if (INTVAL (XEXP (x
, 0)) >= 0)
486 addr_const_to_string (buf1
, XEXP (x
, 0));
491 addr_const_to_string (buf1
, XEXP (x
, 0));
493 if (INTVAL (XEXP (x
, 1)) >= 0)
495 addr_const_to_string (buf1
, XEXP (x
, 1));
501 /* Avoid outputting things like x-x or x+5-x, since some assemblers
502 can't handle that. */
503 x
= simplify_subtraction (x
);
504 if (GET_CODE (x
) != MINUS
)
507 addr_const_to_string (buf1
, XEXP (x
, 0));
510 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
511 && INTVAL (XEXP (x
, 1)) < 0)
514 addr_const_to_string (buf1
, XEXP (x
, 1));
520 addr_const_to_string (buf1
, XEXP (x
, 1));
527 addr_const_to_string (buf1
, XEXP (x
, 0));
532 output_operand_lossage ("invalid expression as operand");
536 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
537 set. Return the header size. Just return the size if DOSIZEONLY is
541 write_debug_header (header
, comment
, dosizeonly
)
548 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
549 header
->dst__header_length
.dst_w_length
);
551 if (flag_verbose_asm
)
552 fprintf (asm_out_file
, "\t%s record length", ASM_COMMENT_START
);
553 fputc ('\n', asm_out_file
);
555 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
556 header
->dst__header_type
.dst_w_type
);
558 if (flag_verbose_asm
)
559 fprintf (asm_out_file
, "\t%s record type (%s)", ASM_COMMENT_START
,
562 fputc ('\n', asm_out_file
);
568 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
569 set. Return the address size. Just return the size if DOSIZEONLY is
573 write_debug_addr (symbol
, comment
, dosizeonly
)
580 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, symbol
);
581 if (flag_verbose_asm
)
582 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
583 fputc ('\n', asm_out_file
);
589 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
590 set. Return the data size. Just return the size if DOSIZEONLY is
594 write_debug_data1 (data1
, comment
, dosizeonly
)
601 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file
, data1
);
602 if (flag_verbose_asm
)
603 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
604 fputc ('\n', asm_out_file
);
610 /* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
611 set. Return the data size. Just return the size if DOSIZEONLY is
615 write_debug_data2 (data2
, comment
, dosizeonly
)
622 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
, data2
);
623 if (flag_verbose_asm
)
624 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
625 fputc ('\n', asm_out_file
);
631 /* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
632 Return the data size. Just return the size if DOSIZEONLY is non-zero. */
635 write_debug_data4 (data4
, comment
, dosizeonly
)
642 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file
, data4
);
643 if (flag_verbose_asm
)
644 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
645 fputc ('\n', asm_out_file
);
651 /* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
652 Return the data size. Just return the size if DOSIZEONLY is non-zero. */
655 write_debug_data8 (data8
, comment
, dosizeonly
)
656 unsigned long long data8
;
662 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file
, data8
);
663 if (flag_verbose_asm
)
664 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
665 fputc ('\n', asm_out_file
);
671 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
672 flag_verbose_asm is set. Return the data size. Just return the size if
673 DOSIZEONLY is non-zero. */
676 write_debug_delta4 (label1
, label2
, comment
, dosizeonly
)
684 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file
, label1
, label2
);
685 if (flag_verbose_asm
)
686 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
687 fputc ('\n', asm_out_file
);
693 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
694 set. Return the string length. Just return the length if DOSIZEONLY is
698 write_debug_string (string
, comment
, dosizeonly
)
705 ASM_OUTPUT_DEBUG_STRING (asm_out_file
, string
);
706 if (flag_verbose_asm
)
707 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
708 fputc ('\n', asm_out_file
);
711 return strlen (string
);
714 /* Output a module begin header and return the header size. Just return the
715 size if DOSIZEONLY is non-zero. */
718 write_modbeg (dosizeonly
)
721 DST_MODULE_BEGIN modbeg
;
724 char *module_name
, *m
;
729 /* Assumes primary filename has Unix syntax file spec. */
730 module_name
= xstrdup (basename ((char *) primary_filename
));
732 m
= strrchr (module_name
, '.');
736 modnamelen
= strlen (module_name
);
737 for (i
= 0; i
< modnamelen
; i
++)
738 module_name
[i
] = TOUPPER (module_name
[i
]);
740 prodnamelen
= strlen (module_producer
);
742 modbeg
.dst_a_modbeg_header
.dst__header_length
.dst_w_length
743 = DST_K_MODBEG_SIZE
+ modnamelen
+ DST_K_MB_TRLR_SIZE
+ prodnamelen
- 1;
744 modbeg
.dst_a_modbeg_header
.dst__header_type
.dst_w_type
= DST_K_MODBEG
;
745 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_hide
= 0;
746 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_version
= 1;
747 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_unused
= 0;
748 modbeg
.dst_b_modbeg_unused
= 0;
749 modbeg
.dst_l_modbeg_language
= module_language
;
750 modbeg
.dst_w_version_major
= DST_K_VERSION_MAJOR
;
751 modbeg
.dst_w_version_minor
= DST_K_VERSION_MINOR
;
752 modbeg
.dst_b_modbeg_name
= strlen (module_name
);
754 mb_trlr
.dst_b_compiler
= strlen (module_producer
);
756 totsize
+= write_debug_header (&modbeg
.dst_a_modbeg_header
,
757 "modbeg", dosizeonly
);
758 totsize
+= write_debug_data1 (*((char *) &modbeg
.dst_b_modbeg_flags
),
759 "flags", dosizeonly
);
760 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_unused
,
761 "unused", dosizeonly
);
762 totsize
+= write_debug_data4 (modbeg
.dst_l_modbeg_language
,
763 "language", dosizeonly
);
764 totsize
+= write_debug_data2 (modbeg
.dst_w_version_major
,
765 "DST major version", dosizeonly
);
766 totsize
+= write_debug_data2 (modbeg
.dst_w_version_minor
,
767 "DST minor version", dosizeonly
);
768 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_name
,
769 "length of module name", dosizeonly
);
770 totsize
+= write_debug_string (module_name
, "module name", dosizeonly
);
771 totsize
+= write_debug_data1 (mb_trlr
.dst_b_compiler
,
772 "length of compiler name", dosizeonly
);
773 totsize
+= write_debug_string (module_producer
, "compiler name", dosizeonly
);
778 /* Output a module end trailer and return the trailer size. Just return
779 the size if DOSIZEONLY is non-zero. */
782 write_modend (dosizeonly
)
785 DST_MODULE_END modend
;
788 modend
.dst_a_modend_header
.dst__header_length
.dst_w_length
789 = DST_K_MODEND_SIZE
- 1;
790 modend
.dst_a_modend_header
.dst__header_type
.dst_w_type
= DST_K_MODEND
;
792 totsize
+= write_debug_header (&modend
.dst_a_modend_header
, "modend",
798 /* Output a routine begin header routine RTNNUM and return the header size.
799 Just return the size if DOSIZEONLY is non-zero. */
802 write_rtnbeg (rtnnum
, dosizeonly
)
807 int rtnnamelen
, rtnentrynamelen
;
810 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
811 DST_ROUTINE_BEGIN rtnbeg
;
814 rtnname
= func_table
[rtnnum
];
815 rtnnamelen
= strlen (rtnname
);
816 rtnentrynamelen
= rtnnamelen
+ 4; /* "..en" */
817 rtnentryname
= (char *) xmalloc (rtnentrynamelen
+ 1);
818 strcpy (rtnentryname
, rtnname
);
819 strcat (rtnentryname
, "..en");
821 if (!strcmp (rtnname
, "main"))
824 const char *go
= "TRANSFER$BREAK$GO";
826 /* This command isn't documented in DSTRECORDS, so it's made to
827 look like what DEC C does */
829 /* header size - 1st byte + flag byte + STO_LW size
830 + string count byte + string length */
831 header
.dst__header_length
.dst_w_length
832 = DST_K_DST_HEADER_SIZE
- 1 + 1 + 4 + 1 + strlen (go
);
833 header
.dst__header_type
.dst_w_type
= 0x17;
835 totsize
+= write_debug_header (&header
, "transfer", dosizeonly
);
837 /* I think this is a flag byte, but I don't know what this flag means */
838 totsize
+= write_debug_data1 (0x1, "flags ???", dosizeonly
);
840 /* Routine Begin PD Address */
841 totsize
+= write_debug_addr (rtnname
, "main procedure descriptor",
843 totsize
+= write_debug_data1 (strlen (go
), "length of main_name",
845 totsize
+= write_debug_string ((char *) go
, "main name", dosizeonly
);
848 /* The header length never includes the length byte */
849 rtnbeg
.dst_a_rtnbeg_header
.dst__header_length
.dst_w_length
850 = DST_K_RTNBEG_SIZE
+ rtnnamelen
- 1;
851 rtnbeg
.dst_a_rtnbeg_header
.dst__header_type
.dst_w_type
= DST_K_RTNBEG
;
852 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unused
= 0;
853 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unalloc
= 0;
854 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_prototype
= 0;
855 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_inlined
= 0;
856 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_no_call
= 1;
857 rtnbeg
.dst_b_rtnbeg_name
= rtnnamelen
;
859 totsize
+= write_debug_header (&rtnbeg
.dst_a_rtnbeg_header
, "rtnbeg",
861 totsize
+= write_debug_data1 (*((char *) &rtnbeg
.dst_b_rtnbeg_flags
),
862 "flags", dosizeonly
);
864 /* Routine Begin Address */
865 totsize
+= write_debug_addr (rtnentryname
, "routine entry name", dosizeonly
);
867 /* Routine Begin PD Address */
868 totsize
+= write_debug_addr (rtnname
, "routine procedure descriptor",
871 /* Routine Begin Name */
872 totsize
+= write_debug_data1 (rtnbeg
.dst_b_rtnbeg_name
,
873 "length of routine name", dosizeonly
);
875 totsize
+= write_debug_string (rtnname
, "routine name", dosizeonly
);
879 if (debug_info_level
> DINFO_LEVEL_TERSE
)
881 prolog
.dst_a_prolog_header
.dst__header_length
.dst_w_length
882 = DST_K_PROLOG_SIZE
- 1;
883 prolog
.dst_a_prolog_header
.dst__header_type
.dst_w_type
= DST_K_PROLOG
;
885 totsize
+= write_debug_header (&prolog
.dst_a_prolog_header
, "prolog",
888 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
, rtnnum
);
889 totsize
+= write_debug_addr (label
, "prolog breakpoint addr",
896 /* Output a routine end trailer for routine RTNNUM and return the header size.
897 Just return the size if DOSIZEONLY is non-zero. */
900 write_rtnend (rtnnum
, dosizeonly
)
904 DST_ROUTINE_END rtnend
;
905 char label1
[MAX_ARTIFICIAL_LABEL_BYTES
];
906 char label2
[MAX_ARTIFICIAL_LABEL_BYTES
];
911 rtnend
.dst_a_rtnend_header
.dst__header_length
.dst_w_length
912 = DST_K_RTNEND_SIZE
- 1;
913 rtnend
.dst_a_rtnend_header
.dst__header_type
.dst_w_type
= DST_K_RTNEND
;
914 rtnend
.dst_b_rtnend_unused
= 0;
915 rtnend
.dst_l_rtnend_size
= 0; /* Calculated below. */
917 totsize
+= write_debug_header (&rtnend
.dst_a_rtnend_header
, "rtnend",
919 totsize
+= write_debug_data1 (rtnend
.dst_b_rtnend_unused
, "unused",
922 ASM_GENERATE_INTERNAL_LABEL (label1
, FUNC_BEGIN_LABEL
, rtnnum
);
923 ASM_GENERATE_INTERNAL_LABEL (label2
, FUNC_END_LABEL
, rtnnum
);
924 totsize
+= write_debug_delta4 (label2
, label1
, "routine size", dosizeonly
);
929 #define K_DELTA_PC(I) \
930 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
932 #define K_SET_LINUM(I) \
933 ((I) < 256 ? DST_K_SET_LINUM_B \
934 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
936 #define K_INCR_LINUM(I) \
937 ((I) < 256 ? DST_K_INCR_LINUM \
938 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
940 /* Output the PC to line number correlations and return the size. Just return
941 the size if DOSIZEONLY is non-zero */
944 write_pclines (dosizeonly
)
952 DST_LINE_NUM_HEADER line_num
;
953 DST_PCLINE_COMMANDS pcline
;
954 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
955 char lastlabel
[MAX_ARTIFICIAL_LABEL_BYTES
];
959 max_line
= file_info_table
[1].max_line
;
960 file_info_table
[1].listing_line_start
= linestart
;
961 linestart
= linestart
+ ((max_line
/ 100000) + 1) * 100000;
963 for (i
= 2; i
< file_info_table_in_use
; i
++)
965 max_line
= file_info_table
[i
].max_line
;
966 file_info_table
[i
].listing_line_start
= linestart
;
967 linestart
= linestart
+ ((max_line
/ 10000) + 1) * 10000;
970 /* Set starting address to beginning of text section */
971 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 8;
972 line_num
.dst_a_line_num_header
.dst__header_type
.dst_w_type
= DST_K_LINE_NUM
;
973 pcline
.dst_b_pcline_command
= DST_K_SET_ABS_PC
;
975 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
976 "line_num", dosizeonly
);
977 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
978 "line_num (SET ABS PC)", dosizeonly
);
984 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, TEXT_SECTION_ASM_OP
);
985 if (flag_verbose_asm
)
986 fprintf (asm_out_file
, "\t%s line_num", ASM_COMMENT_START
);
987 fputc ('\n', asm_out_file
);
990 fn
= line_info_table
[1].dst_file_num
;
991 ln
= (file_info_table
[fn
].listing_line_start
992 + line_info_table
[1].dst_line_num
);
993 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 4 + 4;
994 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
996 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
997 "line_num", dosizeonly
);
998 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
999 "line_num (SET LINUM LONG)", dosizeonly
);
1001 sprintf (buff
, "line_num (%d)", ln
- 1);
1002 totsize
+= write_debug_data4 (ln
- 1, buff
, dosizeonly
);
1005 strcpy (lastlabel
, TEXT_SECTION_ASM_OP
);
1006 for (i
= 1; i
< line_info_table_in_use
; i
++)
1010 fn
= line_info_table
[i
].dst_file_num
;
1011 ln
= (file_info_table
[fn
].listing_line_start
1012 + line_info_table
[i
].dst_line_num
);
1014 if (ln
- lastln
> 1)
1015 extrabytes
= 5; /* NUMBYTES (ln - lastln - 1) + 1; */
1016 else if (ln
<= lastln
)
1017 extrabytes
= 5; /* NUMBYTES (ln - 1) + 1; */
1021 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
1024 totsize
+= write_debug_header
1025 (&line_num
.dst_a_line_num_header
, "line_num", dosizeonly
);
1027 if (ln
- lastln
> 1)
1029 int lndif
= ln
- lastln
- 1;
1031 /* K_INCR_LINUM (lndif); */
1032 pcline
.dst_b_pcline_command
= DST_K_INCR_LINUM_L
;
1034 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1035 "line_num (INCR LINUM LONG)",
1038 sprintf (buff
, "line_num (%d)", lndif
);
1039 totsize
+= write_debug_data4 (lndif
, buff
, dosizeonly
);
1041 else if (ln
<= lastln
)
1043 /* K_SET_LINUM (ln-1); */
1044 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
1046 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1047 "line_num (SET LINUM LONG)",
1050 sprintf (buff
, "line_num (%d)", ln
- 1);
1051 totsize
+= write_debug_data4 (ln
- 1, buff
, dosizeonly
);
1054 pcline
.dst_b_pcline_command
= DST_K_DELTA_PC_L
;
1056 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1057 "line_num (DELTA PC LONG)", dosizeonly
);
1059 ASM_GENERATE_INTERNAL_LABEL (label
, LINE_CODE_LABEL
, i
);
1060 totsize
+= write_debug_delta4 (label
, lastlabel
, "increment line_num",
1064 strcpy (lastlabel
, label
);
1070 /* Output a source correlation for file FILEID using information saved in
1071 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
1075 write_srccorr (fileid
, file_info_entry
, dosizeonly
)
1077 dst_file_info_entry file_info_entry
;
1080 int src_command_size
;
1081 int linesleft
= file_info_entry
.max_line
;
1082 int linestart
= file_info_entry
.listing_line_start
;
1083 int flen
= file_info_entry
.flen
;
1085 DST_SOURCE_CORR src_header
;
1086 DST_SRC_COMMAND src_command
;
1087 DST_SRC_COMMAND src_command_sf
;
1088 DST_SRC_COMMAND src_command_sl
;
1089 DST_SRC_COMMAND src_command_sr
;
1090 DST_SRC_COMMAND src_command_dl
;
1091 DST_SRC_CMDTRLR src_cmdtrlr
;
1097 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1098 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 1 - 1;
1099 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1101 src_command
.dst_b_src_command
= DST_K_SRC_FORMFEED
;
1103 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1104 "source corr", dosizeonly
);
1106 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
1107 "source_corr (SRC FORMFEED)",
1112 = DST_K_SRC_COMMAND_SIZE
+ flen
+ DST_K_SRC_CMDTRLR_SIZE
;
1113 src_command
.dst_b_src_command
= DST_K_SRC_DECLFILE
;
1114 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
1115 = src_command_size
- 2;
1116 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
= 0;
1117 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
1119 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
1120 = file_info_entry
.cdt
;
1121 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
1122 = file_info_entry
.ebk
;
1123 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
1124 = file_info_entry
.ffb
;
1125 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
1126 = file_info_entry
.rfo
;
1127 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
1128 = file_info_entry
.flen
;
1130 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1131 = DST_K_SOURCE_CORR_HEADER_SIZE
+ src_command_size
- 1;
1132 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1135 src_cmdtrlr
.dst_b_src_df_libmodname
= 0;
1137 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1138 "source corr", dosizeonly
);
1139 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
1140 "source_corr (DECL SRC FILE)", dosizeonly
);
1141 totsize
+= write_debug_data1
1142 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
,
1143 "source_corr (length)", dosizeonly
);
1145 totsize
+= write_debug_data1
1146 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
,
1147 "source_corr (flags)", dosizeonly
);
1149 totsize
+= write_debug_data2
1150 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
,
1151 "source_corr (fileid)", dosizeonly
);
1153 totsize
+= write_debug_data8
1154 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
,
1155 "source_corr (creation date)", dosizeonly
);
1157 totsize
+= write_debug_data4
1158 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
,
1159 "source_corr (EOF block number)", dosizeonly
);
1161 totsize
+= write_debug_data2
1162 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
,
1163 "source_corr (first free byte)", dosizeonly
);
1165 totsize
+= write_debug_data1
1166 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
,
1167 "source_corr (record and file organization)", dosizeonly
);
1169 totsize
+= write_debug_data1
1170 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
,
1171 "source_corr (filename length)", dosizeonly
);
1173 totsize
+= write_debug_string (file_info_entry
.file_name
,
1174 "source file name", dosizeonly
);
1175 totsize
+= write_debug_data1 (src_cmdtrlr
.dst_b_src_df_libmodname
,
1176 "source_corr (libmodname)", dosizeonly
);
1178 src_command_sf
.dst_b_src_command
= DST_K_SRC_SETFILE
;
1179 src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
= fileid
;
1181 src_command_sr
.dst_b_src_command
= DST_K_SRC_SETREC_W
;
1182 src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
= 1;
1184 src_command_sl
.dst_b_src_command
= DST_K_SRC_SETLNUM_L
;
1185 src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
= linestart
+ 1;
1187 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1189 if (linesleft
> 65534)
1190 linesleft
= linesleft
- 65534, linestodo
= 65534;
1192 linestodo
= linesleft
, linesleft
= 0;
1194 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1196 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1197 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 + 3 + 5 + 3 - 1;
1198 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1201 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1202 "source corr", dosizeonly
);
1204 totsize
+= write_debug_data1 (src_command_sf
.dst_b_src_command
,
1205 "source_corr (src setfile)", dosizeonly
);
1207 totsize
+= write_debug_data2
1208 (src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1209 "source_corr (fileid)", dosizeonly
);
1211 totsize
+= write_debug_data1 (src_command_sr
.dst_b_src_command
,
1212 "source_corr (setrec)", dosizeonly
);
1214 totsize
+= write_debug_data2
1215 (src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1216 "source_corr (recnum)", dosizeonly
);
1218 totsize
+= write_debug_data1 (src_command_sl
.dst_b_src_command
,
1219 "source_corr (setlnum)", dosizeonly
);
1221 totsize
+= write_debug_data4
1222 (src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
,
1223 "source_corr (linenum)", dosizeonly
);
1225 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1226 "source_corr (deflines)", dosizeonly
);
1228 sprintf (buff
, "source_corr (%d)",
1229 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1230 totsize
+= write_debug_data2
1231 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
, buff
, dosizeonly
);
1233 while (linesleft
> 0)
1235 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1236 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 - 1;
1237 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1239 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1241 if (linesleft
> 65534)
1242 linesleft
= linesleft
- 65534, linestodo
= 65534;
1244 linestodo
= linesleft
, linesleft
= 0;
1246 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1248 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1249 "source corr", dosizeonly
);
1250 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1251 "source_corr (deflines)", dosizeonly
);
1252 sprintf (buff
, "source_corr (%d)",
1253 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1254 totsize
+= write_debug_data2
1255 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1262 /* Output all the source correlation entries and return the size. Just return
1263 the size if DOSIZEONLY is non-zero. */
1266 write_srccorrs (dosizeonly
)
1272 for (i
= 1; i
< file_info_table_in_use
; i
++)
1273 totsize
+= write_srccorr (i
, file_info_table
[i
], dosizeonly
);
1278 /* Output a marker (i.e. a label) for the beginning of a function, before
1282 vmsdbgout_begin_prologue (line
, file
)
1286 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1288 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1289 (*dwarf2_debug_hooks
.begin_prologue
) (line
, file
);
1291 if (debug_info_level
> DINFO_LEVEL_NONE
)
1293 current_funcdef_number
++;
1294 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_BEGIN_LABEL
,
1295 current_funcdef_number
);
1296 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1300 /* Output a marker (i.e. a label) for the beginning of a function, after
1304 vmsdbgout_after_prologue ()
1306 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1308 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1310 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
,
1311 current_funcdef_number
);
1312 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1316 /* Output a marker (i.e. a label) for the absolute end of the generated code
1317 for a function definition. This gets called *after* the epilogue code has
1321 vmsdbgout_end_epilogue ()
1323 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1325 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1326 (*dwarf2_debug_hooks
.end_epilogue
) ();
1328 if (debug_info_level
> DINFO_LEVEL_NONE
)
1330 /* Output a label to mark the endpoint of the code generated for this
1332 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_END_LABEL
,
1333 current_funcdef_number
);
1334 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1338 /* Output a marker (i.e. a label) for the beginning of the generated code for
1342 vmsdbgout_begin_block (line
, blocknum
)
1343 register unsigned line
;
1344 register unsigned blocknum
;
1346 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1347 (*dwarf2_debug_hooks
.begin_block
) (line
, blocknum
);
1349 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1350 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, BLOCK_BEGIN_LABEL
, blocknum
);
1353 /* Output a marker (i.e. a label) for the end of the generated code for a
1357 vmsdbgout_end_block (line
, blocknum
)
1358 register unsigned line
;
1359 register unsigned blocknum
;
1361 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1362 (*dwarf2_debug_hooks
.end_block
) (line
, blocknum
);
1364 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1365 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, BLOCK_END_LABEL
, blocknum
);
1368 /* Not implemented in VMS Debug. */
1371 vmsdbgout_ignore_block (block
)
1376 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1377 retval
= (*dwarf2_debug_hooks
.ignore_block
) (block
);
1382 /* Add an entry for function DECL into the func_table. */
1385 vmsdbgout_begin_function (decl
)
1388 const char *name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
1390 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1391 (*dwarf2_debug_hooks
.begin_function
) (decl
);
1393 if (func_table_in_use
== func_table_allocated
)
1395 func_table_allocated
+= FUNC_TABLE_INCREMENT
;
1396 func_table
= (char **) xrealloc (func_table
,
1397 func_table_allocated
* sizeof (char *));
1400 /* Add the new entry to the end of the function name table. */
1401 func_table
[func_table_in_use
++] = xstrdup (name
);
1404 static char fullname_buff
[4096];
1406 /* Return the full file specification for FILENAME. The specification must be
1407 in VMS syntax in order to be processed by VMS Debug. */
1410 full_name (filename
)
1411 const char *filename
;
1414 FILE *fp
= fopen (filename
, "r");
1416 fgetname (fp
, fullname_buff
, 1);
1419 getcwd (fullname_buff
, sizeof (fullname_buff
));
1421 strcat (fullname_buff
, "/");
1422 strcat (fullname_buff
, filename
);
1424 /* ??? Insert hairy code here to translate Unix style file specification
1428 return fullname_buff
;
1431 /* Lookup a filename (in the list of filenames that we know about here in
1432 vmsdbgout.c) and return its "index". The index of each (known) filename is
1433 just a unique number which is associated with only that one filename. We
1434 need such numbers for the sake of generating labels and references
1435 to those files numbers. If the filename given as an argument is not
1436 found in our current list, add it to the list and assign it the next
1437 available unique index number. In order to speed up searches, we remember
1438 the index of the filename was looked up last. This handles the majority of
1442 lookup_filename (file_name
)
1443 const char *file_name
;
1445 static unsigned int last_file_lookup_index
= 0;
1447 register unsigned i
;
1454 struct stat statbuf
;
1456 if (stat (file_name
, &statbuf
) == 0)
1462 /* Adjust for GMT */
1463 ts
= (struct tm
*) localtime (&statbuf
.st_ctime
);
1464 gmtoff
= ts
->tm_gmtoff
;
1466 /* VMS has multiple file format types */
1467 rfo
= statbuf
.st_fab_rfm
;
1469 /* Is GMT adjustment an issue with a cross-compiler? */
1472 /* Assume stream LF type file */
1475 cdt
= 10000000 * (statbuf
.st_ctime
+ gmtoff
+ vms_epoch_offset
);
1476 ebk
= statbuf
.st_size
/ 512 + 1;
1477 ffb
= statbuf
.st_size
- ((statbuf
.st_size
/ 512) * 512);
1478 fnam
= full_name (file_name
);
1479 flen
= strlen (fnam
);
1491 /* Check to see if the file name that was searched on the previous call
1492 matches this file name. If so, return the index. */
1493 if (last_file_lookup_index
!= 0)
1495 fn
= file_info_table
[last_file_lookup_index
].file_name
;
1496 if (strcmp (fnam
, fn
) == 0)
1497 return last_file_lookup_index
;
1500 /* Didn't match the previous lookup, search the table */
1501 for (i
= 1; i
< file_info_table_in_use
; ++i
)
1503 fn
= file_info_table
[i
].file_name
;
1504 if (strcmp (fnam
, fn
) == 0)
1506 last_file_lookup_index
= i
;
1511 /* Prepare to add a new table entry by making sure there is enough space in
1512 the table to do so. If not, expand the current table. */
1513 if (file_info_table_in_use
== file_info_table_allocated
)
1516 file_info_table_allocated
+= FILE_TABLE_INCREMENT
;
1518 = (dst_file_info_ref
) xrealloc (file_info_table
,
1519 (file_info_table_allocated
1520 * sizeof (dst_file_info_entry
)));
1523 /* Add the new entry to the end of the filename table. */
1524 file_info_table
[file_info_table_in_use
].file_name
= xstrdup (fnam
);
1525 file_info_table
[file_info_table_in_use
].max_line
= 0;
1526 file_info_table
[file_info_table_in_use
].cdt
= cdt
;
1527 file_info_table
[file_info_table_in_use
].ebk
= ebk
;
1528 file_info_table
[file_info_table_in_use
].ffb
= ffb
;
1529 file_info_table
[file_info_table_in_use
].rfo
= rfo
;
1530 file_info_table
[file_info_table_in_use
].flen
= flen
;
1532 last_file_lookup_index
= file_info_table_in_use
++;
1533 return last_file_lookup_index
;
1536 /* Output a label to mark the beginning of a source code line entry
1537 and record information relating to this source line, in
1538 'line_info_table' for later output of the .debug_line section. */
1541 vmsdbgout_source_line (line
, filename
)
1542 register unsigned line
;
1543 register const char *filename
;
1545 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1546 (*dwarf2_debug_hooks
.source_line
) (line
, filename
);
1548 if (debug_info_level
>= DINFO_LEVEL_TERSE
)
1550 dst_line_info_ref line_info
;
1552 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, LINE_CODE_LABEL
,
1553 line_info_table_in_use
);
1555 /* Expand the line info table if necessary. */
1556 if (line_info_table_in_use
== line_info_table_allocated
)
1558 line_info_table_allocated
+= LINE_INFO_TABLE_INCREMENT
;
1560 = (dst_line_info_ref
) xrealloc (line_info_table
,
1561 (line_info_table_allocated
1562 * sizeof (dst_line_info_entry
)));
1565 /* Add the new entry at the end of the line_info_table. */
1566 line_info
= &line_info_table
[line_info_table_in_use
++];
1567 line_info
->dst_file_num
= lookup_filename (filename
);
1568 line_info
->dst_line_num
= line
;
1569 if (line
> file_info_table
[line_info
->dst_file_num
].max_line
)
1570 file_info_table
[line_info
->dst_file_num
].max_line
= line
;
1574 /* Record the beginning of a new source file, for later output.
1575 At present, unimplemented. */
1578 vmsdbgout_start_source_file (lineno
, filename
)
1579 unsigned int lineno
;
1580 const char *filename
;
1582 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1583 (*dwarf2_debug_hooks
.start_source_file
) (lineno
, filename
);
1586 /* Record the end of a source file, for later output.
1587 At present, unimplemented. */
1590 vmsdbgout_end_source_file (lineno
)
1591 unsigned int lineno ATTRIBUTE_UNUSED
;
1593 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1594 (*dwarf2_debug_hooks
.end_source_file
) (lineno
);
1597 /* Set up for Debug output at the start of compilation. */
1600 vmsdbgout_init (main_input_filename
)
1601 const char *main_input_filename
;
1603 const char *language_string
= lang_hooks
.name
;
1605 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1606 (*dwarf2_debug_hooks
.init
) (main_input_filename
);
1608 if (debug_info_level
== DINFO_LEVEL_NONE
)
1611 /* Remember the name of the primary input file. */
1612 primary_filename
= main_input_filename
;
1614 /* Allocate the initial hunk of the file_info_table. */
1616 = (dst_file_info_ref
) xcalloc (FILE_TABLE_INCREMENT
,
1617 sizeof (dst_file_info_entry
));
1618 file_info_table_allocated
= FILE_TABLE_INCREMENT
;
1620 /* Skip the first entry - file numbers begin at 1 */
1621 file_info_table_in_use
= 1;
1623 func_table
= (char **) xcalloc (FUNC_TABLE_INCREMENT
, sizeof (char *));
1624 func_table_allocated
= FUNC_TABLE_INCREMENT
;
1625 func_table_in_use
= 1;
1627 /* Allocate the initial hunk of the line_info_table. */
1629 = (dst_line_info_ref
) xcalloc (LINE_INFO_TABLE_INCREMENT
,
1630 sizeof (dst_line_info_entry
));
1631 line_info_table_allocated
= LINE_INFO_TABLE_INCREMENT
;
1632 /* zero-th entry is allocated, but unused */
1633 line_info_table_in_use
= 1;
1635 lookup_filename (primary_filename
);
1637 if (!strcmp (language_string
, "GNU C"))
1638 module_language
= DST_K_C
;
1639 else if (!strcmp (language_string
, "GNU C++"))
1640 module_language
= DST_K_CXX
;
1641 else if (!strcmp (language_string
, "GNU Ada"))
1642 module_language
= DST_K_ADA
;
1643 else if (!strcmp (language_string
, "GNU F77"))
1644 module_language
= DST_K_FORTRAN
;
1646 module_language
= DST_K_UNKNOWN
;
1649 = (char *) xmalloc (strlen (language_string
) + 1
1650 + strlen (version_string
) + 1);
1651 sprintf (module_producer
, "%s %s", language_string
, version_string
);
1653 ASM_GENERATE_INTERNAL_LABEL (text_end_label
, TEXT_END_LABEL
, 0);
1657 /* Not implemented in VMS Debug. */
1660 vmsdbgout_define (lineno
, buffer
)
1661 unsigned int lineno
;
1664 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1665 (*dwarf2_debug_hooks
.define
) (lineno
, buffer
);
1668 /* Not implemented in VMS Debug. */
1671 vmsdbgout_undef (lineno
, buffer
)
1672 unsigned int lineno
;
1675 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1676 (*dwarf2_debug_hooks
.undef
) (lineno
, buffer
);
1679 /* Not implemented in VMS Debug. */
1682 vmsdbgout_decl (decl
)
1685 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1686 (*dwarf2_debug_hooks
.function_decl
) (decl
);
1689 /* Not implemented in VMS Debug. */
1692 vmsdbgout_global_decl (decl
)
1695 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1696 (*dwarf2_debug_hooks
.global_decl
) (decl
);
1699 /* Not implemented in VMS Debug. */
1702 vmsdbgout_abstract_function (decl
)
1705 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1706 (*dwarf2_debug_hooks
.outlining_inline_function
) (decl
);
1709 /* Output stuff that Debug requires at the end of every file and generate the
1710 VMS Debug debugging info. */
1713 vmsdbgout_finish (input_filename
)
1714 const char *input_filename ATTRIBUTE_UNUSED
;
1719 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1720 (*dwarf2_debug_hooks
.finish
) (input_filename
);
1722 if (debug_info_level
== DINFO_LEVEL_NONE
)
1725 /* Output a terminator label for the .text section. */
1727 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file
, TEXT_END_LABEL
, 0);
1729 /* Output debugging information.
1730 Warning! Do not change the name of the .vmsdebug section without
1731 changing it in the assembler also. */
1732 named_section (NULL_TREE
, ".vmsdebug", 0);
1733 ASM_OUTPUT_ALIGN (asm_out_file
, 0);
1735 totsize
= write_modbeg (1);
1736 for (i
= 1; i
< func_table_in_use
; i
++)
1738 totsize
+= write_rtnbeg (i
, 1);
1739 totsize
+= write_rtnend (i
, 1);
1741 totsize
+= write_pclines (1);
1744 for (i
= 1; i
< func_table_in_use
; i
++)
1746 write_rtnbeg (i
, 0);
1747 write_rtnend (i
, 0);
1751 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1753 totsize
= write_srccorrs (1);
1757 totsize
= write_modend (1);
1760 #endif /* VMS_DEBUGGING_INFO */