1 /* Output VMS debug format symbol table information from GCC.
2 Copyright (C) 1987-2025 Free Software Foundation, Inc.
3 Contributed by Douglas B. Rupp (rupp@gnat.com).
4 Updated by Bernard W. Giroud (bgiroud@users.sourceforge.net).
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 3, 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 COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
27 #ifdef VMS_DEBUGGING_INFO
37 #include "langhooks.h"
40 #include "file-prefix-map.h" /* remap_debug_filename() */
42 /* Difference in seconds between the VMS Epoch and the Unix Epoch */
43 static const long long vms_epoch_offset
= 3506716800ll;
45 int vms_file_stats_name (const char *, long long *, long *, char *, int *);
47 /* NOTE: In the comments in this file, many references are made to "Debug
48 Symbol Table". This term is abbreviated as `DST' throughout the remainder
51 typedef struct dst_line_info_struct
*dst_line_info_ref
;
53 /* Each entry in the line_info_table maintains the file and
54 line number associated with the label generated for that
55 entry. The label gives the PC value associated with
56 the line number entry. */
57 typedef struct dst_line_info_struct
59 unsigned long dst_file_num
;
60 unsigned long dst_line_num
;
64 typedef struct dst_file_info_struct
*dst_file_info_ref
;
66 typedef struct dst_file_info_struct
69 unsigned int max_line
;
70 unsigned int listing_line_start
;
78 /* Maximum size (in bytes) of an artificially generated label. */
79 #define MAX_ARTIFICIAL_LABEL_BYTES 30
81 /* Make sure we know the sizes of the various types debug can describe. These
82 are only defaults. If the sizes are different for your target, you should
83 override these values by defining the appropriate symbols in your tm.h
86 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
89 /* Pointer to a structure of filenames referenced by this compilation unit. */
90 static dst_file_info_ref file_info_table
;
92 /* Total number of entries in the table (i.e. array) pointed to by
93 `file_info_table'. This is the *total* and includes both used and unused
95 static unsigned int file_info_table_allocated
;
97 /* Number of entries in the file_info_table which are actually in use. */
98 static unsigned int file_info_table_in_use
;
100 /* Size (in elements) of increments by which we may expand the filename
102 #define FILE_TABLE_INCREMENT 64
104 typedef char *char_p
;
106 static vec
<char_p
> funcnam_table
;
107 static vec
<unsigned> funcnum_table
;
108 #define FUNC_TABLE_INITIAL 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 int write_debug_header (DST_HEADER
*, const char *, int);
134 static int write_debug_addr (const char *, const char *, int);
135 static int write_debug_data1 (unsigned int, const char *, int);
136 static int write_debug_data2 (unsigned int, const char *, int);
137 static int write_debug_data4 (unsigned long, const char *, int);
138 static int write_debug_data8 (unsigned long long, const char *, int);
139 static int write_debug_delta4 (const char *, const char *, const char *, int);
140 static int write_debug_string (const char *, const char *, int);
141 static int write_modbeg (int);
142 static int write_modend (int);
143 static int write_rtnbeg (int, int);
144 static int write_rtnend (int, int);
145 static int write_pclines (int);
146 static int write_srccorr (int, dst_file_info_entry
, int);
147 static int write_srccorrs (int);
149 static void vmsdbgout_init (const char *);
150 static void vmsdbgout_finish (const char *);
151 static void vmsdbgout_early_finish (const char *);
152 static void vmsdbgout_assembly_start (void);
153 static void vmsdbgout_define (unsigned int, const char *);
154 static void vmsdbgout_undef (unsigned int, const char *);
155 static void vmsdbgout_start_source_file (unsigned int, const char *);
156 static void vmsdbgout_end_source_file (unsigned int);
157 static void vmsdbgout_begin_block (unsigned int, unsigned int, tree
);
158 static void vmsdbgout_end_block (unsigned int, unsigned int);
159 static bool vmsdbgout_ignore_block (const_tree
);
160 static void vmsdbgout_source_line (unsigned int, unsigned int, const char *,
162 static void vmsdbgout_write_source_line (unsigned, const char *, int , bool);
163 static void vmsdbgout_begin_prologue (unsigned int, unsigned int,
165 static void vmsdbgout_end_prologue (unsigned int, const char *);
166 static void vmsdbgout_end_function (unsigned int);
167 static void vmsdbgout_begin_epilogue (unsigned int, const char *);
168 static void vmsdbgout_end_epilogue (unsigned int, const char *);
169 static void vmsdbgout_begin_function (tree
);
170 static void vmsdbgout_function_decl (tree
);
171 static void vmsdbgout_early_global_decl (tree
);
172 static void vmsdbgout_late_global_decl (tree
);
173 static void vmsdbgout_type_decl (tree
, int);
174 static void vmsdbgout_abstract_function (tree
);
176 /* The debug hooks structure. */
178 const struct gcc_debug_hooks vmsdbg_debug_hooks
181 vmsdbgout_early_finish
,
182 vmsdbgout_assembly_start
,
185 vmsdbgout_start_source_file
,
186 vmsdbgout_end_source_file
,
187 vmsdbgout_begin_block
,
189 vmsdbgout_ignore_block
,
190 vmsdbgout_source_line
,
191 debug_nothing_int_int_charstar
, /* set_ignored_loc */
192 vmsdbgout_begin_prologue
,
193 vmsdbgout_end_prologue
,
194 vmsdbgout_begin_epilogue
,
195 vmsdbgout_end_epilogue
,
196 vmsdbgout_begin_function
,
197 vmsdbgout_end_function
,
198 debug_nothing_tree
, /* register_main_translation_unit */
199 vmsdbgout_function_decl
,
200 vmsdbgout_early_global_decl
,
201 vmsdbgout_late_global_decl
,
202 vmsdbgout_type_decl
, /* type_decl */
203 debug_nothing_tree_tree_tree_bool_bool
, /* imported_module_or_decl */
204 debug_false_tree_charstarstar_uhwistar
, /* die_ref_for_decl */
205 debug_nothing_tree_charstar_uhwi
, /* register_external_die */
206 debug_nothing_tree
, /* deferred_inline_function */
207 vmsdbgout_abstract_function
,
208 debug_nothing_rtx_code_label
, /* label */
209 debug_nothing_int
, /* handle_pch */
210 debug_nothing_rtx_insn
, /* var_location */
211 debug_nothing_tree
, /* inline_entry */
212 debug_nothing_tree
, /* size_function */
213 debug_nothing_void
, /* switch_text_section */
214 debug_nothing_tree_tree
, /* set_name */
215 0, /* start_end_main_source_file */
216 TYPE_SYMTAB_IS_ADDRESS
/* tree_type_symtab_field */
219 /* Definitions of defaults for assembler-dependent names of various
220 pseudo-ops and section names. */
221 #define VMS_UNALIGNED_SHORT_ASM_OP ".word"
222 #define VMS_UNALIGNED_INT_ASM_OP ".long"
223 #define VMS_UNALIGNED_LONG_ASM_OP ".long"
224 #define VMS_UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
226 #define VMS_ASM_BYTE_OP ".byte"
228 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
230 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
232 #ifndef UNALIGNED_PTR_ASM_OP
233 #define UNALIGNED_PTR_ASM_OP \
234 (PTR_SIZE == 8 ? VMS_UNALIGNED_DOUBLE_INT_ASM_OP : VMS_UNALIGNED_INT_ASM_OP)
237 #ifndef UNALIGNED_OFFSET_ASM_OP
238 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
239 (NUMBYTES (OFFSET) == 4 \
240 ? VMS_UNALIGNED_LONG_ASM_OP \
241 : (NUMBYTES (OFFSET) == 2 ? VMS_UNALIGNED_SHORT_ASM_OP : VMS_ASM_BYTE_OP))
244 /* Definitions of defaults for formats and names of various special
245 (artificial) labels which may be generated within this file (when the -g
246 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
247 may be overridden from within the tm.h file, but typically, overriding these
248 defaults is unnecessary. */
250 static char text_end_label
[MAX_ARTIFICIAL_LABEL_BYTES
];
252 #ifndef TEXT_END_LABEL
253 #define TEXT_END_LABEL "Lvetext"
255 #ifndef FUNC_BEGIN_LABEL
256 #define FUNC_BEGIN_LABEL "LVFB"
258 #ifndef FUNC_PROLOG_LABEL
259 #define FUNC_PROLOG_LABEL "LVFP"
261 #ifndef FUNC_EPILOG_LABEL
262 #define FUNC_EPILOG_LABEL "LVEB"
264 #ifndef FUNC_END_LABEL
265 #define FUNC_END_LABEL "LVFE"
267 #ifndef BLOCK_BEGIN_LABEL
268 #define BLOCK_BEGIN_LABEL "LVBB"
270 #ifndef BLOCK_END_LABEL
271 #define BLOCK_END_LABEL "LVBE"
273 #ifndef LINE_CODE_LABEL
274 #define LINE_CODE_LABEL "LVM"
277 #ifndef ASM_OUTPUT_DEBUG_DELTA2
278 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
281 fprintf ((FILE), "\t%s\t", VMS_UNALIGNED_SHORT_ASM_OP); \
282 assemble_name (FILE, LABEL1); \
283 fprintf (FILE, "-"); \
284 assemble_name (FILE, LABEL2); \
289 #ifndef ASM_OUTPUT_DEBUG_DELTA4
290 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
293 fprintf ((FILE), "\t%s\t", VMS_UNALIGNED_INT_ASM_OP); \
294 assemble_name (FILE, LABEL1); \
295 fprintf (FILE, "-"); \
296 assemble_name (FILE, LABEL2); \
301 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
302 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
305 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
306 assemble_name (FILE, LABEL1); \
307 fprintf (FILE, "-"); \
308 assemble_name (FILE, LABEL2); \
313 #ifndef ASM_OUTPUT_DEBUG_ADDR
314 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
317 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
318 assemble_name (FILE, LABEL); \
323 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
324 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
325 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
328 #ifndef ASM_OUTPUT_DEBUG_DATA1
329 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
330 fprintf ((FILE), "\t%s\t%#x", VMS_ASM_BYTE_OP, (unsigned char) VALUE)
333 #ifndef ASM_OUTPUT_DEBUG_DATA2
334 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
335 fprintf ((FILE), "\t%s\t%#x", VMS_UNALIGNED_SHORT_ASM_OP, \
336 (unsigned short) VALUE)
339 #ifndef ASM_OUTPUT_DEBUG_DATA4
340 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
341 fprintf ((FILE), "\t%s\t%#lx", VMS_UNALIGNED_INT_ASM_OP, \
342 (unsigned long) VALUE)
345 #ifndef ASM_OUTPUT_DEBUG_DATA
346 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
347 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_OFFSET_ASM_OP (VALUE), VALUE)
350 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
351 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
352 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_PTR_ASM_OP, \
353 (unsigned long) VALUE)
356 #ifndef ASM_OUTPUT_DEBUG_DATA8
357 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
358 fprintf ((FILE), "\t%s\t%#llx", VMS_UNALIGNED_DOUBLE_INT_ASM_OP, \
359 (unsigned long long) VALUE)
362 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
363 newline is produced. When flag_verbose_asm is asserted, we add commentary
364 at the end of the line, so we must avoid output of a newline here. */
365 #ifndef ASM_OUTPUT_DEBUG_STRING
366 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
369 int slen = strlen (P); \
370 const char *p = (P); \
372 fprintf (FILE, "\t.ascii \""); \
373 for (i = 0; i < slen; i++) \
376 if (c == '\"' || c == '\\') \
378 if (c >= ' ' && c < 0177) \
381 fprintf (FILE, "\\%o", c); \
383 fprintf (FILE, "\""); \
388 /* Convert a reference to the assembler name of a C-level name. This
389 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
390 a string rather than writing to a file. */
391 #ifndef ASM_NAME_TO_STRING
392 #define ASM_NAME_TO_STRING(STR, NAME) \
395 if ((NAME)[0] == '*') \
396 strcpy (STR, NAME+1); \
398 strcpy (STR, NAME); \
404 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
405 set. Return the header size. Just return the size if DOSIZEONLY is
409 write_debug_header (DST_HEADER
*header
, const char *comment
, int dosizeonly
)
413 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
414 header
->dst__header_length
.dst_w_length
);
416 if (flag_verbose_asm
)
417 fprintf (asm_out_file
, "\t%s record length", ASM_COMMENT_START
);
418 fputc ('\n', asm_out_file
);
420 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
,
421 header
->dst__header_type
.dst_w_type
);
423 if (flag_verbose_asm
)
424 fprintf (asm_out_file
, "\t%s record type (%s)", ASM_COMMENT_START
,
427 fputc ('\n', asm_out_file
);
433 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
434 set. Return the address size. Just return the size if DOSIZEONLY is
438 write_debug_addr (const char *symbol
, const char *comment
, int dosizeonly
)
442 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, symbol
);
443 if (flag_verbose_asm
)
444 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
445 fputc ('\n', asm_out_file
);
451 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
452 set. Return the data size. Just return the size if DOSIZEONLY is
456 write_debug_data1 (unsigned int data1
, const char *comment
, int dosizeonly
)
460 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file
, data1
);
461 if (flag_verbose_asm
)
462 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
463 fputc ('\n', asm_out_file
);
469 /* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
470 set. Return the data size. Just return the size if DOSIZEONLY is
474 write_debug_data2 (unsigned int data2
, const char *comment
, int dosizeonly
)
478 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file
, data2
);
479 if (flag_verbose_asm
)
480 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
481 fputc ('\n', asm_out_file
);
487 /* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
488 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
491 write_debug_data4 (unsigned long data4
, const char *comment
, int dosizeonly
)
495 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file
, data4
);
496 if (flag_verbose_asm
)
497 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
498 fputc ('\n', asm_out_file
);
504 /* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
505 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
508 write_debug_data8 (unsigned long long data8
, const char *comment
,
513 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file
, data8
);
514 if (flag_verbose_asm
)
515 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
516 fputc ('\n', asm_out_file
);
522 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
523 flag_verbose_asm is set. Return the data size. Just return the size if
524 DOSIZEONLY is nonzero. */
527 write_debug_delta4 (const char *label1
, const char *label2
,
528 const char *comment
, int dosizeonly
)
532 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file
, label1
, label2
);
533 if (flag_verbose_asm
)
534 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
535 fputc ('\n', asm_out_file
);
541 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
542 set. Return the string length. Just return the length if DOSIZEONLY is
546 write_debug_string (const char *string
, const char *comment
, int dosizeonly
)
550 ASM_OUTPUT_DEBUG_STRING (asm_out_file
, string
);
551 if (flag_verbose_asm
)
552 fprintf (asm_out_file
, "\t%s %s", ASM_COMMENT_START
, comment
);
553 fputc ('\n', asm_out_file
);
556 return strlen (string
);
559 /* Output a module begin header and return the header size. Just return the
560 size if DOSIZEONLY is nonzero. */
563 write_modbeg (int dosizeonly
)
565 DST_MODULE_BEGIN modbeg
;
568 char *module_name
, *m
;
573 /* Assumes primary filename has Unix syntax file spec. */
574 module_name
= xstrdup (lbasename (primary_filename
));
576 m
= strrchr (module_name
, '.');
580 modnamelen
= strlen (module_name
);
581 for (i
= 0; i
< modnamelen
; i
++)
582 module_name
[i
] = TOUPPER (module_name
[i
]);
584 prodnamelen
= strlen (module_producer
);
586 modbeg
.dst_a_modbeg_header
.dst__header_length
.dst_w_length
587 = DST_K_MODBEG_SIZE
+ modnamelen
+ DST_K_MB_TRLR_SIZE
+ prodnamelen
- 1;
588 modbeg
.dst_a_modbeg_header
.dst__header_type
.dst_w_type
= DST_K_MODBEG
;
589 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_hide
= 0;
590 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_version
= 1;
591 modbeg
.dst_b_modbeg_flags
.dst_v_modbeg_unused
= 0;
592 modbeg
.dst_b_modbeg_unused
= 0;
593 modbeg
.dst_l_modbeg_language
= (DST_LANGUAGE
) module_language
;
594 modbeg
.dst_w_version_major
= DST_K_VERSION_MAJOR
;
595 modbeg
.dst_w_version_minor
= DST_K_VERSION_MINOR
;
596 modbeg
.dst_b_modbeg_name
= strlen (module_name
);
598 mb_trlr
.dst_b_compiler
= strlen (module_producer
);
600 totsize
+= write_debug_header (&modbeg
.dst_a_modbeg_header
,
601 "modbeg", dosizeonly
);
602 totsize
+= write_debug_data1 (*((char *) &modbeg
.dst_b_modbeg_flags
),
603 "flags", dosizeonly
);
604 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_unused
,
605 "unused", dosizeonly
);
606 totsize
+= write_debug_data4 (modbeg
.dst_l_modbeg_language
,
607 "language", dosizeonly
);
608 totsize
+= write_debug_data2 (modbeg
.dst_w_version_major
,
609 "DST major version", dosizeonly
);
610 totsize
+= write_debug_data2 (modbeg
.dst_w_version_minor
,
611 "DST minor version", dosizeonly
);
612 totsize
+= write_debug_data1 (modbeg
.dst_b_modbeg_name
,
613 "length of module name", dosizeonly
);
614 totsize
+= write_debug_string (module_name
, "module name", dosizeonly
);
615 totsize
+= write_debug_data1 (mb_trlr
.dst_b_compiler
,
616 "length of compiler name", dosizeonly
);
617 totsize
+= write_debug_string (module_producer
, "compiler name", dosizeonly
);
622 /* Output a module end trailer and return the trailer size. Just return
623 the size if DOSIZEONLY is nonzero. */
626 write_modend (int dosizeonly
)
628 DST_MODULE_END modend
;
631 modend
.dst_a_modend_header
.dst__header_length
.dst_w_length
632 = DST_K_MODEND_SIZE
- 1;
633 modend
.dst_a_modend_header
.dst__header_type
.dst_w_type
= DST_K_MODEND
;
635 totsize
+= write_debug_header (&modend
.dst_a_modend_header
, "modend",
641 /* Output a routine begin header routine RTNNUM and return the header size.
642 Just return the size if DOSIZEONLY is nonzero. */
645 write_rtnbeg (int rtnnum
, int dosizeonly
)
651 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
652 DST_ROUTINE_BEGIN rtnbeg
;
655 rtnname
= funcnam_table
[rtnnum
];
656 rtnnamelen
= strlen (rtnname
);
657 rtnentryname
= concat (rtnname
, "..en", NULL
);
659 if (!strcmp (rtnname
, "main"))
662 const char *go
= "TRANSFER$BREAK$GO";
664 /* This command isn't documented in DSTRECORDS, so it's made to
665 look like what DEC C does */
667 /* header size - 1st byte + flag byte + STO_LW size
668 + string count byte + string length */
669 header
.dst__header_length
.dst_w_length
670 = DST_K_DST_HEADER_SIZE
- 1 + 1 + 4 + 1 + strlen (go
);
671 header
.dst__header_type
.dst_w_type
= DST_K_TBG
;
673 totsize
+= write_debug_header (&header
, "transfer", dosizeonly
);
675 /* I think this is a flag byte, but I don't know what this flag means */
676 totsize
+= write_debug_data1 (0x1, "flags ???", dosizeonly
);
678 /* Routine Begin PD Address */
679 totsize
+= write_debug_addr (rtnname
, "main procedure descriptor",
681 totsize
+= write_debug_data1 (strlen (go
), "length of main_name",
683 totsize
+= write_debug_string (go
, "main name", dosizeonly
);
686 /* The header length never includes the length byte. */
687 rtnbeg
.dst_a_rtnbeg_header
.dst__header_length
.dst_w_length
688 = DST_K_RTNBEG_SIZE
+ rtnnamelen
- 1;
689 rtnbeg
.dst_a_rtnbeg_header
.dst__header_type
.dst_w_type
= DST_K_RTNBEG
;
690 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unused
= 0;
691 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_unalloc
= 0;
692 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_prototype
= 0;
693 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_inlined
= 0;
694 rtnbeg
.dst_b_rtnbeg_flags
.dst_v_rtnbeg_no_call
= 1;
695 rtnbeg
.dst_b_rtnbeg_name
= rtnnamelen
;
697 totsize
+= write_debug_header (&rtnbeg
.dst_a_rtnbeg_header
, "rtnbeg",
699 totsize
+= write_debug_data1 (*((char *) &rtnbeg
.dst_b_rtnbeg_flags
),
700 "flags", dosizeonly
);
702 /* Routine Begin Address */
703 totsize
+= write_debug_addr (rtnentryname
, "routine entry name", dosizeonly
);
705 /* Routine Begin PD Address */
706 totsize
+= write_debug_addr (rtnname
, "routine procedure descriptor",
709 /* Routine Begin Name */
710 totsize
+= write_debug_data1 (rtnbeg
.dst_b_rtnbeg_name
,
711 "length of routine name", dosizeonly
);
713 totsize
+= write_debug_string (rtnname
, "routine name", dosizeonly
);
717 if (debug_info_level
> DINFO_LEVEL_TERSE
)
719 prolog
.dst_a_prolog_header
.dst__header_length
.dst_w_length
720 = DST_K_PROLOG_SIZE
- 1;
721 prolog
.dst_a_prolog_header
.dst__header_type
.dst_w_type
= DST_K_PROLOG
;
723 totsize
+= write_debug_header (&prolog
.dst_a_prolog_header
, "prolog",
726 ASM_GENERATE_INTERNAL_LABEL
727 (label
, FUNC_PROLOG_LABEL
,
728 funcnum_table
[rtnnum
]);
729 totsize
+= write_debug_addr (label
, "prolog breakpoint addr",
736 /* Output a routine end trailer for routine RTNNUM and return the header size.
737 Just return the size if DOSIZEONLY is nonzero. */
740 write_rtnend (int rtnnum
, int dosizeonly
)
742 DST_ROUTINE_END rtnend
;
743 char label1
[MAX_ARTIFICIAL_LABEL_BYTES
];
744 char label2
[MAX_ARTIFICIAL_LABEL_BYTES
];
749 rtnend
.dst_a_rtnend_header
.dst__header_length
.dst_w_length
750 = DST_K_RTNEND_SIZE
- 1;
751 rtnend
.dst_a_rtnend_header
.dst__header_type
.dst_w_type
= DST_K_RTNEND
;
752 rtnend
.dst_b_rtnend_unused
= 0;
753 rtnend
.dst_l_rtnend_size
= 0; /* Calculated below. */
755 totsize
+= write_debug_header (&rtnend
.dst_a_rtnend_header
, "rtnend",
757 totsize
+= write_debug_data1 (rtnend
.dst_b_rtnend_unused
, "unused",
760 ASM_GENERATE_INTERNAL_LABEL
761 (label1
, FUNC_BEGIN_LABEL
,
762 funcnum_table
[rtnnum
]);
763 ASM_GENERATE_INTERNAL_LABEL
764 (label2
, FUNC_END_LABEL
,
765 funcnum_table
[rtnnum
]);
766 totsize
+= write_debug_delta4 (label2
, label1
, "routine size", dosizeonly
);
771 #define K_DELTA_PC(I) \
772 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
774 #define K_SET_LINUM(I) \
775 ((I) < 256 ? DST_K_SET_LINUM_B \
776 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
778 #define K_INCR_LINUM(I) \
779 ((I) < 256 ? DST_K_INCR_LINUM \
780 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
782 /* Output the PC to line number correlations and return the size. Just return
783 the size if DOSIZEONLY is nonzero */
786 write_pclines (int dosizeonly
)
793 DST_LINE_NUM_HEADER line_num
;
794 DST_PCLINE_COMMANDS pcline
;
795 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
796 char lastlabel
[MAX_ARTIFICIAL_LABEL_BYTES
];
800 max_line
= file_info_table
[1].max_line
;
801 file_info_table
[1].listing_line_start
= linestart
;
802 linestart
= linestart
+ ((max_line
/ 100000) + 1) * 100000;
804 for (i
= 2; i
< file_info_table_in_use
; i
++)
806 max_line
= file_info_table
[i
].max_line
;
807 file_info_table
[i
].listing_line_start
= linestart
;
808 linestart
= linestart
+ ((max_line
/ 10000) + 1) * 10000;
811 /* Set starting address to beginning of text section. */
812 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 8;
813 line_num
.dst_a_line_num_header
.dst__header_type
.dst_w_type
= DST_K_LINE_NUM
;
814 pcline
.dst_b_pcline_command
= DST_K_SET_ABS_PC
;
816 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
817 "line_num", dosizeonly
);
818 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
819 "line_num (SET ABS PC)", dosizeonly
);
825 ASM_OUTPUT_DEBUG_ADDR (asm_out_file
, TEXT_SECTION_ASM_OP
);
826 if (flag_verbose_asm
)
827 fprintf (asm_out_file
, "\t%s line_num", ASM_COMMENT_START
);
828 fputc ('\n', asm_out_file
);
831 fn
= line_info_table
[1].dst_file_num
;
832 ln
= (file_info_table
[fn
].listing_line_start
833 + line_info_table
[1].dst_line_num
);
834 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
= 4 + 4;
835 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
837 totsize
+= write_debug_header (&line_num
.dst_a_line_num_header
,
838 "line_num", dosizeonly
);
839 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
840 "line_num (SET LINUM LONG)", dosizeonly
);
842 sprintf (buff
, "line_num (%d)", ln
? ln
- 1 : 0);
843 totsize
+= write_debug_data4 (ln
? ln
- 1 : 0, buff
, dosizeonly
);
846 strcpy (lastlabel
, TEXT_SECTION_ASM_OP
);
847 for (i
= 1; i
< line_info_table_in_use
; i
++)
851 fn
= line_info_table
[i
].dst_file_num
;
852 ln
= (file_info_table
[fn
].listing_line_start
853 + line_info_table
[i
].dst_line_num
);
856 extrabytes
= 5; /* NUMBYTES (ln - lastln - 1) + 1; */
857 else if (ln
<= lastln
)
858 extrabytes
= 5; /* NUMBYTES (ln - 1) + 1; */
862 line_num
.dst_a_line_num_header
.dst__header_length
.dst_w_length
865 totsize
+= write_debug_header
866 (&line_num
.dst_a_line_num_header
, "line_num", dosizeonly
);
870 int lndif
= ln
- lastln
- 1;
872 /* K_INCR_LINUM (lndif); */
873 pcline
.dst_b_pcline_command
= DST_K_INCR_LINUM_L
;
875 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
876 "line_num (INCR LINUM LONG)",
879 sprintf (buff
, "line_num (%d)", lndif
);
880 totsize
+= write_debug_data4 (lndif
, buff
, dosizeonly
);
882 else if (ln
<= lastln
)
884 /* K_SET_LINUM (ln-1); */
885 pcline
.dst_b_pcline_command
= DST_K_SET_LINUM_L
;
887 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
888 "line_num (SET LINUM LONG)",
891 sprintf (buff
, "line_num (%d)", ln
- 1);
892 totsize
+= write_debug_data4 (ln
- 1, buff
, dosizeonly
);
895 pcline
.dst_b_pcline_command
= DST_K_DELTA_PC_L
;
897 totsize
+= write_debug_data1 (pcline
.dst_b_pcline_command
,
898 "line_num (DELTA PC LONG)", dosizeonly
);
900 ASM_GENERATE_INTERNAL_LABEL (label
, LINE_CODE_LABEL
, i
);
901 totsize
+= write_debug_delta4 (label
, lastlabel
, "increment line_num",
905 strcpy (lastlabel
, label
);
911 /* Output a source correlation for file FILEID using information saved in
912 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
916 write_srccorr (int fileid
, dst_file_info_entry file_info_entry
,
919 int src_command_size
;
920 int linesleft
= file_info_entry
.max_line
;
921 int linestart
= file_info_entry
.listing_line_start
;
922 int flen
= strlen (file_info_entry
.file_name
);
924 DST_SOURCE_CORR src_header
;
925 DST_SRC_COMMAND src_command
;
926 DST_SRC_COMMAND src_command_sf
;
927 DST_SRC_COMMAND src_command_sl
;
928 DST_SRC_COMMAND src_command_sr
;
929 DST_SRC_COMMAND src_command_dl
;
930 DST_SRC_CMDTRLR src_cmdtrlr
;
936 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
937 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 1 - 1;
938 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
940 src_command
.dst_b_src_command
= DST_K_SRC_FORMFEED
;
942 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
943 "source corr", dosizeonly
);
945 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
946 "source_corr (SRC FORMFEED)",
951 = DST_K_SRC_COMMAND_SIZE
+ flen
+ DST_K_SRC_CMDTRLR_SIZE
;
952 src_command
.dst_b_src_command
= DST_K_SRC_DECLFILE
;
953 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
954 = src_command_size
- 2;
955 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
= 0;
956 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
958 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
959 = file_info_entry
.cdt
;
960 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
961 = file_info_entry
.ebk
;
962 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
963 = file_info_entry
.ffb
;
964 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
965 = file_info_entry
.rfo
;
966 src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
969 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
970 = DST_K_SOURCE_CORR_HEADER_SIZE
+ src_command_size
- 1;
971 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
974 src_cmdtrlr
.dst_b_src_df_libmodname
= 0;
976 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
977 "source corr", dosizeonly
);
978 totsize
+= write_debug_data1 (src_command
.dst_b_src_command
,
979 "source_corr (DECL SRC FILE)", dosizeonly
);
980 totsize
+= write_debug_data1
981 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_length
,
982 "source_corr (length)", dosizeonly
);
984 totsize
+= write_debug_data1
985 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_flags
,
986 "source_corr (flags)", dosizeonly
);
988 totsize
+= write_debug_data2
989 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_fileid
,
990 "source_corr (fileid)", dosizeonly
);
992 totsize
+= write_debug_data8
993 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_q_src_df_rms_cdt
,
994 "source_corr (creation date)", dosizeonly
);
996 totsize
+= write_debug_data4
997 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_l_src_df_rms_ebk
,
998 "source_corr (EOF block number)", dosizeonly
);
1000 totsize
+= write_debug_data2
1001 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_w_src_df_rms_ffb
,
1002 "source_corr (first free byte)", dosizeonly
);
1004 totsize
+= write_debug_data1
1005 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_rms_rfo
,
1006 "source_corr (record and file organization)", dosizeonly
);
1008 totsize
+= write_debug_data1
1009 (src_command
.dst_a_src_cmd_fields
.dst_a_src_decl_src
.dst_b_src_df_filename
,
1010 "source_corr (filename length)", dosizeonly
);
1012 totsize
+= write_debug_string (remap_debug_filename (
1013 file_info_entry
.file_name
),
1014 "source file name", dosizeonly
);
1015 totsize
+= write_debug_data1 (src_cmdtrlr
.dst_b_src_df_libmodname
,
1016 "source_corr (libmodname)", dosizeonly
);
1018 src_command_sf
.dst_b_src_command
= DST_K_SRC_SETFILE
;
1019 src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
= fileid
;
1021 src_command_sr
.dst_b_src_command
= DST_K_SRC_SETREC_W
;
1022 src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
= 1;
1024 src_command_sl
.dst_b_src_command
= DST_K_SRC_SETLNUM_L
;
1025 src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
= linestart
+ 1;
1027 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1029 if (linesleft
> 65534)
1030 linesleft
= linesleft
- 65534, linestodo
= 65534;
1032 linestodo
= linesleft
, linesleft
= 0;
1034 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1036 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1037 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 + 3 + 5 + 3 - 1;
1038 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1041 if (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
)
1043 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1044 "source corr", dosizeonly
);
1046 totsize
+= write_debug_data1 (src_command_sf
.dst_b_src_command
,
1047 "source_corr (src setfile)", dosizeonly
);
1049 totsize
+= write_debug_data2
1050 (src_command_sf
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1051 "source_corr (fileid)", dosizeonly
);
1053 totsize
+= write_debug_data1 (src_command_sr
.dst_b_src_command
,
1054 "source_corr (setrec)", dosizeonly
);
1056 totsize
+= write_debug_data2
1057 (src_command_sr
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1058 "source_corr (recnum)", dosizeonly
);
1060 totsize
+= write_debug_data1 (src_command_sl
.dst_b_src_command
,
1061 "source_corr (setlnum)", dosizeonly
);
1063 totsize
+= write_debug_data4
1064 (src_command_sl
.dst_a_src_cmd_fields
.dst_l_src_unslong
,
1065 "source_corr (linenum)", dosizeonly
);
1067 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1068 "source_corr (deflines)", dosizeonly
);
1070 sprintf (buff
, "source_corr (%d)",
1071 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1072 totsize
+= write_debug_data2
1073 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1076 while (linesleft
> 0)
1078 src_header
.dst_a_source_corr_header
.dst__header_length
.dst_w_length
1079 = DST_K_SOURCE_CORR_HEADER_SIZE
+ 3 - 1;
1080 src_header
.dst_a_source_corr_header
.dst__header_type
.dst_w_type
1082 src_command_dl
.dst_b_src_command
= DST_K_SRC_DEFLINES_W
;
1084 if (linesleft
> 65534)
1085 linesleft
= linesleft
- 65534, linestodo
= 65534;
1087 linestodo
= linesleft
, linesleft
= 0;
1089 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
= linestodo
;
1091 totsize
+= write_debug_header (&src_header
.dst_a_source_corr_header
,
1092 "source corr", dosizeonly
);
1093 totsize
+= write_debug_data1 (src_command_dl
.dst_b_src_command
,
1094 "source_corr (deflines)", dosizeonly
);
1095 sprintf (buff
, "source_corr (%d)",
1096 src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
);
1097 totsize
+= write_debug_data2
1098 (src_command_dl
.dst_a_src_cmd_fields
.dst_w_src_unsword
,
1106 /* Output all the source correlation entries and return the size. Just return
1107 the size if DOSIZEONLY is nonzero. */
1110 write_srccorrs (int dosizeonly
)
1115 for (i
= 1; i
< file_info_table_in_use
; i
++)
1116 totsize
+= write_srccorr (i
, file_info_table
[i
], dosizeonly
);
1121 /* Output a marker (i.e. a label) for the beginning of a function, before
1125 vmsdbgout_begin_prologue (unsigned int line
, unsigned int column
,
1128 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1130 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1131 (*dwarf2_debug_hooks
.begin_prologue
) (line
, column
, file
);
1133 if (debug_info_level
> DINFO_LEVEL_NONE
)
1135 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_BEGIN_LABEL
,
1136 current_function_funcdef_no
);
1137 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1141 /* Output a marker (i.e. a label) for the beginning of a function, after
1145 vmsdbgout_end_prologue (unsigned int line
, const char *file
)
1147 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1149 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1150 (*dwarf2_debug_hooks
.end_prologue
) (line
, file
);
1152 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1154 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_PROLOG_LABEL
,
1155 current_function_funcdef_no
);
1156 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1158 /* VMS PCA expects every PC range to correlate to some line and file. */
1159 vmsdbgout_write_source_line (line
, file
, 0, true);
1163 /* No output for VMS debug, but make obligatory call to Dwarf2 debug */
1166 vmsdbgout_end_function (unsigned int line
)
1168 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1169 (*dwarf2_debug_hooks
.end_function
) (line
);
1172 /* Output a marker (i.e. a label) for the beginning of the epilogue.
1173 This gets called *before* the epilogue code has been generated. */
1176 vmsdbgout_begin_epilogue (unsigned int line
, const char *file
)
1178 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1179 static int save_current_function_funcdef_no
= -1;
1181 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1182 (*dwarf2_debug_hooks
.begin_epilogue
) (line
, file
);
1184 if (debug_info_level
> DINFO_LEVEL_NONE
)
1186 if (save_current_function_funcdef_no
!= current_function_funcdef_no
)
1188 /* Output a label to mark the endpoint of the code generated for this
1190 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_EPILOG_LABEL
,
1191 current_function_funcdef_no
);
1193 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1195 save_current_function_funcdef_no
= current_function_funcdef_no
;
1197 /* VMS PCA expects every PC range to correlate to some line and
1199 vmsdbgout_write_source_line (line
, file
, 0, true);
1204 /* Output a marker (i.e. a label) for the absolute end of the generated code
1205 for a function definition. This gets called *after* the epilogue code has
1209 vmsdbgout_end_epilogue (unsigned int line
, const char *file
)
1211 char label
[MAX_ARTIFICIAL_LABEL_BYTES
];
1213 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1214 (*dwarf2_debug_hooks
.end_epilogue
) (line
, file
);
1216 if (debug_info_level
> DINFO_LEVEL_NONE
)
1218 /* Output a label to mark the endpoint of the code generated for this
1220 ASM_GENERATE_INTERNAL_LABEL (label
, FUNC_END_LABEL
,
1221 current_function_funcdef_no
);
1222 ASM_OUTPUT_LABEL (asm_out_file
, label
);
1224 /* VMS PCA expects every PC range to correlate to some line and file. */
1225 vmsdbgout_write_source_line (line
, file
, 0, true);
1229 /* Output a marker (i.e. a label) for the beginning of the generated code for
1233 vmsdbgout_begin_block (unsigned line
, unsigned blocknum
,
1236 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1237 (*dwarf2_debug_hooks
.begin_block
) (line
, blocknum
, block
);
1239 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1240 targetm
.asm_out
.internal_label (asm_out_file
, BLOCK_BEGIN_LABEL
, blocknum
);
1243 /* Output a marker (i.e. a label) for the end of the generated code for a
1247 vmsdbgout_end_block (unsigned line
, unsigned blocknum
)
1249 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1250 (*dwarf2_debug_hooks
.end_block
) (line
, blocknum
);
1252 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1253 targetm
.asm_out
.internal_label (asm_out_file
, BLOCK_END_LABEL
, blocknum
);
1256 /* Not implemented in VMS Debug. */
1259 vmsdbgout_ignore_block (const_tree block
)
1263 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1264 retval
= (*dwarf2_debug_hooks
.ignore_block
) (block
);
1269 /* Add an entry for function DECL into the funcnam_table. */
1272 vmsdbgout_begin_function (tree decl
)
1274 const char *name
= XSTR (XEXP (DECL_RTL (decl
), 0), 0);
1276 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1277 (*dwarf2_debug_hooks
.begin_function
) (decl
);
1279 /* Add the new entry to the end of the function name table. */
1280 funcnam_table
.safe_push (xstrdup (name
));
1281 funcnum_table
.safe_push (current_function_funcdef_no
);
1284 static char fullname_buff
[4096];
1286 /* Return the full file specification for FILENAME. The specification must be
1287 in VMS syntax in order to be processed by VMS Debug. */
1290 full_name (const char *filename
)
1293 FILE *fp
= fopen (filename
, "r");
1295 fgetname (fp
, fullname_buff
, 1);
1298 /* Unix paths really mess up VMS debug. Better to just output the
1300 strcpy (fullname_buff
, filename
);
1303 return fullname_buff
;
1306 /* Lookup a filename (in the list of filenames that we know about here in
1307 vmsdbgout.cc) and return its "index". The index of each (known) filename is
1308 just a unique number which is associated with only that one filename. We
1309 need such numbers for the sake of generating labels and references
1310 to those files numbers. If the filename given as an argument is not
1311 found in our current list, add it to the list and assign it the next
1312 available unique index number. In order to speed up searches, we remember
1313 the index of the filename was looked up last. This handles the majority of
1317 lookup_filename (const char *file_name
)
1319 static unsigned int last_file_lookup_index
= 0;
1330 fnam
= full_name (file_name
);
1332 /* Check to see if the file name that was searched on the previous call
1333 matches this file name. If so, return the index. */
1334 if (last_file_lookup_index
!= 0)
1336 fn
= file_info_table
[last_file_lookup_index
].file_name
;
1337 if (strcmp (fnam
, fn
) == 0)
1338 return last_file_lookup_index
;
1341 /* Didn't match the previous lookup, search the table */
1342 for (i
= 1; i
< file_info_table_in_use
; ++i
)
1344 fn
= file_info_table
[i
].file_name
;
1345 if (strcmp (fnam
, fn
) == 0)
1347 last_file_lookup_index
= i
;
1352 /* Prepare to add a new table entry by making sure there is enough space in
1353 the table to do so. If not, expand the current table. */
1354 if (file_info_table_in_use
== file_info_table_allocated
)
1357 file_info_table_allocated
+= FILE_TABLE_INCREMENT
;
1358 file_info_table
= XRESIZEVEC (dst_file_info_entry
, file_info_table
,
1359 file_info_table_allocated
);
1362 if (vms_file_stats_name (file_name
, &cdt
, &siz
, &rfo
, &ver
) == 0)
1364 ebk
= siz
/ 512 + 1;
1365 ffb
= siz
- ((siz
/ 512) * 512);
1368 /* Add the new entry to the end of the filename table. */
1369 file_info_table
[file_info_table_in_use
].file_name
= xstrdup (fnam
);
1370 file_info_table
[file_info_table_in_use
].max_line
= 0;
1371 file_info_table
[file_info_table_in_use
].cdt
= cdt
;
1372 file_info_table
[file_info_table_in_use
].ebk
= ebk
;
1373 file_info_table
[file_info_table_in_use
].ffb
= ffb
;
1374 file_info_table
[file_info_table_in_use
].rfo
= rfo
;
1376 last_file_lookup_index
= file_info_table_in_use
++;
1377 return last_file_lookup_index
;
1380 /* Output a label to mark the beginning of a source code line entry
1381 and record information relating to this source line, in
1382 'line_info_table' for later output of the .debug_line section. */
1385 vmsdbgout_write_source_line (unsigned line
, const char *filename
,
1386 int /* discriminator */, bool /* is_stmt */)
1388 dst_line_info_ref line_info
;
1390 targetm
.asm_out
.internal_label (asm_out_file
, LINE_CODE_LABEL
,
1391 line_info_table_in_use
);
1393 /* Expand the line info table if necessary. */
1394 if (line_info_table_in_use
== line_info_table_allocated
)
1396 line_info_table_allocated
+= LINE_INFO_TABLE_INCREMENT
;
1397 line_info_table
= XRESIZEVEC (dst_line_info_entry
, line_info_table
,
1398 line_info_table_allocated
);
1401 /* Add the new entry at the end of the line_info_table. */
1402 line_info
= &line_info_table
[line_info_table_in_use
++];
1403 line_info
->dst_file_num
= lookup_filename (filename
);
1404 line_info
->dst_line_num
= line
;
1405 if (line
> file_info_table
[line_info
->dst_file_num
].max_line
)
1406 file_info_table
[line_info
->dst_file_num
].max_line
= line
;
1410 vmsdbgout_source_line (unsigned line
, unsigned int column
,
1411 const char *filename
,
1412 int discriminator
, bool is_stmt
)
1414 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1415 (*dwarf2_debug_hooks
.source_line
) (line
, column
, filename
, discriminator
,
1418 if (debug_info_level
>= DINFO_LEVEL_TERSE
)
1419 vmsdbgout_write_source_line (line
, filename
, discriminator
, is_stmt
);
1422 /* Record the beginning of a new source file, for later output.
1423 At present, unimplemented. */
1426 vmsdbgout_start_source_file (unsigned int lineno
, const char *filename
)
1428 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1429 (*dwarf2_debug_hooks
.start_source_file
) (lineno
, filename
);
1432 /* Record the end of a source file, for later output.
1433 At present, unimplemented. */
1436 vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED
)
1438 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1439 (*dwarf2_debug_hooks
.end_source_file
) (lineno
);
1442 /* Set up for Debug output at the start of compilation. */
1445 vmsdbgout_init (const char *filename
)
1447 const char *language_string
= lang_hooks
.name
;
1449 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1450 (*dwarf2_debug_hooks
.init
) (filename
);
1452 if (debug_info_level
== DINFO_LEVEL_NONE
)
1455 /* Remember the name of the primary input file. */
1456 primary_filename
= filename
;
1458 /* Allocate the initial hunk of the file_info_table. */
1459 file_info_table
= XCNEWVEC (dst_file_info_entry
, FILE_TABLE_INCREMENT
);
1460 file_info_table_allocated
= FILE_TABLE_INCREMENT
;
1461 /* Skip the first entry - file numbers begin at 1. */
1462 file_info_table_in_use
= 1;
1464 funcnam_table
.create (FUNC_TABLE_INITIAL
);
1465 funcnum_table
.create (FUNC_TABLE_INITIAL
);
1467 /* Allocate the initial hunk of the line_info_table. */
1468 line_info_table
= XCNEWVEC (dst_line_info_entry
, LINE_INFO_TABLE_INCREMENT
);
1469 line_info_table_allocated
= LINE_INFO_TABLE_INCREMENT
;
1470 /* zero-th entry is allocated, but unused */
1471 line_info_table_in_use
= 1;
1473 lookup_filename (primary_filename
);
1476 module_language
= DST_K_C
;
1477 else if (lang_GNU_CXX ())
1478 module_language
= DST_K_CXX
;
1479 else if (!strcmp (language_string
, "GNU Ada"))
1480 module_language
= DST_K_ADA
;
1481 else if (!strcmp (language_string
, "GNU F77"))
1482 module_language
= DST_K_FORTRAN
;
1484 module_language
= DST_K_UNKNOWN
;
1486 module_producer
= concat (language_string
, " ", version_string
, NULL
);
1488 ASM_GENERATE_INTERNAL_LABEL (text_end_label
, TEXT_END_LABEL
, 0);
1492 /* Not implemented in VMS Debug. */
1495 vmsdbgout_assembly_start (void)
1497 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1498 (*dwarf2_debug_hooks
.assembly_start
) ();
1501 /* Not implemented in VMS Debug. */
1504 vmsdbgout_define (unsigned int lineno
, const char *buffer
)
1506 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1507 (*dwarf2_debug_hooks
.define
) (lineno
, buffer
);
1510 /* Not implemented in VMS Debug. */
1513 vmsdbgout_undef (unsigned int lineno
, const char *buffer
)
1515 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1516 (*dwarf2_debug_hooks
.undef
) (lineno
, buffer
);
1519 /* Not implemented in VMS Debug. */
1522 vmsdbgout_function_decl (tree decl
)
1524 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1525 (*dwarf2_debug_hooks
.function_decl
) (decl
);
1528 /* Not implemented in VMS Debug. */
1531 vmsdbgout_early_global_decl (tree decl
)
1533 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1534 (*dwarf2_debug_hooks
.early_global_decl
) (decl
);
1537 /* Not implemented in VMS Debug. */
1540 vmsdbgout_late_global_decl (tree decl
)
1542 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1543 (*dwarf2_debug_hooks
.late_global_decl
) (decl
);
1546 /* Not implemented in VMS Debug. */
1549 vmsdbgout_type_decl (tree decl
, int local
)
1551 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1552 (*dwarf2_debug_hooks
.type_decl
) (decl
, local
);
1555 /* Not implemented in VMS Debug. */
1558 vmsdbgout_abstract_function (tree decl
)
1560 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1561 (*dwarf2_debug_hooks
.outlining_inline_function
) (decl
);
1565 vmsdbgout_early_finish (const char *filename
)
1567 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1568 (*dwarf2_debug_hooks
.early_finish
) (filename
);
1571 /* Output stuff that Debug requires at the end of every file and generate the
1572 VMS Debug debugging info. */
1575 vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED
)
1577 unsigned int i
, ifunc
;
1580 if (write_symbols
== VMS_AND_DWARF2_DEBUG
)
1581 (*dwarf2_debug_hooks
.finish
) (filename
);
1583 if (debug_info_level
== DINFO_LEVEL_NONE
)
1586 /* Output a terminator label for the .text section. */
1587 switch_to_section (text_section
);
1588 targetm
.asm_out
.internal_label (asm_out_file
, TEXT_END_LABEL
, 0);
1590 /* Output debugging information.
1591 Warning! Do not change the name of the .vmsdebug section without
1592 changing it in the assembler also. */
1593 switch_to_section (get_named_section (NULL
, ".vmsdebug", 0));
1594 ASM_OUTPUT_ALIGN (asm_out_file
, 0);
1596 totsize
= write_modbeg (1);
1597 FOR_EACH_VEC_ELT (funcnum_table
, i
, ifunc
)
1599 totsize
+= write_rtnbeg (i
, 1);
1600 totsize
+= write_rtnend (i
, 1);
1602 totsize
+= write_pclines (1);
1605 FOR_EACH_VEC_ELT (funcnum_table
, i
, ifunc
)
1607 write_rtnbeg (i
, 0);
1608 write_rtnend (i
, 0);
1612 if (debug_info_level
> DINFO_LEVEL_TERSE
)
1614 totsize
= write_srccorrs (1);
1618 totsize
= write_modend (1);
1622 /* Need for both Dwarf2 on IVMS and VMS Debug on AVMS */
1625 #define __NEW_STARLET 1
1626 #include <vms/rms.h>
1627 #include <vms/atrdef.h>
1628 #include <vms/fibdef.h>
1629 #include <vms/stsdef.h>
1630 #include <vms/iodef.h>
1631 #include <vms/fatdef.h>
1632 #include <vms/descrip.h>
1633 #include <unixlib.h>
1637 /* descrip.h doesn't have everything ... */
1638 typedef struct fibdef
* __fibdef_ptr32
__attribute__ (( mode (SI
) ));
1639 struct dsc$descriptor_fib
1641 unsigned int fib$l_len
;
1642 __fibdef_ptr32 fib$l_addr
;
1645 /* I/O Status Block. */
1648 unsigned short status
, count
;
1649 unsigned int devdep
;
1652 static char *tryfile
;
1654 /* Variable length string. */
1658 char string
[NAM$C_MAXRSS
+1];
1661 static char filename_buff
[MAXPATH
];
1662 static char vms_filespec
[MAXPATH
];
1664 /* Callback function for filespec style conversion. */
1667 translate_unix (char *name
, int type ATTRIBUTE_UNUSED
)
1669 strncpy (filename_buff
, name
, MAXPATH
);
1670 filename_buff
[MAXPATH
- 1] = (char) 0;
1674 /* Wrapper for DECC function that converts a Unix filespec
1675 to VMS style filespec. */
1678 to_vms_file_spec (char *filespec
)
1680 strncpy (vms_filespec
, "", MAXPATH
);
1681 decc$
to_vms (filespec
, translate_unix
, 1, 1);
1682 strncpy (vms_filespec
, filename_buff
, MAXPATH
);
1684 vms_filespec
[MAXPATH
- 1] = (char) 0;
1686 return vms_filespec
;
1690 #define VMS_EPOCH_OFFSET 35067168000000000LL
1691 #define VMS_GRANULARITY_FACTOR 10000000
1694 /* Return VMS file date, size, format, version given a name. */
1697 vms_file_stats_name (const char *filename
, long long *cdt
, long *siz
, char *rfo
,
1704 unsigned long long create
;
1706 char ascnamebuff
[256];
1710 { ATR$S_CREDATE
, ATR$C_CREDATE
, &create
},
1711 { ATR$S_RECATTR
, ATR$C_RECATTR
, &recattr
},
1712 { ATR$S_ASCNAME
, ATR$C_ASCNAME
, &ascnamebuff
},
1717 struct dsc$descriptor_fib fibdsc
= {sizeof (fib
), (void *) &fib
};
1722 unsigned short chan
;
1724 struct vstring file
;
1725 struct dsc$descriptor_s filedsc
1726 = {NAM$C_MAXRSS
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, (void *) file
.string
};
1727 struct vstring device
;
1728 struct dsc$descriptor_s devicedsc
1729 = {NAM$C_MAXRSS
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, (void *) device
.string
};
1730 struct vstring result
;
1731 struct dsc$descriptor_s resultdsc
1732 = {NAM$C_MAXRSS
, DSC$K_DTYPE_VT
, DSC$K_CLASS_VS
, (void *) result
.string
};
1734 if (strcmp (filename
, "<internal>") == 0
1735 || strcmp (filename
, "<built-in>") == 0)
1752 tryfile
= to_vms_file_spec (filename
);
1754 /* Allocate and initialize a FAB and NAM structures. */
1758 nam
.nam$l_esa
= file
.string
;
1759 nam
.nam$b_ess
= NAM$C_MAXRSS
;
1760 nam
.nam$l_rsa
= result
.string
;
1761 nam
.nam$b_rss
= NAM$C_MAXRSS
;
1762 fab
.fab$l_fna
= tryfile
;
1763 fab
.fab$b_fns
= strlen (tryfile
);
1764 fab
.fab$l_nam
= &nam
;
1766 /* Validate filespec syntax and device existence. */
1767 status
= SYS$
PARSE (&fab
, 0, 0);
1768 if ((status
& 1) != 1)
1771 file
.string
[nam
.nam$b_esl
] = 0;
1773 /* Find matching filespec. */
1774 status
= SYS$
SEARCH (&fab
, 0, 0);
1775 if ((status
& 1) != 1)
1778 file
.string
[nam
.nam$b_esl
] = 0;
1779 result
.string
[result
.length
=nam
.nam$b_rsl
] = 0;
1781 /* Get the device name and assign an IO channel. */
1782 strncpy (device
.string
, nam
.nam$l_dev
, nam
.nam$b_dev
);
1783 devicedsc
.dsc$w_length
= nam
.nam$b_dev
;
1785 status
= SYS$
ASSIGN (&devicedsc
, &chan
, 0, 0, 0);
1786 if ((status
& 1) != 1)
1789 /* Initialize the FIB and fill in the directory id field. */
1790 memset (&fib
, 0, sizeof (fib
));
1791 fib
.fib$w_did
[0] = nam
.nam$w_did
[0];
1792 fib
.fib$w_did
[1] = nam
.nam$w_did
[1];
1793 fib
.fib$w_did
[2] = nam
.nam$w_did
[2];
1794 fib
.fib$l_acctl
= 0;
1796 strcpy (file
.string
, (strrchr (result
.string
, ']') + 1));
1797 filedsc
.dsc$w_length
= strlen (file
.string
);
1798 result
.string
[result
.length
= 0] = 0;
1800 /* Open and close the file to fill in the attributes. */
1802 = SYS$
QIOW (0, chan
, IO$_ACCESS
|IO$M_ACCESS
, &iosb
, 0, 0,
1803 &fibdsc
, &filedsc
, &result
.length
, &resultdsc
, &atrlst
, 0);
1804 if ((status
& 1) != 1)
1806 if ((iosb
.status
& 1) != 1)
1809 result
.string
[result
.length
] = 0;
1810 status
= SYS$
QIOW (0, chan
, IO$_DEACCESS
, &iosb
, 0, 0, &fibdsc
, 0, 0, 0,
1812 if ((status
& 1) != 1)
1814 if ((iosb
.status
& 1) != 1)
1817 /* Deassign the channel and exit. */
1818 status
= SYS$
DASSGN (chan
);
1819 if ((status
& 1) != 1)
1822 if (cdt
) *cdt
= create
;
1823 if (siz
) *siz
= (512 * 65536 * recattr
.fat$w_efblkh
) +
1824 (512 * (recattr
.fat$w_efblkl
- 1)) +
1825 recattr
.fat$w_ffbyte
;
1826 if (rfo
) *rfo
= recattr
.fat$v_rtype
;
1827 if (ver
) *ver
= strtol (strrchr (ascnamebuff
, ';')+1, 0, 10);
1833 if ((stat (filename
, &buff
)) != 0)
1837 *cdt
= (long long) (buff
.st_mtime
* VMS_GRANULARITY_FACTOR
)
1841 *siz
= buff
.st_size
;
1844 *rfo
= 2; /* Stream LF format */