re PR lto/48086 (bootstrap-lto creates c-common.s with too many sections on x86_64...
[official-gcc.git] / gcc / vmsdbgout.c
blob01191001ac238a04d583f5f2ccc1f514e22f3569
1 /* Output VMS debug format symbol table information from GCC.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
5 Contributed by Douglas B. Rupp (rupp@gnat.com).
6 Updated by Bernard W. Giroud (bgiroud@users.sourceforge.net).
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
29 #ifdef VMS_DEBUGGING_INFO
30 #include "tree.h"
31 #include "version.h"
32 #include "flags.h"
33 #include "rtl.h"
34 #include "output.h"
35 #include "vmsdbg.h"
36 #include "debug.h"
37 #include "langhooks.h"
38 #include "function.h"
39 #include "target.h"
41 /* Difference in seconds between the VMS Epoch and the Unix Epoch */
42 static const long long vms_epoch_offset = 3506716800ll;
44 int vms_file_stats_name (const char *, long long *, long *, char *, int *);
46 /* NOTE: In the comments in this file, many references are made to "Debug
47 Symbol Table". This term is abbreviated as `DST' throughout the remainder
48 of this file. */
50 typedef struct dst_line_info_struct *dst_line_info_ref;
52 /* Each entry in the line_info_table maintains the file and
53 line number associated with the label generated for that
54 entry. The label gives the PC value associated with
55 the line number entry. */
56 typedef struct dst_line_info_struct
58 unsigned long dst_file_num;
59 unsigned long dst_line_num;
61 dst_line_info_entry;
63 typedef struct dst_file_info_struct *dst_file_info_ref;
65 typedef struct dst_file_info_struct
67 char *file_name;
68 unsigned int max_line;
69 unsigned int listing_line_start;
70 long long cdt;
71 long ebk;
72 short ffb;
73 char rfo;
74 char flen;
76 dst_file_info_entry;
78 /* How to start an assembler comment. */
79 #ifndef ASM_COMMENT_START
80 #define ASM_COMMENT_START ";#"
81 #endif
83 /* Maximum size (in bytes) of an artificially generated label. */
84 #define MAX_ARTIFICIAL_LABEL_BYTES 30
86 /* Make sure we know the sizes of the various types debug can describe. These
87 are only defaults. If the sizes are different for your target, you should
88 override these values by defining the appropriate symbols in your tm.h
89 file. */
90 #ifndef PTR_SIZE
91 #define PTR_SIZE 4 /* Must be 32 bits for VMS debug info */
92 #endif
94 /* Pointer to a structure of filenames referenced by this compilation unit. */
95 static dst_file_info_ref file_info_table;
97 /* Total number of entries in the table (i.e. array) pointed to by
98 `file_info_table'. This is the *total* and includes both used and unused
99 slots. */
100 static unsigned int file_info_table_allocated;
102 /* Number of entries in the file_info_table which are actually in use. */
103 static unsigned int file_info_table_in_use;
105 /* Size (in elements) of increments by which we may expand the filename
106 table. */
107 #define FILE_TABLE_INCREMENT 64
109 typedef char *char_p;
110 DEF_VEC_P(char_p);
111 DEF_VEC_ALLOC_P(char_p,heap);
113 static VEC(char_p,heap) *funcnam_table;
114 static VEC(unsigned,heap) *funcnum_table;
115 #define FUNC_TABLE_INITIAL 256
117 /* Local pointer to the name of the main input file. Initialized in
118 vmsdbgout_init. */
119 static const char *primary_filename;
121 static char *module_producer;
122 static unsigned int module_language;
124 /* A pointer to the base of a table that contains line information
125 for each source code line in .text in the compilation unit. */
126 static dst_line_info_ref line_info_table;
128 /* Number of elements currently allocated for line_info_table. */
129 static unsigned int line_info_table_allocated;
131 /* Number of elements in line_info_table currently in use. */
132 static unsigned int line_info_table_in_use;
134 /* Size (in elements) of increments by which we may expand line_info_table. */
135 #define LINE_INFO_TABLE_INCREMENT 1024
137 /* Forward declarations for functions defined in this file. */
138 static char *full_name (const char *);
139 static unsigned int lookup_filename (const char *);
140 static int write_debug_header (DST_HEADER *, const char *, int);
141 static int write_debug_addr (const char *, const char *, int);
142 static int write_debug_data1 (unsigned int, const char *, int);
143 static int write_debug_data2 (unsigned int, const char *, int);
144 static int write_debug_data4 (unsigned long, const char *, int);
145 static int write_debug_data8 (unsigned long long, const char *, int);
146 static int write_debug_delta4 (const char *, const char *, const char *, int);
147 static int write_debug_string (const char *, const char *, int);
148 static int write_modbeg (int);
149 static int write_modend (int);
150 static int write_rtnbeg (int, int);
151 static int write_rtnend (int, int);
152 static int write_pclines (int);
153 static int write_srccorr (int, dst_file_info_entry, int);
154 static int write_srccorrs (int);
156 static void vmsdbgout_init (const char *);
157 static void vmsdbgout_finish (const char *);
158 static void vmsdbgout_assembly_start (void);
159 static void vmsdbgout_define (unsigned int, const char *);
160 static void vmsdbgout_undef (unsigned int, const char *);
161 static void vmsdbgout_start_source_file (unsigned int, const char *);
162 static void vmsdbgout_end_source_file (unsigned int);
163 static void vmsdbgout_begin_block (unsigned int, unsigned int);
164 static void vmsdbgout_end_block (unsigned int, unsigned int);
165 static bool vmsdbgout_ignore_block (const_tree);
166 static void vmsdbgout_source_line (unsigned int, const char *, int, bool);
167 static void vmsdbgout_begin_prologue (unsigned int, const char *);
168 static void vmsdbgout_end_prologue (unsigned int, const char *);
169 static void vmsdbgout_end_function (unsigned int);
170 static void vmsdbgout_begin_epilogue (unsigned int, const char *);
171 static void vmsdbgout_end_epilogue (unsigned int, const char *);
172 static void vmsdbgout_begin_function (tree);
173 static void vmsdbgout_decl (tree);
174 static void vmsdbgout_global_decl (tree);
175 static void vmsdbgout_type_decl (tree, int);
176 static void vmsdbgout_abstract_function (tree);
178 /* The debug hooks structure. */
180 const struct gcc_debug_hooks vmsdbg_debug_hooks
181 = {vmsdbgout_init,
182 vmsdbgout_finish,
183 vmsdbgout_assembly_start,
184 vmsdbgout_define,
185 vmsdbgout_undef,
186 vmsdbgout_start_source_file,
187 vmsdbgout_end_source_file,
188 vmsdbgout_begin_block,
189 vmsdbgout_end_block,
190 vmsdbgout_ignore_block,
191 vmsdbgout_source_line,
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 vmsdbgout_decl,
199 vmsdbgout_global_decl,
200 vmsdbgout_type_decl, /* type_decl */
201 debug_nothing_tree_tree_tree_bool, /* imported_module_or_decl */
202 debug_nothing_tree, /* deferred_inline_function */
203 vmsdbgout_abstract_function,
204 debug_nothing_rtx, /* label */
205 debug_nothing_int, /* handle_pch */
206 debug_nothing_rtx, /* var_location */
207 debug_nothing_void, /* switch_text_section */
208 debug_nothing_tree_tree, /* set_name */
209 0, /* start_end_main_source_file */
210 TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */
213 /* Definitions of defaults for assembler-dependent names of various
214 pseudo-ops and section names.
215 Theses may be overridden in the tm.h file (if necessary) for a particular
216 assembler. */
217 #ifdef UNALIGNED_SHORT_ASM_OP
218 #undef UNALIGNED_SHORT_ASM_OP
219 #endif
220 #define UNALIGNED_SHORT_ASM_OP ".word"
222 #ifdef UNALIGNED_INT_ASM_OP
223 #undef UNALIGNED_INT_ASM_OP
224 #endif
225 #define UNALIGNED_INT_ASM_OP ".long"
227 #ifdef UNALIGNED_LONG_ASM_OP
228 #undef UNALIGNED_LONG_ASM_OP
229 #endif
230 #define UNALIGNED_LONG_ASM_OP ".long"
232 #ifdef UNALIGNED_DOUBLE_INT_ASM_OP
233 #undef UNALIGNED_DOUBLE_INT_ASM_OP
234 #endif
235 #define UNALIGNED_DOUBLE_INT_ASM_OP ".quad"
237 #ifdef ASM_BYTE_OP
238 #undef ASM_BYTE_OP
239 #endif
240 #define ASM_BYTE_OP ".byte"
242 #define NUMBYTES(I) ((I) < 256 ? 1 : (I) < 65536 ? 2 : 4)
244 #define NUMBYTES0(I) ((I) < 128 ? 0 : (I) < 65536 ? 2 : 4)
246 #ifndef UNALIGNED_PTR_ASM_OP
247 #define UNALIGNED_PTR_ASM_OP \
248 (PTR_SIZE == 8 ? UNALIGNED_DOUBLE_INT_ASM_OP : UNALIGNED_INT_ASM_OP)
249 #endif
251 #ifndef UNALIGNED_OFFSET_ASM_OP
252 #define UNALIGNED_OFFSET_ASM_OP(OFFSET) \
253 (NUMBYTES(OFFSET) == 4 \
254 ? UNALIGNED_LONG_ASM_OP \
255 : (NUMBYTES(OFFSET) == 2 ? UNALIGNED_SHORT_ASM_OP : ASM_BYTE_OP))
256 #endif
258 /* Definitions of defaults for formats and names of various special
259 (artificial) labels which may be generated within this file (when the -g
260 options is used and VMS_DEBUGGING_INFO is in effect. If necessary, these
261 may be overridden from within the tm.h file, but typically, overriding these
262 defaults is unnecessary. */
264 static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
266 #ifndef TEXT_END_LABEL
267 #define TEXT_END_LABEL "Lvetext"
268 #endif
269 #ifndef FUNC_BEGIN_LABEL
270 #define FUNC_BEGIN_LABEL "LVFB"
271 #endif
272 #ifndef FUNC_PROLOG_LABEL
273 #define FUNC_PROLOG_LABEL "LVFP"
274 #endif
275 #ifndef FUNC_EPILOG_LABEL
276 #define FUNC_EPILOG_LABEL "LVEB"
277 #endif
278 #ifndef FUNC_END_LABEL
279 #define FUNC_END_LABEL "LVFE"
280 #endif
281 #ifndef BLOCK_BEGIN_LABEL
282 #define BLOCK_BEGIN_LABEL "LVBB"
283 #endif
284 #ifndef BLOCK_END_LABEL
285 #define BLOCK_END_LABEL "LVBE"
286 #endif
287 #ifndef LINE_CODE_LABEL
288 #define LINE_CODE_LABEL "LVM"
289 #endif
291 #ifndef ASM_OUTPUT_DEBUG_DELTA2
292 #define ASM_OUTPUT_DEBUG_DELTA2(FILE,LABEL1,LABEL2) \
293 do \
295 fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP); \
296 assemble_name (FILE, LABEL1); \
297 fprintf (FILE, "-"); \
298 assemble_name (FILE, LABEL2); \
300 while (0)
301 #endif
303 #ifndef ASM_OUTPUT_DEBUG_DELTA4
304 #define ASM_OUTPUT_DEBUG_DELTA4(FILE,LABEL1,LABEL2) \
305 do \
307 fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP); \
308 assemble_name (FILE, LABEL1); \
309 fprintf (FILE, "-"); \
310 assemble_name (FILE, LABEL2); \
312 while (0)
313 #endif
315 #ifndef ASM_OUTPUT_DEBUG_ADDR_DELTA
316 #define ASM_OUTPUT_DEBUG_ADDR_DELTA(FILE,LABEL1,LABEL2) \
317 do \
319 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
320 assemble_name (FILE, LABEL1); \
321 fprintf (FILE, "-"); \
322 assemble_name (FILE, LABEL2); \
324 while (0)
325 #endif
327 #ifndef ASM_OUTPUT_DEBUG_ADDR
328 #define ASM_OUTPUT_DEBUG_ADDR(FILE,LABEL) \
329 do \
331 fprintf ((FILE), "\t%s\t", UNALIGNED_PTR_ASM_OP); \
332 assemble_name (FILE, LABEL); \
334 while (0)
335 #endif
337 #ifndef ASM_OUTPUT_DEBUG_ADDR_CONST
338 #define ASM_OUTPUT_DEBUG_ADDR_CONST(FILE,ADDR) \
339 fprintf ((FILE), "\t%s\t%s", UNALIGNED_PTR_ASM_OP, (ADDR))
340 #endif
342 #ifndef ASM_OUTPUT_DEBUG_DATA1
343 #define ASM_OUTPUT_DEBUG_DATA1(FILE,VALUE) \
344 fprintf ((FILE), "\t%s\t%#x", ASM_BYTE_OP, (unsigned char) VALUE)
345 #endif
347 #ifndef ASM_OUTPUT_DEBUG_DATA2
348 #define ASM_OUTPUT_DEBUG_DATA2(FILE,VALUE) \
349 fprintf ((FILE), "\t%s\t%#x", UNALIGNED_SHORT_ASM_OP, \
350 (unsigned short) VALUE)
351 #endif
353 #ifndef ASM_OUTPUT_DEBUG_DATA4
354 #define ASM_OUTPUT_DEBUG_DATA4(FILE,VALUE) \
355 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_INT_ASM_OP, (unsigned long) VALUE)
356 #endif
358 #ifndef ASM_OUTPUT_DEBUG_DATA
359 #define ASM_OUTPUT_DEBUG_DATA(FILE,VALUE) \
360 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_OFFSET_ASM_OP(VALUE), VALUE)
361 #endif
363 #ifndef ASM_OUTPUT_DEBUG_ADDR_DATA
364 #define ASM_OUTPUT_DEBUG_ADDR_DATA(FILE,VALUE) \
365 fprintf ((FILE), "\t%s\t%#lx", UNALIGNED_PTR_ASM_OP, \
366 (unsigned long) VALUE)
367 #endif
369 #ifndef ASM_OUTPUT_DEBUG_DATA8
370 #define ASM_OUTPUT_DEBUG_DATA8(FILE,VALUE) \
371 fprintf ((FILE), "\t%s\t%#llx", UNALIGNED_DOUBLE_INT_ASM_OP, \
372 (unsigned long long) VALUE)
373 #endif
375 /* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
376 newline is produced. When flag_verbose_asm is asserted, we add commentary
377 at the end of the line, so we must avoid output of a newline here. */
378 #ifndef ASM_OUTPUT_DEBUG_STRING
379 #define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
380 do \
382 register int slen = strlen(P); \
383 register const char *p = (P); \
384 register int i; \
385 fprintf (FILE, "\t.ascii \""); \
386 for (i = 0; i < slen; i++) \
388 register int c = p[i]; \
389 if (c == '\"' || c == '\\') \
390 putc ('\\', FILE); \
391 if (c >= ' ' && c < 0177) \
392 putc (c, FILE); \
393 else \
394 fprintf (FILE, "\\%o", c); \
396 fprintf (FILE, "\""); \
398 while (0)
399 #endif
401 /* Convert a reference to the assembler name of a C-level name. This
402 macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
403 a string rather than writing to a file. */
404 #ifndef ASM_NAME_TO_STRING
405 #define ASM_NAME_TO_STRING(STR, NAME) \
406 do \
408 if ((NAME)[0] == '*') \
409 strcpy (STR, NAME+1); \
410 else \
411 strcpy (STR, NAME); \
413 while (0)
414 #endif
417 /* Output the debug header HEADER. Also output COMMENT if flag_verbose_asm is
418 set. Return the header size. Just return the size if DOSIZEONLY is
419 nonzero. */
421 static int
422 write_debug_header (DST_HEADER *header, const char *comment, int dosizeonly)
424 if (!dosizeonly)
426 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
427 header->dst__header_length.dst_w_length);
429 if (flag_verbose_asm)
430 fprintf (asm_out_file, "\t%s record length", ASM_COMMENT_START);
431 fputc ('\n', asm_out_file);
433 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file,
434 header->dst__header_type.dst_w_type);
436 if (flag_verbose_asm)
437 fprintf (asm_out_file, "\t%s record type (%s)", ASM_COMMENT_START,
438 comment);
440 fputc ('\n', asm_out_file);
443 return 4;
446 /* Output the address of SYMBOL. Also output COMMENT if flag_verbose_asm is
447 set. Return the address size. Just return the size if DOSIZEONLY is
448 nonzero. */
450 static int
451 write_debug_addr (const char *symbol, const char *comment, int dosizeonly)
453 if (!dosizeonly)
455 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, symbol);
456 if (flag_verbose_asm)
457 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
458 fputc ('\n', asm_out_file);
461 return PTR_SIZE;
464 /* Output the single byte DATA1. Also output COMMENT if flag_verbose_asm is
465 set. Return the data size. Just return the size if DOSIZEONLY is
466 nonzero. */
468 static int
469 write_debug_data1 (unsigned int data1, const char *comment, int dosizeonly)
471 if (!dosizeonly)
473 ASM_OUTPUT_DEBUG_DATA1 (asm_out_file, data1);
474 if (flag_verbose_asm)
475 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
476 fputc ('\n', asm_out_file);
479 return 1;
482 /* Output the single word DATA2. Also output COMMENT if flag_verbose_asm is
483 set. Return the data size. Just return the size if DOSIZEONLY is
484 nonzero. */
486 static int
487 write_debug_data2 (unsigned int data2, const char *comment, int dosizeonly)
489 if (!dosizeonly)
491 ASM_OUTPUT_DEBUG_DATA2 (asm_out_file, data2);
492 if (flag_verbose_asm)
493 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
494 fputc ('\n', asm_out_file);
497 return 2;
500 /* Output double word DATA4. Also output COMMENT if flag_verbose_asm is set.
501 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
503 static int
504 write_debug_data4 (unsigned long data4, const char *comment, int dosizeonly)
506 if (!dosizeonly)
508 ASM_OUTPUT_DEBUG_DATA4 (asm_out_file, data4);
509 if (flag_verbose_asm)
510 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
511 fputc ('\n', asm_out_file);
514 return 4;
517 /* Output quad word DATA8. Also output COMMENT if flag_verbose_asm is set.
518 Return the data size. Just return the size if DOSIZEONLY is nonzero. */
520 static int
521 write_debug_data8 (unsigned long long data8, const char *comment,
522 int dosizeonly)
524 if (!dosizeonly)
526 ASM_OUTPUT_DEBUG_DATA8 (asm_out_file, data8);
527 if (flag_verbose_asm)
528 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
529 fputc ('\n', asm_out_file);
532 return 8;
535 /* Output the difference between LABEL1 and LABEL2. Also output COMMENT if
536 flag_verbose_asm is set. Return the data size. Just return the size if
537 DOSIZEONLY is nonzero. */
539 static int
540 write_debug_delta4 (const char *label1, const char *label2,
541 const char *comment, int dosizeonly)
543 if (!dosizeonly)
545 ASM_OUTPUT_DEBUG_DELTA4 (asm_out_file, label1, label2);
546 if (flag_verbose_asm)
547 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
548 fputc ('\n', asm_out_file);
551 return 4;
554 /* Output a character string STRING. Also write COMMENT if flag_verbose_asm is
555 set. Return the string length. Just return the length if DOSIZEONLY is
556 nonzero. */
558 static int
559 write_debug_string (const char *string, const char *comment, int dosizeonly)
561 if (!dosizeonly)
563 ASM_OUTPUT_DEBUG_STRING (asm_out_file, string);
564 if (flag_verbose_asm)
565 fprintf (asm_out_file, "\t%s %s", ASM_COMMENT_START, comment);
566 fputc ('\n', asm_out_file);
569 return strlen (string);
572 /* Output a module begin header and return the header size. Just return the
573 size if DOSIZEONLY is nonzero. */
575 static int
576 write_modbeg (int dosizeonly)
578 DST_MODULE_BEGIN modbeg;
579 DST_MB_TRLR mb_trlr;
580 int i;
581 char *module_name, *m;
582 int modnamelen;
583 int prodnamelen;
584 int totsize = 0;
586 /* Assumes primary filename has Unix syntax file spec. */
587 module_name = xstrdup (lbasename (primary_filename));
589 m = strrchr (module_name, '.');
590 if (m)
591 *m = 0;
593 modnamelen = strlen (module_name);
594 for (i = 0; i < modnamelen; i++)
595 module_name[i] = TOUPPER (module_name[i]);
597 prodnamelen = strlen (module_producer);
599 modbeg.dst_a_modbeg_header.dst__header_length.dst_w_length
600 = DST_K_MODBEG_SIZE + modnamelen + DST_K_MB_TRLR_SIZE + prodnamelen - 1;
601 modbeg.dst_a_modbeg_header.dst__header_type.dst_w_type = DST_K_MODBEG;
602 modbeg.dst_b_modbeg_flags.dst_v_modbeg_hide = 0;
603 modbeg.dst_b_modbeg_flags.dst_v_modbeg_version = 1;
604 modbeg.dst_b_modbeg_flags.dst_v_modbeg_unused = 0;
605 modbeg.dst_b_modbeg_unused = 0;
606 modbeg.dst_l_modbeg_language = (DST_LANGUAGE) module_language;
607 modbeg.dst_w_version_major = DST_K_VERSION_MAJOR;
608 modbeg.dst_w_version_minor = DST_K_VERSION_MINOR;
609 modbeg.dst_b_modbeg_name = strlen (module_name);
611 mb_trlr.dst_b_compiler = strlen (module_producer);
613 totsize += write_debug_header (&modbeg.dst_a_modbeg_header,
614 "modbeg", dosizeonly);
615 totsize += write_debug_data1 (*((char *) &modbeg.dst_b_modbeg_flags),
616 "flags", dosizeonly);
617 totsize += write_debug_data1 (modbeg.dst_b_modbeg_unused,
618 "unused", dosizeonly);
619 totsize += write_debug_data4 (modbeg.dst_l_modbeg_language,
620 "language", dosizeonly);
621 totsize += write_debug_data2 (modbeg.dst_w_version_major,
622 "DST major version", dosizeonly);
623 totsize += write_debug_data2 (modbeg.dst_w_version_minor,
624 "DST minor version", dosizeonly);
625 totsize += write_debug_data1 (modbeg.dst_b_modbeg_name,
626 "length of module name", dosizeonly);
627 totsize += write_debug_string (module_name, "module name", dosizeonly);
628 totsize += write_debug_data1 (mb_trlr.dst_b_compiler,
629 "length of compiler name", dosizeonly);
630 totsize += write_debug_string (module_producer, "compiler name", dosizeonly);
632 return totsize;
635 /* Output a module end trailer and return the trailer size. Just return
636 the size if DOSIZEONLY is nonzero. */
638 static int
639 write_modend (int dosizeonly)
641 DST_MODULE_END modend;
642 int totsize = 0;
644 modend.dst_a_modend_header.dst__header_length.dst_w_length
645 = DST_K_MODEND_SIZE - 1;
646 modend.dst_a_modend_header.dst__header_type.dst_w_type = DST_K_MODEND;
648 totsize += write_debug_header (&modend.dst_a_modend_header, "modend",
649 dosizeonly);
651 return totsize;
654 /* Output a routine begin header routine RTNNUM and return the header size.
655 Just return the size if DOSIZEONLY is nonzero. */
657 static int
658 write_rtnbeg (int rtnnum, int dosizeonly)
660 const char *rtnname;
661 int rtnnamelen;
662 char *rtnentryname;
663 int totsize = 0;
664 char label[MAX_ARTIFICIAL_LABEL_BYTES];
665 DST_ROUTINE_BEGIN rtnbeg;
666 DST_PROLOG prolog;
668 rtnname = VEC_index (char_p, funcnam_table, rtnnum);
669 rtnnamelen = strlen (rtnname);
670 rtnentryname = concat (rtnname, "..en", NULL);
672 if (!strcmp (rtnname, "main"))
674 DST_HEADER header;
675 const char *go = "TRANSFER$BREAK$GO";
677 /* This command isn't documented in DSTRECORDS, so it's made to
678 look like what DEC C does */
680 /* header size - 1st byte + flag byte + STO_LW size
681 + string count byte + string length */
682 header.dst__header_length.dst_w_length
683 = DST_K_DST_HEADER_SIZE - 1 + 1 + 4 + 1 + strlen (go);
684 header.dst__header_type.dst_w_type = DST_K_TBG;
686 totsize += write_debug_header (&header, "transfer", dosizeonly);
688 /* I think this is a flag byte, but I don't know what this flag means */
689 totsize += write_debug_data1 (0x1, "flags ???", dosizeonly);
691 /* Routine Begin PD Address */
692 totsize += write_debug_addr (rtnname, "main procedure descriptor",
693 dosizeonly);
694 totsize += write_debug_data1 (strlen (go), "length of main_name",
695 dosizeonly);
696 totsize += write_debug_string (go, "main name", dosizeonly);
699 /* The header length never includes the length byte. */
700 rtnbeg.dst_a_rtnbeg_header.dst__header_length.dst_w_length
701 = DST_K_RTNBEG_SIZE + rtnnamelen - 1;
702 rtnbeg.dst_a_rtnbeg_header.dst__header_type.dst_w_type = DST_K_RTNBEG;
703 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unused = 0;
704 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_unalloc = 0;
705 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_prototype = 0;
706 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_inlined = 0;
707 rtnbeg.dst_b_rtnbeg_flags.dst_v_rtnbeg_no_call = 1;
708 rtnbeg.dst_b_rtnbeg_name = rtnnamelen;
710 totsize += write_debug_header (&rtnbeg.dst_a_rtnbeg_header, "rtnbeg",
711 dosizeonly);
712 totsize += write_debug_data1 (*((char *) &rtnbeg.dst_b_rtnbeg_flags),
713 "flags", dosizeonly);
715 /* Routine Begin Address */
716 totsize += write_debug_addr (rtnentryname, "routine entry name", dosizeonly);
718 /* Routine Begin PD Address */
719 totsize += write_debug_addr (rtnname, "routine procedure descriptor",
720 dosizeonly);
722 /* Routine Begin Name */
723 totsize += write_debug_data1 (rtnbeg.dst_b_rtnbeg_name,
724 "length of routine name", dosizeonly);
726 totsize += write_debug_string (rtnname, "routine name", dosizeonly);
728 free (rtnentryname);
730 if (debug_info_level > DINFO_LEVEL_TERSE)
732 prolog.dst_a_prolog_header.dst__header_length.dst_w_length
733 = DST_K_PROLOG_SIZE - 1;
734 prolog.dst_a_prolog_header.dst__header_type.dst_w_type = DST_K_PROLOG;
736 totsize += write_debug_header (&prolog.dst_a_prolog_header, "prolog",
737 dosizeonly);
739 ASM_GENERATE_INTERNAL_LABEL
740 (label, FUNC_PROLOG_LABEL,
741 VEC_index (unsigned, funcnum_table, rtnnum));
742 totsize += write_debug_addr (label, "prolog breakpoint addr",
743 dosizeonly);
746 return totsize;
749 /* Output a routine end trailer for routine RTNNUM and return the header size.
750 Just return the size if DOSIZEONLY is nonzero. */
752 static int
753 write_rtnend (int rtnnum, int dosizeonly)
755 DST_ROUTINE_END rtnend;
756 char label1[MAX_ARTIFICIAL_LABEL_BYTES];
757 char label2[MAX_ARTIFICIAL_LABEL_BYTES];
758 int totsize;
760 totsize = 0;
762 rtnend.dst_a_rtnend_header.dst__header_length.dst_w_length
763 = DST_K_RTNEND_SIZE - 1;
764 rtnend.dst_a_rtnend_header.dst__header_type.dst_w_type = DST_K_RTNEND;
765 rtnend.dst_b_rtnend_unused = 0;
766 rtnend.dst_l_rtnend_size = 0; /* Calculated below. */
768 totsize += write_debug_header (&rtnend.dst_a_rtnend_header, "rtnend",
769 dosizeonly);
770 totsize += write_debug_data1 (rtnend.dst_b_rtnend_unused, "unused",
771 dosizeonly);
773 ASM_GENERATE_INTERNAL_LABEL
774 (label1, FUNC_BEGIN_LABEL,
775 VEC_index (unsigned, funcnum_table, rtnnum));
776 ASM_GENERATE_INTERNAL_LABEL
777 (label2, FUNC_END_LABEL,
778 VEC_index (unsigned, funcnum_table, rtnnum));
779 totsize += write_debug_delta4 (label2, label1, "routine size", dosizeonly);
781 return totsize;
784 #define K_DELTA_PC(I) \
785 ((I) < 128 ? -(I) : (I) < 65536 ? DST_K_DELTA_PC_W : DST_K_DELTA_PC_L)
787 #define K_SET_LINUM(I) \
788 ((I) < 256 ? DST_K_SET_LINUM_B \
789 : (I) < 65536 ? DST_K_SET_LINUM : DST_K_SET_LINUM_L)
791 #define K_INCR_LINUM(I) \
792 ((I) < 256 ? DST_K_INCR_LINUM \
793 : (I) < 65536 ? DST_K_INCR_LINUM_W : DST_K_INCR_LINUM_L)
795 /* Output the PC to line number correlations and return the size. Just return
796 the size if DOSIZEONLY is nonzero */
798 static int
799 write_pclines (int dosizeonly)
801 unsigned i;
802 int fn;
803 int ln, lastln;
804 int linestart = 0;
805 int max_line;
806 DST_LINE_NUM_HEADER line_num;
807 DST_PCLINE_COMMANDS pcline;
808 char label[MAX_ARTIFICIAL_LABEL_BYTES];
809 char lastlabel[MAX_ARTIFICIAL_LABEL_BYTES];
810 int totsize = 0;
811 char buff[256];
813 max_line = file_info_table[1].max_line;
814 file_info_table[1].listing_line_start = linestart;
815 linestart = linestart + ((max_line / 100000) + 1) * 100000;
817 for (i = 2; i < file_info_table_in_use; i++)
819 max_line = file_info_table[i].max_line;
820 file_info_table[i].listing_line_start = linestart;
821 linestart = linestart + ((max_line / 10000) + 1) * 10000;
824 /* Set starting address to beginning of text section. */
825 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 8;
826 line_num.dst_a_line_num_header.dst__header_type.dst_w_type = DST_K_LINE_NUM;
827 pcline.dst_b_pcline_command = DST_K_SET_ABS_PC;
829 totsize += write_debug_header (&line_num.dst_a_line_num_header,
830 "line_num", dosizeonly);
831 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
832 "line_num (SET ABS PC)", dosizeonly);
834 if (dosizeonly)
835 totsize += 4;
836 else
838 ASM_OUTPUT_DEBUG_ADDR (asm_out_file, TEXT_SECTION_ASM_OP);
839 if (flag_verbose_asm)
840 fprintf (asm_out_file, "\t%s line_num", ASM_COMMENT_START);
841 fputc ('\n', asm_out_file);
844 fn = line_info_table[1].dst_file_num;
845 ln = (file_info_table[fn].listing_line_start
846 + line_info_table[1].dst_line_num);
847 line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 4 + 4;
848 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
850 totsize += write_debug_header (&line_num.dst_a_line_num_header,
851 "line_num", dosizeonly);
852 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
853 "line_num (SET LINUM LONG)", dosizeonly);
855 sprintf (buff, "line_num (%d)", ln ? ln - 1 : 0);
856 totsize += write_debug_data4 (ln ? ln - 1 : 0, buff, dosizeonly);
858 lastln = ln;
859 strcpy (lastlabel, TEXT_SECTION_ASM_OP);
860 for (i = 1; i < line_info_table_in_use; i++)
862 int extrabytes;
864 fn = line_info_table[i].dst_file_num;
865 ln = (file_info_table[fn].listing_line_start
866 + line_info_table[i].dst_line_num);
868 if (ln - lastln > 1)
869 extrabytes = 5; /* NUMBYTES (ln - lastln - 1) + 1; */
870 else if (ln <= lastln)
871 extrabytes = 5; /* NUMBYTES (ln - 1) + 1; */
872 else
873 extrabytes = 0;
875 line_num.dst_a_line_num_header.dst__header_length.dst_w_length
876 = 8 + extrabytes;
878 totsize += write_debug_header
879 (&line_num.dst_a_line_num_header, "line_num", dosizeonly);
881 if (ln - lastln > 1)
883 int lndif = ln - lastln - 1;
885 /* K_INCR_LINUM (lndif); */
886 pcline.dst_b_pcline_command = DST_K_INCR_LINUM_L;
888 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
889 "line_num (INCR LINUM LONG)",
890 dosizeonly);
892 sprintf (buff, "line_num (%d)", lndif);
893 totsize += write_debug_data4 (lndif, buff, dosizeonly);
895 else if (ln <= lastln)
897 /* K_SET_LINUM (ln-1); */
898 pcline.dst_b_pcline_command = DST_K_SET_LINUM_L;
900 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
901 "line_num (SET LINUM LONG)",
902 dosizeonly);
904 sprintf (buff, "line_num (%d)", ln - 1);
905 totsize += write_debug_data4 (ln - 1, buff, dosizeonly);
908 pcline.dst_b_pcline_command = DST_K_DELTA_PC_L;
910 totsize += write_debug_data1 (pcline.dst_b_pcline_command,
911 "line_num (DELTA PC LONG)", dosizeonly);
913 ASM_GENERATE_INTERNAL_LABEL (label, LINE_CODE_LABEL, i);
914 totsize += write_debug_delta4 (label, lastlabel, "increment line_num",
915 dosizeonly);
917 lastln = ln;
918 strcpy (lastlabel, label);
921 return totsize;
924 /* Output a source correlation for file FILEID using information saved in
925 FILE_INFO_ENTRY and return the size. Just return the size if DOSIZEONLY is
926 nonzero. */
928 static int
929 write_srccorr (int fileid, dst_file_info_entry file_info_entry,
930 int dosizeonly)
932 int src_command_size;
933 int linesleft = file_info_entry.max_line;
934 int linestart = file_info_entry.listing_line_start;
935 int flen = file_info_entry.flen;
936 int linestodo = 0;
937 DST_SOURCE_CORR src_header;
938 DST_SRC_COMMAND src_command;
939 DST_SRC_COMMAND src_command_sf;
940 DST_SRC_COMMAND src_command_sl;
941 DST_SRC_COMMAND src_command_sr;
942 DST_SRC_COMMAND src_command_dl;
943 DST_SRC_CMDTRLR src_cmdtrlr;
944 char buff[256];
945 int totsize = 0;
947 if (fileid == 1)
949 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
950 = DST_K_SOURCE_CORR_HEADER_SIZE + 1 - 1;
951 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
952 = DST_K_SOURCE;
953 src_command.dst_b_src_command = DST_K_SRC_FORMFEED;
955 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
956 "source corr", dosizeonly);
958 totsize += write_debug_data1 (src_command.dst_b_src_command,
959 "source_corr (SRC FORMFEED)",
960 dosizeonly);
963 src_command_size
964 = DST_K_SRC_COMMAND_SIZE + flen + DST_K_SRC_CMDTRLR_SIZE;
965 src_command.dst_b_src_command = DST_K_SRC_DECLFILE;
966 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length
967 = src_command_size - 2;
968 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags = 0;
969 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid
970 = fileid;
971 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt
972 = file_info_entry.cdt;
973 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk
974 = file_info_entry.ebk;
975 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb
976 = file_info_entry.ffb;
977 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo
978 = file_info_entry.rfo;
979 src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename
980 = file_info_entry.flen;
982 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
983 = DST_K_SOURCE_CORR_HEADER_SIZE + src_command_size - 1;
984 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
985 = DST_K_SOURCE;
987 src_cmdtrlr.dst_b_src_df_libmodname = 0;
989 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
990 "source corr", dosizeonly);
991 totsize += write_debug_data1 (src_command.dst_b_src_command,
992 "source_corr (DECL SRC FILE)", dosizeonly);
993 totsize += write_debug_data1
994 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_length,
995 "source_corr (length)", dosizeonly);
997 totsize += write_debug_data1
998 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_flags,
999 "source_corr (flags)", dosizeonly);
1001 totsize += write_debug_data2
1002 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_fileid,
1003 "source_corr (fileid)", dosizeonly);
1005 totsize += write_debug_data8
1006 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_q_src_df_rms_cdt,
1007 "source_corr (creation date)", dosizeonly);
1009 totsize += write_debug_data4
1010 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_l_src_df_rms_ebk,
1011 "source_corr (EOF block number)", dosizeonly);
1013 totsize += write_debug_data2
1014 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_w_src_df_rms_ffb,
1015 "source_corr (first free byte)", dosizeonly);
1017 totsize += write_debug_data1
1018 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_rms_rfo,
1019 "source_corr (record and file organization)", dosizeonly);
1021 totsize += write_debug_data1
1022 (src_command.dst_a_src_cmd_fields.dst_a_src_decl_src.dst_b_src_df_filename,
1023 "source_corr (filename length)", dosizeonly);
1025 totsize += write_debug_string (remap_debug_filename (
1026 file_info_entry.file_name),
1027 "source file name", dosizeonly);
1028 totsize += write_debug_data1 (src_cmdtrlr.dst_b_src_df_libmodname,
1029 "source_corr (libmodname)", dosizeonly);
1031 src_command_sf.dst_b_src_command = DST_K_SRC_SETFILE;
1032 src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword = fileid;
1034 src_command_sr.dst_b_src_command = DST_K_SRC_SETREC_W;
1035 src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword = 1;
1037 src_command_sl.dst_b_src_command = DST_K_SRC_SETLNUM_L;
1038 src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong = linestart + 1;
1040 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1042 if (linesleft > 65534)
1043 linesleft = linesleft - 65534, linestodo = 65534;
1044 else
1045 linestodo = linesleft, linesleft = 0;
1047 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1049 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1050 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 + 3 + 5 + 3 - 1;
1051 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1052 = DST_K_SOURCE;
1054 if (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword)
1056 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1057 "source corr", dosizeonly);
1059 totsize += write_debug_data1 (src_command_sf.dst_b_src_command,
1060 "source_corr (src setfile)", dosizeonly);
1062 totsize += write_debug_data2
1063 (src_command_sf.dst_a_src_cmd_fields.dst_w_src_unsword,
1064 "source_corr (fileid)", dosizeonly);
1066 totsize += write_debug_data1 (src_command_sr.dst_b_src_command,
1067 "source_corr (setrec)", dosizeonly);
1069 totsize += write_debug_data2
1070 (src_command_sr.dst_a_src_cmd_fields.dst_w_src_unsword,
1071 "source_corr (recnum)", dosizeonly);
1073 totsize += write_debug_data1 (src_command_sl.dst_b_src_command,
1074 "source_corr (setlnum)", dosizeonly);
1076 totsize += write_debug_data4
1077 (src_command_sl.dst_a_src_cmd_fields.dst_l_src_unslong,
1078 "source_corr (linenum)", dosizeonly);
1080 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1081 "source_corr (deflines)", dosizeonly);
1083 sprintf (buff, "source_corr (%d)",
1084 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1085 totsize += write_debug_data2
1086 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1087 buff, dosizeonly);
1089 while (linesleft > 0)
1091 src_header.dst_a_source_corr_header.dst__header_length.dst_w_length
1092 = DST_K_SOURCE_CORR_HEADER_SIZE + 3 - 1;
1093 src_header.dst_a_source_corr_header.dst__header_type.dst_w_type
1094 = DST_K_SOURCE;
1095 src_command_dl.dst_b_src_command = DST_K_SRC_DEFLINES_W;
1097 if (linesleft > 65534)
1098 linesleft = linesleft - 65534, linestodo = 65534;
1099 else
1100 linestodo = linesleft, linesleft = 0;
1102 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword = linestodo;
1104 totsize += write_debug_header (&src_header.dst_a_source_corr_header,
1105 "source corr", dosizeonly);
1106 totsize += write_debug_data1 (src_command_dl.dst_b_src_command,
1107 "source_corr (deflines)", dosizeonly);
1108 sprintf (buff, "source_corr (%d)",
1109 src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword);
1110 totsize += write_debug_data2
1111 (src_command_dl.dst_a_src_cmd_fields.dst_w_src_unsword,
1112 buff, dosizeonly);
1116 return totsize;
1119 /* Output all the source correlation entries and return the size. Just return
1120 the size if DOSIZEONLY is nonzero. */
1122 static int
1123 write_srccorrs (int dosizeonly)
1125 unsigned int i;
1126 int totsize = 0;
1128 for (i = 1; i < file_info_table_in_use; i++)
1129 totsize += write_srccorr (i, file_info_table[i], dosizeonly);
1131 return totsize;
1134 /* Output a marker (i.e. a label) for the beginning of a function, before
1135 the prologue. */
1137 static void
1138 vmsdbgout_begin_prologue (unsigned int line, const char *file)
1140 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1142 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1143 (*dwarf2_debug_hooks.begin_prologue) (line, file);
1145 if (debug_info_level > DINFO_LEVEL_NONE)
1147 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
1148 current_function_funcdef_no);
1149 ASM_OUTPUT_LABEL (asm_out_file, label);
1153 /* Output a marker (i.e. a label) for the beginning of a function, after
1154 the prologue. */
1156 static void
1157 vmsdbgout_end_prologue (unsigned int line, const char *file)
1159 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1161 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1162 (*dwarf2_debug_hooks.end_prologue) (line, file);
1164 if (debug_info_level > DINFO_LEVEL_TERSE)
1166 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_PROLOG_LABEL,
1167 current_function_funcdef_no);
1168 ASM_OUTPUT_LABEL (asm_out_file, label);
1170 /* VMS PCA expects every PC range to correlate to some line and file. */
1171 vmsdbgout_source_line (line, file, 0, true);
1175 /* No output for VMS debug, but make obligatory call to Dwarf2 debug */
1177 static void
1178 vmsdbgout_end_function (unsigned int line)
1180 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1181 (*dwarf2_debug_hooks.end_function) (line);
1184 /* Output a marker (i.e. a label) for the beginning of the epilogue.
1185 This gets called *before* the epilogue code has been generated. */
1187 static void
1188 vmsdbgout_begin_epilogue (unsigned int line, const char *file)
1190 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1191 static int save_current_function_funcdef_no = -1;
1193 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1194 (*dwarf2_debug_hooks.begin_epilogue) (line, file);
1196 if (debug_info_level > DINFO_LEVEL_NONE)
1198 if (save_current_function_funcdef_no != current_function_funcdef_no)
1200 /* Output a label to mark the endpoint of the code generated for this
1201 function. */
1202 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_EPILOG_LABEL,
1203 current_function_funcdef_no);
1205 ASM_OUTPUT_LABEL (asm_out_file, label);
1207 save_current_function_funcdef_no = current_function_funcdef_no;
1209 /* VMS PCA expects every PC range to correlate to some line and
1210 file. */
1211 vmsdbgout_source_line (line, file, 0, true);
1216 /* Output a marker (i.e. a label) for the absolute end of the generated code
1217 for a function definition. This gets called *after* the epilogue code has
1218 been generated. */
1220 static void
1221 vmsdbgout_end_epilogue (unsigned int line, const char *file)
1223 char label[MAX_ARTIFICIAL_LABEL_BYTES];
1225 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1226 (*dwarf2_debug_hooks.end_epilogue) (line, file);
1228 if (debug_info_level > DINFO_LEVEL_NONE)
1230 /* Output a label to mark the endpoint of the code generated for this
1231 function. */
1232 ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
1233 current_function_funcdef_no);
1234 ASM_OUTPUT_LABEL (asm_out_file, label);
1236 /* VMS PCA expects every PC range to correlate to some line and file. */
1237 vmsdbgout_source_line (line, file, 0, true);
1241 /* Output a marker (i.e. a label) for the beginning of the generated code for
1242 a lexical block. */
1244 static void
1245 vmsdbgout_begin_block (register unsigned line, register unsigned blocknum)
1247 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1248 (*dwarf2_debug_hooks.begin_block) (line, blocknum);
1250 if (debug_info_level > DINFO_LEVEL_TERSE)
1251 targetm.asm_out.internal_label (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
1254 /* Output a marker (i.e. a label) for the end of the generated code for a
1255 lexical block. */
1257 static void
1258 vmsdbgout_end_block (register unsigned line, register unsigned blocknum)
1260 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1261 (*dwarf2_debug_hooks.end_block) (line, blocknum);
1263 if (debug_info_level > DINFO_LEVEL_TERSE)
1264 targetm.asm_out.internal_label (asm_out_file, BLOCK_END_LABEL, blocknum);
1267 /* Not implemented in VMS Debug. */
1269 static bool
1270 vmsdbgout_ignore_block (const_tree block)
1272 bool retval = 0;
1274 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1275 retval = (*dwarf2_debug_hooks.ignore_block) (block);
1277 return retval;
1280 /* Add an entry for function DECL into the funcnam_table. */
1282 static void
1283 vmsdbgout_begin_function (tree decl)
1285 const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
1287 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1288 (*dwarf2_debug_hooks.begin_function) (decl);
1290 /* Add the new entry to the end of the function name table. */
1291 VEC_safe_push (char_p, heap, funcnam_table, xstrdup (name));
1292 VEC_safe_push (unsigned, heap, funcnum_table,
1293 current_function_funcdef_no);
1296 static char fullname_buff [4096];
1298 /* Return the full file specification for FILENAME. The specification must be
1299 in VMS syntax in order to be processed by VMS Debug. */
1301 static char *
1302 full_name (const char *filename)
1304 #ifdef VMS
1305 FILE *fp = fopen (filename, "r");
1307 fgetname (fp, fullname_buff, 1);
1308 fclose (fp);
1309 #else
1310 /* Unix paths really mess up VMS debug. Better to just output the
1311 base filename. */
1312 strcpy (fullname_buff, filename);
1313 #endif
1315 return fullname_buff;
1318 /* Lookup a filename (in the list of filenames that we know about here in
1319 vmsdbgout.c) and return its "index". The index of each (known) filename is
1320 just a unique number which is associated with only that one filename. We
1321 need such numbers for the sake of generating labels and references
1322 to those files numbers. If the filename given as an argument is not
1323 found in our current list, add it to the list and assign it the next
1324 available unique index number. In order to speed up searches, we remember
1325 the index of the filename was looked up last. This handles the majority of
1326 all searches. */
1328 static unsigned int
1329 lookup_filename (const char *file_name)
1331 static unsigned int last_file_lookup_index = 0;
1332 register char *fn;
1333 register unsigned i;
1334 const char *fnam;
1335 char flen;
1336 long long cdt = 0;
1337 long ebk = 0;
1338 short ffb = 0;
1339 char rfo = 0;
1340 long siz = 0;
1341 int ver = 0;
1343 fnam = full_name (file_name);
1344 flen = strlen (fnam);
1346 /* Check to see if the file name that was searched on the previous call
1347 matches this file name. If so, return the index. */
1348 if (last_file_lookup_index != 0)
1350 fn = file_info_table[last_file_lookup_index].file_name;
1351 if (strcmp (fnam, fn) == 0)
1352 return last_file_lookup_index;
1355 /* Didn't match the previous lookup, search the table */
1356 for (i = 1; i < file_info_table_in_use; ++i)
1358 fn = file_info_table[i].file_name;
1359 if (strcmp (fnam, fn) == 0)
1361 last_file_lookup_index = i;
1362 return i;
1366 /* Prepare to add a new table entry by making sure there is enough space in
1367 the table to do so. If not, expand the current table. */
1368 if (file_info_table_in_use == file_info_table_allocated)
1371 file_info_table_allocated += FILE_TABLE_INCREMENT;
1372 file_info_table = XRESIZEVEC (dst_file_info_entry, file_info_table,
1373 file_info_table_allocated);
1376 if (vms_file_stats_name (file_name, &cdt, &siz, &rfo, &ver) == 0)
1378 ebk = siz / 512 + 1;
1379 ffb = siz - ((siz / 512) * 512);
1382 /* Add the new entry to the end of the filename table. */
1383 file_info_table[file_info_table_in_use].file_name = xstrdup (fnam);
1384 file_info_table[file_info_table_in_use].max_line = 0;
1385 file_info_table[file_info_table_in_use].cdt = cdt;
1386 file_info_table[file_info_table_in_use].ebk = ebk;
1387 file_info_table[file_info_table_in_use].ffb = ffb;
1388 file_info_table[file_info_table_in_use].rfo = rfo;
1389 file_info_table[file_info_table_in_use].flen = flen;
1391 last_file_lookup_index = file_info_table_in_use++;
1392 return last_file_lookup_index;
1395 /* Output a label to mark the beginning of a source code line entry
1396 and record information relating to this source line, in
1397 'line_info_table' for later output of the .debug_line section. */
1399 static void
1400 vmsdbgout_source_line (register unsigned line, register const char *filename,
1401 int discriminator, bool is_stmt)
1403 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1404 (*dwarf2_debug_hooks.source_line) (line, filename, discriminator, is_stmt);
1406 if (debug_info_level >= DINFO_LEVEL_TERSE)
1408 dst_line_info_ref line_info;
1410 targetm.asm_out.internal_label (asm_out_file, LINE_CODE_LABEL,
1411 line_info_table_in_use);
1413 /* Expand the line info table if necessary. */
1414 if (line_info_table_in_use == line_info_table_allocated)
1416 line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
1417 line_info_table = XRESIZEVEC (dst_line_info_entry, line_info_table,
1418 line_info_table_allocated);
1421 /* Add the new entry at the end of the line_info_table. */
1422 line_info = &line_info_table[line_info_table_in_use++];
1423 line_info->dst_file_num = lookup_filename (filename);
1424 line_info->dst_line_num = line;
1425 if (line > file_info_table[line_info->dst_file_num].max_line)
1426 file_info_table[line_info->dst_file_num].max_line = line;
1430 /* Record the beginning of a new source file, for later output.
1431 At present, unimplemented. */
1433 static void
1434 vmsdbgout_start_source_file (unsigned int lineno, const char *filename)
1436 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1437 (*dwarf2_debug_hooks.start_source_file) (lineno, filename);
1440 /* Record the end of a source file, for later output.
1441 At present, unimplemented. */
1443 static void
1444 vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
1446 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1447 (*dwarf2_debug_hooks.end_source_file) (lineno);
1450 /* Set up for Debug output at the start of compilation. */
1452 static void
1453 vmsdbgout_init (const char *filename)
1455 const char *language_string = lang_hooks.name;
1457 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1458 (*dwarf2_debug_hooks.init) (filename);
1460 if (debug_info_level == DINFO_LEVEL_NONE)
1461 return;
1463 /* Remember the name of the primary input file. */
1464 primary_filename = filename;
1466 /* Allocate the initial hunk of the file_info_table. */
1467 file_info_table = XCNEWVEC (dst_file_info_entry, FILE_TABLE_INCREMENT);
1468 file_info_table_allocated = FILE_TABLE_INCREMENT;
1469 /* Skip the first entry - file numbers begin at 1. */
1470 file_info_table_in_use = 1;
1472 funcnam_table = VEC_alloc (char_p, heap, FUNC_TABLE_INITIAL);
1473 funcnum_table = VEC_alloc (unsigned, heap, FUNC_TABLE_INITIAL);
1475 /* Allocate the initial hunk of the line_info_table. */
1476 line_info_table = XCNEWVEC (dst_line_info_entry, LINE_INFO_TABLE_INCREMENT);
1477 line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
1478 /* zero-th entry is allocated, but unused */
1479 line_info_table_in_use = 1;
1481 lookup_filename (primary_filename);
1483 if (!strcmp (language_string, "GNU C"))
1484 module_language = DST_K_C;
1485 else if (!strcmp (language_string, "GNU C++"))
1486 module_language = DST_K_CXX;
1487 else if (!strcmp (language_string, "GNU Ada"))
1488 module_language = DST_K_ADA;
1489 else if (!strcmp (language_string, "GNU F77"))
1490 module_language = DST_K_FORTRAN;
1491 else
1492 module_language = DST_K_UNKNOWN;
1494 module_producer = concat (language_string, " ", version_string, NULL);
1496 ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
1500 /* Not implemented in VMS Debug. */
1502 static void
1503 vmsdbgout_assembly_start (void)
1505 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1506 (*dwarf2_debug_hooks.assembly_start) ();
1509 /* Not implemented in VMS Debug. */
1511 static void
1512 vmsdbgout_define (unsigned int lineno, const char *buffer)
1514 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1515 (*dwarf2_debug_hooks.define) (lineno, buffer);
1518 /* Not implemented in VMS Debug. */
1520 static void
1521 vmsdbgout_undef (unsigned int lineno, const char *buffer)
1523 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1524 (*dwarf2_debug_hooks.undef) (lineno, buffer);
1527 /* Not implemented in VMS Debug. */
1529 static void
1530 vmsdbgout_decl (tree decl)
1532 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1533 (*dwarf2_debug_hooks.function_decl) (decl);
1536 /* Not implemented in VMS Debug. */
1538 static void
1539 vmsdbgout_global_decl (tree decl)
1541 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1542 (*dwarf2_debug_hooks.global_decl) (decl);
1545 /* Not implemented in VMS Debug. */
1547 static void
1548 vmsdbgout_type_decl (tree decl, int local)
1550 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1551 (*dwarf2_debug_hooks.type_decl) (decl, local);
1554 /* Not implemented in VMS Debug. */
1556 static void
1557 vmsdbgout_abstract_function (tree decl)
1559 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1560 (*dwarf2_debug_hooks.outlining_inline_function) (decl);
1563 /* Output stuff that Debug requires at the end of every file and generate the
1564 VMS Debug debugging info. */
1566 static void
1567 vmsdbgout_finish (const char *filename ATTRIBUTE_UNUSED)
1569 unsigned int i, ifunc;
1570 int totsize;
1572 if (write_symbols == VMS_AND_DWARF2_DEBUG)
1573 (*dwarf2_debug_hooks.finish) (filename);
1575 if (debug_info_level == DINFO_LEVEL_NONE)
1576 return;
1578 /* Output a terminator label for the .text section. */
1579 switch_to_section (text_section);
1580 targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
1582 /* Output debugging information.
1583 Warning! Do not change the name of the .vmsdebug section without
1584 changing it in the assembler also. */
1585 switch_to_section (get_named_section (NULL, ".vmsdebug", 0));
1586 ASM_OUTPUT_ALIGN (asm_out_file, 0);
1588 totsize = write_modbeg (1);
1589 FOR_EACH_VEC_ELT (unsigned, funcnum_table, i, ifunc)
1591 totsize += write_rtnbeg (i, 1);
1592 totsize += write_rtnend (i, 1);
1594 totsize += write_pclines (1);
1596 write_modbeg (0);
1597 FOR_EACH_VEC_ELT (unsigned, funcnum_table, i, ifunc)
1599 write_rtnbeg (i, 0);
1600 write_rtnend (i, 0);
1602 write_pclines (0);
1604 if (debug_info_level > DINFO_LEVEL_TERSE)
1606 totsize = write_srccorrs (1);
1607 write_srccorrs (0);
1610 totsize = write_modend (1);
1611 write_modend (0);
1614 /* Need for both Dwarf2 on IVMS and VMS Debug on AVMS */
1616 #ifdef VMS
1617 #define __NEW_STARLET 1
1618 #include <vms/rms.h>
1619 #include <vms/atrdef.h>
1620 #include <vms/fibdef.h>
1621 #include <vms/stsdef.h>
1622 #include <vms/iodef.h>
1623 #include <vms/fatdef.h>
1624 #include <vms/descrip.h>
1625 #include <unixlib.h>
1627 #define MAXPATH 256
1629 /* descrip.h doesn't have everything ... */
1630 typedef struct fibdef* __fibdef_ptr32 __attribute__ (( mode (SI) ));
1631 struct dsc$descriptor_fib
1633 unsigned int fib$l_len;
1634 __fibdef_ptr32 fib$l_addr;
1637 /* I/O Status Block. */
1638 struct IOSB
1640 unsigned short status, count;
1641 unsigned int devdep;
1644 static char *tryfile;
1646 /* Variable length string. */
1647 struct vstring
1649 short length;
1650 char string[NAM$C_MAXRSS+1];
1653 static char filename_buff [MAXPATH];
1654 static char vms_filespec [MAXPATH];
1656 /* Callback function for filespec style conversion. */
1658 static int
1659 translate_unix (char *name, int type ATTRIBUTE_UNUSED)
1661 strncpy (filename_buff, name, MAXPATH);
1662 filename_buff [MAXPATH - 1] = (char) 0;
1663 return 0;
1666 /* Wrapper for DECC function that converts a Unix filespec
1667 to VMS style filespec. */
1669 static char *
1670 to_vms_file_spec (char *filespec)
1672 strncpy (vms_filespec, "", MAXPATH);
1673 decc$to_vms (filespec, translate_unix, 1, 1);
1674 strncpy (vms_filespec, filename_buff, MAXPATH);
1676 vms_filespec [MAXPATH - 1] = (char) 0;
1678 return vms_filespec;
1681 #else
1682 #define VMS_EPOCH_OFFSET 35067168000000000
1683 #define VMS_GRANULARITY_FACTOR 10000000
1684 #endif
1686 /* Return VMS file date, size, format, version given a name. */
1689 vms_file_stats_name (const char *filename, long long *cdt, long *siz, char *rfo,
1690 int *ver)
1692 #ifdef VMS
1693 struct FAB fab;
1694 struct NAM nam;
1696 unsigned long long create;
1697 FAT recattr;
1698 char ascnamebuff [256];
1700 ATRDEF atrlst[]
1702 { ATR$S_CREDATE, ATR$C_CREDATE, &create },
1703 { ATR$S_RECATTR, ATR$C_RECATTR, &recattr },
1704 { ATR$S_ASCNAME, ATR$C_ASCNAME, &ascnamebuff },
1705 { 0, 0, 0}
1708 FIBDEF fib;
1709 struct dsc$descriptor_fib fibdsc = {sizeof (fib), (void *) &fib};
1711 struct IOSB iosb;
1713 long status;
1714 unsigned short chan;
1716 struct vstring file;
1717 struct dsc$descriptor_s filedsc
1718 = {NAM$C_MAXRSS, DSC$K_DTYPE_T, DSC$K_CLASS_S, (void *) file.string};
1719 struct vstring device;
1720 struct dsc$descriptor_s devicedsc
1721 = {NAM$C_MAXRSS, DSC$K_DTYPE_T, DSC$K_CLASS_S, (void *) device.string};
1722 struct vstring result;
1723 struct dsc$descriptor_s resultdsc
1724 = {NAM$C_MAXRSS, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, (void *) result.string};
1726 if (strcmp (filename, "<internal>") == 0
1727 || strcmp (filename, "<built-in>") == 0)
1729 if (cdt)
1730 *cdt = 0;
1732 if (siz)
1733 *siz = 0;
1735 if (rfo)
1736 *rfo = 0;
1738 if (ver)
1739 *ver = 0;
1741 return 0;
1744 tryfile = to_vms_file_spec (filename);
1746 /* Allocate and initialize a FAB and NAM structures. */
1747 fab = cc$rms_fab;
1748 nam = cc$rms_nam;
1750 nam.nam$l_esa = file.string;
1751 nam.nam$b_ess = NAM$C_MAXRSS;
1752 nam.nam$l_rsa = result.string;
1753 nam.nam$b_rss = NAM$C_MAXRSS;
1754 fab.fab$l_fna = tryfile;
1755 fab.fab$b_fns = strlen (tryfile);
1756 fab.fab$l_nam = &nam;
1758 /* Validate filespec syntax and device existence. */
1759 status = SYS$PARSE (&fab, 0, 0);
1760 if ((status & 1) != 1)
1761 return 1;
1763 file.string[nam.nam$b_esl] = 0;
1765 /* Find matching filespec. */
1766 status = SYS$SEARCH (&fab, 0, 0);
1767 if ((status & 1) != 1)
1768 return 1;
1770 file.string[nam.nam$b_esl] = 0;
1771 result.string[result.length=nam.nam$b_rsl] = 0;
1773 /* Get the device name and assign an IO channel. */
1774 strncpy (device.string, nam.nam$l_dev, nam.nam$b_dev);
1775 devicedsc.dsc$w_length = nam.nam$b_dev;
1776 chan = 0;
1777 status = SYS$ASSIGN (&devicedsc, &chan, 0, 0, 0);
1778 if ((status & 1) != 1)
1779 return 1;
1781 /* Initialize the FIB and fill in the directory id field. */
1782 memset (&fib, 0, sizeof (fib));
1783 fib.fib$w_did[0] = nam.nam$w_did[0];
1784 fib.fib$w_did[1] = nam.nam$w_did[1];
1785 fib.fib$w_did[2] = nam.nam$w_did[2];
1786 fib.fib$l_acctl = 0;
1787 fib.fib$l_wcc = 0;
1788 strcpy (file.string, (strrchr (result.string, ']') + 1));
1789 filedsc.dsc$w_length = strlen (file.string);
1790 result.string[result.length = 0] = 0;
1792 /* Open and close the file to fill in the attributes. */
1793 status
1794 = SYS$QIOW (0, chan, IO$_ACCESS|IO$M_ACCESS, &iosb, 0, 0,
1795 &fibdsc, &filedsc, &result.length, &resultdsc, &atrlst, 0);
1796 if ((status & 1) != 1)
1797 return 1;
1798 if ((iosb.status & 1) != 1)
1799 return 1;
1801 result.string[result.length] = 0;
1802 status = SYS$QIOW (0, chan, IO$_DEACCESS, &iosb, 0, 0, &fibdsc, 0, 0, 0,
1803 &atrlst, 0);
1804 if ((status & 1) != 1)
1805 return 1;
1806 if ((iosb.status & 1) != 1)
1807 return 1;
1809 /* Deassign the channel and exit. */
1810 status = SYS$DASSGN (chan);
1811 if ((status & 1) != 1)
1812 return 1;
1814 if (cdt) *cdt = create;
1815 if (siz) *siz = (512 * 65536 * recattr.fat$w_efblkh) +
1816 (512 * (recattr.fat$w_efblkl - 1)) +
1817 recattr.fat$w_ffbyte;
1818 if (rfo) *rfo = recattr.fat$v_rtype;
1819 if (ver) *ver = strtol (strrchr (ascnamebuff, ';')+1, 0, 10);
1821 return 0;
1822 #else
1823 struct stat buff;
1825 if ((stat (filename, &buff)) != 0)
1826 return 1;
1828 if (cdt)
1829 *cdt = (long long) (buff.st_mtime * VMS_GRANULARITY_FACTOR)
1830 + VMS_EPOCH_OFFSET;
1832 if (siz)
1833 *siz = buff.st_size;
1835 if (rfo)
1836 *rfo = 2; /* Stream LF format */
1838 if (ver)
1839 *ver = 1;
1841 return 0;
1842 #endif
1844 #endif