1 /* Output VMS debug format symbol table information from GCC.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 Contributed by Douglas B. Rupp (rupp@gnat.com).
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 #include "coretypes.h"
28 #ifdef VMS_DEBUGGING_INFO
35 #include "langhooks.h"
39 /* Difference in seconds between the VMS Epoch and the Unix Epoch */
40 static const long long vms_epoch_offset
= 3506716800ll;
42 /* NOTE: In the comments in this file, many references are made to "Debug
43 Symbol Table". This term is abbreviated as `DST' throughout the remainder
46 typedef struct dst_line_info_struct
*dst_line_info_ref
;
48 /* Each entry in the line_info_table maintains the file and
49 line number associated with the label generated for that
50 entry. The label gives the PC value associated with
51 the line number entry. */
52 typedef struct dst_line_info_struct
54 unsigned long dst_file_num
;
55 unsigned long dst_line_num
;
59 typedef struct dst_file_info_struct
*dst_file_info_ref
;
61 typedef struct dst_file_info_struct
64 unsigned int max_line
;
65 unsigned int listing_line_start
;
74 /* How to start an assembler comment. */
75 #ifndef ASM_COMMENT_START
76 #define ASM_COMMENT_START ";#"
79 /* Maximum size (in bytes) of an artificially generated label. */
80 #define MAX_ARTIFICIAL_LABEL_BYTES 30
82 /* Make sure we know the sizes of the various types debug can describe. These
83 are only defaults. If the sizes are different for your target, you should
84 override these values by defining the appropriate symbols in your tm.h
87 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
90 /* Pointer to a structure of filenames referenced by this compilation unit. */
91 static dst_file_info_ref file_info_table
;
93 /* Total number of entries in the table (i.e. array) pointed to by
94 `file_info_table'. This is the *total* and includes both used and unused
96 static unsigned int file_info_table_allocated
;
98 /* Number of entries in the file_info_table which are actually in use. */
99 static unsigned int file_info_table_in_use
;
101 /* Size (in elements) of increments by which we may expand the filename
103 #define FILE_TABLE_INCREMENT 64
105 static char **func_table
;
106 static unsigned int func_table_allocated
;
107 static unsigned int func_table_in_use
;
108 #define FUNC_TABLE_INCREMENT 256
110 /* Local pointer to the name of the main input file. Initialized in
112 static const char *primary_filename
;
114 static char *module_producer
;
115 static unsigned int module_language
;
117 /* A pointer to the base of a table that contains line information
118 for each source code line in .text in the compilation unit. */
119 static dst_line_info_ref line_info_table
;
121 /* Number of elements currently allocated for line_info_table. */
122 static unsigned int line_info_table_allocated
;
124 /* Number of elements in line_info_table currently in use. */
125 static unsigned int line_info_table_in_use
;
127 /* Size (in elements) of increments by which we may expand line_info_table. */
128 #define LINE_INFO_TABLE_INCREMENT 1024
130 /* Forward declarations for functions defined in this file. */
131 static char *full_name (const char *);
132 static unsigned int lookup_filename (const char *);
133 static void addr_const_to_string (char *, rtx
);
134 static int write_debug_header (DST_HEADER
*, const char *, int);
135 static int write_debug_addr (char *, const char *, int);
136 static int write_debug_data1 (unsigned int, const char *, int);
137 static int write_debug_data2 (unsigned int, const char *, int);
138 static int write_debug_data4 (unsigned long, const char *, int);
139 static int write_debug_data8 (unsigned long long, const char *, int);
140 static int write_debug_delta4 (char *, char *, const char *, int);
141 static int write_debug_string (char *, const char *, int);
142 static int write_modbeg (int);
143 static int write_modend (int);
144 static int write_rtnbeg (int, int);
145 static int write_rtnend (int, int);
146 static int write_pclines (int);
147 static int write_srccorr (int, dst_file_info_entry
, int);
148 static int write_srccorrs (int);
150 static void vmsdbgout_init (const char *);
151 static void vmsdbgout_finish (const char *);
152 static void vmsdbgout_define (unsigned int, const char *);
153 static void vmsdbgout_undef (unsigned int, const char *);
154 static void vmsdbgout_start_source_file (unsigned int, const char *);
155 static void vmsdbgout_end_source_file (unsigned int);
156 static void vmsdbgout_begin_block (unsigned int, unsigned int);
157 static void vmsdbgout_end_block (unsigned int, unsigned int);
158 static bool vmsdbgout_ignore_block (tree
);
159 static void vmsdbgout_source_line (unsigned int, const char *);
160 static void vmsdbgout_begin_prologue (unsigned int, const char *);
161 static void vmsdbgout_end_prologue (unsigned int, const char *);
162 static void vmsdbgout_end_function (unsigned int);
163 static void vmsdbgout_end_epilogue (unsigned int, const char *);
164 static void vmsdbgout_begin_function (tree
);
165 static void vmsdbgout_decl (tree
);
166 static void vmsdbgout_global_decl (tree
);
167 static void vmsdbgout_abstract_function (tree
);
169 /* The debug hooks structure. */
171 const struct gcc_debug_hooks vmsdbg_debug_hooks
176 vmsdbgout_start_source_file
,
177 vmsdbgout_end_source_file
,
178 vmsdbgout_begin_block
,
180 vmsdbgout_ignore_block
,
181 vmsdbgout_source_line
,
182 vmsdbgout_begin_prologue
,
183 vmsdbgout_end_prologue
,
184 vmsdbgout_end_epilogue
,
185 vmsdbgout_begin_function
,
186 vmsdbgout_end_function
,
188 vmsdbgout_global_decl
,
189 debug_nothing_tree
, /* deferred_inline_function */
190 vmsdbgout_abstract_function
,
191 debug_nothing_rtx
, /* label */
192 debug_nothing_int
/* handle_pch */
195 /* Definitions of defaults for assembler-dependent names of various
196 pseudo-ops and section names.
197 Theses may be overridden in the tm.h file (if necessary) for a particular
199 #ifdef UNALIGNED_SHORT_ASM_OP
200 #undef UNALIGNED_SHORT_ASM_OP
202 #define UNALIGNED_SHORT_ASM_OP ".word"
204 #ifdef UNALIGNED_INT_ASM_OP
205 #undef UNALIGNED_INT_ASM_OP
207 #define UNALIGNED_INT_ASM_OP ".long"
209 #ifdef UNALIGNED_LONG_ASM_OP
210 #undef UNALIGNED_LONG_ASM_OP
212 #define UNALIGNED_LONG_ASM_OP ".long"
214 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
215 #undef UNALIGNED_DOUBLE_INT_ASM_OP
217 #define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
222 #define ASM_BYTE_OP ".byte"
224 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
226 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
228 #ifndef UNALIGNED_PTR_ASM_OP
229 #define UNALIGNED_PTR_ASM_OP \
230 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
233 #ifndef UNALIGNED_OFFSET_ASM_OP
234 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
235 (NUMBYTES(OFFSET) == 4 \
236 ? UNALIGNED_LONG_ASM_OP \
237 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
240 /* Definitions of defaults for formats and names of various special
241 (artificial) labels which may be generated within this file (when the -g
242 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
243 may be overridden from within the tm.h file, but typically, overriding these
244 defaults is unnecessary. */
246 static char text_end_label
[MAX_ARTIFICIAL_LABEL_BYTES
];
248 #ifndef TEXT_END_LABEL
249 #define TEXT_END_LABEL "Lvetext"
251 #ifndef FUNC_BEGIN_LABEL
252 #define FUNC_BEGIN_LABEL "LVFB"
254 #ifndef FUNC_PROLOG_LABEL
255 #define FUNC_PROLOG_LABEL "LVFP"
257 #ifndef FUNC_END_LABEL
258 #define FUNC_END_LABEL "LVFE"
260 #ifndef BLOCK_BEGIN_LABEL
261 #define BLOCK_BEGIN_LABEL "LVBB"
263 #ifndef BLOCK_END_LABEL
264 #define BLOCK_END_LABEL "LVBE"
266 #ifndef LINE_CODE_LABEL
267 #define LINE_CODE_LABEL "LVM"
270 #ifndef ASM_OUTPUT_DEBUG_DELTA2
271 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
274 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
275 assemble_name (FILE, LABEL1); \
276 fprintf (FILE, "-"); \
277 assemble_name (FILE, LABEL2); \
282 #ifndef ASM_OUTPUT_DEBUG_DELTA4
283 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
286 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
287 assemble_name (FILE, LABEL1); \
288 fprintf (FILE, "-"); \
289 assemble_name (FILE, LABEL2); \
294 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
295 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
298 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
299 assemble_name (FILE, LABEL1); \
300 fprintf (FILE, "-"); \
301 assemble_name (FILE, LABEL2); \
306 #ifndef ASM_OUTPUT_DEBUG_ADDR
307 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
310 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
311 assemble_name (FILE, LABEL); \
316 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
317 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
318 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
321 #ifndef ASM_OUTPUT_DEBUG_DATA1
322 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
323 fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned char) VALUE)
326 #ifndef ASM_OUTPUT_DEBUG_DATA2
327 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
328 fprintf ((FILE), "\t%s\t0x%x", UNALIGNED_SHORT_ASM_OP, \
329 (unsigned short) VALUE)
332 #ifndef ASM_OUTPUT_DEBUG_DATA4
333 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
334 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
337 #ifndef ASM_OUTPUT_DEBUG_DATA
338 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
339 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
342 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
343 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
344 fprintf ((FILE), "\t%s\t0x%lx", UNALIGNED_PTR_ASM_OP, \
345 (unsigned long) VALUE)
348 #ifndef ASM_OUTPUT_DEBUG_DATA8
349 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
350 fprintf ((FILE), "\t%s\t0x%llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
351 (unsigned long long) VALUE)
354 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
355 newline is produced. When flag_verbose_asm is asserted, we add commentary
356 at the end of the line, so we must avoid output of a newline here. */
357 #ifndef ASM_OUTPUT_DEBUG_STRING
358 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
361 register int slen = strlen(P); \
362 register char *p = (P); \
364 fprintf (FILE, "\t.ascii \""); \
365 for (i = 0; i < slen; i++) \
367 register int c = p[i]; \
368 if (c == '\"' || c == '\\') \
370 if (c >= ' ' && c < 0177) \
373 fprintf (FILE, "\\%o", c); \
375 fprintf (FILE, "\""); \
380 /* Convert a reference to the assembler name of a C-level name. This
381 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
382 a string rather than writing to a file. */
383 #ifndef ASM_NAME_TO_STRING
384 #define ASM_NAME_TO_STRING(STR, NAME) \
387 if ((NAME)[0] == '*') \
388 strcpy (STR, NAME+1); \
390 strcpy (STR, NAME); \
396 /* General utility functions. */
398 /* Convert an integer constant expression into assembler syntax. Addition and
399 subtraction are the only arithmetic that may appear in these expressions.
400 This is an adaptation of output_addr_const in final.c. Here, the target
401 of the conversion is a string buffer. We can't use output_addr_const
402 directly, because it writes to a file. */
405 addr_const_to_string (char *str
, rtx x
)
412 switch (GET_CODE (x
))
422 ASM_NAME_TO_STRING (buf1
, XSTR (x
, 0));
427 ASM_GENERATE_INTERNAL_LABEL (buf1
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
428 ASM_NAME_TO_STRING (buf2
, buf1
);
433 ASM_GENERATE_INTERNAL_LABEL (buf1
, "L", CODE_LABEL_NUMBER (x
));
434 ASM_NAME_TO_STRING (buf2
, buf1
);
439 sprintf (buf1
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
444 /* This used to output parentheses around the expression, but that does
445 not work on the 386 (either ATT or BSD assembler). */
446 addr_const_to_string (buf1
, XEXP (x
, 0));
451 if (GET_MODE (x
) == VOIDmode
)
453 /* We can use %d if the number is one word and positive. */
454 if (CONST_DOUBLE_HIGH (x
))
455 sprintf (buf1
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
456 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
457 else if (CONST_DOUBLE_LOW (x
) < 0)
458 sprintf (buf1
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
460 sprintf (buf1
, HOST_WIDE_INT_PRINT_DEC
,
461 CONST_DOUBLE_LOW (x
));
465 /* We can't handle floating point constants; PRINT_OPERAND must
467 output_operand_lossage ("floating constant misused");
471 /* Some assemblers need integer constants to appear last (eg masm). */
472 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
474 addr_const_to_string (buf1
, XEXP (x
, 1));
476 if (INTVAL (XEXP (x
, 0)) >= 0)
478 addr_const_to_string (buf1
, XEXP (x
, 0));
483 addr_const_to_string (buf1
, XEXP (x
, 0));
485 if (INTVAL (XEXP (x
, 1)) >= 0)
487 addr_const_to_string (buf1
, XEXP (x
, 1));
493 /* Avoid outputting things like x-x or x+5-x, since some assemblers
494 can't handle that. */
495 x
= simplify_subtraction (x
);
496 if (GET_CODE (x
) != MINUS
)
499 addr_const_to_string (buf1
, XEXP (x
, 0));
502 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
503 && INTVAL (XEXP (x
, 1)) < 0)
506 addr_const_to_string (buf1
, XEXP (x
, 1));
512 addr_const_to_string (buf1
, XEXP (x
, 1));
519 addr_const_to_string (buf1
, XEXP (x
, 0));
524 output_operand_lossage ("invalid expression as operand");
528 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
529 set. Return the header size. Just return the size if DOSIZEONLY is
533 write_debug_header (DST_HEADER
*header
, const char *comment
, int dosizeonly
)
537 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
538 header
->dst__header_length
.dst_w_length
);
540 if (flag_verbose_asm
)
541 fprintf (asm_out_file
, "\t%s record length", ASM_COMMENT_START
);
542 fputc ('\n', asm_out_file
);
544 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
545 header
->dst__header_type
.dst_w_type
);
547 if (flag_verbose_asm
)
548 fprintf (asm_out_file
, "\t%s record type (%s)", ASM_COMMENT_START
,
551 fputc ('\n', asm_out_file
);
557 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
558 set. Return the address size. Just return the size if DOSIZEONLY is
562 write_debug_addr (char *symbol
, const char *comment
, int dosizeonly
)
566 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, symbol
);
567 if (flag_verbose_asm
)
568 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
569 fputc ('\n', asm_out_file
);
575 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
576 set. Return the data size. Just return the size if DOSIZEONLY is
580 write_debug_data1 (unsigned int data1
, const char *comment
, int dosizeonly
)
584 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file
, data1
);
585 if (flag_verbose_asm
)
586 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
587 fputc ('\n', asm_out_file
);
593 /* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
594 set. Return the data size. Just return the size if DOSIZEONLY is
598 write_debug_data2 (unsigned int data2
, const char *comment
, int dosizeonly
)
602 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
, data2
);
603 if (flag_verbose_asm
)
604 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
605 fputc ('\n', asm_out_file
);
611 /* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
612 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
615 write_debug_data4 (unsigned long data4
, const char *comment
, int dosizeonly
)
619 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file
, data4
);
620 if (flag_verbose_asm
)
621 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
622 fputc ('\n', asm_out_file
);
628 /* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
629 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
632 write_debug_data8 (unsigned long long data8
, const char *comment
,
637 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file
, data8
);
638 if (flag_verbose_asm
)
639 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
640 fputc ('\n', asm_out_file
);
646 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
647 flag_verbose_asm is set. Return the data size. Just return the size if
648 DOSIZEONLY is nonzero. */
651 write_debug_delta4 (char *label1
, char *label2
, const char *comment
,
656 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file
, label1
, label2
);
657 if (flag_verbose_asm
)
658 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
659 fputc ('\n', asm_out_file
);
665 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
666 set. Return the string length. Just return the length if DOSIZEONLY is
670 write_debug_string (char *string
, const char *comment
, int dosizeonly
)
674 ASM_OUTPUT_DEBUG_STRING (asm_out_file
, string
);
675 if (flag_verbose_asm
)
676 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
677 fputc ('\n', asm_out_file
);
680 return strlen (string
);
683 /* Output a module begin header and return the header size. Just return the
684 size if DOSIZEONLY is nonzero. */
687 write_modbeg (int dosizeonly
)
689 DST_MODULE_BEGIN modbeg
;
692 char *module_name
, *m
;
697 /* Assumes primary filename has Unix syntax file spec. */
698 module_name
= xstrdup (basename ((char *) primary_filename
));
700 m
= strrchr (module_name
, '.');
704 modnamelen
= strlen (module_name
);
705 for (i
= 0; i
< modnamelen
; i
++)
706 module_name
[i
] = TOUPPER (module_name
[i
]);
708 prodnamelen
= strlen (module_producer
);
710 modbeg
.dst_a_modbeg_header
.dst__header_length
.dst_w_length
711 = DST_K_MODBEG_SIZE
+ modnamelen
+ DST_K_MB_TRLR_SIZE
+ prodnamelen
- 1;
712 modbeg
.dst_a_modbeg_header
.dst__header_type
.dst_w_type
= DST_K_MODBEG
;
713 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_hide
= 0;
714 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_version
= 1;
715 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_unused
= 0;
716 modbeg
.dst_b_modbeg_unused
= 0;
717 modbeg
.dst_l_modbeg_language
= module_language
;
718 modbeg
.dst_w_version_major
= DST_K_VERSION_MAJOR
;
719 modbeg
.dst_w_version_minor
= DST_K_VERSION_MINOR
;
720 modbeg
.dst_b_modbeg_name
= strlen (module_name
);
722 mb_trlr
.dst_b_compiler
= strlen (module_producer
);
724 totsize
+= write_debug_header (&modbeg
.dst_a_modbeg_header
,
725 "modbeg", dosizeonly
);
726 totsize
+= write_debug_data1 (*((char *) &modbeg
.dst_b_modbeg_flags
),
727 "flags", dosizeonly
);
728 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_unused
,
729 "unused", dosizeonly
);
730 totsize
+= write_debug_data4 (modbeg
.dst_l_modbeg_language
,
731 "language", dosizeonly
);
732 totsize
+= write_debug_data2 (modbeg
.dst_w_version_major
,
733 "DST major version", dosizeonly
);
734 totsize
+= write_debug_data2 (modbeg
.dst_w_version_minor
,
735 "DST minor version", dosizeonly
);
736 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_name
,
737 "length of module name", dosizeonly
);
738 totsize
+= write_debug_string (module_name
, "module name", dosizeonly
);
739 totsize
+= write_debug_data1 (mb_trlr
.dst_b_compiler
,
740 "length of compiler name", dosizeonly
);
741 totsize
+= write_debug_string (module_producer
, "compiler name", dosizeonly
);
746 /* Output a module end trailer and return the trailer size. Just return
747 the size if DOSIZEONLY is nonzero. */
750 write_modend (int dosizeonly
)
752 DST_MODULE_END modend
;
755 modend
.dst_a_modend_header
.dst__header_length
.dst_w_length
756 = DST_K_MODEND_SIZE
- 1;
757 modend
.dst_a_modend_header
.dst__header_type
.dst_w_type
= DST_K_MODEND
;
759 totsize
+= write_debug_header (&modend
.dst_a_modend_header
, "modend",
765 /* Output a routine begin header routine RTNNUM and return the header size.
766 Just return the size if DOSIZEONLY is nonzero. */
769 write_rtnbeg (int rtnnum
, int dosizeonly
)
775 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
776 DST_ROUTINE_BEGIN rtnbeg
;
779 rtnname
= func_table
[rtnnum
];
780 rtnnamelen
= strlen (rtnname
);
781 rtnentryname
= concat (rtnname
, "..en", NULL
);
783 if (!strcmp (rtnname
, "main"))
786 const char *go
= "TRANSFER$BREAK$GO";
788 /* This command isn't documented in DSTRECORDS, so it's made to
789 look like what DEC C does */
791 /* header size - 1st byte + flag byte + STO_LW size
792 + string count byte + string length */
793 header
.dst__header_length
.dst_w_length
794 = DST_K_DST_HEADER_SIZE
- 1 + 1 + 4 + 1 + strlen (go
);
795 header
.dst__header_type
.dst_w_type
= 0x17;
797 totsize
+= write_debug_header (&header
, "transfer", dosizeonly
);
799 /* I think this is a flag byte, but I don't know what this flag means */
800 totsize
+= write_debug_data1 (0x1, "flags ???", dosizeonly
);
802 /* Routine Begin PD Address */
803 totsize
+= write_debug_addr (rtnname
, "main procedure descriptor",
805 totsize
+= write_debug_data1 (strlen (go
), "length of main_name",
807 totsize
+= write_debug_string ((char *) go
, "main name", dosizeonly
);
810 /* The header length never includes the length byte. */
811 rtnbeg
.dst_a_rtnbeg_header
.dst__header_length
.dst_w_length
812 = DST_K_RTNBEG_SIZE
+ rtnnamelen
- 1;
813 rtnbeg
.dst_a_rtnbeg_header
.dst__header_type
.dst_w_type
= DST_K_RTNBEG
;
814 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unused
= 0;
815 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unalloc
= 0;
816 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_prototype
= 0;
817 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_inlined
= 0;
818 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_no_call
= 1;
819 rtnbeg
.dst_b_rtnbeg_name
= rtnnamelen
;
821 totsize
+= write_debug_header (&rtnbeg
.dst_a_rtnbeg_header
, "rtnbeg",
823 totsize
+= write_debug_data1 (*((char *) &rtnbeg
.dst_b_rtnbeg_flags
),
824 "flags", dosizeonly
);
826 /* Routine Begin Address */
827 totsize
+= write_debug_addr (rtnentryname
, "routine entry name", dosizeonly
);
829 /* Routine Begin PD Address */
830 totsize
+= write_debug_addr (rtnname
, "routine procedure descriptor",
833 /* Routine Begin Name */
834 totsize
+= write_debug_data1 (rtnbeg
.dst_b_rtnbeg_name
,
835 "length of routine name", dosizeonly
);
837 totsize
+= write_debug_string (rtnname
, "routine name", dosizeonly
);
841 if (debug_info_level
> DINFO_LEVEL_TERSE
)
843 prolog
.dst_a_prolog_header
.dst__header_length
.dst_w_length
844 = DST_K_PROLOG_SIZE
- 1;
845 prolog
.dst_a_prolog_header
.dst__header_type
.dst_w_type
= DST_K_PROLOG
;
847 totsize
+= write_debug_header (&prolog
.dst_a_prolog_header
, "prolog",
850 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
, rtnnum
);
851 totsize
+= write_debug_addr (label
, "prolog breakpoint addr",
858 /* Output a routine end trailer for routine RTNNUM and return the header size.
859 Just return the size if DOSIZEONLY is nonzero. */
862 write_rtnend (int rtnnum
, int dosizeonly
)
864 DST_ROUTINE_END rtnend
;
865 char label1
[MAX_ARTIFICIAL_LABEL_BYTES
];
866 char label2
[MAX_ARTIFICIAL_LABEL_BYTES
];
871 rtnend
.dst_a_rtnend_header
.dst__header_length
.dst_w_length
872 = DST_K_RTNEND_SIZE
- 1;
873 rtnend
.dst_a_rtnend_header
.dst__header_type
.dst_w_type
= DST_K_RTNEND
;
874 rtnend
.dst_b_rtnend_unused
= 0;
875 rtnend
.dst_l_rtnend_size
= 0; /* Calculated below. */
877 totsize
+= write_debug_header (&rtnend
.dst_a_rtnend_header
, "rtnend",
879 totsize
+= write_debug_data1 (rtnend
.dst_b_rtnend_unused
, "unused",
882 ASM_GENERATE_INTERNAL_LABEL (label1
, FUNC_BEGIN_LABEL
, rtnnum
);
883 ASM_GENERATE_INTERNAL_LABEL (label2
, FUNC_END_LABEL
, rtnnum
);
884 totsize
+= write_debug_delta4 (label2
, label1
, "routine size", dosizeonly
);
889 #define K_DELTA_PC(I) \
890 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
892 #define K_SET_LINUM(I) \
893 ((I) < 256 ? DST_K_SET_LINUM_B \
894 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
896 #define K_INCR_LINUM(I) \
897 ((I) < 256 ? DST_K_INCR_LINUM \
898 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
900 /* Output the PC to line number correlations and return the size. Just return
901 the size if DOSIZEONLY is nonzero */
904 write_pclines (int dosizeonly
)
911 DST_LINE_NUM_HEADER line_num
;
912 DST_PCLINE_COMMANDS pcline
;
913 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
914 char lastlabel
[MAX_ARTIFICIAL_LABEL_BYTES
];
918 max_line
= file_info_table
[1].max_line
;
919 file_info_table
[1].listing_line_start
= linestart
;
920 linestart
= linestart
+ ((max_line
/ 100000) + 1) * 100000;
922 for (i
= 2; i
< file_info_table_in_use
; i
++)
924 max_line
= file_info_table
[i
].max_line
;
925 file_info_table
[i
].listing_line_start
= linestart
;
926 linestart
= linestart
+ ((max_line
/ 10000) + 1) * 10000;
929 /* Set starting address to beginning of text section. */
930 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 8;
931 line_num
.dst_a_line_num_header
.dst__header_type
.dst_w_type
= DST_K_LINE_NUM
;
932 pcline
.dst_b_pcline_command
= DST_K_SET_ABS_PC
;
934 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
935 "line_num", dosizeonly
);
936 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
937 "line_num (SET ABS PC)", dosizeonly
);
943 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, TEXT_SECTION_ASM_OP
);
944 if (flag_verbose_asm
)
945 fprintf (asm_out_file
, "\t%s line_num", ASM_COMMENT_START
);
946 fputc ('\n', asm_out_file
);
949 fn
= line_info_table
[1].dst_file_num
;
950 ln
= (file_info_table
[fn
].listing_line_start
951 + line_info_table
[1].dst_line_num
);
952 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 4 + 4;
953 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
955 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
956 "line_num", dosizeonly
);
957 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
958 "line_num (SET LINUM LONG)", dosizeonly
);
960 sprintf (buff
, "line_num (%d)", ln
? ln
- 1 : 0);
961 totsize
+= write_debug_data4 (ln
? ln
- 1 : 0, buff
, dosizeonly
);
964 strcpy (lastlabel
, TEXT_SECTION_ASM_OP
);
965 for (i
= 1; i
< line_info_table_in_use
; i
++)
969 fn
= line_info_table
[i
].dst_file_num
;
970 ln
= (file_info_table
[fn
].listing_line_start
971 + line_info_table
[i
].dst_line_num
);
974 extrabytes
= 5; /* NUMBYTES (ln - lastln - 1) + 1; */
975 else if (ln
<= lastln
)
976 extrabytes
= 5; /* NUMBYTES (ln - 1) + 1; */
980 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
983 totsize
+= write_debug_header
984 (&line_num
.dst_a_line_num_header
, "line_num", dosizeonly
);
988 int lndif
= ln
- lastln
- 1;
990 /* K_INCR_LINUM (lndif); */
991 pcline
.dst_b_pcline_command
= DST_K_INCR_LINUM_L
;
993 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
994 "line_num (INCR LINUM LONG)",
997 sprintf (buff
, "line_num (%d)", lndif
);
998 totsize
+= write_debug_data4 (lndif
, buff
, dosizeonly
);
1000 else if (ln
<= lastln
)
1002 /* K_SET_LINUM (ln-1); */
1003 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
1005 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1006 "line_num (SET LINUM LONG)",
1009 sprintf (buff
, "line_num (%d)", ln
- 1);
1010 totsize
+= write_debug_data4 (ln
- 1, buff
, dosizeonly
);
1013 pcline
.dst_b_pcline_command
= DST_K_DELTA_PC_L
;
1015 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
1016 "line_num (DELTA PC LONG)", dosizeonly
);
1018 ASM_GENERATE_INTERNAL_LABEL (label
, LINE_CODE_LABEL
, i
);
1019 totsize
+= write_debug_delta4 (label
, lastlabel
, "increment line_num",
1023 strcpy (lastlabel
, label
);
1029 /* Output a source correlation for file FILEID using information saved in
1030 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
1034 write_srccorr (int fileid
, dst_file_info_entry file_info_entry
,
1037 int src_command_size
;
1038 int linesleft
= file_info_entry
.max_line
;
1039 int linestart
= file_info_entry
.listing_line_start
;
1040 int flen
= file_info_entry
.flen
;
1042 DST_SOURCE_CORR src_header
;
1043 DST_SRC_COMMAND src_command
;
1044 DST_SRC_COMMAND src_command_sf
;
1045 DST_SRC_COMMAND src_command_sl
;
1046 DST_SRC_COMMAND src_command_sr
;
1047 DST_SRC_COMMAND src_command_dl
;
1048 DST_SRC_CMDTRLR src_cmdtrlr
;
1054 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1055 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 1 - 1;
1056 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1058 src_command
.dst_b_src_command
= DST_K_SRC_FORMFEED
;
1060 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1061 "source corr", dosizeonly
);
1063 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
1064 "source_corr (SRC FORMFEED)",
1069 = DST_K_SRC_COMMAND_SIZE
+ flen
+ DST_K_SRC_CMDTRLR_SIZE
;
1070 src_command
.dst_b_src_command
= DST_K_SRC_DECLFILE
;
1071 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
1072 = src_command_size
- 2;
1073 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
= 0;
1074 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
1076 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
1077 = file_info_entry
.cdt
;
1078 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
1079 = file_info_entry
.ebk
;
1080 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
1081 = file_info_entry
.ffb
;
1082 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
1083 = file_info_entry
.rfo
;
1084 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
1085 = file_info_entry
.flen
;
1087 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1088 = DST_K_SOURCE_CORR_HEADER_SIZE
+ src_command_size
- 1;
1089 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1092 src_cmdtrlr
.dst_b_src_df_libmodname
= 0;
1094 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1095 "source corr", dosizeonly
);
1096 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
1097 "source_corr (DECL SRC FILE)", dosizeonly
);
1098 totsize
+= write_debug_data1
1099 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
,
1100 "source_corr (length)", dosizeonly
);
1102 totsize
+= write_debug_data1
1103 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
,
1104 "source_corr (flags)", dosizeonly
);
1106 totsize
+= write_debug_data2
1107 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
,
1108 "source_corr (fileid)", dosizeonly
);
1110 totsize
+= write_debug_data8
1111 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
,
1112 "source_corr (creation date)", dosizeonly
);
1114 totsize
+= write_debug_data4
1115 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
,
1116 "source_corr (EOF block number)", dosizeonly
);
1118 totsize
+= write_debug_data2
1119 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
,
1120 "source_corr (first free byte)", dosizeonly
);
1122 totsize
+= write_debug_data1
1123 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
,
1124 "source_corr (record and file organization)", dosizeonly
);
1126 totsize
+= write_debug_data1
1127 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
,
1128 "source_corr (filename length)", dosizeonly
);
1130 totsize
+= write_debug_string (file_info_entry
.file_name
,
1131 "source file name", dosizeonly
);
1132 totsize
+= write_debug_data1 (src_cmdtrlr
.dst_b_src_df_libmodname
,
1133 "source_corr (libmodname)", dosizeonly
);
1135 src_command_sf
.dst_b_src_command
= DST_K_SRC_SETFILE
;
1136 src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
= fileid
;
1138 src_command_sr
.dst_b_src_command
= DST_K_SRC_SETREC_W
;
1139 src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
= 1;
1141 src_command_sl
.dst_b_src_command
= DST_K_SRC_SETLNUM_L
;
1142 src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
= linestart
+ 1;
1144 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1146 if (linesleft
> 65534)
1147 linesleft
= linesleft
- 65534, linestodo
= 65534;
1149 linestodo
= linesleft
, linesleft
= 0;
1151 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1153 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1154 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 + 3 + 5 + 3 - 1;
1155 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1158 if (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
)
1160 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1161 "source corr", dosizeonly
);
1163 totsize
+= write_debug_data1 (src_command_sf
.dst_b_src_command
,
1164 "source_corr (src setfile)", dosizeonly
);
1166 totsize
+= write_debug_data2
1167 (src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1168 "source_corr (fileid)", dosizeonly
);
1170 totsize
+= write_debug_data1 (src_command_sr
.dst_b_src_command
,
1171 "source_corr (setrec)", dosizeonly
);
1173 totsize
+= write_debug_data2
1174 (src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1175 "source_corr (recnum)", dosizeonly
);
1177 totsize
+= write_debug_data1 (src_command_sl
.dst_b_src_command
,
1178 "source_corr (setlnum)", dosizeonly
);
1180 totsize
+= write_debug_data4
1181 (src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
,
1182 "source_corr (linenum)", dosizeonly
);
1184 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1185 "source_corr (deflines)", dosizeonly
);
1187 sprintf (buff
, "source_corr (%d)",
1188 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1189 totsize
+= write_debug_data2
1190 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1193 while (linesleft
> 0)
1195 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1196 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 - 1;
1197 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1199 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1201 if (linesleft
> 65534)
1202 linesleft
= linesleft
- 65534, linestodo
= 65534;
1204 linestodo
= linesleft
, linesleft
= 0;
1206 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1208 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1209 "source corr", dosizeonly
);
1210 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1211 "source_corr (deflines)", dosizeonly
);
1212 sprintf (buff
, "source_corr (%d)",
1213 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1214 totsize
+= write_debug_data2
1215 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1223 /* Output all the source correlation entries and return the size. Just return
1224 the size if DOSIZEONLY is nonzero. */
1227 write_srccorrs (int dosizeonly
)
1232 for (i
= 1; i
< file_info_table_in_use
; i
++)
1233 totsize
+= write_srccorr (i
, file_info_table
[i
], dosizeonly
);
1238 /* Output a marker (i.e. a label) for the beginning of a function, before
1242 vmsdbgout_begin_prologue (unsigned int line
, const char *file
)
1244 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1246 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1247 (*dwarf2_debug_hooks
.begin_prologue
) (line
, file
);
1249 if (debug_info_level
> DINFO_LEVEL_NONE
)
1251 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_BEGIN_LABEL
,
1252 current_function_funcdef_no
);
1253 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1257 /* Output a marker (i.e. a label) for the beginning of a function, after
1261 vmsdbgout_end_prologue (unsigned int line
, const char *file
)
1263 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1265 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1266 (*dwarf2_debug_hooks
.end_prologue
) (line
, file
);
1268 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1270 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
,
1271 current_function_funcdef_no
);
1272 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1274 /* VMS PCA expects every PC range to correlate to some line and file. */
1275 vmsdbgout_source_line (line
, file
);
1279 /* No output for VMS debug, but make obligatory call to Dwarf2 debug */
1282 vmsdbgout_end_function (unsigned int line
)
1284 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1285 (*dwarf2_debug_hooks
.end_function
) (line
);
1288 /* Output a marker (i.e. a label) for the absolute end of the generated code
1289 for a function definition. This gets called *after* the epilogue code has
1293 vmsdbgout_end_epilogue (unsigned int line
, const char *file
)
1295 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1297 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1298 (*dwarf2_debug_hooks
.end_epilogue
) (line
, file
);
1300 if (debug_info_level
> DINFO_LEVEL_NONE
)
1302 /* Output a label to mark the endpoint of the code generated for this
1304 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_END_LABEL
,
1305 current_function_funcdef_no
);
1306 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1308 /* VMS PCA expects every PC range to correlate to some line and file. */
1309 vmsdbgout_source_line (line
, file
);
1313 /* Output a marker (i.e. a label) for the beginning of the generated code for
1317 vmsdbgout_begin_block (register unsigned line
, register unsigned blocknum
)
1319 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1320 (*dwarf2_debug_hooks
.begin_block
) (line
, blocknum
);
1322 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1323 (*targetm
.asm_out
.internal_label
) (asm_out_file
, BLOCK_BEGIN_LABEL
, blocknum
);
1326 /* Output a marker (i.e. a label) for the end of the generated code for a
1330 vmsdbgout_end_block (register unsigned line
, register unsigned blocknum
)
1332 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1333 (*dwarf2_debug_hooks
.end_block
) (line
, blocknum
);
1335 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1336 (*targetm
.asm_out
.internal_label
) (asm_out_file
, BLOCK_END_LABEL
, blocknum
);
1339 /* Not implemented in VMS Debug. */
1342 vmsdbgout_ignore_block (tree block
)
1346 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1347 retval
= (*dwarf2_debug_hooks
.ignore_block
) (block
);
1352 /* Add an entry for function DECL into the func_table. */
1355 vmsdbgout_begin_function (tree decl
)
1357 const char *name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
1359 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1360 (*dwarf2_debug_hooks
.begin_function
) (decl
);
1362 if (func_table_in_use
== func_table_allocated
)
1364 func_table_allocated
+= FUNC_TABLE_INCREMENT
;
1365 func_table
= (char **) xrealloc (func_table
,
1366 func_table_allocated
* sizeof (char *));
1369 /* Add the new entry to the end of the function name table. */
1370 func_table
[func_table_in_use
++] = xstrdup (name
);
1373 static char fullname_buff
[4096];
1375 /* Return the full file specification for FILENAME. The specification must be
1376 in VMS syntax in order to be processed by VMS Debug. */
1379 full_name (const char *filename
)
1382 FILE *fp
= fopen (filename
, "r");
1384 fgetname (fp
, fullname_buff
, 1);
1387 getcwd (fullname_buff
, sizeof (fullname_buff
));
1389 strcat (fullname_buff
, "/");
1390 strcat (fullname_buff
, filename
);
1392 /* ??? Insert hairy code here to translate Unix style file specification
1396 return fullname_buff
;
1399 /* Lookup a filename (in the list of filenames that we know about here in
1400 vmsdbgout.c) and return its "index". The index of each (known) filename is
1401 just a unique number which is associated with only that one filename. We
1402 need such numbers for the sake of generating labels and references
1403 to those files numbers. If the filename given as an argument is not
1404 found in our current list, add it to the list and assign it the next
1405 available unique index number. In order to speed up searches, we remember
1406 the index of the filename was looked up last. This handles the majority of
1410 lookup_filename (const char *file_name
)
1412 static unsigned int last_file_lookup_index
= 0;
1414 register unsigned i
;
1421 struct stat statbuf
;
1423 if (stat (file_name
, &statbuf
) == 0)
1429 /* Adjust for GMT. */
1430 ts
= (struct tm
*) localtime (&statbuf
.st_ctime
);
1431 gmtoff
= ts
->tm_gmtoff
;
1433 /* VMS has multiple file format types. */
1434 rfo
= statbuf
.st_fab_rfm
;
1436 /* Is GMT adjustment an issue with a cross-compiler? */
1439 /* Assume stream LF type file. */
1442 cdt
= 10000000 * (statbuf
.st_ctime
+ gmtoff
+ vms_epoch_offset
);
1443 ebk
= statbuf
.st_size
/ 512 + 1;
1444 ffb
= statbuf
.st_size
- ((statbuf
.st_size
/ 512) * 512);
1445 fnam
= full_name (file_name
);
1446 flen
= strlen (fnam
);
1458 /* Check to see if the file name that was searched on the previous call
1459 matches this file name. If so, return the index. */
1460 if (last_file_lookup_index
!= 0)
1462 fn
= file_info_table
[last_file_lookup_index
].file_name
;
1463 if (strcmp (fnam
, fn
) == 0)
1464 return last_file_lookup_index
;
1467 /* Didn't match the previous lookup, search the table */
1468 for (i
= 1; i
< file_info_table_in_use
; ++i
)
1470 fn
= file_info_table
[i
].file_name
;
1471 if (strcmp (fnam
, fn
) == 0)
1473 last_file_lookup_index
= i
;
1478 /* Prepare to add a new table entry by making sure there is enough space in
1479 the table to do so. If not, expand the current table. */
1480 if (file_info_table_in_use
== file_info_table_allocated
)
1483 file_info_table_allocated
+= FILE_TABLE_INCREMENT
;
1485 = (dst_file_info_ref
) xrealloc (file_info_table
,
1486 (file_info_table_allocated
1487 * sizeof (dst_file_info_entry
)));
1490 /* Add the new entry to the end of the filename table. */
1491 file_info_table
[file_info_table_in_use
].file_name
= xstrdup (fnam
);
1492 file_info_table
[file_info_table_in_use
].max_line
= 0;
1493 file_info_table
[file_info_table_in_use
].cdt
= cdt
;
1494 file_info_table
[file_info_table_in_use
].ebk
= ebk
;
1495 file_info_table
[file_info_table_in_use
].ffb
= ffb
;
1496 file_info_table
[file_info_table_in_use
].rfo
= rfo
;
1497 file_info_table
[file_info_table_in_use
].flen
= flen
;
1499 last_file_lookup_index
= file_info_table_in_use
++;
1500 return last_file_lookup_index
;
1503 /* Output a label to mark the beginning of a source code line entry
1504 and record information relating to this source line, in
1505 'line_info_table' for later output of the .debug_line section. */
1508 vmsdbgout_source_line (register unsigned line
, register const char *filename
)
1510 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1511 (*dwarf2_debug_hooks
.source_line
) (line
, filename
);
1513 if (debug_info_level
>= DINFO_LEVEL_TERSE
)
1515 dst_line_info_ref line_info
;
1517 (*targetm
.asm_out
.internal_label
) (asm_out_file
, LINE_CODE_LABEL
,
1518 line_info_table_in_use
);
1520 /* Expand the line info table if necessary. */
1521 if (line_info_table_in_use
== line_info_table_allocated
)
1523 line_info_table_allocated
+= LINE_INFO_TABLE_INCREMENT
;
1525 = (dst_line_info_ref
) xrealloc (line_info_table
,
1526 (line_info_table_allocated
1527 * sizeof (dst_line_info_entry
)));
1530 /* Add the new entry at the end of the line_info_table. */
1531 line_info
= &line_info_table
[line_info_table_in_use
++];
1532 line_info
->dst_file_num
= lookup_filename (filename
);
1533 line_info
->dst_line_num
= line
;
1534 if (line
> file_info_table
[line_info
->dst_file_num
].max_line
)
1535 file_info_table
[line_info
->dst_file_num
].max_line
= line
;
1539 /* Record the beginning of a new source file, for later output.
1540 At present, unimplemented. */
1543 vmsdbgout_start_source_file (unsigned int lineno
, const char *filename
)
1545 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1546 (*dwarf2_debug_hooks
.start_source_file
) (lineno
, filename
);
1549 /* Record the end of a source file, for later output.
1550 At present, unimplemented. */
1553 vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED
)
1555 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1556 (*dwarf2_debug_hooks
.end_source_file
) (lineno
);
1559 /* Set up for Debug output at the start of compilation. */
1562 vmsdbgout_init (const char *main_input_filename
)
1564 const char *language_string
= lang_hooks
.name
;
1566 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1567 (*dwarf2_debug_hooks
.init
) (main_input_filename
);
1569 if (debug_info_level
== DINFO_LEVEL_NONE
)
1572 /* Remember the name of the primary input file. */
1573 primary_filename
= main_input_filename
;
1575 /* Allocate the initial hunk of the file_info_table. */
1577 = (dst_file_info_ref
) xcalloc (FILE_TABLE_INCREMENT
,
1578 sizeof (dst_file_info_entry
));
1579 file_info_table_allocated
= FILE_TABLE_INCREMENT
;
1581 /* Skip the first entry - file numbers begin at 1 */
1582 file_info_table_in_use
= 1;
1584 func_table
= (char **) xcalloc (FUNC_TABLE_INCREMENT
, sizeof (char *));
1585 func_table_allocated
= FUNC_TABLE_INCREMENT
;
1586 func_table_in_use
= 1;
1588 /* Allocate the initial hunk of the line_info_table. */
1590 = (dst_line_info_ref
) xcalloc (LINE_INFO_TABLE_INCREMENT
,
1591 sizeof (dst_line_info_entry
));
1592 line_info_table_allocated
= LINE_INFO_TABLE_INCREMENT
;
1593 /* zero-th entry is allocated, but unused */
1594 line_info_table_in_use
= 1;
1596 lookup_filename (primary_filename
);
1598 if (!strcmp (language_string
, "GNU C"))
1599 module_language
= DST_K_C
;
1600 else if (!strcmp (language_string
, "GNU C++"))
1601 module_language
= DST_K_CXX
;
1602 else if (!strcmp (language_string
, "GNU Ada"))
1603 module_language
= DST_K_ADA
;
1604 else if (!strcmp (language_string
, "GNU F77"))
1605 module_language
= DST_K_FORTRAN
;
1607 module_language
= DST_K_UNKNOWN
;
1609 module_producer
= concat (language_string
, " ", version_string
, NULL
);
1611 ASM_GENERATE_INTERNAL_LABEL (text_end_label
, TEXT_END_LABEL
, 0);
1615 /* Not implemented in VMS Debug. */
1618 vmsdbgout_define (unsigned int lineno
, const char *buffer
)
1620 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1621 (*dwarf2_debug_hooks
.define
) (lineno
, buffer
);
1624 /* Not implemented in VMS Debug. */
1627 vmsdbgout_undef (unsigned int lineno
, const char *buffer
)
1629 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1630 (*dwarf2_debug_hooks
.undef
) (lineno
, buffer
);
1633 /* Not implemented in VMS Debug. */
1636 vmsdbgout_decl (tree decl
)
1638 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1639 (*dwarf2_debug_hooks
.function_decl
) (decl
);
1642 /* Not implemented in VMS Debug. */
1645 vmsdbgout_global_decl (tree decl
)
1647 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1648 (*dwarf2_debug_hooks
.global_decl
) (decl
);
1651 /* Not implemented in VMS Debug. */
1654 vmsdbgout_abstract_function (tree decl
)
1656 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1657 (*dwarf2_debug_hooks
.outlining_inline_function
) (decl
);
1660 /* Output stuff that Debug requires at the end of every file and generate the
1661 VMS Debug debugging info. */
1664 vmsdbgout_finish (const char *main_input_filename ATTRIBUTE_UNUSED
)
1669 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1670 (*dwarf2_debug_hooks
.finish
) (main_input_filename
);
1672 if (debug_info_level
== DINFO_LEVEL_NONE
)
1675 /* Output a terminator label for the .text section. */
1677 (*targetm
.asm_out
.internal_label
) (asm_out_file
, TEXT_END_LABEL
, 0);
1679 /* Output debugging information.
1680 Warning! Do not change the name of the .vmsdebug section without
1681 changing it in the assembler also. */
1682 named_section (NULL_TREE
, ".vmsdebug", 0);
1683 ASM_OUTPUT_ALIGN (asm_out_file
, 0);
1685 totsize
= write_modbeg (1);
1686 for (i
= 1; i
< func_table_in_use
; i
++)
1688 totsize
+= write_rtnbeg (i
, 1);
1689 totsize
+= write_rtnend (i
, 1);
1691 totsize
+= write_pclines (1);
1694 for (i
= 1; i
< func_table_in_use
; i
++)
1696 write_rtnbeg (i
, 0);
1697 write_rtnend (i
, 0);
1701 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1703 totsize
= write_srccorrs (1);
1707 totsize
= write_modend (1);
1710 #endif /* VMS_DEBUGGING_INFO */